深入浅出PytorchTask02打卡

神经网络进行学习的机制:
image
首先数据在进行预处理(预处理的目的是满足网络的需求)后会输入到网络中来,之后需要进行模型的设计,包括模型有多少层,每层有多少个节点,每个节点之间连接方式是怎样的等等;在之后,需要对它们的损失函数和优化方案进行设计,以保证模型能够学到有效的内容,并向着合理的方向进行迭代,之后对数据进行前向传播,输入到模型中,得到输出层的结果,计算损失结果,再把损失函数反向输入到模型中用来更新参数。以上就是神经网络进行机器学习的机制。

深度学习种运用的模型一般也是神经网络,不过深度更深,模型更大。

而深度学习有什么特性呢?
image

  1. 数据量很大,很难一次性的全部加载到模型中去
  2. 深度学习的模型比较复杂,层与层之间的搭建关系也不同
  3. 深度学习的发展带动了损失函数和优化器的发展,当然非深度学习也有很多损失函数和优化器
  4. GPU可用于并行计算,当然也不是必需的,CPU也是可以的

本次课程的学习模块如下:
image

  1. 基本配置
    就是需要导入必要的package,比如os, numpy, pandas等等

Numpy是一个可以操作矩阵计算的库;pandas是一个可以实现表格计算的库

还需要配置训练过程种的超参数,以及配置训练时实用CPU还是GPU等。

首先,导入package:
image

然后配置训练环境和超参数,如下,因为我的笔记本没有GPU所以环境就配置的CPU

这样我们就已经配置好了训练所需要的环境和包、超参数
接下来讲述数据的读入和加载:
第一种方式是下载pytorch的内置数据集
另一种方式是从网站下载的,以CSV格式存储的数据,处理成预期的数据

在第二种读入数据时,需要对数据进行必要的变换,比如说需要将图片变为统一的大小,以便后续能够输入网络训练;需要将数据格式转为Tensor类,等等。操作如下:

将FashionMNIST下载到本地,并放入相应的位置进行读取:

其实这里的train_df和test_df都是表格,如下图:
image
其中label指的时一个个的类别,后面的pixel就是一个个图的像素,这样就像图片存成了一个个向量,而怎么把向量变成我们需要的图片形式呢?
这里就需要构建dataset了。
里面的getitem是非常重要的。
Image = self.images[idx].reshape(28,28,1)
是将第i列的数据重新组合成28*28的图像,1是构建的通道数。
如果有transform,就直接transform(image),如果没有,就需要对图像像素进行归一化,并转成tensor格式。

在构建训练和测试数据集之后,还需要定义DataLoader类,它的作用是在训练和测试时加载数据。


Batch_size是指一次读入数据的size,shuffle是打乱输入的数据,nums_works是读入的线程,这个数值越大,读的也就越快,drop_last是是否丢掉最后一个数据(因为一般在train data中最后一个数据是加不满的,所以要丢掉)

构建好data_set和data_loader之后,就可以进行初步的可视化。
image
Iter相当于for 循环,但是只循环一次,而next是让它再循环一次。
得到结果:
image
image
这样子也证明了我们的数据读入是正确的。

然后就是学习模型的建立,包括:
image
对于模型的设计如下:

__init__中进行初始化,初始化需要做的事情就是层定义,层定义我们做的事情是slef.conv就是卷积的操作,然后让它等于nn.sequential,序贯模型,就是任何模型进入这个conv都需要按照已经列好的顺序进行,首先进行conv2d,2维卷积,然后是ReLu,激活函数,然后是maxpool2d,池化……,完成了卷积以后在进入一个全连接层Linear,第一个(6444,512)指的是从6444个大小的神经元变成512的大小,下面的(512,10)也是同理,注意这个10并不同于中间值512,并不是随便设的,是因为我们这个训练数据有10类,我们才设的10。
设置完了层之后,需要定义顺序的排列,也就是forward函数。

然后是设置损失函数,


注意:
本次代码用的是torch.nn模块自带的CrossEntropy损失。
PyTorch会自动把整数型的label转为one-hot型,用于计算CE loss。
这里需要确保label是从0开始的,同时模型不加softmax层(使用logits计算),这也说明了PyTorch训练中各个部分不是独立的,需要通盘考虑。

当然,如果想强化某一类别的权重,也可以用上图中下面那一行代码进行设置。

接下来是定义优化器:
image
这里直接使用了Adam优化器

优化器进行定义的时候,需要定义lr,即它的步长

接下来就到了训练阶段:
image

首先将loss初始化为0,然后for循环读取data和label,因为模型在CPU上,所以数据,data,label也要放在CPU上去。
这里进行optimizer.zero_grad的原因是,为了让梯度不要进行累加,而是要从0开始。
Model(data)是进行前向传播。
然后用定义的损失函数criterion进行损失值的计算。
Backward是反向传播回去
Optimizer.step是用优化器去更新权重
Train_loss += loss.item()*data.size(0) 就是训练损失的叠加

接下来是验证函数:

对于验证和测试有什么不同呢?
首先因为二者的模式是不同的,所以需要加一个with torch.no_grad,让test不计算梯度。
而且需要计算acc,也就是计算的准确率

接下来就是开始训练了:
image

最后可以看到结果如下:


可以看到training loss仍然在下降,而validation loss也在下降,并没有达到training loss下降而validation loss 增加的这样一个趋势,所以说明我们的训练还没有达到最优解。

浙ICP备19012682号