# Deeplearning.ai 课程笔记第一部分：神经网络与深度学习

## 1 深度学习引言

### 1.2 神经网络的监督学习

• 对于房价预测和在线广告等应用，采用的是相对标准的神经网络
• 对于图像领域的应用，常常使用卷积神经网络（CNN
• 对于序列数据，例如音频、语言等，常常使用循环神经网络（RNN）（注意不要与递归神经网络混淆）

• 结构化数据：数据以类似关系型数据库的表结构的形式展示
• 非结构化数据：音频、图像或文本等特征无法直接展示的数据

### 1.3 为什么深度学习会兴起？

• 信息化社会带来的数据量的巨大提升
• 硬件更新带来更快的计算速度
• 神经网络算法的不断发展

## 2 神经网络的编程基础

### 2.3 梯度下降

#### 2.3.1 逻辑回归中的梯度下降

```X1                  Feature
X2                  Feature
W1                  Weight of the first feature.
W2                  Weight of the second feature.
B                   Logistic Regression parameter.
M                   Number of training examples
Y(i)                Expected output of i```

```d(a)  = d(l)/d(a) = -(y/a) + ((1-y)/(1-a))
d(z)  = d(l)/d(z) = a - y
d(W1) = X1 * d(z)
d(W2) = X2 * d(z)
d(B)  = d(z)```

```J = 0; dW1 = 0; dW2 =0; dB = 0;                 # Devs
W1 = 0; W2 = 0; B=0;                            # Weights
for i = 1 to m
# Forward pass
z(i) = W1*X1(i) + W2*X2(i) + b
a(i) = Sigmoid(z(i))
J += (Y(i)*log(a(i)) + (1-Y(i))*log(1-a(i)))

# Backward pass
dz(i) = a(i) - Y(i)
dW1 += dz(i) * X1(i)
dW2 += dz(i) * X2(i)
dB  += dz(i)
J /= m
dW1/= m
dW2/= m
dB/= m

W1 = W1 - alpha * dW1
W2 = W2 - alpha * dW2
B = B - alpha * dB```

### 2.4 向量化

#### 2.4.1 向量化逻辑回归

```X       Input Feature, X shape is [Nx,m]
Y       Expect Output, Y shape is [Ny,m]
W       Weight, W shape is [Nx,1]
b       Parameter, b shape is [1,1]```

```W = np.zeros((Nx, 1))
b = 0
dW = np.zeros((Nx, 1))
db = 0

for iter in range(1000):
Z = np.dot(W.T, X) + b      # Vectorization, then broadcasting, Z shape is (1, m)
A = 1 / (1 + np.exp(-Z))    # Vectorization, A shape is (1, m)
dZ = A - Y                  # Vectorization, dZ shape is (1, m)
dW = np.dot(X, dZ.T) / m    # Vectorization, dW shape is (Nx, 1)
db = np.sum(dZ) / m         # Vectorization, db shape is (1, 1)

W = W - alpha * dW
b = b - alpha * db```

### 2.5 Python/Numpy 使用笔记

Tip1: 在 Numpy 中，`obj.sum(axis = 0)` 按列求和，`obj.sum(axis = 1)` 按行求和，默认将所有元素求和。

Tip2: 在 Numpy中，`obj.reshape(1, 4)` 将通过广播机制（broadcasting）重组矩阵。reshape 操作的调用代价极低，可以放在任何位置。广播机制的原理参考下图：

Tip3: 关于矩阵 shape 的问题：如果不指定一个矩阵的 shape，将生成 "rank 1 array"，会导致其 shape 为 `(m, )`，无法进行转置。对于这种情况，需要进行 reshape。可以使用 `assert(a.shape == (5,1))` 来判断矩阵的 shape 是否正确

Tip4: 计算 Sigmoid 函数的导数：

```s = sigmoid(x)
ds = s * (1 - s)```

Tip5: 如何将三维图片重组为一个向量：

`v = image.reshape(image.shape[0]*image.shape[1]*image.shape[2],1)`

Tip6: 归一化输入矩阵后，梯度下降将收敛得更快。

### 2.6 构建神经网络

1. 定义神经网络的结构
2. 初始化模型参数
3. 重复以下循环直至收敛：
• 计算当前的代价函数（前向传播）
• 计算当前的梯度（反向传播）
• 更新参数（梯度下降）

## 3 浅层神经网络

### 3.1 神经网络概述

#### 3.1.1 与逻辑回归的对比

```X1  \
X2   ==>  z = XW + B ==> a = Sigmoid(z) ==> l(a,Y)
X3  /```

```X1  \
X2   =>  z1 = XW1 + B1 => a1 = Sig(z1) => z2 = a1W2 + B2 => a2 = Sig(z2) => l(a2,Y)
X3  /```

#### 3.1.2 表示与计算

• `a0 = x` 表示输入层
• `a1` 表示隐藏层的激活值
• `a2` 表示输出层的激活值

• `W1` 是隐藏层的参数矩阵, 其形状为 `(noOfHiddenNeurons, nx)`
• `b1` 是隐藏层的参数矩阵, 其形状为 `(noOfHiddenNeurons, 1)`
• `z1``z1 = W1*X + b` 的计算结果，其形状为 `(noOfHiddenNeurons, 1)`
• `a1``a1 = sigmoid(z1)` 的计算结果，其形状为 `(noOfHiddenNeurons, 1)`
• `W2` 是输出层的参数矩阵，其形状为 `(1, noOfHiddenNeurons)`
• `b2` 是输出层的参数矩阵，其形状为 `(1, 1)`
• `z2``z2 = W2*a1 + b` 的计算结果，其形状为 `(1, 1)`
• `a2``a2 = sigmoid(z2)` 的计算结果，其形状为 `(1, 1)`

#### 3.1.3 代码实现

```for i = 1 to m
z[1, i] = W1*x[i] + b1      # shape of z[1, i] is (noOfHiddenNeurons,1)
a[1, i] = sigmoid(z[1, i])  # shape of a[1, i] is (noOfHiddenNeurons,1)
z[2, i] = W2*a[1, i] + b2   # shape of z[2, i] is (1,1)
a[2, i] = sigmoid(z[2, i])  # shape of a[2, i] is (1,1)```

```Z1 = W1X + b1     # shape of Z1 (noOfHiddenNeurons,m)
A1 = sigmoid(Z1)  # shape of A1 (noOfHiddenNeurons,m)
Z2 = W2A1 + b2    # shape of Z2 is (1,m)
A2 = sigmoid(Z2)  # shape of A2 is (1,m)```

### 3.2 激活函数

#### 3.2.1 常见激活函数

##### sigmoid

sigmoid 激活函数的取值范围是 [0,1] 。

`sigmoid = 1 / (1 + np.exp(-z)) # Where z is the input matrix`
##### tanh

tanh 激活函数的取值范围是 [-1,1]（sigmoid 函数的偏移版本）。

```tanh = (np.exp(z) - np.exp(-z)) / (np.exp(z) + np.exp(-z)) # Where z is the input matrix
tanh = np.tanh(z)   # Where z is the input matrix```
##### ReLU

ReLU 函数可以解决梯度下降慢的问题（针对正数）。如果你的问题是二元分类（0或1），那么输出层使用 sigmoid，隐藏层使用 ReLU。

`ReLU = np.maximum(0,z) # so if z is negative the slope is 0 and if z is positive the slope remains linear.`
##### leaky ReLU

leaky RELU 与 ReLU 的区别在于当输入为负值时，斜率会较小（不为0）。它和 ReLU 同样有效，但大部分人使用 ReLU。

`leaky_ReLU = np.maximum(0.01*z,z)  #the 0.01 can be a parameter for your algorithm.`

#### 3.2.3 激活函数的导数

sigmoid 函数：

```A = 1 / (1 + np.exp(-z))
dA = (1 / (1 + np.exp(-z))) * (1 - (1 / (1 + np.exp(-z))))
dA = A * (1 - A)```

tanh 函数：

```A = (np.exp(z) - np.exp(-z)) / (np.exp(z) + np.exp(-z))
dA = 1 - np.tanh(z)^2 = 1 - A^2```

ReLU 函数：

```A = np.maximum(0,z)
dA = { 0  if z < 0
1  if z >= 0  }```

leaky ReLU 函数：

```A = np.maximum(0.01*z,z)
dA = { 0  if z < 0
1  if z >= 0  }```

### 3.4 随机初始化

```W1 = np.random.randn((2,2)) * 0.01    # 0.01 to make it small enough
b1 = np.zeros((2,1))                  # its ok to have b as zero```

## 4 深层神经网络

### 4.1 深层神经网络概述

#### 4.1.2 符号定义

• 我们使用 `L` 来定义神经网络的层数（不包含输入层）
• `n` 表示每一层的神经元数量集合
• `n[0]` 表示输入层的维数
• `n[L]` 表示输出层的维数
• `g` 表示每一层的激活函数
• `z` 表示每一层的线性输出
• `Z` 表示向量化后的线性输出
• `w``b` 表示每一层线性输出的对应参数
• `W``B` 表示向量化后的参数
• `a` 表示每一层的激活输出
• `a[0]` 表示输出，`a[L]` 表示输出
• `A` 表示向量化后的激活输出

#### 4.1.3 深层网络中的前向传播

```z[l] = W[l]a[l-1] + b[l]
a[l] = g[l](z[l])```

```Z[l] = W[l]A[l-1] + B[l]
A[l] = g[l](Z[l])```

#### 4.1.4 维数的确认

• `w[l]``dw[l]` 的维数：`(n[l], n[l-1])`
• `W[l]``dW[l]` 的维数：`(n[l], n[l-1])`
• `b[l]``db[l]` 的维数：`(n[l], 1)`
• `B[l]``dB[l]` 的维数：`(n[l], m)`
• `z[l]``a[l]` 的维数：`(n[l], 1)`
• `Z[l]``A[l]` 的维数：`(n[l], m)`
• `dZ[l]``dA[l]` 的维数：`(n[l], m)`

### 4.2 为什么要进行深层表示？

• 多个隐藏层可以将问题从简单到复杂进行拆分，先考虑简单的特征，再逐步变得复杂，最终实现预期的效果；
• 电路理论表明越少的层数需要的单元数呈指数级上升，对神经网络来说也是如此。对于一个复杂任务来说，层数越少每一层所要包含的神经元数量会爆炸式增长。

### 4.3 深层神经网络的模块

#### 4.3.1 前向传播模块

```Input  A[l-1]
Z[l] = W[l]A[l-1] + B[l]
A[l] = g[l](Z[l])
Output A[l], cache(Z[l], W[l], B[l])```

#### 4.3.2 反向传播模块

```Input dA[l], Caches
dZ[l] = dA[l] * g'[l](Z[l])
dW[l] = (1/m) * np.dot(dZ[l], A[l-1].T)
dB[l] = (1/m) * np.sum(dZ[l], axis=1, keepdims=True)
dA[l-1] = np.dot(W[l].T, dZ[l])
Output dA[l-1], dW[l], dB[l]```

• 学习速率
• 迭代次数
• 隐藏层层数
• 隐藏层单元数
• 激励函数的选择

0 条评论

• ### CS229 课程笔记之十五：强化学习与控制

本章将开始介绍「强化学习」与适应性控制。在监督学习中，对于训练集我们均有明确的标签，算法只需要模仿训练集中的标签来给出预测即可。但对于某些情况，例如序列性的决策...

• ### CS229 课程笔记之九：EM 算法与聚类

为了证明 k-means 算法能否保证收敛，我们定义「失真函数」（distortion function）为：

• ### CS229 课程笔记之十四：隐马尔可夫模型基础

将会是任意数量变量的函数，将难以建模。因此，我们会提出两个「马尔可夫假设」来便于我们建模。第一个假设是「有限地平线假设」（limited horizon as...

• ### OJ刷题记录：银行业务队列简单模拟 题目编号:1023

题目要求： 设某银行有A、B两个业务窗口，且处理业务的速度不一样，其中A窗口处理速度是B窗口的2倍，即当A窗口每处理完2个顾客时，B窗口处理完1个顾客。给定到...

• ### 用Python制作恋爱日志

最近一直在学习Python，就想到编写一个程序每天早上自动给女朋友发送微信，内容是我俩相恋时间，每日一句以及一句早安。

• ### 初识VBA

把菜单开发工具显示出来方便以后打开VBA编辑器（点“Visual Basic”打开的那个界面）、设置宏安全性是为了能够打开文件就执行程序（这一步设置后，一...