由 deeplearning.ai 出品,网易引进的正版授权中文版深度学习工程师微专业课程,让你在了解丰富的人工智能应用案例的同时,学会在实践中搭建出最先进的神经网络模型,训练出属于你自己的 AI。
deeplearning.ai
https://www.coursera.org/learn/neural-networks-deep-learning?action=enroll
https://study.163.com/my#/smarts
https://www.bilibili.com/video/av66314465
note
https://blog.csdn.net/red_stone1/article/details/78208851
https://www.zhihu.com/column/DeepLearningNotebook
http://www.ai-start.com/dl2017/
课后作业
https://blog.csdn.net/u013733326/article/details/79827273
https://www.heywhale.com/mw/project/5e20243e2823a10036b542da
- 神经网络和深度学习-3.9
$dZ^{[2]}$ ????????????????
输入为房屋面积 , 通过一个神经元(函数运算),然后输出房价 y
ReLU (Rectified Linear Unit,railu) 修正线性单元 修正是指取不小于0的值
中间三个圈为隐藏单元,每个隐藏单元都来自自己学习到的权重,与输入加权求和。
监督学习的应用
实值估计,在线广告,
机智的选择输入和输出,解决特定问题,并把这部分学习过的组件嵌入到更大型的系统。
普通应用 对应 标准的神经网络NN
图像领域内,卷积神经网络 CNN
对于序列数据,循环神经网络 RNN
更复杂的应用 复杂的混合神经网络架构。
训练数据分为结构化数据和非结构化数据
结构化数据 每个特征都有清晰的定义。
非结构化数据 例如音频,图像,文本
好的网络能够同时适应结构化和非结构化数据
普通的模型无法应用海量数据带来的益处,有时也无法处理海量数据,
而给规模足够大(有许多隐藏神经元)的神经网络输入海量数据,会增强performance
一些算法创新可以让神经网络运行效率更高,效果更好,是我们可以训练更大规模的网络。
传统sigmod函数,让负值梯度趋近于零但不是零,学习会变得非常缓慢,因为当梯度接近0时,使用梯度下降法,参数会变化得很慢,学习也变得很慢。
而relu让负值梯度直接为0,直接不学习。加速梯度下降。
很多时候,有了一个新想法,关于神经网络结构的想法,然后写代码实现想法,结果表现神经网络的效果,然后进一步赶紧神经网络结构的细节。
coursea -> disscusion
m个样本的训练集,遍历这个训练集,
正向过程/传播 forward pass/propagation
反向过程/传播 backward pass/propagation
计算机存储图像,用红绿蓝三个通道的矩阵表示。
在进行网络训练时,通常要unroll或者reshape为一维向量。
(x,y) 来表示一个单独的样本,x是n_x维的特征向量
共有m个样本 :$(x^{(1)},y^{(1)}) , (x^{(2)},y^{(2)}), \dots, (x^{(m)},y^{(m)})$
也可以用大写
m列表示m个样本,n_x行表示每个样本有n_x条特征,表示为 X.shape=(n_x,m)
,有时行列相反。
m列表示m个样本,1行表示每个样本有1个输出标签,表示为 Y.shape=(1,m)
给输入
而 logistic 回归给一个 sigmoid 函数 $$ \hat{y} = \sigma (w^Tx+b) $$
输出为从 0 到 1 的光滑函数
神经网络学习 w 和 b 两个参数,通常 b 对应一个 intercepter 拦截器
为了训练 w 和 b 两个参数,需要定义一个 loss function。给定输入$(x^{(1)},y^{(1)}) , (x^{(2)},y^{(2)}), \dots, (x^{(m)},y^{(m)})$ ,我们希望预测到的
我们可以定义损失函数,衡量预测值与实际值的差距,用误差平方不利于梯度下降,因为会将问题变成非凸non-convex函数(w形状,有多个局部最小值)。 $$ \begin{equation} \mathcal{L}(\hat{y}, y)=\frac{1}{2}(\hat{y}-y)^{2} \end{equation} $$ 换一种损失函数,凸convex函数(v形状,有一个全局最小值)。 $$ \begin{equation} \mathcal{L}(\hat{y}, y)=-(y \log \hat{y}+(1-y) \log (1-\hat{y})) \end{equation} $$
如果 y = 1 时,
如果 y = 0 时, $ \mathcal{L}(\hat{y}, y)= -\log (1-\hat{y}))
loss函数衡量了单个训练样本的表现。cost 函数衡量全体训练样本的表现。 $$ \begin{split} J(w, b)&=\frac{1}{m} \sum_{i=1}^{m} L\left(\hat{y}^{(i)}, y^{(i)}\right)\&=-\frac{1}{m} \sum_{i=1}^{m}\left[y^{(i)} \log \hat{y}^{(i)}+\left(1-y^{(i)}\right) \log \left(1-\hat{y}^{(i)}\right)\right] \end{split} $$ 即损失函数的平均值。
凸优化问题是指
$\chi$ 是闭合的凸集且$f$ 是$\chi$ 上的凸函数的最优化问题,这两个条件任一不满足则该问题即为非凸的最优化问题。为什么要求是凸函数呢?因为如果是下图这样的函数,则无法获得全局最优解。
为什么要求是凸集呢?因为如果可行域不是凸集,也会导致局部最优
gradient descent
已知待训练sigmod函数: $ \hat{y}=\sigma\left(w^{T} x+b\right), \sigma(z)=\frac{1}{1+e^{-z}} $
成本函数: $$ \begin{split} J(w, b)&=\frac{1}{m} \sum_{i=1}^{m} L\left(\hat{y}^{(i)}, y^{(i)}\right)\&=-\frac{1}{m} \sum_{i=1}^{m}\left[y^{(i)} \log \hat{y}^{(i)}+\left(1-y^{(i)}\right) \log \left(1-\hat{y}^{(i)}\right)\right]\end{split} $$ 找到合适的 w 和 b 让成本函数较小。
J(w,b) 是在水平轴 w 和 b 上的曲面,找到 J(w,b) 最小值对应的参数。
方法:
用某个随即参数初始化一个点,朝最陡的方向走。
重复执行$ \omega=\omega-\alpha \frac{dJ(\omega)}{d \omega}
w = w - a * dw; // dw = deltaJ / deltaw; dw是此点的导数 此点函数的斜率
b = b - a * db; // db = deltaJ / deltab; pytorch自动求导
derivatives
slope斜率 = 绿色极限三角形的高除以宽 = 0.003/0.001 = 3
a1 = 2 f(a1) = 6
a2 = 2.001 f(a2) = 6.003
df = f(a2) - f(a1) / (a2 - a1) = 6.003 - 6 / (2.001 - 2) = 3
这个函数任何地方的斜率都是 3。
也就是复杂函数求导
computation graph
神经网络都是按照前向或者反向传播过程来实现的。
首先计算出神经网络的输出,紧接着进行一个反向传输操作。后者用来计算出对应的梯度或者导数。
u = b*c
,v = a + u
,J = 3*v
,则有下图
通过一个从左向右的过程,可以计算出
按照上图计算,$J$ 对
链式法则
a是 logistics 函数的输出,y 是标签真值。
如果有两个特征
其中 $$ \frac{dL}{da} = -\frac{y}{a} + \frac{1-y}{1-a} $$ 其中 $$ \begin{split}\frac{dL}{dz} &= \frac{dL}{da} \frac{da}{dz}\&=(-\frac{y}{a} + \frac{1-y}{1-a}) * (a(1-a))\&=a-y\end{split} $$ 其中目标函数对三个参数的导数如下: $$ \begin{split} \frac{dL}{dw_1} &= x_1*\frac{dL}{dz}\ \frac{dL}{dw_2} &= x_2*\frac{dL}{dz}\ \frac{dL}{db} &= \frac{dL}{dz} \end{split} $$ 然后根据下式更新参数。 $$ \begin{split} w_1 &= w_1 - \alpha \frac{dL}{dw_1}\ w_2 &= w_2 - \alpha \frac{dL}{dw_2}\ b &= b - \alpha \frac{dL}{db} \end{split} $$
上一节均为单一样本的求导与参数更新。实际情况下,训练集会有很多样本。
$$ \begin{split} J(w, b)&=\frac{1}{m} \sum_{i=1}^{m} L(\hat{y}^{(i)}, y^{(i)})\&=-\frac{1}{m} \sum_{i=1}^{m}\left[y^{(i)} \log \hat{y}^{(i)}+(1-y^{(i)}) \log (1-\hat{y}^{(i)})\right] \end{split} $$ 其中 $$ \hat{y}^{i} = a =\sigma (z^{i})=\sigma (w^Tx^{i}+b) $$ 直接求导 $$ \frac{\partial J(w, b)}{\partial w_1} = \frac{1}{m} \sum_{i=1}^{m}\frac{\partial L(\hat{y}^{(i)}, y^{(i)})}{\partial w_i} $$ 计算每一个样本的梯度值,然后求平均,会得到全局梯度值,可以直接用到梯度下降法。
整个过程相当于一次epoch。每次将所有样本计算过一边后,梯度下降一次,更改参数。重复多次。
**显式的使用循环,会使算法很低效。**因此向量化编程有很大的帮助。
消除代码中显式for循环语句的艺术。不能使用显式for循环,numpy隐式循环。
import numpy as np
import time
# vectorization version
a = np.randrom.rand(1000000)
b = np.randrom.rand(1000000)
tic = time.time()
c = np.dot(a,b)
toc = time.tiem()
print("Vectorized version:" + str(1000*(toc-tic)) + "ms")
# for loop version
c = 0
tic = time.time()
for i in range(1000000)
c += a[i]*b[i]
toc = time.time()
print("For loop version:" + str(1000*(toc-tic)) + "ms") # 时间比向量化版本长
CPU 和 GPU 都有并行处理能力 SIMD 单指令多数据流
计算 $$ \begin{split} u &= Av\ u_i &= \sum_i\sum_jA_{ij}v_j \end{split} $$
u = np.zeros((n, 1))
for i
for j
u[i] = A[i][j] * v[j]
# 或
u = np.dot(A,v)
计算 $$ u_i = e^{v_i} $$
u = np.zeros((n, 1))
for i in range(n)
u[i] = math.exp(v[i])
# 或
u = np.exp(v);
np.log(v);
np.abs(v);
np.maximun(v,0) # v中所有元素和0之间相比的最大值
v**2 #v^2
1/v #v的倒数
Logistic 回归求导
J = 0, dw1 = 0, dw2 = 0, db = 0
for i = 1 to n:
z[i] = w^T * x[i] + b
a[i] = sigma(z[i]) #sigma 1 / (1 + e^-x)
J += -[y[i] * log(yhat[i]) + (1 - y[i]) * log(1 - yhat[i])]
dz = a[i] * (1 - a[i]) # dz = da/dz
dw1 = x1[i] * dz[i]
dw2 = x2[i] * dz[i]
db += dz[i]
J = J / m
dw1 = dw1 / m
dw2 = dw2 / m
db = db / m
z = np.dot(w.t ,x) + b
a = 1 / np.exp(-z)
b 是一个实数,python会自动把实数b 扩展成一个 1*m
的行向量
dz = a - y; # dz = dL/dz 不是 da/dz
dw = np.sum(np.dot(x, dz.t)) / m
db = np.sum(dz) / m
# 总向量化编程logistics回归
z = np.dot(w.t ,x) + b
a = 1 / np.exp(-z)
dz = a - y; # dz = dL/dz 不是 da/dz
dw = np.sum(np.dot(x, dz.t)) / m
db = np.sum(dz) / m
w = w - alpha * dw
b = b - alpha * db
仍然需要一个大 for 循环,实现每一次梯度更新,即eopch。
A = np.array([56 , 0 , 4.4 , 68],
[1.2, 104, 52, 8],
[1.8, 135, 99, 0.9])
cal = A.sum(axis = 0) #按列求和 按行求和axis = 1
percentage = 100 * A / cal.reshape(1,4) #A 3x4 cal 1x4
#.reshape(1,4) 可以确保矩阵形状是我们想要的
广播(broadcasting)即同型复制
general principle
size :[m,n] +-*/ [1,n] 把 [1,n] 复制m行变成 [m,n]再和前项运算
size :[m,n] +-*/ [m,1] 把 [m,1]复制n列变成 [m,n] 再和前项
# 避免使用秩为 1 的矩阵
import numpy as np
a = np.random.randn(5)
a.shape #(5, ) 秩为1的数组
np.dot(a, a.T) # 算出来是内积 一个数
# 尽量不要使用秩为1的数组 即
a = np.random.randn(5)
# 改为
a = np.random.randn(5, 1)
a.shape #(5, 1) 秩不为1的数组
np.dot(a, a.T) # 算出来是外积 一个矩阵
# 使用断言加以保障 执行很快
assert(a.shape == (5,1))
#确保形状
reshape
shift + enter 执行代码段
kernel 重启内核
submit assignment 提交任务
2.18 logistic 损失函数的解释
我们设定
$$
\begin{equation}
\hat{y}=P(y=1 \mid x)
\end{equation}
$$
即算法的输出
换句话说,如果 y=1,那么在给定 x 得到 y=1的概率等于
反过来说,如果 y=0,那么在给定 x 得到 y=0 的概率等于$1-\hat{y}$
下边有验证。
简单说
0-1分布/二项分布/伯努利分布,上述两条公式可以合并成 $$ \begin{equation} p(y \mid x)=\hat{y}^{y}(1-\hat{y})^{(1-y)} \end{equation} $$ 当 y = 1或 y = 0 代入上式可以得到上上式的结论。
两边同时取对数,方便展开/求导/优化。 $$ \begin{equation} \log p\left(\left.y\right|x\right)=\log \hat{y}^{y}(1-\hat{y})^{(1-y)}=y \log \hat{y}+(1-y) \log (1-\hat{y}) \end{equation} $$ 概率为1时,log函数为0,概率为0时,log函数为负无穷。
假设所有样本独立同分布 $$ \begin{equation} P= \prod_{i=1}^{m} p\left(y^{(i)} \mid x^{(i)}\right) \end{equation} $$ 由于各个样本独立,因此求得全局最优的条件便是求得各样本最优,也即各个样本取得最优的概率的连乘
两边同时取对数,方便展开/求导/优化。 $$ \begin{equation} \log P= \sum_{i=1}^{m} \log p\left(y^{(i)} \mid x^{(i)}\right) \end{equation} $$ 最大似然估计,即求出一组参数,这里就是w和b,使这个式子取最大值。
也就是说这个式子最大值,$\hat{y}$ 和
右上角方括号内表示网络的层数
右上角圆括号表示第几个训练样本
右下角表示特征索引
这是一个简单的两层神经网络的计算过程,第一层得到的概率
下图为双层神经网络,输入层不算在内。
左边一层称为输入层,第二层称为隐藏层,第三层只有一个节点,称为输出层。在训练时,隐藏层节点的值,不知道。
隐藏层有两个相关的参数 W 和 b,W 是(4,3)的矩阵,有三个输入,b 是(4,1)的矩阵。
输出层有两个相关的参数 W 和 b,W 是(1,4)的矩阵,有四个隐藏层单元,b 是(1,4)的矩阵。
这个圆圈代表了回归计算的两个步骤,首先按照步骤计算出z,然后在第二步计算激活函数。神经网络就是不断重复这个过程
第一隐藏层的第一个节点先计算 $$ \begin{equation} z_{1}^{[1]}=\omega_{1}^{[1]} x+b_{1}^{[1]} \end{equation} $$ 再计算 $$ \begin{equation} a_{1}^{[1]}=\sigma(z_{1}^{[1]}) \end{equation} $$ 上标表示层数,下标表示节点索引(1-4)
第一隐藏层的第二个节点先计算 $$ \begin{equation} z_{2}^{[1]}=\omega_{2}^{[1]} x+b_{2}^{[1]} \end{equation} $$ 再计算 $$ \begin{equation} a_{2}^{[1]}=\sigma(z_{2}^{[1]}) \end{equation} $$
如下图
$$ \begin{split} z_{1}^{[1]}=\omega_{1}^{[1]T} x+b_{1}^{[1]}, a_{1}^{[1]}=\sigma(z_{1}^{[1]}) \ z_{2}^{[1]}=\omega_{2}^{[1]T} x+b_{2}^{[1]}, a_{2}^{[1]}=\sigma(z_{2}^{[1]}) \ z_{3}^{[1]}=\omega_{3}^{[1]T} x+b_{3}^{[1]}, a_{3}^{[1]}=\sigma(z_{3}^{[1]}) \ z_{4}^{[1]}=\omega_{4}^{[1]T} x+b_{4}^{[1]}, a_{4}^{[1]}=\sigma(z_{4}^{[1]}) \ \end{split} $$ 矩阵化
上述输出为
给定输入 x $$ \begin{split} z^{[1]}&=W^{[1]} x+b^{[1]} \ a^{[1]}&=\sigma(z^{[1]}) \ \end{split} $$ (4,1) = (4,3) * (3,1) + (4,1) W 是四个不同的节点,对三个输入的权重
(4,1) = (4,1) $$ \begin{split} z^{[2]}&=W^{[2]} a^{[1]}+b^{[2]} \ a^{[2]}&=\sigma(z^{[2]}) \end{split} $$ (1,1) = (1,4) * (4,1) + (1,1)
(1,1) = (1,1)
样本的循环正向反向,权重是同一套。m个样本
全部变成矩阵运算。
以样本数目直接扩展为矩阵
tanh 函数比 sigmoid 函数激活非线性效果好一些,因为值介于-1和1之间,激活函数的均值为 0。类似数据中心化的效果。
但是 tanh 一般不在输出层使用,因为有时输出为概率,概率在 0 - 1 之间。如果做二分类问题,可以试着用 sigmoid 函数。
tanh 和 sigmoid 在 z 很大或很小时,函数的斜率很接近 0,会拖慢梯度下降。
relu 在 z 为正数时,导数为 1,负数时为 0。
sigmoid 二元分类用,其余不用
tanh 可以替代sigmoid
relu 最常用
leaky relu
Relu 的输入值为负的时候,输出始终为0,其一阶导数也始终为0,这样会导致神经元不能更新参数,也就是神经元不学习了,这种现象叫做“Dead Neuron”。失活。为了解决 Relu 函数这个缺点,在 Relu 函数的负半区间引入一个泄露(Leaky)值。
实际选择激活函数可以在交叉验证集上做个小实验。
激活函数(Activation Function)是一种添加到人工神经网络中的函数,旨在帮助网络学习数据中的复杂模式。类似于人类大脑中基于神经元的模型,激活函数最终决定了要发射给下一个神经元的内容。
如果没有激活函数,就只是一个线性组合。
sigmoid 函数
$$ g(z)=\frac{1}{1+e^{-z}} $$ 求导 $$ g^{\prime}(z) = \frac{d}{d z} g(z) = g(z)(1-g(z)) $$ z 特别大 g(z) = 1 梯度为0
z 特别小 g(z) = 0 梯度为0
z = 0 g(z) = 0.5 梯度为0.25
tanh 函数
$$ g(z) = \frac{e^{z}-e^{-z}}{e^{z}+e^{-z}} $$ 求导 $$ g^{\prime}(z) = \frac{d}{d z} g(z) = 1-g(z)^2 $$ z 特别大 g(z) = 1 梯度为0
z 特别小 g(z) = -1 梯度为0
z = 0 g(z) = 0 梯度为1
ReLU函数
Leaky ReLU函数
待训练参数:$w^{[1]}, b^{[1]}, w^{[2]}, b^{[2]}$, 有隐藏单元:
矩阵
cost 函数为:
$$
J\left(\omega^{[1]}, b^{(1)}, \omega^{[2]}, b^{[2]}\right)=\frac{1}{m} \sum_{i=1}^{n}\mathcal{L}(\hat{y}, y)
$$
其中
梯度下降过程:
重复:
正向传播
$$
\begin{split}
Z^{[1]}&=W^{[1]} x+b^{[1]} \
A^{[1]}&=g^{[1]}(Z^{[1]}) \
Z^{[2]}&=W^{[2]} A^{[1]}+b^{[2]} \
A^{[2]}&=g^{[2]}(Z^{[2]})
\end{split}
$$
反向传播
$$
\begin{split}
dZ^{[2]} &= A^{[2]} - Y_{truth}\
dW^{[2]} &= \frac{1}{m}dZ^{[2]}A^{[1]T}\
db^{[2]} &= \frac{1}{m}np.sum(dZ^{[2]}, axis=1, keepdims=True)\
dZ^{[1]} &= W^{[2]T}dZ^{[2]} * g^{[1]\prime}(Z^{[1]})\
dW^{[1]} &= \frac{1}{m}dZ^{[1]}X^{T}\
db^{[1]} &= \frac{1}{m}np.sum(dZ^{[1]}, axis=1, keepdims=True)\
\end{split}
$$
第一行推导过程公式见dZ ,这里假设使用sigmoid激活函数,直接转化为最终式子,所以没有
第二行直接求导结果为系数,$\frac{1}{m}$ 因为是直接对cost function求导,所以要除以m
第三行 axis=1
水平相加求和,keepdims
防止 python 输出秩为 1 的数组$(n^{[2]},) $
第四行 为什么是
答案的$W^{[2]T}dZ^{[2]}$ 与上边偏导对应的位置刚好相反
第五行
上边的公式解释见下节
任意变量与其导数维度相同 $$ \begin{split} dz^{[2]} &= a^{[2]} - y\ dW^{[2]} &= \frac{1}{m}dz^{[2]}a^{[1]T}\ db^{[2]} &= dz^{[2]}\ dz^{[1]} &= W^{[2]T}dz^{[2]} * g^{[1]\prime}(z^{[1]})\ dW^{[1]} &= \frac{1}{m}dz^{[1]}x^{T}\ db^{[1]} &= dz^{[1]}\ \end{split} $$ 向量化 $$ \begin{split} dZ^{[2]} &= A^{[2]} - Y_{truth}\ dW^{[2]} &= \frac{1}{m}dZ^{[2]}A^{[1]T}\ db^{[2]} &= \frac{1}{m}np.sum(dZ^{[2]}, axis=1, keepdims=True)\ dZ^{[1]} &= W^{[2]T}dZ^{[2]} * g^{[1]\prime}(Z^{[1]})\ dW^{[1]} &= \frac{1}{m}dZ^{[1]}X^{T}\ db^{[1]} &= \frac{1}{m}np.sum(dZ^{[1]}, axis=1, keepdims=True)\ \end{split} $$
权重不能初始化为0。偏置可以初始化为0。若初始化为 0 输入不同的样本,计算过程相同,得到相同的结果和梯度。
神经元对称 symmetric
W1 = np.random.randn((2, 2)) * 0.01 #
b1 = np.zeros((2, 1))
W2 = np.random.randn((1, 2)) * 0.01
b2 = np.zeros((2, 1))
w 初始化为很小的数。b 不受影响。
一般初始化为较小的值,如果初始化较大,使用tanh和sigmoid激活函数时,梯度接近 0。
如果没有tanh和sigmoid激活函数时,初始化大小无所谓
如果网络比较深选用0.01外的初始化倍数
L 表示神经网络的层数
四层公式如下: $$ \begin{split} Z^{[1]}&=W^{[1]} x+b^{[1]} \ a^{[1]}&=g^{[1]}(Z^{[1]}) \ Z^{[2]}&=W^{[2]} a^{[1]}+b^{[2]} \ a^{[2]}&=g^{[2]}(Z^{[2]}) \ Z^{[3]}&=W^{[3]} a^{[2]}+b^{[3]} \ a^{[3]}&=g^{[3]}(Z^{[3]}) \ Z^{[4]}&=W^{[4]} a^{[3]}+b^{[4]} \ a^{[4]}&=g^{[4]}(Z^{[4]}) \ \end{split} $$ 通用公式如下: $$ \begin{split} Z^{[L]} &= W^{[L]}a^{[L-1]}+b^{[L-1]}\ a^{[L]} &= g^{[L]}(Z^{[L]}) \ \end{split} $$
检查网络的bug,按照算法流程逐行检查矩阵维度。
归纳演绎法:从特殊到一般;从一个到整体;从一个实数到一组向量;从一组向量到一个矩阵。
单个样本的维度变化:
使用下边两个公式检查
W/dW的size为($n^{[L]},n^{[L-1]}$),b/db的size为($n^{[L]},1$)
z/dz的size为($n^{[L]},1$),x/dx的size为($n^{[L]},1$)
多m个样本的维度变化,即经过向量化后:
使用下边两个公式检查
W/dW的size为($n^{[L]},n^{[L-1]}$),b/db的size为($n^{[L]},m$),其中b使用python广播机制,每列相等
Z/dZ的size为($n^{[L]},m$),X/dX的size为($n^{[L]},m$)
网络第一层,当成一个边缘检测器/特征检测器。隐藏单元就是下边的20ge小方块,第一个小方块会找垂直方向的边缘线,第19个会找水平方向的边缘线。找输入照片的各个边缘。
第二层,把被检测到的边缘组合成面部的不同部分。比如:一个神经元会去找眼睛的部分,另一个神经元会去找鼻子的部分 。然后把这许多的边缘结合在一起,就可以开始检测人脸的不同部分。
第三层,把这些部分放在一起,就可以识别或检测不同的人脸。
语音识别实例:
第一层,探测比较低层次的音频波形的一些特征(低频、高频、音调)
第二层,然后把特征组合成一个单元,去探测声音的基本单元(音位)
第三层,组合音位,识别单词
第四层,组合单词,识别词组/语句
解释
前几层,学习低层次的简单特征,可以理解为探测简单的函数,比如边缘。后几层,把简单的特征结合在一起,就能学习更多复杂的函数。
circuit theory 电路理论
浅层网络需要指数级的隐藏单元才能像一些函数 与或非门一样计算。
可以先用浅层做实验,然后逐步加深。
第一行是正向传播
第二行是反向传播 (需要缓存正向传播过程中 z 的值来计算梯度)
根据反向传播过程中每层计算出的梯度,更新参数
正向传播
输入
输出
循环: $$ \begin{split} Z^{[L]}&=W^{[L]} A^{[L-1]}+b^{[L]} \ a^{[L]}&=g^{[L]}(Z^{[L]}) \end{split} $$
反向传播
输入
提取缓存
输出
循环:
$$
\begin{split}
dz^{[L]}&=da^{[L]} * g^{[L]\prime}(z^{[L]}) \
dW^{[L]}&=dz^{[L]}a^{[L-1]T } \
db^{[L]}&=dz^{[L]} \
da^{[L-1]}&=W^{[L]T}dz^{[L]}\
dz^{[L]}&=W^{[L+1]T}dz^{[L+1]} * g^{[L]\prime}(z^{[L]}) \
\end{split}
$$
这里的导数是损失函数 L 对参数求导,第五行是dz的另一种表示,*表示逐点相乘。
$$
\begin{split}
dZ^{[L]}&=dA^{[L]} * g^{[L]\prime}(Z^{[L]}) \
dW^{[L]}&=\frac{1}{m}dZ^{[L]}A^{[L-1]T } \
db^{[L]}&=\frac{1}{m}np.sum(dZ^{[L]},axis=1,keepdims=True) \
dA^{[L-1]}&=W^{[L]T}dz^{[L]}
\end{split}
$$
上式为向量化后,其中
参数:$W^{[1]},b^{[1]},W^{[2]},b^{[2]},W^{[3]},b^{[3]},\dots$
超参数: 学习率$\alpha$,迭代次数,隐藏层数$L$,隐藏单元$n^{[1]},n^{[2]},\dots$,激活函数
momentum,mini batch_size,正则化参数
超参数确定控制了参数的值。
必须通过训练/交叉验证,试试各种参数。看那个loss下降又小又快
Geoffrey Hinton 推动反向传播/波尔兹曼机
Yann LeCun(Hinton的学生)
Yoshua Bengio 推动RNN
AlexNet
全息图 hologram
Relu 等同于许多 logistics 单元
变分法
建模型:先记录测量, 对其应用非线性变化,直到状态向量变成表达式。这项活动变得线性。
不能假设线性,应该找一个从观察转换到潜在变量(有因果能力)的转换,线性操作。比如潜在变量的矩阵乘积,就是如此。
深度强化学习
概率图模型
GAN