> For the complete documentation index, see [llms.txt](https://baozoulin.gitbook.io/dl-ai-special-notebook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://baozoulin.gitbook.io/dl-ai-special-notebook/course1/di-san-zhou-ff1a-qian-ceng-shen-jing-wang-7edc28-shallow-neural-networks.md).

# 第三周：浅层神经网络(Shallow neural networks)

## 3.1 神经网络概述（Neural Network Overview）

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/21.bmp)

## 3.2 神经网络的表示（Neural Network Representation ）

单隐藏层神经网络就是典型的**浅层（shallow）神经网络**

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/22.bmp)

单隐藏层神经网络也被称为两层神经网络（2 layer NN）

第$$l$$层的权重$$W^{\[l]}$$维度的行等于$$l$$层神经元的个数，列等于$$l-1$$层神经元的个数；第$$i$$层常数项$$b^{\[l]}$$维度的行等于$$l$$层神经元的个数，列始终为1

## 3.3 计算一个神经网络的输出（Computing a Neural Network's output ）

两层神经网络可以看成是逻辑回归再重复计算一次

逻辑回归的正向计算可以分解成计算z和a的两部分：

$$
z=w^Tx+b
$$

$$
a=\sigma(z)
$$

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/212esdsdimport.png)

两层神经网络，从输入层到隐藏层对应一次逻辑回归运算；从隐藏层到输出层对应一次逻辑回归运算

$$
z^{\[1]}=W^{\[1]}x+b^{\[1]}
$$

$$
a^{\[1]}=\sigma(z^{\[1]})
$$

$$
z^{\[2]}=W^{\[2]}a^{\[1]}+b^{\[2]}
$$

$$
a^{\[2]}=\sigma(z^{\[2]})
$$

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/dfddfefefimport.png)

## 3.4 多样本向量化（Vectorizing across multiple examples ）

for循环来求解其正向输出：

for i = 1 to m:

$$\begin{aligned}\&z^{[1](https://baozoulin.gitbook.io/dl-ai-special-notebook/course1/i)}=W^{\[1]}x^{(i)}+b^{\[1]}\\\&a^{[1](https://baozoulin.gitbook.io/dl-ai-special-notebook/course1/i)}=\sigma(z^{[1](https://baozoulin.gitbook.io/dl-ai-special-notebook/course1/i)})\\\&z^{[2](https://baozoulin.gitbook.io/dl-ai-special-notebook/course1/i)}=W^{\[2]}a^{[1](https://baozoulin.gitbook.io/dl-ai-special-notebook/course1/i)}+b^{\[2]} \\\&a^{[2](https://baozoulin.gitbook.io/dl-ai-special-notebook/course1/i)}=\sigma(z^{[2](https://baozoulin.gitbook.io/dl-ai-special-notebook/course1/i)})\end{aligned}$$

矩阵运算的形式：

$$
Z^{\[1]}=W^{\[1]}X+b^{\[1]}
$$

$$
A^{\[1]}=\sigma(Z^{\[1]})
$$

$$
Z^{\[2]}=W^{\[2]}A^{\[1]}+b^{\[2]}
$$

$$
A^{\[2]}=\sigma(Z^{\[2]})
$$

行表示神经元个数，列表示样本数目$$m$$

## 3.5 激活函数（Activation functions）

* sigmoid函数

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/sdsdssimport.png)

* tanh函数

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/23.bmp)

* ReLU函数

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/24.bmp)

* Leaky ReLU函数

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/25.bmp)

对于隐藏层的激活函数，$$tanh$$函数要比$$sigmoid$$函数表现更好一些。因为$$tanh$$函数的取值范围在$$\[-1,+1]$$之间，隐藏层的输出被限定在\[$$-1,+1]$$之间，可以看成是在$$0$$值附近分布，均值为$$0$$。这样从隐藏层到输出层，数据起到了归一化（均值为$$0$$）的效果

对于输出层的激活函数，因为二分类问题的输出取值为$${0,+1}$$，所以一般会选择$$sigmoid$$作为激活函数

选择$$ReLU$$作为激活函数能够保证$$z$$大于零时梯度始终为$$1$$，从而提高神经网络梯度下降算法运算速度。但当$$z$$小于零时，存在梯度为$$0$$的缺点

$$Leaky$$ $$ReLU$$激活函数，能够保证$$z$$小于零时梯度不为$$0$$

## 3.6 为什么需要（ 非线性激活函数？（why need a nonlinear activation function?）

假设所有的激活函数都是线性的，直接令激活函数$$g(z)=z$$，即$$a=z$$

$$
z^{\[1]}=W^{\[1]}x+b^{\[1]}
$$

$$
a^{\[1]}=z^{\[1]}
$$

$$
z^{\[2]}=W^{\[2]}a^{\[1]}+b^{\[2]}
$$

$$
a^{\[2]}=z^{\[2]}
$$

$$
a^{\[2]}=z^{\[2]}=W^{\[2]}a^{\[1]}+b^{\[2]}=W^{\[2]}(W^{\[1]}x+b^{\[1]})+b^{\[2]}=(W^{\[2]}W^{\[1]})x+(W^{\[2]}b^{\[1]}+b^{\[2]})=W'x+b'
$$

多层隐藏层的神经网络，如果使用线性函数作为激活函数，最终的输出仍然是输入$$x$$的线性模型。这样的话神经网络就没有任何作用了。因此，隐藏层的激活函数必须要是非线性的

如果是预测问题而不是分类问题，输出$$y$$是连续的情况下，输出层的激活函数可以使用线性函数。如果输出$$y$$恒为正值，则也可以使用$$ReLU$$激活函数

## 3.7 激活函数的导数（Derivatives of activation functions ）

$$sigmoid$$函数的导数：

$$
g(z)=\frac{1}{1+e^{(-z)}}
$$

$$
g'(z)=\frac{d}{dz}g(z)=g(z)(1-g(z))=a(1-a)
$$

$$tanh$$函数的导数：

$$
g(z)=\frac{e^{(z)}-e^{(-z)}}{e^{(z)}+e^{(-z)}}
$$

$$
g'(z)=\frac{d}{dz}g(z)=1-(g(z))^2=1-a^2
$$

$$ReLU$$函数的导数：

$$
g(z)=max(0,z)
$$

$$
x = \begin{cases}
0 &\text{if } z < 0 \\
1 &\text{if } z \geq 0
\end{cases}
$$

$$Leaky ReLU$$函数：

$$
g(z)=max(0.01z,z)
$$

$$
g'(z) = \begin{cases}
0.01 &\text{if } z < 0 \\
1 &\text{if } z \geq 0
\end{cases}
$$

## 3.8 神经网络的梯度下降（Gradient descent for neural networks）

$$
dZ^{\[2]}=A^{\[2]}-Y
$$

$$
dW^{\[2]}=\frac1mdZ^{\[2]}A^{\[1]T}
$$

$$
db^{\[2]}=\frac1mnp.sum(dZ^{\[2]},axis=1,keepdim=True)
$$

$$
dZ^{\[1]}=W^{\[2]T}dZ^{\[2]}\ast g'(Z^{\[1]})
$$

$$
dW^{\[1]}=\frac1mdZ^{\[1]}X^T
$$

$$
db^{\[1]}=\frac1mnp.sum(dZ^{\[1]},axis=1,keepdim=True)
$$

## 3.9 （选修）直观理解反向传播（Backpropagation intuition ）

单个训练样本反向过程可以根据梯度计算方法逐一推导：

$$
dz^{\[2]}=a^{\[2]}-y
$$

$$
dW^{\[2]}=dz^{\[2]}\cdot \frac{\partial z^{\[2]}}{\partial W^{\[2]}}=dz^{\[2]}a^{\[1]T}
$$

$$
db^{\[2]}=dz^{\[2]}\cdot \frac{\partial z^{\[2]}}{\partial b^{\[2]}}=dz^{\[2]}\cdot 1=dz^{\[2]}
$$

$$
dz^{\[1]}=dz^{\[2]}\cdot \frac{\partial z^{\[2]}}{\partial a^{\[1]}}\cdot \frac{\partial a^{\[1]}}{\partial z^{\[1]}}=W^{\[2]T}dz^{\[2]}\ast g^{\[1]'}(z^{\[1]})
$$

$$
dW^{\[1]}=dz^{\[1]}\cdot \frac{\partial z^{\[1]}}{\partial W^{\[1]}}=dz^{\[1]}x^T
$$

$$
db^{\[1]}=dz^{\[1]}\cdot \frac{\partial z^{\[1]}}{\partial b^{\[1]}}=dz^{\[1]}\cdot 1=dz^{\[1]}
$$

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/26.bmp)

浅层神经网络（包含一个隐藏层），$$m$$个训练样本的正向传播过程和反向传播过程分别包含了$$6$$个表达式，其向量化矩阵形式如下图所示：

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/27.bmp)

## 3.10 随机初始化（Random Initialization）

神经网络模型中的参数权重$$W$$不能全部初始化为零

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/28.bmp)

如果权重$$W^{\[1]}$$和$$W^{\[2]}$$都初始化为零，即：

$$
W^{\[1]}= \left\[ \begin{matrix} 0 & 0 \ 0 & 0 \end{matrix} \right]
$$

$$
W^{\[2]}= \left\[ \begin{matrix} 0 & 0 \end{matrix} \right]
$$

这样使得隐藏层第一个神经元的输出等于第二个神经元的输出，即$$a\_1^{\[1]}=a\_2^{\[1]}$$。经过推导得到$$dz\_1^{\[1]}=dz\_2^{\[1]}$$，$$dW\_1^{\[1]}=dW\_2^{\[1]}$$，这样的结果是隐藏层两个神经元对应的权重行向量$$W\_1^{\[1]}$$和$$W\_2^{\[1]}$$每次迭代更新都会得到完全相同的结果，$$W\_1^{\[1]}$$始终等于$$W\_2^{\[1]}$$，完全对称。这样隐藏层设置多个神经元就没有任何意义

权重$$W$$全部初始化为零带来的问题称为**symmetry breaking problem**

随机初始化：

```python
W_1 = np.random.randn((2,2))*0.01
b_1 = np.zero((2,1))
W_2 = np.random.randn((1,2))*0.01
b_2 = 0
```

让$$W$$比较小，是因为如果使用$$sigmoid$$函数或者$$tanh$$函数作为激活函数的话，$$W$$比较小，得到的$$|z|$$也比较小（靠近零点），而零点区域的梯度比较大，这样能大大提高梯度下降算法的更新速度，尽快找到全局最优解

如果$$W$$较大，得到的$$|z|$$也比较大，附近曲线平缓，梯度较小，训练过程会慢很多

如果激活函数是$$ReLU$$或者$$Leaky$$ $$ReLU$$函数，则不需要考虑这个问题

如果输出层是$$sigmoid$$函数，则对应的权重$$W$$最好初始化到比较小的值
