【DL-CV】激活函数及其选择<前篇---后篇>【DL-CV】卷积神经网络
在介绍了线性分类器,激活函数,损失函数,反向传播这些基础的原理后,已经可以尝试自行搭建像样的神经网络了。但是由于神经网络的许多细节并未过分深入(比如层数和每层神经元数的设定,过拟合等),初建的网络实际上和真实的网络还是有一定差距的。本篇将对这些细节知识点进行补充,以便更好地理解和使用神经网络。
神经网络的结构
- 经典的神经网络由输入层,隐藏层和输出层组成;其中隐藏层可以多层,输入输出层只能各一层;通常输入层和输出层的神经元(也可叫“单元”)个数是定的,隐藏层的神经元个数由权重W的大小决定。
- 和神经网络中其他层不同,输出层的神经元一般不会有激活函数,最后的输出层大多用于表示分类评分值。
- 这些层也叫全连接层(fully-connected layer),因为前后两层的神经元是完全成对连接的,但是在同一层内的神经元之间没有连接。
- 所谓神经网络的层数n不计输入层。
- 输出层的结果输入到损失函数计算损失。
一个具体例子如下图
左图是一个2层神经网络,输入层有3个神经元,隐藏层由4个神经元组成,输出层由2个神经元组成。右图是一个3层神经网络,有两个含4个神经元的隐藏层,输入层有3个神经元,输出层只有一个神经元
网络的尺寸:衡量神经网络的尺寸的标准有两个——神经元个数(不计输入层),和参数个数。继续以上图为例
左图网络有6个神经元,3*4 + 2*4 = 20个权重(也就是多少条线),和6个偏置值(数值上等于神经元个数),共26个可学习参数。
右图网络有9个神经元,3*4 + 4*4 + 4*1 = 32个权重,9个偏置值,共41个可学习参数
全连接层这种网状结构使得神经网络算法使用矩阵向量操作变得简单和高效,输入数据可用矩阵存储,每层神经元的激活值可以用矩阵存储,每层所有的连接强度(权重W)也可以用矩阵储存,实现正向传播只需不断重复矩阵乘法和激活函数即可
#一个三层神经网络的正向传播
# 激活函数使用ReLU
def relu(x):
x[x<0]=0
x = np.random.randn(100, 3072) # 假设输入是100个样本(32*32图像)的数据,每行是该样本的像素数据32*32*3
h1 = relu(np.dot(x, W1) + b1) # 计算第一个隐藏层的激活数据(二维矩阵,每行对应该样本的激活数据)
h2 = relu(np.dot(h1, W2) + b2) # 计算第二个隐藏层的激活数据
out = np.dot(h2, W3) + b3 # 输出(二维矩阵,每行对应该样本的输出得分)
# 之后把输出喂给损失函数即可
表达能力
全连接层的神经网络相当于一系列函数组成的大函数。那这个大函数的表达能力如何?
研究表明,选取了适当的非线性激活函数后,只要有一个隐藏层,神经网络就可以近似任何连续函数。这意味着理论上隐藏层的层数并不影响神经网络的表达能力(它们都是一样的)。但在实践中表现并不如此,多层网络会比单层网络好;而且层数也不是越多越好,通常3层神经网络会比2层神经网络好,但继续增加层数只会增加计算量而性能变化不大。
网络尺寸的设置
要设多少个隐藏层,每个隐藏层的大小怎样?探讨这个问题,我们用一个比较实验引入。这是一个平面二分类问题,我们训练三个不同的神经网络来跑一下,每个神经网络都只有一个隐藏层,但每个隐藏层的神经元数不一样(分别3,6,20个)
上图中点表示数据,颜色代表不同的类别。由图可知,神经元越多,决策边界越复杂越分散(尝试把所有数据都分好),这看起来是个优势,毕竟这样可以分类更复杂的数据;但这也可能潜藏着一个致命的缺陷——对训练数据的过拟合(overfitting),即网络对数据中的噪声有很强的拟合力,导致训练集上表现得很好,但是在测试集中表现不理想;过拟合的出现使得网络的泛化能力(generalization)降低。相反的,神经元较少的网络会用比较宽泛的方式去分类数据,它将数据看做是两个大块,并把个别在绿色区域内的红点看做噪声,但这样可以获得更好的泛化能力。
通过实验这样看来大网络小网络各有利弊啊!但是在这里我抛出结论——不要因过拟合的风险而对更大网络抱有担忧,就大胆的使用吧。深度学习中有许多抑制过拟合的方法(正则化,噪音输入,dropout等),使用大网络配合这些方法远比单纯减少网络尺寸好得多。
不减少网络尺寸的原因是小网络很难用梯度下降法进行有效训练,往往训练出来的参数都不太好;梯度下降法更适合深度较大网络的训练
之前提到的正则化就是一个抑制过拟合的好方法(当然前提是设置得当),对于同一个网络结构,正则化强度越大,决策边界越平滑,抑制过拟合能力越强。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。