吴恩达深度学习笔记——二、第一课第三周:浅层神经网络
- 0 变量定义
- 1 神经网络基本结构
- 2 将多个样本用向量化的形式表达
- 3 其他激活函数的选择
- 3.1 双曲正切函数
- 3.2 线性修正单元(ReLU)
- 3.3 leaky ReLU
- 3.4 为什么一定要用非线性激活函数
- 4 激活函数的导数计算
- 5 神经网络的梯度下降算法
- 6 参数初始化
0 变量定义
基础变量与吴恩达老师机器学习系列课程的变量定义规则一样。
□[1]:表示神经网络第一个隐层的相关参数
其中a[i]表示神经网络中不同层的输出值,也是不同层中向下一层输出的值,则输入层的X也就可以用a[0]来表示。
w2[1]:第一隐层,第二个神经元的参数
1 神经网络基本结构
上图中的神经网络共有2层(不计输入层),其中每个隐层都有两个参数w,b。
其中第一个隐层的参数w[1]是4×3矩阵,b[1]是4×1矩阵。
第二个隐层的参数w[2]是1×4矩阵,b[2]是1×1矩阵。
其中将每个神经元放大,其包含两层计算:
其中第一隐层有4个神经元,则有四组不同参数:
将上式向量化表达:
即:
2 将多个样本用向量化的形式表达
上图中输入层的三个量x1, x2, x3是一个样本的三个特征,我们用以下符号表示不同样本在不同层的输出值:
则我们通过向量化的方法实现:
输入训练集的形式:
计算中间量:
中间量的形式:
A矩阵横向每一列代表一个训练样本,纵向每个元素代表该训练样本在该隐层的不同神经元的输出。
3 其他激活函数的选择
3.1 双曲正切函数
其本质是Sigmoid函数平移后的结果,其表达式如下:
使用tanh函数的效果几乎总是比Sigmoid函数要好,因为在训练数据时我们经常进行数据中心化操作,令数据的平均值为0,而tanh函数刚好可以起到数据中心化的效果。
一个例外是如果y是标签为0或1的样本,那么我们希望预测值也介于0到1之间,此时使用Sigmoid函数更好一些,此时我们一般在隐层中使用tanh函数,而在随后的输出层使用Sigmoid函数。
使用tanh和Sigmoid函数共同的缺点是,如果z非常大或非常小,那么两个函数在该处的梯度将会很小,这将拖慢梯度下降算法的速度,因此,人们开发了更好的激活函数:ReLU(Rectified Linear Unit)。
3.2 线性修正单元(ReLU)
如果输出是1或0的二分类问题,我们一般令输出神经元为Sigmoid函数,而其他单元都令为ReLU。
但是ReLU的缺点是当z小于0时,导数为0,但在实际应用中,大量的神经元中的z都是大于0的,实际中的ReLU性能其实是很好的。
3.3 leaky ReLU
带泄露的ReLU有时候性能比普通ReLU好,但是不常用。
3.4 为什么一定要用非线性激活函数
如果直接使用z作为激活函数的话,那么不论叠加多少层,不管每次有几个神经元,其实最终得到的输出还是X的线性表达,所以还不如直接去掉所有的隐层,而这样学习也就失败了:
当然,如多我们使用机器学习处理的是一个回归问题,那么就可以使用线性激活函数。
4 激活函数的导数计算
Sigmoid函数的导数如下:
tanh函数的导数如下:
ReLU函数的导数如下:
5 神经网络的梯度下降算法
首先从数学表达式上回顾一下梯度下降法计算流程:
表示成Python代码形式:其中keepdims = True是令输出的矩阵维度为(n[i], 1),而不是(n, …)
6 参数初始化
神经网络的权重初始化不要都初始化为0,这将导致梯度下降算法迭代失败。正确做法是随机初始化,使用np.random.rand函数。