深度学习之PyTorch实战(2)——神经网络模型搭建和参数优化

上一篇博客先搭建了基础环境,并熟悉了基础知识,本节基于此,再进行深一步的学习。

接下来看看如何基于PyTorch深度学习框架用简单快捷的方式搭建出复杂的神经网络模型,同时让模型参数的优化方法趋于高效。如同使用PyTorch中的自动梯度方法一样,在搭建复杂的神经网络模型的时候,我们也可以使用PyTorch中已定义的类和方法,这些类和方法覆盖了神经网络中的线性变换、激活函数、卷积层、全连接层、池化层等常用神经网络结构的实现。在完成模型的搭建之后,我们还可以使用PyTorch提供的类型丰富的优化函数来完成对模型参数的优化,除此之外,还有很多防止模型在模型训练过程中发生过拟合的类。

批量,即Batch,是深度学习中的一个重要概念。批量通常是指两个不同的概念——如果对应的是模型训练方法,那么批量指的是将所有数据处理完以后一次性更新权重或者参数的估计,如果对应的是模型训练中的数据,那么对应的是一次输入供模型计算用的数据量。这两个概念有着紧密的关系。

(1)初始化参数

(2)重复以下步骤:处理所有数据,更新参数

(2)重复以下步骤:处理一个或者一组数据点,更新参数

我们看到,这里的主要区别是批量算法一次处理所有的数据;而在递增算法中,每处理一个或者数个观测值就要更新一次参数。这里“处理”和“更新”二词根据算法的不同有不同的含义。在后向传播算法中,“处理”对应的具体操作就是在计算损失函数的梯度变化曲线。如果是批量算法,则计算平均或者总的损失函数的梯度变化曲线;而如果是递增算法,则计算损失函数仅在对应于该观测值或者数个观测值时的梯度变化曲线。“更新”则是从已有的参数值中减去梯度变化率和学习速率的乘积。

在深度学习中,另外两个常见的概念是在线学习(OnlineLearning)和离线学习(OfflineLearning)。在离线学习中,所有的数据都可以被反复获取,比如上面的批量学习就是离线学习的一种。而在在线学习中,每个观测值在处理以后会被遗弃,同时参数得到更新。在线学习永远是递增算法的一种,但是递增算法却既可以离线学习也可以在线学习。

离线学习有如下几个优点。

在线学习无法实现上述功能,因为数据并没有被存储,不能反复获取,因此对于任何固定的参数集,无法在训练集上计算损失函数,也无法在验证集上计算误差。这就造成在线算法一般来说比离线算法更加复杂和不稳定。但是离线递增算法并没有在线算法的问题,因此有必要理解在线学习和递增算法的区别。

在机器学习和深度学习中,常常会出现对数据标准化这个动作。那么什么是标准化数据呢?其实这里是用“标准化”这个词代替了几个类似的但又不同的动作。下面详细讲解三个常见的“标准化”数据处理动作。

那么在深度学习中是否应该进行以上任何一种数据处理呢?答案是依照情况而定。一般来讲,如果激活函数的值域在0到1之间,那么规范化数据到[0,1]的值域区间是比较好的。另外一个考虑是规范化数据能使计算过程更加稳定,特别是在数据值域范围区别较大的时候,规范化数据总是相对稳健的一个选择。而且很多算法的初始值设定也是针对使规范化以后的数据更有效来设计的。

下面使用PyTorch的torch.nn包来简化我们之前的代码,开始部分的代码变化不大,如下所示:

和之前一样,这里首先导入必要的包、类并定义了4个变量,不过这里仅定义了输入和输出的变量,之前定义神经网络模型中的权重参数的代码被删减了,这和我们之后在代码中使用的torch.nn包中的类有关,因为这个类能够帮助我们自动生成和初始化对应维度的权重参数。

torch.nn.Sequential括号内的内容就是我们搭建的神经网络模型的具体结构,这里首先通过torch.nn.Linear(input_data,hidden_layer)完成从输入层到隐藏层的线性变换,然后经过激活函数及torch.nn.Linear(hidden_layer,output_data)完成从隐藏层到输出层的线性变换。下面分别对在以上代码中使用的torch.nn.Sequential、torch.nn.Linear和torch.nn.RelU这三个类进行详细介绍

首先,使用直接嵌套搭建的模型代码如下:

这里对模型的结构进行打印输出,结果如下:

使用orderdict有序字典进行传入来搭建的模型代码如下:

这里对该模型的结构进行打印输出,结果如下:

通过对这两种方式进行比较,我们会发现,对模块使用自定义的名称可让我们更便捷地找到模型中相应的模块并进行操作。

torch.nn.Linear类用于定义模型的线性层,即完成前面提到的不同的层之间的线性变换。torch.nn.Linear类接收的参数有三个,分别是输入特征数、输出特征数和是否使用偏置,设置是否使用偏置的参数是一个布尔值,默认为True,即使用偏置。在实际使用的过程中,我们只需将输入的特征数和输出的特征数传递给torch.nn.Linear类,就会自动生成对应维度的权重参数和偏置,对于生成的权重参数和偏置,我们的模型默认使用了一种比之前的简单随机方式更好的参数初始化方法。根据我们搭建模型的输入、输出和层次结构需求,它的输入是在一个批次中包含100个特征数为1000的数据,最后得到100个特征数为10的输出数据,中间需要经过两次线性变换,所以要使用两个线性层,两个线性层的代码分别是torch.nn.Linear(input_data,hidden_layer)和torch.nn.Linear(hidden_layer,output_data)。可看到,其代替了之前使用矩阵乘法方式的实现,代码更精炼、简洁。

torch.nn.ReLU类属于非线性激活分类,在定义时默认不需要传入参数。当然,在torch.nn包中还有许多非线性激活函数类可供选择,比如之前讲到的PReLU、LeakyReLU、Tanh、Sigmoid、Softmax等。

在掌握torch.nn.Sequential、torch.nn.Linear和torch.nn.RelU的使用方法后,快速搭建更复杂的多层神经网络模型变为可能,而且在整个模型的搭建过程中不需要对在模型中使用到的权重参数和偏置进行任何定义和初始化说明,因为参数已经完成了自动生成。

前两句代码和之前的代码没有多大区别,只是单纯地增加了学习速率和训练次数,学习速率现在是0.0001,训练次数增加到了10000次,这样做是为了让最终得到的结果更好。不过计算损失函数的代码发生了改变,现在使用的是在torch.nn包中已经定义好的均方误差函数类torch.nn.MSELoss来计算损失值,而之前的代码是根据损失函数的计算公式来编写的。

下面简单介绍在torch.nn包中常用的损失函数的具体用法,如下所述:

torch.nn.MSELoss类使用均方误差函数对损失值进行计算,在定义类的对象时不用传入任何参数,但在使用实例时需要输入两个维度一样的参数方可进行计算。示例如下

以上代码首先通过随机方式生成了两个维度都是(100,100)的参数,然后使用均方误差函数来计算两组参数的损失值,打印输出的结果如下:

torch.nn.L1Loss类使用平均绝对误差函数对损失值进行计算,同样,在定义类的对象时不用传入任何参数,但在使用实例时需要输入两个维度一样的参数进行计算。示例如下:

以上代码也是通过随机方式生成了两个维度都是(100,100)的参数,然后使用平均绝对误差函数来计算两组参数的损失值,打印输出的结果如下:

torch.nn.CrossEntropyLoss类用于计算交叉熵,在定义类的对象时不用传入任何参数,在使用实例时需要输入两个满足交叉熵的计算条件的参数,代码如下:

这里生成的第1组参数是一个随机参数,维度为(3,5);第2组参数是3个范围为0~4的随机数字。计算这两组参数的损失值,打印输出的结果如下

在学会使用PyTorch中的优化函数之后,我们就可以对自己建立的神经网络模型进行训练并对参数进行优化了,代码如下:

以上代码中的绝大部分和之前训练和优化部分的代码是一样的,但是参数梯度更新的方式发生了改变。因为使用了不同的模型搭建方法,所以访问模型中的全部参数是通过对“models.parameters()”进行遍历完成的,然后才对每个遍历的参数进行梯度更新。其打印输入结果的方式是每完成1000次训练,就打印输出当前的loss值.

从结果可以看出,参数的优化效果比较理想,loss值被控制在相对较小的范围之内,这和我们增强了训练次数有很大关系。

到目前为止,代码中的神经网络权重的参数优化和更新还没有实现自动化,并且目前使用的优化方法都有固定的学习速率,所以优化函数相对简单,如果我们自己实现一些高级的参数优化算法,则优化函数部分的代码会变得较为复杂。在PyTorch的torch.optim包中提供了非常多的可实现参数自动优化的类,比如SGD、AdaGrad、RMSProp、Adam等,这些类都可以被直接调用,使用起来也非常方便。

我们使用自动化的优化函数实现方法对之前的代码进行替换,新的代码如下:

这里使用了torch.optim包中的torch.optim.Adam类作为我们的模型参数的优化函数,在torch.optim.Adam类中输入的是被优化的参数和学习速率的初始值,如果没有输入学习速率的初始值,那么默认使用0.001这个值。因为我们需要优化的是模型中的全部参数,所以传递给torch.optim.Adam类的参数是models.parameters。另外,Adam优化函数还有一个强大的功能,就是可以对梯度更新使用到的学习速率进行自适应调节,所以最后得到的结果自然会比之前的代码更理想。

进行模型训练的代码如下:

在以上代码中有几处代码和之前的训练代码不同,这是因为我们引入了优化算法,所以通过直接调用optimzer.zero_grad来完成对模型参数梯度的归零;并且在以上代码中增加了optimzer.step,它的主要功能是使用计算得到的梯度值对各个节点的参数进行梯度更新。

这里只进行20次训练并打印每轮训练的loss值,结果如下:

在看到这个结果后我们会很惊讶,因为使用torch.optim.Adam类进行参数优化后仅仅进行了20次训练,得到的loss值就已经远远低于之前进行10000次优化训练的结果。所以,如果对torch.optim中的优化算法类使用得当,就更能帮助我们优化好模型中的参数。

在前面讲到过,在torch.transforms中提供了丰富的类对载入的数据进行变换,现在让我们看看如何进行变换。我们知道,在计算机视觉中处理的数据集有很大一部分是图片类型的,而在PyTorch中实际进行计算的是Tensor数据类型的变量,所以我们首先需要解决的是数据类型转换的问题,如果获取的数据是格式或者大小不一的图片,则还需要进行归一化和大小缩放等操作,庆幸的是,这些方法在torch.transforms中都能找到。在torch.transforms中有大量的数据变换类,其中有很大一部分可以用于实现数据增强(DataArgumentation)。若在我们需要解决的问题上能够参与到模型训练中的图片数据非常有限,则这时就要通过对有限的图片数据进行各种变换,来生成新的训练集了,这些变换可以是缩小或者放大图片的大小、对图片进行水平或者垂直翻转等,都是数据增强的方法。不过在手写数字识别的问题上可以不使用数据增强的方法,因为可用于模型训练的数据已经足够了。对数据进行载入及有相应变化的代码如下:

我们可以将上面代码中的torchvision.transforms.Compose类看作是一种容器,它能够同时对多种数据变换进行组合。传入的参数是一个列表,列表中的元素就是对载入的数据进行的各种变换操作。

在以上的代码中,在torchvision.transforms.Compose类中只是用了一个类型的转换变化transfroms.ToTensor和一个数据标准化变换transforms.Normalize。这里使用的是标准化变换也叫标准差变换法,这种方法需要使用原始数据的均值(Mean)和标准差(StandardDeviation)来进行数据的标准化,在经过标准化变换之后,数据全部符合均值为0,标准差为1的标准正态分布,计算公式入选:

不过这里我们偷了一个懒,均值和标准差的值并非来自原始数据的,而是自行定义了一个,不过仍然能够达到我们的目的。

下面看看在torchvision.transforms中常用的数据变换操作。

用于对载入的图片数据按我们需求的大小进行缩放。传递给这个类的参数可以是一个整型数据,也可以是一个类似于(h,w)的序列,其中,h代表高度,w代表宽度,但是如果使用的是一个整型数据,那么表示缩放的宽度和高度都是这个整型数据的值。

用于对载入的图片数据按我们需求的大小进行缩放,用法和torchvision.transforms.Resize类似。

用于对载入的图片以图片中心为参考点,按我们需要的大小进行裁剪。传递给这个类的参数可以是一个整型数据,也可以是一个类似于(h,w)的序列。

用于对载入的图片按我们需要的大小进行随机裁剪。传递给这个类的参数可以是一个整型数据,也可以是一个类似于(h,w)的序列。

用于对载入的图片按随机概率进行水平翻转。我们可以通过传递给这个类的参数自定义随机概率,如果没有定义,则使用默认的概率值0.5。

用于对载入的图片按随机概率进行垂直翻转。我们可以通过传递给这个类的参数自定义随机概率,如果没有定义,则使用默认的概率值0.5。

用于对载入的图片数据进行类型转换,将之前构成PIL图片的数据转换成Tensor数据类型的变量,让PyTorch能够对其进行计算和处理。

用于将Tensor变量的数据转换成PIL图片数据,主要是为了方便图片内容的显示

神经网络的典型处理如下所示:

weight=weight-learning_rate*gradient

首先我们看一个卷积神经网络模型搭建的代码:

上面我们选择搭建了一个在结构层次上有所简化的卷积神经网络模型,在结构上使用了两个卷积层:一个最大池化层和两个全连接层,这里对具体的使用方法进行补充说明。

用于搭建卷积神经网络的卷积层,主要的输入参数有输入通道数、输出通道数、卷积核大小、卷积核移动步长和Paddingde值。其中,输入通道数的数据类型是整型,用于确定输入数据的层数;输出通道数的数据类型也是整型,用于确定输出数据的层数;卷积核大小的数据类型是整型,用于确定卷积核的大小;卷积核移动步长的数据类型是整型,用于确定卷积核每次滑动的步长;Paddingde的数据类型是整型,值为0时表示不进行边界像素的填充,如果值大于0,那么增加数字所对应的边界像素层数。

用于实现卷积神经网络中的最大池化层,主要的输入参数是池化窗口大小、池化窗口移动步长和Padding的值。同样,池化窗口大小的数据类型是整型,用于确定池化窗口的大小。池化窗口步长的数据类型也是整型,用于确定池化窗口每次移动的步长。Padding的值和在torch.nn.Conv2d中定义的Paddingde值的用法和意义是一样的。

torch.nn.Dropout类用于防止卷积神经网络在训练的过程中发生过拟合,其工作原理简单来说就是在模型训练的过程中,以一定的随机概率将卷积神经网络模型的部分参数归零,以达到减少相邻两层神经连接的目的。下图显示了Dropout方法的效果。

在上图中的打叉的神经节点就是被随机抽中并丢弃的神经连接,正是因为选取的方式的随机性,所以在模型的每轮训练中选择丢弃的神经连接也是不同的,这样做是为了让我们最后训练出来的模型对各部分的权重参数不产生过度依赖,从而防止过拟合,对于torch.nn.Dropout类,我们可以对随机概率值的大小进行设置,如果不足任何设置,我们就使用默认的概率值0.5。

最后说一下代码中前向传播forward函数中的内容,首先经过self.conv1进行卷积处理,然后进行x.view(-1,14*14*128),对参数实现扁平化,因为之后紧接着的就是全连接层,所以如果不进行扁平化,则全连接层的实际输出的参数维度和其定义输入的维度将不匹配,程序将会报错,最后通过self.dense定义的全连接层进行最后的分类。

从上面代码可以看到,不论是在定义网络结构还是定义网络层的操作(Op),均需要定义forward函数,下面学习。

首先看forward的使用流程,以一个Module为例:

上述中调用module的call方法是指nn.Module的__call__方法的类可以当做函数调用,具体参考Python的面向对象编程。也就是说,当把定义的网络模型model当做函数调用的时候就自动调用定义的网络模型forward方法。

nn.Module的__call__方法部分源码如下:

可以看到,当执行model(x)的时候,底层自动调用forward方法计算结果。

下面举例说明:

实际上module(data)是等价于module.forward(data)。等价的原因是因为pyhonclass中的__call__和__init__方法。

__call__里调用其他的函数

这句话一般出现在model类的forward函数中,具体位置一般都是在调用分类器之前(可以参考之前的代码),分类器是一个简单的nn.Linear()结构,输入输出都是维度为1的值,x=x.view(x.size(0),-1)这句话的出现就是为了将前面多维度的tensor展平成一维。

下面写一个简单的例子,我们根据这个解析:

上面是个简单的网络结构,包含一个卷积层和一个分类层。forward()函数中,input首先经过卷积层,此时的输出x是包含batchsize维度为4的tensor,即(batchsize,channels,x,y),x.size(0)指batchsize的值。x=x.view(x.size(0),-1)简化为x=x.view(batchsize,-1)。

view()函数的功能跟reshape类似,用来转换size大小。x=x.view(batchsize,-1)中的batchsize指转换后有几行,而-1指在不告诉函数有多少列的情况下,根据原tensor数据和batchsize自动分配列数。

THE END
1.在线课程的特点依托现代信息技术,随着网站设计、网络课程等的出现,网络课程具有不同于传统课程的功能和特点。总之,在线课程可以适应基础教育课程改革的趋势和要求。具体来说,它表现出以下主要特点。 I、课程覆盖的民主化 让不同地区、不同国家、无论贫富的青少年都能享受到最理想的教育,义务教育成为受教育的权利,教育民主化在互联网https://www.xjcj-edu.com/web/12457.html
2.AI自习室与传统自习室的区别是什么?AI自习室与传统自习室在学习环境、教学资源、个性化程度、学习效果、互动性、成本效益以及适应性等方面存在显著差异。学习环境 · AI自习室:融入高科技,能根据学生需求智能调整光线、温度等,创造最佳学习条件。此外,AI自习室利用虚拟现实(VR)、增强现实(AR)等先进技术,打造沉浸式学习环境,极大地提升了学习的沉浸感https://baijiahao.baidu.com/s?id=1817571087265156947&wfr=spider&for=pc
3.推荐算法中的在线学习和离线学习有何区别,各自的优缺点是什么在实际应用中,可以根据具体的场景需求来选择在线学习或离线学习,也可以结合两者的优势进行混合使用。例如,在推荐系统中可以使用离线学习来训练初始模型,在线学习来实时更新模型参数,以实现更好的推荐效果和用户体验。 综上所述,在线学习和离线学习各有优缺点,具体选择取决于应用场景和需求。0https://www.mbalib.com/ask/question-ec5c1bbee149c6534d0a725ffdb15235.html
4.线上线下融合教学的优势不足与发展策略内容这种全新的学习模式不仅可以实现教师的学习目标,而且可以满足学生的学习需求,激发学生的学习兴趣,在良好的学习氛围中提高学习效果。然而,线上与线下这两种教学方式各有优点和缺点,这两种方式是不能完全替代的,有一定的互补性。笔者在分析两种教学方式优缺点的基础上,从不同的层面对深化两种教学方式的融合进行了思考。https://tpd.xhedu.sh.cn/cms/app/info/doc/index.php/92024
5.在线初中数学,重塑学习体验的革命性新模式科技在线初中数学为学习者提供了全新的学习体验,学生应充分利用在线资源,发挥主观能动性,提高学习效果,家长和教育工作者也应关注在线教育的发展,为学生提供支持和指导,相信随着技术的不断进步,在线初中数学学习将越来越受到青睐,为更多学生带来更好的学习体验。 http://www.huayiii.com/post/13980.html
6.java学习路线(鱼皮)鱼皮java学习路线资源Java学习路线(鱼皮) Java学习路线(鱼皮)是一条龙版本的学习路线,从入门到入土,旨在帮助学习者快速掌握Java开发的所有知识点。本路线的特点是新、完整、实用、开源、回馈社区、持续更新。 学习路线的主要内容包括准备阶段、Java入门、Java进阶、Java高级、Java框架、Java项目等多个部分,每个部分都包含了相关的知识点、https://download.csdn.net/download/qq_25355771/86248683
7.懂了么app官方版下载官方手机版利用平台的考试分析系统,根据孩子的优缺点提供改进建议;实现家长与学校的实时沟通,让家长辅导孩子省心省力,增加参与度。 软件特色 1、全国名师在线答疑 系统提供来自全国各地一线名师的在线指导和答疑。 2、数据文件实时查询 学生过往成绩可通过微信公众号和APP随时查看 3、统一考试、联合考试网上启动 通过智慧教育云平台https://www.dianlut.com/soft/703734.html
8.AIR学术李升波:将强化学习用于自动驾驶:技术挑战与发展趋势实际上,我们具有两套将强化学习应用于自动驾驶汽车的途径:第一,先离线训练策略、再在线应用策略,即OTOI方法:将强化学习视作最优控制问题的求解器。或使用模型,或使用预先采集的数据,先离线训练一个最优策略,然后部署到自动驾驶汽车,实现在线控制应用。第二,同时训练和应用策略,即SOTI方法:这是利用强化学习的探索试错https://air.tsinghua.edu.cn/info/1008/1323.htm
9.2024年打字练习软件推荐作为一个互联网老兵,深知在选择打字练习工具时,用户不仅关注其实用性和效果,还越来越重视软件的便捷性、个性化以及互动体验。今天,我们将深入探讨本地桌面软件与在线打字练习平台两大类别的优缺点,并基于实际测评与市场反馈,推荐当前最热门的六款打字练习软件。 https://m.zol.com.cn/otherbbs/d4_32406.html
10.MLK机器学习常见算法优缺点了解一下腾讯云开发者社区MLK | 机器学习常见算法优缺点了解一下 MLK,即Machine Learning Knowledge,本专栏在于对机器学习的重点知识做一次梳理,便于日后温习,这篇文章很久之前在本公众号发过,现在拿回来整理下,也算是一种温故而知新了。 ? 前情回顾 MLK | 那些常见的特征工程https://cloud.tencent.com/developer/article/1485883
11.息流FlowUs评测:从输入到输出,内置工作流的笔记软件和知识管理AI写作助手:支持头脑风暴、列出执行步骤、罗列大纲、分析优缺点、内容解释、日常小记、故事创作、写文章、翻译、总结、扩写、续写等多种 AI写作场景。 AI 多维表格:通过 AI一键创建多维表格,对多维表格内容进行总结、解释、翻译等数据处理任务。 支持中文界面,针对中文用户使用习惯进行细节优化 https://sspai.com/post/73465
12.强化学习的基本概念在线学习和离线学习针对的是在强化学习模型在训练过程中交互数据的使用方式。在线学习的强化学习模型,会在一个交互之后,立即用本次交互得到的经验进行训练。而离线学习的强化学习模型,往往是先将多个交互的经验存储起来,然后在学习的时候,从存储的经验中取出一批交互经验来学习。 https://www.jianshu.com/p/28625d3a60e6
13.学科类阅读写作编程成人考证学习类等都有!网课哪家学习者可以通过在家上网学习,只要有网的地方,即可利用碎片化的时间学习。 视频、图片和资料可在电子产品上反复观看,学习者可针对自己学习弱项强化训练。 网上通过课程学习,对学习者而言,价格相对友好。 停课不停学。 打破地域和国界。 网课有哪些优缺点? https://www.extrabux.cn/chs/guide/6435200