1.神经网络的表示
- 名称:输入层,隐藏层hidden layer,输出层。
- 神经网络的层数,我们一般不计入输入层,因此这是一个两层的神经网络;
- 用 a [ 0 ] , a [ 1 ] . . a^{[0]},a^{[1]}.. a[0],a[1]..分别表示每一层的激活单元,用下标表示每个激活单元中的第几个结点,所以 a 1 [ 1 ] a^{[1]}_1 a1[1]表示第一层的激活单元的第一个结点;
- w , b w,b w,b向量的维数,w的行是这一层的单元数,列是上一层的单元数;b的行是这一层的单元数,列是1.
2.神经网络的输出
当只有一个样本输入时:
这个图中可以看出每一层的每一个结点都需要一个w,b矢量来计算,图中给出了第一层的每一个
a
i
[
1
]
a^{[1]}_i
ai[1]的计算,将这个用向量化表示,就可以将w,b写成矩阵形式,也就得出了w,b矩阵的size。
当有多个输入x时,将每个输入
x
(
i
)
x^{(i)}
x(i)按列排列成一个矩阵,那么可以向量化为
3 激活函数
因为tanh函数可以将数据中心点移到0点,因此经常被用来代替sigmoid函数,当输出为{0,1}的时候,在隐藏层的激活函数使用
tanh
=
e
z
−
e
(
−
z
)
e
z
+
e
(
−
z
)
\tanh=\frac{e^z-e^{(-z)}}{e^z+e^{(-z)}}
tanh=ez+e(−z)ez−e(−z),而只在输出层使用sigmoid函数。但它们的共同缺点是当Z太大或者太小的时候,函数斜率接近为0,会降低梯度下降的速度,因此可以使用Relu(修正线性单元)函数或者Leaky Relu函数代替tanh函数或者sigmoid函数作为隐藏层的激活函数。Relu函数在Z大于0的时候,斜率不会接近于0,只有当Z小于0时,斜率为0,但一般通过设计w,b参数,可以使得z一直大于0.
那为什么需要使用非线性激活函数呢?
如果在隐藏层只使用线性函数,那么神经网络只是把输入线性组合再输出,那么隐藏层就没有起到实质上的作用。只有在输出为实数R时,我们可以在输出层使用一个线性函数组合输出。
已知激活函数之后,如何计算激活函数的导数?
(为什么要计算导数?因为在梯度下降的时候,
d
w
=
x
d
z
=
x
d
a
d
z
d
L
d
a
{\rm d}w=x{\rm d}z=x\frac{{\rm d}a}{{\rm d}z}\frac{{\rm d}L}{{\rm d}a}
dw=xdz=xdzdadadL,其中
d
a
d
z
\frac{{\rm d}a}{{\rm d}z}
dzda就是激活函数的导数)
对于sigmoid函数,
d
a
d
z
=
a
(
1
−
a
)
\frac{{\rm d}a}{{\rm d}z}=a(1-a)
dzda=a(1−a)
对于tanh函数,
d
a
d
z
=
1
−
a
2
\frac{{\rm d}a}{{\rm d}z}=1-a^2
dzda=1−a2
对于Relu函数,
d
a
d
z
=
{
1
,
if z>0
0
,
if z<0
\frac{{\rm d}a}{{\rm d}z}=\begin{cases} 1 , \text{if z>0}\\ 0, \text{if z<0} \end{cases}
dzda={1,if z>00,if z<0,另外在工程中可以自己定义z=0时导数为1。
对于Leaky Relu函数,
d
a
d
z
=
{
1
,
if z > 0
0.01
,
if z <0
\frac{{\rm d}a}{{\rm d}z}=\begin{cases} 1, \text{if z > 0}\\ 0.01, \text{if z <0} \end{cases}
dzda={1,if z > 00.01,if z <0
(注意上面的导数形式都是对a,即因变量表示的)
4 反向推导梯度下降
假设隐藏层只有一层,输出激活函数为sigmoid函数时:
每次只对Z,w,b计算梯度,有:
注意,反向传播的公式向量化之后有一个
1
m
\frac{1}{m}
m1的系数,这是因为使用矩阵计算时对m个样本求平均。(使用一个样本时是w,使用m个样本时对求出来的矩阵除m求均值)。
5 参数初始化
当初始化参数均为0时,隐藏层中的各个单元呈对称性,在计算梯度下降时,各层的各个单元也呈对称性,那么多个隐藏单元都在做同样的事情,因为多个隐藏单元没有意义。
那么在初始化时,我们应该将各个隐藏层的w函数初始化为:
w
=
np.random.randn((shape))
∗
0.01
\textbf w=\text{np.random.randn((shape))}*0.01
w=np.random.randn((shape))∗0.01
参数b可以初始化为0,因为它不会使整个网络呈对称性。参数乘0.01的原因是当参数值很大时,会使得每一层的线性输出z很大,那么就有可能落在tanh函数或sigmoid函数的平缓区域,此时梯度很小,会降低梯度下降的速度。在深层神经网络中,我们可以需要用到除0.01之外的其他常数,在下一周的深层神经网络中会给出。
总结
学完本周内容你应该知道:
- 神经网络的一些参数符号;
- 正向传播与反向传播的公式表达;
- 激活函数有哪几种,如何选择,为什么?
- 参数初始化怎么做,为什么?