写在前面,本文主要帮助自己抠细节,把学习过程中不懂的记录下来。
本文参考了官网以及Pytorch打怪路(一)pytorch进行CIFAR-10分类(1)CIFAR-10数据加载和处理_朝花&夕拾-CSDN博客
Pytorch打怪路(一)pytorch进行CIFAR-10分类(2)定义卷积神经网络_朝花&夕拾-CSDN博客
侵删,有错欢迎指正
(1)数据加载和处理
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize(mean = (0.5, 0.5, 0.5), std = (0.5, 0.5, 0.5))])
●ToTensor是指把PIL.Image(RGB) 或者numpy.ndarray(H x W x C) 从0到255的值映射到0到1的范围内,并转化成Tensor格式。
这是归一化的过程,目的是消除特征的差异。
●Normalize(mean,std)是实现标准化,公式是channel=(channel-mean)/std,让整体数据由一般的正态分布变化到N(0,1)
标准化后,实现了数据中心化,这符合数据分布规律,能增加模型的泛化能力。
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
download=True, transform=transform)
●cifar10的数据已经被封装在torchvision.datasets中了,这里就是把它下载下来,如果下载训练集train = True,下载测试集就设置为False,transform对数据进行变换。
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
shuffle=True, num_workers=2)
● trainset大数据量,需要使用 shuffle, 分割成mini-batch 等操作的时候,可以用到DataLoader。●pytorch中dataloader的大小将根据batch_size的大小自动调整。如果训练数据集有1000个样本,并且batch_size的大小为10,则dataloader的长度就是100。shuffle表示是否要把数据打乱,num_workers表示可以有多少个并行的进程(ps:我是在windows用cpu跑的,这个值只能设为0)
(2)模型建立
首先先了解一下卷积的基础知识:
一般CNN的架构是这样的:input一张图像,先通过Convolution的layer(卷积层),接下来做Max pooling(池化)(池化就是二次抽样,相当于把image分块然后提取每一块的最大值,可以让image缩小),然后再做Convolution,再做Max pooling...
这个process可以反复进行多次,次数事先决定。最后把数据进行flatten(展成一列),把flatten output丢到一般的全连接层里去,最终得到影像识别结果。
● nn.Module是所有神经网络的基类,我们自己定义任何神经网络, 都要继承nn.Module
● Conv2d(in_channels, out_channels, kernel_size, stride=1,padding=0, dilation=1, groups=1,bias=True, padding_mode=‘zeros’)
输入是in_channels通道的图像,输出是out_channels通道,也就是out_channels个卷积核,卷积核是kernel_size*kernel_size。
(ps:Conv1d和Conv2d的区别:
conv1的输入是三维的,[batch, channels, w],卷积核是一维的,卷积操作沿着第二维在第三维上进行。
conv2的输入是四维的,常用于图像卷积,[batch, channels, H, W],卷积核是矩形,在三四维上进行。
图像格式是这样的,4个batch,3个channels,长和宽都是32像素
所以表示把输入的3个channel的输出为6个channels,而卷积层采用的都是5x5大小的卷积核
记住,图像卷积conv2d。)
● torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
一般就设置kernel_size和stride(步长)
● 全连接层:
卷积取的是局部特征,全连接就是把以前的局部特征重新通过权值矩阵组装成完整的图。
因为用到了所有的局部特征,所以叫全连接。
● nn.Linear:
● x = x.view()
可以将四维张量转化为二维张量,只有这样才能作为全连接层的输入