步骤/目录:
无

本文首发于个人博客https://lisper517.top/index.php/archives/4260/,转载请注明出处。
本文的原文写作日期为2020年11月17日,主要目的是总结《深度学习入门 基于Python的理论与实现》。
笔者的毕业论文有很多东西来自这本书。

下面的内容有些缩进或者图片缺失,可以参考 原word文档

本书主要用numpy来处理运算,用matplotlib将结果可视化。对于没有基础的人十分友好,只需要高中的线代知识就可以看懂。

1.x=x.flatten() 将矩阵及张量转换为一维数组。x>15,结果得到一个由True和False组成的一维列表,x[x>15]即可输出所有大于15的成员。

矩阵与一维数组的*乘,(数组长度与矩阵列数相同)将一维数组扩张为矩阵形状后简单相乘,符合交换率,符号为*;
矩阵与数组dot乘,(数组长度与矩阵列数相同)将一维数组与每行对应索引相乘求和,得到一维数组,长度为矩阵的行数:如[[1, 2], [3, 4], [7, 8]] dot [5,6],则得[1*5+2*6, 3*5+4*6,7*5+8*6],不符合交换律,用np.dot计算。

一次绘图流程:p42

2.感知机:接受一个或多个输入,输出一个信号。有多个输入时,可以给各个输入配置权重。机器学习就是人给机器一些数据,机器根据这些数据选出权重的过程。
P56从图像上,感知机是一条直线,有局限性。叠加多个感知机可以构造类似曲线。

3.对于单层感知机,实际上有两个函数,比如首先有y=b+x1*w1+x2*w2,其中b为偏置,w1、w2为权重;然后通过激活函数,比如h(x)=1或0(当y<=0时为0,否则为1。这种函数的输出是跳跃的,可称为阶跃函数)。若把激活函数换成其他形式,就接近神经网络的概念了。常用的一个激活函数(sigmoid函数):1/(1+exp(-x)),其中exp(-x)为e的-x次方。

接受numpy数组为参数的阶跃函数见p69。

激活函数也可以使用ReLU函数,其在x<=0时输出0,在x>0时则为线性关系。P74

对于输出层的激活函数,如果是分类问题(类似阶跃函数)用softmax函数,回归问题(连续输出数值)用恒等函数。P89
softmax函数的输出是连续的,总和为1,可以看作概率。为了节省算力,对未知模型进行预测时通常也可以省略输出层的softmax激活函数(接受数据进行学习时可以不省略)。

在分类问题中,输出层的神经元数量通常等于类别的数量。哪个神经元的输出最大,就会归类为该类别。

4.正规化:将数据进行处理,使其限制在某个范围内。正规化是一种预处理。

批处理:相同的神经网络,多个输出,多个结果。批处理可以大大加快运算速度。P101

5.损失函数:描述当前神经网络与测试数据(即监督数据)在多大程度上不拟合。一般可用均方误差函数和交叉熵。均方考虑了非正确解、越接近0(越小)越好,交叉熵只包含正确解、越接近0(越小)越好。
机器学习就是要使得损失函数值最小。如果训练数据太多,可以从中随机选择部分数据来学习,称为mini batch。
不用精确度作为评价标准,因为要设定参数的导数(变化梯度),如果用精确度为指标,容易导致导数为0,参数无法更新(精确度常常是跳跃的,微调无法产生影响,而损失函数是连续变化的)。这也是sigmoid函数优于阶跃函数的地方(激活函数)。

对于矩阵,y[0,2]的写法等同于y[0][2]

梯度指示的方向是损失函数减少量最多的地方,不一定指向损失函数值最小的地方。所以,机器学习可能会陷入局部最小值、鞍点或者学习平原。
鞍点处的梯度也为0,比如一个马鞍形曲面,(0,0,0)处的形状就很像马鞍。

梯度,就是一个一维数组。一个函数有多个输入,那么梯度就是这个多维函数(在某一点处)的导数。梯度数组的大小和输入多少相等,意义是对每一个输入,在保持其他输入不变时求该输入的导数,最终组成一个导数数组。为了使损失函数减小,需要沿负梯度方向下降。

6.反向传播法算梯度的速度比微积分法快许多,主要应用了复合函数的求导(相乘)。

7.有时SGD(随机梯度下降),即沿着梯度最大的地方下山的方法,不一定能最快下山。还有其他一些方法。

Momentum(动量法),如果某一方向上的梯度较小,但是持续很久,就适合用这种方法。模拟静止小球在山中的运动,某一方向累计的梯度会给小球积累该方向的速度,于是在该方向上移动越来越快。

AdaGrad(Adaptive适应梯度法),对梯度中的每一个导数都有一个学习率,该学习率还会不断衰减。AdaGrad是通过记录过去所有梯度的平方和实现的,最终学习率会衰减到0。不想让学习率衰减太快可以用RMSProp法,其会更多地考虑最近的梯度、逐渐减小久远梯度的权重。

Adam(直观上讲,类似于融合了AdaGrad与Momentum法,2015年提出),甚至可对一些超参数调校。

一些技巧:
(1)权重的初始值:对于sigmoid或tanh等激活函数,使用Xavier方法,上一层的节点个数为n,本层的初始值大概是标准差1/sqrt(n)的高斯分布;
对relu激活函数,可以使用He初始值。
在手头数据集少时,可以“学习迁移”,即训练完一个数据集,将权重的最终值作为下一次学习的初始值。
(2)调整激活值的分布:使用batch normalization,优点是增大学习率(学的快)、对初始值不会过于敏感、抑制过拟合。
(3)抑制过拟合:过拟合主要是由于训练数据少、网络参数太多(层数多、节点多等)。过拟合的表现常常是训练数据准确度高,测试数据准确度不佳。对简单网络,常用权值衰减来抑制过拟合。对复杂网络,可用Dropout方法,随机删除一些节点。另外,可以用已有的数据生成新的数据,比如对手写数字图片,可对图片进行平移、旋转等操作。
(4)高效寻找超参数:对于网络层数与节点数、batch大小、学习率、权值衰减等超参数,需要高效寻找之。可在训练数据和测试数据之外再分一个验证数据,用来对探讨超参数取什么值,然后让超参数不断*10,在对数尺度上变化,并观测其对学习的影响。一般来说,测试数据应该只在最后用一次。
(5)GPU运算:GPU擅长大量的并行运算,比如矩阵的乘法;而CPU擅长连续的复杂运算。使用GPU,可以将训练和测试时间大大缩短。据书中称,NVIDIA的显卡比AMD的更合适。
(6)分布式学习:和用GPU一样,可缩短学习时间。Google的TensorFlow和微软的CNTK都很重视分布式学习。

8.CNN(Convolutional Neural Network),书中之前实现的网络,隐藏层的结构是Affine+Relu(或者其他激活函数),最后一层是Affine+Softmax,而CNN的隐藏层是Conv(卷积层)+Relu+Pooling(池化层),最后一层不变。普通Affine的问题是没有考虑图片的形状,比如矩阵中相距较远的两个点关联度较小,近大。从原理上,卷积层使用了类似滤波器的方法,用了矩阵的*乘,并且偏置只有一个。*乘,即相同大小矩阵的对应位置乘积之和。
池化层则是将层中的数据减少形成特征化的数据,比如只取最大值、只取平均值。

CNN是图像识别中常用的操作。通过观察,CNN的不同Conv层,大概在进行从基础到抽象的观察。

在各种CNN中,书中介绍了CNN元组LeNet及2012年提出的AlexNet。据称,AlexNet是深度学习热潮的导火索。

Google旗下的Deep Mind公司,开发出了AlphaGo和DQN。其中DQN可以接受游戏的图像输入(比如每秒4帧),学习如何玩游戏,甚至可以做出超越人类的手柄操作。

标签: none

添加新评论