RNN

序列数据

一个序列$x^{\langle 1 \rangle}, x^{\langle 2 \rangle}, …, x^{\langle t \rangle}, …, x^{\langle T_{x} \rangle}$,长度为$T_{x}$

  • $x^{\langle t \rangle}$可使用vocabulary中的形如$[0,0,0,…,1,…,0]$的one-hot表示

RNN结构

输入输出长度相同(每个时刻一个输出)

当前时刻的处理,引入了前一时刻的activation

  • parameters第一个下标,表示该p是用于计算谁的系数;第二个下标,表示该p是谁前面的系数
  • $W_{a}$为$W_{aa},W_{ax}$横向拼接;$[a^{\langle t-1 \rangle},x^{\langle t \rangle}]$为$a^{\langle t-1 \rangle},x^{\langle t \rangle}$纵向拼接
  • 相当于$x^{\langle t \rangle}$位于输入层,$a^{\langle t \rangle}$位于(一层)隐藏层,$\hat{y}^{\langle t \rangle}$位于输出层

一些其他结构的RNN包括:

many-to-one

输出只使用$\hat{y}^{\langle T_{x} \rangle}$

one-to-many

输入只使用$\hat{x}^{\langle 1 \rangle}$

输入输出长度不同

两个结构拼接 encoder+decoder
前一个结构只有输入;后一个结构只有输出

语言模型

  • 输入:$x = [0, y^{\langle 1 \rangle}, y^{\langle 2 \rangle}, …, y^{\langle T_{y} - 1 \rangle}]$
  • softmax,p维度为字典size
  • 输出:$y = [p(\hat{y}^{\langle 1 \rangle}|0), p(\hat{y}^{\langle 2 \rangle}|y^{\langle 1 \rangle}), p(\hat{y}^{\langle 3 \rangle}|y^{\langle 1 \rangle}y^{\langle 2 \rangle}), …]$
    • 即,given $y^{\langle 1 \rangle}, y^{\langle 2 \rangle}, …, y^{\langle t \rangle}$,得到$y^{\langle t + 1\rangle}$的各字典项概率
    • 例如,$p(\hat{y}^{\langle 1 \rangle}|0)$为句子开头(已输入为$0$时,下一个)单词,为字典各项的概率

sampling novel sequences

利用训好的语言模型,随机生成语句

即,将$(\hat{y}^{\langle 1 \rangle}|0)$,作为$y^{\langle 1 \rangle}$,得到$(\hat{y}^{\langle 2 \rangle}|y^{\langle 1 \rangle})$;继续将$(\hat{y}^{\langle 2 \rangle}|y^{\langle 1 \rangle})$,作为$y^{\langle 2 \rangle}$…

具体来讲,首先,从第一个0元素输出$\hat{y}^{\langle 1 \rangle}$的softmax分布中,sample一个word作为新语句的首词$y^{\langle 1 \rangle}$。然后,计算$\hat{y}^{\langle 2 \rangle}$,从$\hat{y}^{\langle 2 \rangle}$的softmax分布中,继续sample一个word作为$y^{\langle 2 \rangle}$,以此类推,直到产生EOS(或设定语句长度上限)

  • sample方式,使用softmax得到的词汇表中各word的概率,来进行选取(np.random.choice可以设定序列中各个元素的出现概率,来进行选取)
  • 引入采样的是为了保证每个单词都有产生的可能,如果每次只是选取softmax对应的最大值,那么有些单词会永远生成不到,而且生成的句子会极为相似
  • 采样过程中可能会生成UNK字符,为了避免生成这种无意义字符,可以重复采样,直到得到一个非UNK字符
  • 模型的初始输入可以不用零向量,而是用某一个单词的one hot向量作为赋值,这样可以生成与该单词主题相关的句子

这样得到的生成语句,体现着该语言模型的特性(例如新闻报道风格、莎士比亚文学风格…)

cost funtion

定义各个时刻的loss,则序列总体loss为各时刻loss的累加

门控递归单元 get recurrent unit, GRU

解决梯度消失问题,使得较深层能够利用浅层信息


对比naive RNN

关键在于$a^{\langle t-1 \rangle}, x^{\langle t \rangle}, a^{\langle t \rangle}$,而$\hat{y}^{\langle t \rangle}$可由$a^{\langle t \rangle}$算出


GRU,引入记忆细胞$c^{\langle t \rangle}$,相当于$a^{\langle t \rangle}$
由此,关键在于通过$c^{\langle t-1 \rangle}, x^{\langle t \rangle}$,如何求算$c^{\langle t \rangle}$

  • 若按naive计算,$\tilde{c}^{\langle t \rangle} = g_{1}(W_{c}[c^{\langle t-1 \rangle},x^{\langle t \rangle}] + b_{c}) = tanh(W_{c}[c^{\langle t-1 \rangle},x^{\langle t \rangle}] + b_{c})$
  • 或者直接透传,即本层不进行计算,直接输出$c^{\langle t-1 \rangle}$

进一步定义一个门,update gate, $\Gamma_{u} = \sigma(W_{u}[c^{\langle t-1 \rangle},x^{\langle t \rangle}] + b_{u})$

  • 由于使用sigmoid,$\Gamma_{u}$的值,大多数情形下,或者极为接近0,或者极为接近1
  • $\Gamma_{u}$决定使用按naive计算(遗忘),还是直接透传(记忆)

综上,

  • $*$为逐元素乘
  • $c^{\langle t \rangle}$是多维的,可能某些位上需要计算(遗忘),某些位上需要透传(记忆)

完整版GRU

  • related gate, $\Gamma_{r}$描述$c^{\langle t-1 \rangle}$与$c^{\langle t \rangle}$之间的相关性
  • 记忆细胞$c^{\langle t \rangle}$相当于$a^{\langle t \rangle}$

长短期记忆单元 long short term memory, LSTM

  • 记忆细胞$c^{\langle t \rangle}$不再相当于$a^{\langle t \rangle}$
  • 关键在于通过$c^{\langle t-1 \rangle}, a^{\langle t-1 \rangle}, x^{\langle t \rangle}$,如何求算$c^{\langle t \rangle}, a^{\langle t \rangle}$
  • update、forget门,分别考虑需要计算(遗忘),某些位上需要透传(记忆)
  • 通过output门指定,基于$c^{\langle t \rangle}$计算$a^{\langle t \rangle}$

双向RNN

  • $a^{\langle t \rangle}$分为$\overrightarrow{a}^{\langle t \rangle}$和$\overleftarrow{a}^{\langle t \rangle}$
  • 先正向计算从$\overrightarrow{a}^{\langle 1 \rangle}$至$\overrightarrow{a}^{\langle T_{x} \rangle}$;再反向计算$\overleftarrow{a}^{\langle T_{x} \rangle}$至$\overleftarrow{a}^{\langle 1 \rangle}$
    • 可将初始化$\overrightarrow{a}^{\langle 0 \rangle}$和$\overrightarrow{a}^{\langle T_{x}+1 \rangle}$都设为0
  • $\hat{y}^{\langle t \rangle}$由$\overrightarrow{a}^{\langle t \rangle}$和$\overleftarrow{a}^{\langle t \rangle}$算出,(如naiveRNN,$g(W_{y}[\overrightarrow{a}^{\langle t \rangle},\overleftarrow{a}^{\langle t \rangle}]) + b_{y}$)

Deep RNN

  • 隐藏层有多层,注意Deep RNN的隐藏层是要引入了前一时刻的activation的!
    • 不引入前一时刻的activation,可直接在RNN隐藏层上,堆一个NN来给出$\hat{y}^{\langle t \rangle}$(相当于RNN的hidden unit使用的一个NN)
  • 由于Deep RNN的隐藏层是要引入了前一时刻的activation,系数会很多,隐藏层一般不多(3,不像Deep NN、Deep CNN,可以很深)

人脸验证

问题分析

输出:砍掉softmax层,直接输出一个多维向量,相当于对输入图像进行encoding
验证:待验证输入、目标,分别计算网络输出(特征)向量,衡量两向量的相似程度

  • 足够相似(相近),则认为匹配成功;否则,认为匹配不成功
  • 除了基于距离计算相似度,也可以训练一个二分类器,给出两种类别(同一个人、不同的人)

问题处理

  • 多分类:不同人物采集多张图片,每个人物作为一个类,多分类问题训练RNN
    • 缺点是各类中(即同一个人)数据可能较少
  • triplet cost
    • 使用$(Anchor, Positive, Negative)$形式数据训练,构造cost function使得A-P相似度大于A-N
    • 构造triplet时,选择与A-P相近的A-N,以确保能区分相似不同的人脸

人脸识别

  • 全库遍历,与待识别输入做人脸验证,成功hit的结果作为识别成功

注意

人脸验证的RNN应用,表明NN不单单可以通过(训练一个网络),由输出层(sigmoid、softmax)给出分类、回归结果
还可以直接使用(预训练好的网络)中间隐藏层的输出,作为把输入进行encoding

  • 输入 <-> encoding可以认为是一一映射,这个对应着图片的内容,即用一个多维encoding向量来描述输入图片
  • 因此,可以基于不同输入encoding的相似性,衡量两个图片是否是同一内容,来解决一些问题
  • 选择深、浅隐藏层输出,对应着使用大、小粒度的特性

目标检测 object detection

问题分析

输出:给出是否存在object的概率$p_{c}$,object的中心点$b_{x},b_{y}$和宽高$b_{w},b_{h}$,以及object属于哪个具体类别的指示$c_{1},c_{2},c_{3},…$

$(p_{c},b_{x},b_{y},b_{w},b_{h},c_{1},c_{2},c_{3},…)$

问题处理

  • sliding windows
    • 训练:closely cropped data;检测:sliding windows with different sizes
    • sliding windows计算效率较低
    • 使用卷积替代FC,使得图像整体输入处理,即可得到sliding windows结果(提高计算效率)
  • YOLO
    • 输入打格子,不做滑动,每个格子粒度构建label训练、检测
    • $b_{w},b_{h}$可能大于1(跨格子)
    • 非最大值抑制 non-max suppression:高IoU的一系列格子,只选$p_{c}$最大的
    • 多object在同一个grid:anchor box预定义bounding box形状,来区分不同的object
      • 使用前:各object <-> grid cell
      • 使用后:各object <-> (grid cell, bounding box)

评价指标

  • 交并比 intersection over union,IoU

CNN

图像卷积

卷积filter

一般为$3 \times 3$,例如:

垂直边缘检测

水平边缘检测

  • 若其他filter内数值不同,对应不同的特性、角度
  • 可以把这些数值作为参数$w$

padding

将原图像四周,补充一圈(对于$3 \times 3$大小的filter)

  • 卷积之后,图像大小不变
  • (用0padding)

步长

filter每次求卷积值后移动的长度,可以大于1

图像$n \times n$,filter $f \times f$,padding $p$,步长$s$,则输出维度为:$\left \lfloor \frac{n+2p-f}{s} + 1 \right \rfloor$

multiple filters卷积

  • 维度:$(n \times n \times n_{c}) * (f \times f \times n_{c})$ —> $((n - f + 1) \times (n - f + 1) \times n_{f})$,其中$n_{c}$为chanel数,$n_{f}$为卷积filter数
    • 使用一个$f \times f \times n_{c}$卷积,得到$((n - f + 1) \times (n - f + 1))$
    • 使用$n_{f}$个$f \times f \times n_{c}$卷积,将结果堆叠,得到$((n - f + 1) \times (n - f + 1) \times n_{f})$

卷积unit

维度检查

对于第$l$层

  • $f^{[l]}$:filter大小
  • $p^{[l]}$:padding大小
  • $s^{[l]}$:stride大小
  • input维度:$n^{[l-1]} \times n^{[l-1]} \times n_{c}^{[l-1]}$
  • output维度:$n^{[l]} \times n^{[l]} \times n_{c}^{[l]}$

可知关系

  • $n^{[l]} = \left \lfloor \frac{n^{[l-1]}+2p^{[l]}-f^{[l]}}{s^{[l]}} + 1 \right \rfloor$
  • $n_{c}^{[l]}$:本层filter数量($n_{c}^{[0]}$原始图像chanel数)
  • 本层filter的维度:$f^{[l]} \times f^{[l]} \times n_{c}^{[l-1]}$

activation

  • 卷积操作相当于线性$W$,进而将卷积结果进一步加$b$
  • 上述结果输入一个激活函数(如ReLU)

多个filters操作、堆叠,即构成一个卷积层

CNN各层

conv卷积层

pooling

  • 按filter抽取(如max pooling,找到各filter区域最大值)(有点像马赛克化)
  • 没有需要学习的参数,只需要设置超参数(filter大小、步长)

fully connected,FC

  • 这是NN一层

一般的,随着层数变深,图像长宽的大小$n^{[l]}$变小,但$n_{c}^{[l]}$会变大

CNN结构

经典结构

conv + pooling -> conv + pooling -> fc -> fc -> softmax

残差网络 residual network

residual block

第$l$层输入,向第$l+2$层激活函数传递

$1 \times 1$ conv

  • 控制$n_{c}$大小
  • 增加非线性(使用了激活函数)

inception network

并行堆叠conv、pooling等模块作为一层

  • $1 \times 1$ conv作为bottleneck层,加速计算

深度学习基础

NN基础

损失函数 & 成本函数 loss function & cost function

  • 损失函数loss:单样本
  • 成本函数cost:全体平均

激活函数 activation function

  • slgmold / tanh
  • ReLU / leaky ReLU / P ReLU

输出层

  • softmax,多分类,和为1(归一化)

梯度下降 gradient descent

寻找合适的$w$、$b$的值,能够minimize $J(w,b)$,即fit the model

  1. 初始化$w$、$b$
  2. 计算$dw$、$db$
  3. 更新$w$、$b$
  4. 迭代2、3步骤至指定次数

根据$L$ -> $J(w,b)$,单样本 -> 全体
计算$dw$、$db$的方式:

正向传播 forward propagation

正向传播,计算结果

单样本,第$l$层

  • W.shape = $(n^{[l]}, n^{[l-1]})$
  • b.shape = $(n^{[l]}, 1)$
  • $a^{[l-1]}$.shape = $(n^{[l-1]}, 1)$
  • $z^{[l]}$.shape = $(n^{[l]}, 1)$
  • $a^{[l]}$.shape = $(n^{[l]}, 1)$

全体,第$l$层

  • $A^{[l-1]}$.shape = $(n^{[l-1]}, m)$
  • $Z^{[l]}$.shape = $(n^{[l]}, m)$
  • $A^{[l]}$.shape = $(n^{[l]}, m)$

反向传播 backward propagation

反向传播,计算梯度

简略推导(箭头反向求导,使用相乘,依据链式法则)

  • $dZ^{[l]}$.shape = $Z^{[l]}$.shape
  • $dW^{[l]}$.shape = $W^{[l]}$.shape
  • $db^{[l]}$.shape = $b^{[l]}$.shape

  • 根据$J(w,b)$计算最后的$dA^{[L]}$

  • 求算时,输入$dA^{[l]}$,输出$dA^{[l-1]}$

模型性能

解决high bias

训练误差大(比如和人工相比)
模型性能不够

  • 更大更深的网络
  • 增加训练时长
  • (尝试其他网络结构)

解决high variance

训练误差小,验证/测试误差相对训练误差增大较多
模型过拟合

  • 更多(多样)的数据
  • 正则化
  • (尝试其他网络结构)

模型可能同时存在high bias和high variance
尝试独立的先解决high bias再解决high variance

正则化 regularization

L2正则,解决过拟合

(L1正则,使w稀疏化)

  • $\lambda$作为超参数

向量化的L2正则求算

  • w.shape = $(n^{[l]}, n^{[l-1]})$

如何使用

  • dw的增加项,为L2正则项的求导结果

随机失活 dropout

随机去除网络中一些节点

对每一层,设置该层的节点使用概率
例如,对于第3层
d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep_prob
a3 = np.multiply(a3, d3)
a3 \= keep_prob <- inverted dropout,修正期望值

使用时机:

  • 训练,例如每个样本,或者每次梯度下降
  • 测试,不使用dropout

训练性能

初始化$W$

使得w不太大也不太小,尽量避免梯度爆炸和消失

  • ReLU:$W^{[l]} = np.random.rand(W^{[l]}.shape) * np.sqrt(\frac{2}{n^{[l-1]}})$
  • tanh:$W^{[l]} = np.random.rand(W^{[l]}.shape) * np.sqrt(\frac{1}{n^{[l-1]}})$

梯度检查 grad check

  1. 已知的$J(W, b)$看做$\theta_{i}$的函数,$J(W^{[1]}, b^{[1]}, W^{[2]}, b^{[2]}, …) = J(\theta_{1}, \theta_{2}, \theta_{3}, \theta_{4}, …)$
  2. 已知的$dW, db$看做$d\theta_{i}$
  3. 对于每一个$i$,计算$d\theta_{approx}[i]$,最终得到$d\theta_{approx}$,对比$d\theta_{approx}$和$d\theta$
  • 注意norm没有平方,是距离,需要差方和后开方

mini-batch gradient descent

加速训练
将整个数据集分为若干个mini-batch,每个梯度下降迭代,使用一个mini-batch进行
这样,用整体数据集进行一次训练迭代(epoch),可进行多次梯度下降迭代(全体数据量/mini-batch大小)

typical mini-batch size: 64, 128, 256, 512

梯度下降替代算法

背景知识:指数平滑

平滑值$v_t$

效果接近于每次对$\frac{1}{1-\beta}$个值做平均

迭代获取:

  1. $v_{\theta} = 0$
  2. repeat: 获取下一个$\theta_{t}$,$v_{\theta} = \beta v_{\theta} + (1-\beta) \theta_{t}$

偏差修正(修正冷启动):

动量梯度下降 momentum

对梯度下降应用指数平滑($\beta=0.9$),本质上减少了不必要的抖动,也就加速向最优值靠拢

on iteration $t$

  • compute $dw$, $db$ on current mini-batch
  • $v_{dw} = \beta v_{dw} + (1 - \beta)dw$
  • $v_{db} = \beta v_{db} + (1 - \beta)db$
  • $w = w - \alpha \ v_{dw}$
  • $b = b - \alpha \ v_{db}$

RMSprop

比率化$dw$, $db$

on iteration $t$

  • compute $dw$, $db$ on current mini-batch
  • $s_{dw} = \beta s_{dw} + (1 - \beta)dw^{2}$
  • $s_{db} = \beta s_{db} + (1 - \beta)db^{2}$
  • $w = w - \alpha \frac{dw}{\sqrt{s_{dw}}}$
  • $b = b - \alpha \frac{db}{\sqrt{s_{db}}}$

Adam

结合momentum、RMSprop($\beta_{1}=0.9, \beta_{2}=0.999$)

on iteration $t$

  • compute $dw$, $db$ on current mini-batch
  • $v_{dw} = \beta_{1} v_{dw} + (1 - \beta_{1})dw$
  • $v_{db} = \beta_{1} v_{db} + (1 - \beta_{1})db$
  • $s_{dw} = \beta_{2} s_{dw} + (1 - \beta_{2})dw^{2}$
  • $s_{db} = \beta_{2} s_{db} + (1 - \beta_{2})db^{2}$
  • $V^{corrected}_{dw} = \frac{v_{dw}}{1 - \beta_{1}^{t}}$
  • $V^{corrected}_{db} = \frac{v_{db}}{1 - \beta_{1}^{t}}$
  • $S^{corrected}_{dw} = \frac{s_{dw}}{1 - \beta_{2}^{t}}$
  • $S^{corrected}_{db} = \frac{s_{db}}{1 - \beta_{2}^{t}}$
  • $w = w - \alpha \frac{V^{corrected}_{dw}}{\sqrt{S^{corrected}_{dw}}}$
  • $b = b - \alpha \frac{V^{corrected}_{db}}{\sqrt{S^{corrected}_{db}}}$

学习率衰减 learning rate dacay

学习率随epoch进行而衰减

log-scale random搜索超参数

例如,对于学习率$\alpha$,希望从0.0001至1范围内选择

r = -4 * np.random.rand()
alpha = 10 ** r

正则化激活函数输入 batch norm

输入数据正则化

激活函数输入正则化

进一步设定均值、标准差,对$z^{(i)}_{nrom}$进行变换,$\tilde{z}^{(i)} = \gamma z^{(i)}_{nrom} + \beta$,使用$\tilde{z}^{(i)}$代替$z^{(i)}$输入激活函数
$\gamma$、$\beta$为参数
此外,batch nrom会消除参数$b$,即模型参数为$w, \gamma, \beta$

  • batch nrom不仅能加速训练(最优求解过程),在covariate shift问题(例如检测对象从“黑猫”偏移至“橘猫”)上也能一定程度上提升模型性能(限定了稳定的均值和标准差,前层输出变动,对后层输入影响较小)
  • mini-batch训练时,batch norm的均值、标准差计算,使用current mini-batch的数据
  • mini-batch测试时,batch norm的均值、标准差计算,使用训练时(同一层)各个mini-batch获取的均值、标准差,进行指数平滑来估算

学习策略

evaluation metric

dev set + evaluation metric,进行模型选择(模型形式、超参数)

  • optimizing metric
  • satisficing metric

只使用一个定量的evaluation (optimizing) metric

通常的工作流程:

  1. 选择算法/超参数等
  2. 使用training set对模型进行训练
  3. 使用dev set + evaluation metric对训练得到的模型进行评估
  4. 更换算法/超参数,返回2,直到找到最佳模型
  5. 使用test set对最终得到的模型进行评估,得到对模型性能的无偏估计

此外,特别的,当模型在实际应用上出现问题时,需要考虑是否改变dev set + evaluation metric

bias & variance

  1. 根据training error与Bayes error/human level error对比,判断bias
  2. 根据dev/test error与training error对比,判断variance

处理方式见上文

error analysis
分析error中,大部分是哪种类型,专门进行关注(并能得到解决后,性能提升的ceiling)
注意,这个ceiling可以指导模型下一步的关注方向

training set v.s. dev/test set

training set的数据与dev/test set的数据(分布)不同
dev/test set为真实(关注问题)的数据

bias & variance analysis

  • 从training set中split一部分来做training-dev set,这部分不做training,只用于对比dev error,这样可区分high variance和data mismatch
training set dev set
human level human level error
error on examples trained on training error
error on examples not trained on training-dev error dev/test error
  • human level error <-> training error: avoidable bias
  • training error <-> training-dev error: variance
  • training-dev error <-> dev/test error: data mismatch

data mismatch处理方法:

重分数据集

  • mix -> shuffle -> re-split:但是新的dev/test set不能较好反映真正关心的问题(已经与原dev/test set不同)
  • 从dev/test set中抽出一部分,加入training set

模拟数据集

  • 找到dev/test set特殊在哪里,尝试在training set中合成模拟/收集类似的数据作为训练集
  • 模拟数据集时,需要注意合成方法有可能会引入过拟合问题(模拟的数据之间太相似)

迁移学习 transfer learning

已经不只是数据偏移这么简单了,target问题完全发生了变化

场景:

  • Task A、Task B输入类别相同(例如都是图像)
  • Task A的数据量大于Task B(否则直接用B的数据就好了)
  • Task A的low level特征,应该对Task B是有益的

处理方法:

  • 先用一个数据集pre training,再用另一个数据集fine tuning(随机参数/层替换最后一/若干层,冻结其它层及参数,重新训练)

多任务学习 multi-task learning

target问题同时有多个

场景:

  • low level特征对各个Task是有益的
  • 各个Task的数据量差不多,但都不多(合起来则还可以)

处理方法:

  • 一个网络,输出层对应各个Task