网站首页 > 技术文章 正文
pytorch——人工智能的开源深度学习框架
pytorch深度学习框架之tensor张量
计算机视觉的基石——读懂 CNN卷积神经网络
本期文章的主要内容:
1、CNN卷积神经网络
2、torchvision.datasets
3、MINIST数据集
4、神经网络的训练
5、pytorch训练模型的保存
PyTorch 提供了许多预加载的数据集(例如 FashionMNIST),所有数据集都是torch.utils.data.Dataset 的子类,它们具有__getitem__和__len__实现的方法。因此,它们都可以传递给torch.utils.data.DataLoader 也可以使用torch.multiprocessing并行加载多个样本的数据 。例如:
以下是如何从 TorchVision加载Fashion-MNIST数据集的示例。Fashion-MNIST由 60,000 个训练示例和 10,000 个测试示例组成。每个示例都包含一个 28×28 灰度图像和来自 10 个类别之一的相关标签。
MINIST数据
MINIST的数据分为2个部分:55000份训练数据(mnist.train)和10000份测试数据(mnist.test)。这个划分有重要的象征意义,他展示了在机器学习中如何使用数据。在训练的过程中,我们必须单独保留一份没有用于机器训练的数据作为验证的数据,这才能确保训练的结果的可行性。
前面已经提到,每一份MINIST数据都由图片以及标签组成。我们将图片命名为“x”,将标记数字的标签命名为“y”。训练数据集和测试数据集都是同样的结构,例如:训练的图片名为 mnist.train.images 而训练的标签名为 mnist.train.labels。
每一个图片均为28×28像素,我们可以将其理解为一个二维数组的结构:
我们使用以下参数加载MNIST 数据集:
- root ( string ) – 数据集所在MNIST/processed/training.pt 和 MNIST/processed/test.pt存在的根目录。
- train ( bool , optional ) – 如果为 True,则从 中创建数据集training.pt,否则从test.pt.
- download ( bool , optional ) – 如果为 true,则从 Internet 下载数据集并将其放在根目录中。如果数据集已经下载,则不会再次下载。
- transform ( callable , optional ) – 一个函数/转换,它接收一个 PIL 图像并返回一个转换后的版本。例如,transforms.RandomCrop
- target_transform ( callable , optional ) – 一个接收目标并对其进行转换的函数/转换。
torchvision.datasets.MNIST( root: str ,
train: bool = True ,
transform: Optional[Callable] = None ,
target_transform: Optional[Callable] = None ,
download: bool = False )
所有数据集都有几乎相似的 API。它们都有两个共同的参数: transform和 target_transform,本期文章,我们基于MNIST数据集来写一个简单的神经网络,并进行神经网络的训练
下载数据集 torchvision.datasets
import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision # 数据库模块
import matplotlib.pyplot as plt
# torch.manual_seed(1) # reproducible
EPOCH = 20 # 训练整批数据次数,训练次数越多,精度越高
BATCH_SIZE = 50 # 每次训练的数据集个数
LR = 0.001 # 学习效率
DOWNLOAD_MNIST = False # 如果你已经下载好了mnist数据就设置 False
# Mnist 手写数字 训练集
train_data = torchvision.datasets.MNIST(
root='./data/', # 保存或者提取位置
train=True, # this is training data
transform=torchvision.transforms.ToTensor(), # 转换 PIL.Image or numpy.ndarray 成tensor
# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间
download=DOWNLOAD_MNIST, # 没下载就会自动下载数据集,当等于true
)
# Mnist 手写数字 测试集
test_data = torchvision.datasets.MNIST(
root='./mnist/',
train=False, # this is training data
)
通过以上代码,我们便在工程目录下的data文件夹下下载了MNIST的全部数据集,torchvision.datasets是pytorch为了方便研发者,进行了绝大部分的数据库的集合,通过torchvision.datasets可以很方便地下载使用其包含的数据集,其torchvision.datasets下面主要包含如下数据集,其他方面的数据集可以自行下载尝试
torchvision.datasets
Caltech
CelebA
CIFAR
Cityscapes
COCO
EMNIST
FakeData
Fashion-MNIST
Flickr
HMDB51
ImageNet
Kinetics-400
KITTI
KMNIST
LSUN
MNIST
Omniglot
PhotoTour
Places365
QMNIST
SBD
SBU
SEMEION
STL10
SVHN
UCF101
USPS
VOC
WIDERFace
CNN卷积神经网络搭建
# 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
# 每一步 loader 释放50个数据用来学习
# 为了演示, 我们测试时提取2000个数据先
# shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_x = torch.unsqueeze(test_data.data, dim=1).type(torch.FloatTensor)[:2000] / 255.
test_y = test_data.targets[:2000]
#test_x = test_x.cuda() # 若有cuda环境,取消注释
#test_y = test_y.cuda() # 若有cuda环境,取消注释
# 定义神经网络
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Sequential( # input shape (1, 28, 28)
nn.Conv2d(
in_channels=1, # 输入通道数
out_channels=16, # 输出通道数
kernel_size=5, # 卷积核大小
stride=1, #卷积部数
padding=2, # 如果想要 con2d 出来的图片长宽没有变化,
# padding=(kernel_size-1)/2 当 stride=1
), # output shape (16, 28, 28)
nn.ReLU(), # activation
nn.MaxPool2d(kernel_size=2), # 在 2x2 空间里向下采样, output shape (16, 14, 14)
)
self.conv2 = nn.Sequential( # input shape (16, 14, 14)
nn.Conv2d(16, 32, 5, 1, 2), # output shape (32, 14, 14)
nn.ReLU(), # activation
nn.MaxPool2d(2), # output shape (32, 7, 7)
)
self.out = nn.Linear(32 * 7 * 7, 10) # 全连接层,0-9一共10个类
# 前向反馈
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1) # 展平多维的卷积图成 (batch_size, 32 * 7 * 7)
output = self.out(x)
return output
我们使用Data.DataLoader来加载我们下载好的MNIST数据集,并分开训练集与测试集
接下来我们建立一个CNN卷积神经网络:
第一层,我们输入minist的数据集,minist的数据图片是一维 28*28的图片,所以第一层的输入(1,28,28),高度为1,设置输出16通道,使用5*5的卷积核对图片进行卷积运算,每步移动一格,为了避免图片尺寸变化,设置pading为2,则经过第一层卷积就输出(16,28,28)数据格式
再经过relu与maxpooling (使用2*2卷积核)数据输出(16,14,14)
第二层卷积层是简化写法nn.Conv2d(16, 32, 5, 1, 2)的第一个参数为输入通道数in_channels=16,其第二个参数是输出通道数out_channels=32, # n_filters(输出通道数),第三个参数为卷积核大小,第四个参数为卷积步数,最后一个为pading,此参数为保证输入输出图片的尺寸大小一致
self.conv2 = nn.Sequential( # input shape (16, 14, 14)
nn.Conv2d(16, 32, 5, 1, 2), # output shape (32, 14, 14)
nn.ReLU(), # activation
nn.MaxPool2d(2), # output shape (32, 7, 7)
)
全连接层,最后使用nn.linear()全连接层进行数据的全连接数据结构(32*7*7,10)以上便是整个卷积神经网络的结构,
大致为:input-卷积-Relu-pooling-卷积-Relu-pooling-linear-output
卷积神经网络建完后,使用forward()前向传播神经网络进行输入图片的训练
通过以上的神经网络的搭建,我们便建立一个神经网络,此神经网络类似MINIST的双隐藏层结构
神经网络的训练
神经网络搭建完成后,我们便可以进行神经网络的训练
cnn = CNN() # 创建CNN
# cnn = cnn.cuda() # 若有cuda环境,取消注释
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)
loss_func = nn.CrossEntropyLoss()
for epoch in range(EPOCH):
for step, (b_x, b_y) in enumerate(train_loader): # 每一步 loader 释放50个数据用来学习
#b_x = b_x.cuda() # 若有cuda环境,取消注释
#b_y = b_y.cuda() # 若有cuda环境,取消注释
output = cnn(b_x) # 输入一张图片进行神经网络训练
loss = loss_func(output, b_y) # 计算神经网络的预测值与实际的误差
optimizer.zero_grad() #将所有优化的torch.Tensors的梯度设置为零
loss.backward() # 反向传播的梯度计算
optimizer.step() # 执行单个优化步骤
if step % 50 == 0: # 我们每50步来查看一下神经网络训练的结果
test_output = cnn(test_x)
pred_y = torch.max(test_output, 1)[1].data.squeeze()
# 若有cuda环境,使用84行,注释82行
# pred_y = torch.max(test_output, 1)[1].cuda().data.squeeze()
accuracy = float((pred_y == test_y).sum()) / float(test_y.size(0))
print('Epoch: ', epoch, '| train loss: %.4f' % loss.data,
'| test accuracy: %.2f' % accuracy)
首先我们使用CNN()函数进行神经网络的初始化,并建立一个神经网络模型,并利用optim.Adam优化函数建立一个optimizer神经网络优化器,torch.optim是一个实现各种优化算法的包。大部分常用的方法都已经支持,接口也足够通用,以后也可以轻松集成更复杂的方法。
常用的优化器主要有:
Optimizer
GradientDescentOptimizer
AdadeltaOptimizer
AdagradOptimizer
AdagradDAOptimizer
MomentumOptimizer
AdamOptimizer
FtrlOptimizer
ProximalGradientDescentOptimizer
ProximalAdagradOptimizer
RMSPropOptimizer
然后建立一个损失函数,我们神经网络的目的就是使用损失函数使神经网络的训练loss越来越小。然后进行神经网络的训练,我们每50步打印一下神经网络的训练效果
测试神经网络的结果与保存神经网络
# test 神经网络
test_output = cnn(test_x[:10])
pred_y = torch.max(test_output, 1)[1].data.squeeze()
# 若有cuda环境,使用92行,注释90行
#pred_y = torch.max(test_output, 1)[1].cuda().data.squeeze()
print(pred_y, 'prediction number')
print(test_y[:10], 'real number')
# save CNN
# 仅保存CNN参数,速度较快
torch.save(cnn.state_dict(), './model/CNN_NO1.pk')
# 保存CNN整个结构
#torch.save(cnn(), './model/CNN.pkl')
我们提取前10个MNIST的数据,并进行神经网络的预测,此时我们可以打印出来神经网络的预测值与实际值,最后并保存神经网络的模型,此模型我们可以直接使用来进行手写数字的识别
从训练结果可以看出,只训练了24*50个循环,神经网络的精度已经达到0.97
Epoch: 0 | train loss: 2.3018 | test accuracy: 0.18
Epoch: 0 | train loss: 0.5784 | test accuracy: 0.82
Epoch: 0 | train loss: 0.3423 | test accuracy: 0.89
Epoch: 0 | train loss: 0.1502 | test accuracy: 0.92
Epoch: 0 | train loss: 0.2063 | test accuracy: 0.93
Epoch: 0 | train loss: 0.1348 | test accuracy: 0.92
Epoch: 0 | train loss: 0.1209 | test accuracy: 0.95
Epoch: 0 | train loss: 0.0577 | test accuracy: 0.95
Epoch: 0 | train loss: 0.1297 | test accuracy: 0.95
Epoch: 0 | train loss: 0.0237 | test accuracy: 0.96
Epoch: 0 | train loss: 0.1275 | test accuracy: 0.97
Epoch: 0 | train loss: 0.1364 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0728 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0752 | test accuracy: 0.98
Epoch: 0 | train loss: 0.1444 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0597 | test accuracy: 0.97
Epoch: 0 | train loss: 0.1162 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0260 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0830 | test accuracy: 0.97
Epoch: 0 | train loss: 0.1918 | test accuracy: 0.97
Epoch: 0 | train loss: 0.2217 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0767 | test accuracy: 0.97
Epoch: 0 | train loss: 0.2015 | test accuracy: 0.97
Epoch: 0 | train loss: 0.1214 | test accuracy: 0.97
tensor([7, 2, 1, 0, 4, 1, 4, 9, 5, 9]) prediction number
tensor([7, 2, 1, 0, 4, 1, 4, 9, 5, 9]) real number
最后打印出来的前10个预测模型,完全一致
ok,本期我们分享了神经网络的搭建,并利用MNIST的数据集进行了神经网络的训练,并进行了神经网络的预测,下期文章我们利用训练好的模型进行神经网络的识别。
猜你喜欢
- 2024-10-12 神经网络训练模型 神经网络训练好的模型怎么用
- 2024-10-12 人工智能Keras的第一个图像分类器(CNN卷积神经网络的图片识别)
- 2024-10-12 使用Keras进行深度学习(二):CNN讲解及实践
- 2024-10-12 pytorch利用CNN卷积神经网络来识别手写数字
- 2024-10-12 Tensorflow入门教程-第五课:TensorFlow中的卷积神经网络(CNN)
- 2024-10-12 7 大类卷积神经网络(CNN)创新综述
- 2024-10-12 卷积神经网络(CNN)简要教程 卷积神经网络代码入门
- 2024-10-12 测试开发 | 卷积神经网络(CNN):图像识别的骨干
- 2024-10-12 C++ 中的卷积神经网络 (CNN) c++实现卷积神经网络
- 2024-10-12 MNIST数字识别——CNN篇 数字识别网络
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)