目录

​编辑

前言

一,线性神经网络

1.1 线性回归

1.2 softmax回归

二,多层感知机

2.1 隐藏层和激活函数

2.2 模型选择、欠拟合和过拟合

2.3  权重衰减和暂退法(dropout)

2.4 前向传播和反向传播

2.5 数值稳定性和模型初始化

2.6 环境和分布偏移

问题:

代码知识

三,深度学习计算

3.1 层和块

3.2 参数管理

3.3 其他

问题

代码知识

四,卷积神经网络

问题

代码知识

参考


前言

不想看了书,所得的感悟忘掉,所以记录一下。由于是个人感悟所以可能理解不太准确,望看到的朋友见谅。而看这本书的原因也很简单,yolov5用得很舒服,但数据集的格式一改变,就无从下手了,数据集的格式改变就导致了模型的输入改变,输出也会改变,而这些改变对算法结构也会有所改变。这时感觉对yolov5很熟悉的我,才突然发现自己就是一个调参侠。于是本菜鸡就动手学习深度学习了

一,线性神经网络

(2022.6.1)线性神经网络是基础的神经网络,只有单层结构。虽然简单但包含了神经网络的基础步骤,设计模型,训练模型,用模型预测。这一章主要讲了线性回归和softmax回归,分别解决了预测和分类这两个问题。

1.1 线性回归

   线性回归,简单的说就是求一条直线能够大致拟合已有的数据,然后得出直线的系数和截距,求出自变量和因变量的函数关系,对未知的数据进行预测。用神经网络的角度来分析的话,就是确立线性模型、损失函数、优化算法,系数就是线性模型的权重,截距就是线性模型的偏置。设置初始的权重和偏置,输入已有的数据集让线性模型预测,通过损失函数计算出预测结果和真实结果的偏差(也就是预测损失loss),然后优化算法根据损失对权重和偏置进行修改。细品一下神经网络好像就是这么回事,不同的算法使用不同的模型、损失函数和优化算法而已。

1.2 softmax回归

  softmax回归,这个名字开始的时候接触,不是很懂。看完这章有所理解,分类有硬性和软性,硬性就是直接给出结果这是哪一类,软性是给出结果是哪一类的概率。softmax中的soft表示的是软性的意思,max则表示以结果输出概率最大的为最终分类结果,可以称作概率最大输出回归。整个流程和线性回归差不多,不同的是有了一个拉平的操作。这一章的分类是以图片作为数据的,而图片是一个28*28的矩阵,所以需要拉平变成一个784的向量。拉成向量后就和第一步差不多了,不过模型换成了softmax,损失函数换成了交叉熵损失。但不是很懂的是,对图片的每一个像素点求权重,然后得出十个分类概率,这种方式能有不错的效果,还有就是在运行过程中CPU消耗巨大。据书中所说这是将每个像素位置当作一个特征来看的方式。

(2022.6.18)SGD(随机梯度下降)老是忘其含义和公式,在这里简要总结一下:

新的权重和偏置=原来的权重和偏置-(学习率/随机样本批量)*随机样本验证损失。随机梯度体现在随机样本的选取。

总结一下,学完本章对神经网络的理解有所深入,尤其是优化算法的理解,以前觉得优化是辅助,但实际上优化算法是直接对模型的权重进行修改,可以说训练结果的好坏与优化算法直接有关。

二,多层感知机

(2022.6.29)多层感知机比线性网络多了一层隐藏层,不再是单一的输入-输出网络结构,而是输入-隐藏层-输出网络结构。多了隐藏层,使模型的学习能力大大增强,同时也多了许多问题如过拟合、欠拟合、隐藏层的选择、梯度消失、梯度爆炸等等。有了隐藏层,其实就使得模型具有了深度,最简单的深度网络就称为多层感知机。这一章讲了多层感知机和在深度学习中出现的问题以及问题的解决办法,以及和模型好坏相关的许多概念。

2.1 隐藏层和激活函数

隐藏层和激活函数是多层感知机区别线性神经网络最大的地方。将线性网络的线性预测学习能力变为跟普遍的函数关系类型。但只是加入隐藏层,并不能让模型具有从线性到非线性的变化。从数学上也很好理解,输入为X,经过一层权重变化后输出到下一层再进行一次权重变化,这两层可以简单的合为一层,依旧是线性模型如公式4.1.2所示。由此引入了激活函数,激活函数在两层之间做了对一层到下一层的输入,做了一个选择,选择是否激活这个单元的输出到下一层。常见的激活函数有ReLU、sigmoid、tanh。不过sigmoid和tanh都存在梯度消失的问题,所以最常用的激活函数为ReLU。一般来说,有了激活函数,多层感知机就不会再退化为线性模型。激活原理公式如下,σ为激活函数:

2.2 模型选择、欠拟合和过拟合

模型选择、欠拟合和过拟合,是深度学习中常见的问题。在这里有一个很重要的概念:模式。我们深度学习的目标是发现模式,也就是发现特征和规律,能通过数据集训练得出的特征和规律来判断数据集之外的所有数据称为泛化。为了判断模式泛化性优劣,所以数据集一般分为训练数据集和测试数据集(验证数据集),在训练数据集上训练好后,用模型来推理测试数据集,如果准确率高则泛化性好(这只是简单的评价,因为测试数据集代表不了所有的数据)。在模型训练过程中:训练集和测试集上的误差都很严重,但它们之间仅有一点差距称为欠拟合;训练集的误差很小,而测试集上的误差很大时称为过拟合。欠拟合和过拟合问题往往与数据集、模型复杂度有关。数据集制作粗糙容易引起欠拟合、数据集太小会过拟合,模型复杂度一定程度上代表了模型的学习能力,模型太简单会欠拟合、太复杂会过拟合。模型复杂度的影响如下图所示:

2.3  权重衰减和暂退法(dropout)

        权重衰减和暂退法(dropout),是解决过拟合的方法。原理一句话就可以说完:降低模型复杂度。权重衰减通过增强损失使权重缩小到0的方式,降低模型复杂度;暂退法通过减少隐藏层的隐藏单元数量的方式,降低模型复杂度。

权重衰减是一种最广泛使用的正则化技术之一。那么什么是正则化呢,正则化是防止模型过拟合的技术之一。但可能还是很难理解正则化,这三个字凑到一起无法用字面意思去深入理解,简单的说,就是取名不够通俗。按照含义其实正则化叫约束化或者限制化更好。再回过头来看权重衰减,它的作用是约束(限制)要优化的参数(权重),因此称之为正则化技术。在实现上,权重衰减采用了L2范数,对模型的权重进行惩罚。为什么选取L2范数而不是L1范数,在书中也有详细解答。使用L2范数的原因是它对权重向量的⼤分量施加了巨⼤的惩罚。这使得我们的学习算法偏向于在⼤量特征上均匀分布权重的模型。使模型观测误差更为稳定。不使用L1范数的原因是L1惩罚会导致模型将权重集中在⼀⼩部分特征上,⽽将其他权重清除为零。权重衰减实现的过程也简单粗暴,将损失和L2惩罚相加,一起加入到优化算法中。

暂退法,以一定的概率将隐藏单元置为0,让隐藏单元消失的方式降低模型复杂度防止过拟合的发生。简单性的另一个角度是平滑性,在多层神经网络中注入噪声可以增加模型的平滑性。暂退法在前向传播计算每一层的同时注入噪声,丢弃一些神经单元。还有就是暂退法仅在训练期间使用,测试时需要完整的模型,才能测出模型的泛化能力。

2.4 前向传播和反向传播

前向传播是按顺序从输入层到输出层计算和储存神经网络中每一层的结果。反向传播则是通过链式法则从输出层到输入计算每一层权重的梯度。个人理解,前向传播的作用得出损失,反向传播的作用是得出梯度,然后在优化算法中根据损失和梯度调整网络参数(权重)。

2.5 数值稳定性和模型初始化

模型参数的初始化是一直被忽略的问题,在yolo中模型的初始化使用的是已经训练过的权重进行初始化达到加快训练速度的作用,选择好的模型初始化方案可以加快速度,这是容易理解的,但模型初始化的作用不仅于此。在这节中强调了另一个模型初始化的作用,保持数值稳定性。如果模型初始化方案可能会导致梯度消失问题和梯度爆炸问题。

梯度爆炸指参数更新过大,破坏了模型的稳定收敛;梯度消失指参数更新过小,在每次更新时⼏乎不会移动,导致模型⽆法学习。还有一个问题就是对称性,如果权重非常对称可能会减小模型的表达能力,就是两个隐藏单元采用相同的输入和参数,那么这两个隐藏单元实际上等于一个神经单元。因为前向传播根据输入得出损失,反向传播根据参数得出参数的梯度也是一样的。
        而怎么选择模型参数初始化方案,书中没有细讲,实现了Xavier初始化,提供参数绑定,超分辨率,序列模型等了几种思路。暂时没遇到模型初始化的相关问题,若遇到了,再深入研究一下。

2.6 环境和分布偏移

这节主要讲了数据的问题,现实中的数据多种多样,而有些数据会随时间、环境变化。这些变化给模型的预测带来了不稳定性,也就是训练好了的模型在某些情况下不能一直通用。等以后遇到问题再详细补充。

问题:

(2022.6.18)

1,为何增加非线性因素的激活函数ReLU通过舍弃小于0的元素对模型的训练有益?

激活函数的作用是使两个线性层相连不会变为一个线性层,就是加入非线性因素。激活函数的方式是将输入小于0的元素的梯度变为0,使他在计算损失中不起作用,大于0的元素梯度保留达到激活的效果。并不是所有的激活函数都是舍弃小于0的元素,达到加入非线性因素的目的,可能在实际中保留正元素的梯度,效果大于保留负元素的,所以一般都使用ReLU。

总结一下,激活函数通过舍弃小于0的元素,在两层相连时做了一个选择,使多层模型变得不再是单一的线性,能够学得更多特征,所以有益。

2,L2正则化(权重衰减)如何实现缩小权重的?表面上的形式是损失加上了一个对权重的L2正则化,难道是通过增大损失的方式缩小权重?好像是这样,所以称为惩罚权重的大小,但还不太确定。

是的,权重衰减在模型优化这一步中增大了损失,使得每一次优化对权重的修改力度都强了许多,而这种修改是根据估计值与观测值之间的差异来更新w的同时也在试图将w的⼤⼩缩⼩到零,实现了缩小权重的效果。

(2022.6.20)

3,为什么权重衰减能够解决过拟合问题?

为什么能解决,还是得了解什么是过拟合。过拟合和泛化是相对的,从损失的角度里看,过拟合指模型在训练集上的损失远小于验证集上的损失,泛化则是训练集上的损失和验证集上损失几乎相等。而往往模型越简单,泛化性就越好,越不容易出现过拟合现象。权重衰减通过缩小权重的方式,让模型更小,更简单,解决过拟合的现象。

(2022.6.25)

4,反向传播如何计算梯度,计算谁的梯度?

反向传播就是一个求导的过程,但深度学习网络是一个复杂的函数模型,需要采用链式法则,依次对参数求偏导,也就是根据前向传播的计算过程,反向采用链式法则计算梯度,不好理解的地方是之前都是求因变量x的导数,而反向传播将x作为已知量求权重的导数也就是梯度。反向传播计算的是中间变量和参数的梯度。

代码知识

(2022.6.18)

1,lambda使用

net, loss = lambda X: d2l.linreg(X, w, b), d2l.squared_loss

lambda表达式,又称匿名函数,是现代各种编程语言争相引入的一种语法,其功能堪比函数,设计却比函数简洁。

lambda 表达式的语法格式为:lambda [parameter_list] : 表达式,输入的parameter_list

lambda x , y : x * y   =   def add(x, y):return x * y

示例:X = lambda x :x*x, range(10)#X=[ 0, 1, 4 , 9, 16, 25, 36, 49, 81, 100]

三,深度学习计算

(2022.7.1)这一章主要讲的是实践知识,理论知识较少,所以看得挺快的。许多知识之前就讲过,不过这一章将网络的构建规范到了类当中,以类为基础讲解了nn.Modul的一些使用方法。不过只讲了怎么构建,没有讲为什么这么构建,所以学完还是懵懵的,对pytorch的工具有了深入的了解,而对如何构建自己的网络解决实际问题还不清楚。

3.1 层和块

层和块(block)是神经网络的基础组成部分,在复杂的模型当中,以块为基础来构建网络。从发展来看,网络的构建是一个越来越抽象的过程,从神经单元到网络层,再到块,不知道以后还会不会扩大到以神经网络为单位构建更大的网络。(我感觉还真有可能会是这样,随着多模态深度学习的发展,网络模型迟早要处理不同的数据来进行预测或分析,而不同数据,用不同数据领域的最优网络来处理,将结果再作为下一个网络的输入,进行综合分析效果应该会比较好,不过对于设备的要求会更大。)跑偏了,简单的说神经单元组成层,层组成块,块组成神经网络模型。

这里又有一个重要的Module子类:nn.Sequential,这个子类可以按顺序将层连接起来组成块,也可将块放进去组成更大的块。在前面的多层感知机简洁实现中,就是用nn.Sequential来组成多层感知机的。使用也很简单,将层添加进去就行,不过注意层与层之间的输入输出就行。

net = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))

3.2 参数管理

参数访问,在pytorch中提供了非常实用的工具让我们查看模型的参数,这些工具都被集成到了nn.Module中,继承它构建的子类,都能调用工具查看参数。实例化好网络之后,可以用net.state_dict()查看网络所有层的参数,也可以用net[0].weight和net[0].bias查看指定0层的参数或偏置。不过值得注意的是.weight方式是访问到指定层的参数,如果组成的网络中有块,得在块的基础上再向下访问才行,如net[0][0][0].weight,否则会报错,不过用.state_dict()不会。总结一下,.state_dict()查看多层的参数,.weight查看单层的参数。

        参数初始化分为内置初始化和自定义初始化。 内置初始化是使用pytorch自带的nn.init中提供的各种方式进行初始化,常用的如nn.init.normal_(),nn.init.zeros_(),nn.init.constant_(),nn.init.xavier_uniform_()等。自定义初始化,就是手动为参数赋值,使用(net).weight.data就可以访问参数中的数据,并进行修改。
        参数绑定,也就是参数共享,多个层共享一个参数。也就是当这个参数改变时,使用这参数的层的参数也会变化。不过梯度的变化有点不太理解,在书中说,使用共享参数的梯度会加在一起,我的理解是根据每一层的运算单独计算参数的梯度,最后把每一层的计算的参数梯度加在一起为最终该共享参数的梯度。

3.3 延后初始化

(2022.7.7)延后初始化,是指参数在输入数据信息确定之后才开始初始化参数。在yolov5当中维度是确定的,模型的输入默认是640x640图片(也可自己更改),即使我们的数据集不是,也会在程序中转化为640x640分辨率的图片,省却了延后初始化的这一步骤(不太确定)。

我个人感觉吧,延后初始化有一些理想化。它虽然让模型的参数自由了,可以由第一次输入的信息确定维度,但是如果数据集里面的图片分辨率不一样,那么延后初始化就使用不了。现实的情况,大多自制图片数据集都是从网上爬取而来,分辨率不会统一。所以不太懂延后初始化使用的地方,我个人喜欢yolov5里的处理方式,不管输入是什么,处理一遍再传递给模型,根据处理的数据确定参数。不过,yolov5里可以更改模型的输入图片分辨率,不知道这一步有没有用到,延后初始化。。。

3.4 自定义层

自定义层应该才是深度学习最深奥的、最有创新的地方吧,不然老是单纯的排列组合别人设计好的层,可能会取得很好的效果,但过程未免有些太过枯燥。

自定义层呢,其实就是自定义一种处理数据的方式,比如全连接层、卷积层、池化层,都有自己处理数据方式的特点和优点。不过这个得需要很深的数学功底才行,每一个流行的网络层背后都有严谨的公式支撑的。本菜鸡暂时还是先学会怎么排列组合吧。

3.3 读写文件

这一章都是实践内容,没啥好记的。以后遇到问题了再来补充。

延后初始化

自定义层

读写文件

GPU

问题

(2022.6.30)

1,共享参数有什么好处?

通过共享参数,减少网络中的权重数量,减少训练实践,减少反向传播的权重更新次数。

2,为什么要参数延迟初始化,模型确定,输入的维度不就确定了吗?

代码知识

(2022.6.29)

1,enumerate()使用

for idx, module in enumerate(args):

enumerate函数提供了一种获取列表下标和元素的精简方法。

示例:enumerate(["a","b","c"]) 返回(0,"a"),(1,"b"),(2,"c").

四,卷积神经网络

问题

(2022.7.3)

1,卷积如何将图分为多通道的?

不好意思,大意了,一直在想一次卷积怎么生成多通道,走进了误区。在卷积中是通过增加卷积核的方式增加通道的,也就是一张图和一个卷积核卷积运行一下会生成一个通道,依次和多个卷积核运算就生成了多个通道,一次卷积只能生成一个。

代码知识

(2022.7.5)

1,[:]的应用

conv2d.weight.data[:] -= lr * conv2d.weight.grad

列表的[:]有两种功能一种是复制列表的值,一种是节省内存,此处的使用是为了减少内存消耗

复制列表的值,在python中没有引用&和指针*,而是将变量分为可变对象和不可变对象。

        可变对象:如列表list和字典dict,set,自己定义的类对象,numpy中的ndarray对象,在进行参数传递,拷贝时会传递地址。也就是函数形参变为实参,赋值操作变为赋值变量地址。不可变对象:如整型int、浮点型float、字符串型string和元组tuple,以及frozenset,只能单纯传递一下值,无法传递地址。

这两种对象在函数中的传递也叫做引用传递和值传递。[:]使用示例如下:

a = [1,1,1,1,1]
b = a  # 引用传递
b = [2,2,2,2,2]   # a = [2,2,2,2,2]c = b[:] #值传递
c = [3,3,3,3,3]  # b = [2,2,2,2,2]

节省内存,这个功能,在书中的 2.1.5节详细说过,在进行变量之间的赋值传递时,每次直接使用=进行赋值会让系统每次都会分配新的位置,在深度学习中,赋值操作非常的频繁,若每次都分配新的位置,内存会承受不住。使用[:]进行原地赋值,则不会出现这种情况。

参考

https://zh.d2l.ai

动手学习深度学习感悟相关推荐

  1. 「动手学深度学习」在B站火到没谁,加这个免费实操平台,妥妥天花板!

    论 AI 圈活菩萨,非李沐老师莫属. 前有编写「动手学深度学习」,成就圈内入门经典,后又在B站免费讲斯坦福 AI 课,一则艰深硬核讲论文的视频播放量36万,不少课题组从导师到见习本科生都在追番. 如此 ...

  2. 《动手学深度学习》中文第二版预览版发布

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨李沐@知乎 来源丨https://zhuanlan.zhihu ...

  3. 收藏 |《动手学深度学习》中文版PDF

    对于初学者来说,直接阅读英文资料,效率慢,估计读着读着都没有信心读下去了.对于初学者,中文资料是再好不过了.今天小编就来安利一本中文资料--中文版本的<动手学深度学习>. 资料领取: 扫码 ...

  4. 深度学习经典教程:深度学习+动手学深度学习

    作者:[美] Ian,Goodfellow(伊恩·古德费洛),[加] Yoshua,Bengio(约书亚·本吉奥)等 出版社:人民邮电出版社 品牌:异步图书 出版时间:2019-06-01 深度学习经 ...

  5. 资源 | 李沐等人开源中文书《动手学深度学习》预览版上线

    来源:机器之心 本文约2000字,建议阅读10分钟. 本文为大家介绍了一本交互式深度学习书籍. 近日,由 Aston Zhang.李沐等人所著图书<动手学深度学习>放出了在线预览版,以供读 ...

  6. 最新版 | 2020李沐《动手学深度学习》

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 强烈推荐李沐等人的<动手学深度学习>最新版!完整中文版 PDF 终于 在 ...

  7. 最新版动手学习深度学习和GAN电子书免费下载!

    今天给大家推荐一个GAN方面的优质公众号---机器学习与生成对抗网络.该公众号里分享了几本深度学习.GAN等好的电子书资源! 强烈推荐李沐等人的<动手学习深度学习>最新版!完整中文版 PD ...

  8. 动手学深度学习需要这些数学基础知识

    https://www.toutiao.com/a6716993354439066124/ 本附录总结了本书中涉及的有关线性代数.微分和概率的基础知识.为避免赘述本书未涉及的数学背景知识,本节中的少数 ...

  9. 《动手学深度学习》PyTorch版GitHub资源

    之前,偶然间看到过这个PyTorch版<动手学深度学习>,当时留意了一下,后来,着手学习pytorch,发现找不到这个资源了.今天又看到了,赶紧保存下来. <动手学深度学习>P ...

最新文章

  1. Docker 容器技术 — Dockerfile
  2. 011_TreeMap对键实现了Comparable接口的对象排序
  3. FTServer 1.1 发布,多语言全文搜索服务器
  4. DDP、DDU、DAP的区别你都知道吗?
  5. 用requests爬取一个招聘网站
  6. 2021ICPC(沈阳) - String Problem(后缀树+贪心)
  7. Red Hat日志文件系统-ext3
  8. 洛谷 1313 计算系数——水题
  9. Netty工作笔记0034---Netty架构设计--线程模型
  10. 什么是ZigBee技术
  11. ENVI辐射校正(辐射定标+大气校正)
  12. LoadRunner安装时没法注册DLL文件的问题
  13. 开源ESB服务总线记录
  14. 基于爬取百合网的数据,用matplotlib生成图表
  15. 计算机病毒的常用方法,常用计算机检测病毒的方法
  16. 关于大学初入计算机学习的一些建议
  17. 不同麻醉方案以及清醒条件下大鼠大脑连接模式分析
  18. 基于javaweb+jsp的在线点餐系统(java+SSM+jsp+mysql+maven)
  19. sqoop 导数据从 mysql 到 hdfs,load 进 hive
  20. Fzu 2198 快来快来数一数【矩阵快速幂】

热门文章

  1. 关于Symbian 模拟器一闪就没的解决办法(Eclipse+MTJ+symbian模拟器)
  2. 8点揭示模具爆裂的具体原因
  3. 经典培训小游戏(一)
  4. Java中原生(native)函数的用法
  5. 解决Chrome中调试JS提示“Uncaught (in promise) TypeError: Cannot use ‘in‘ operator to search for ‘”错误信息问题
  6. 解决Themida加壳程序在VMware虚拟机无法运行问题_HS_TMD
  7. 电脑系统数据堆积过多想要重装win10系统,一键装机工具哪个好用?
  8. 业界分享 | 深度学习下的京东搜索召回技术
  9. VB编写欧姆龙PLC和霍尼韦尔扫描枪 的串口调试程序,可供大家参考
  10. 如何使用流量精灵刷网站流量