Ref:

  1. https://zh.d2l.ai/index.html
    《动手学深度学习》第二版
  2. https://www.bilibili.com/video/BV1Pa411X76s/?p=17&spm_id_from=pageDriver&vd_source=21687f13b3a0514d15ea0171e45d7ded
    吴恩达机器学习Deeplearning.ai课程
  3. https://speech.ee.ntu.edu.tw/~hylee/ml/2022-spring.php
    HUNG-YI LEE MACHINE LEARNING 2022 SPRING

对机器学习的查漏补缺

1. 模型收敛——代价函数极小:梯度下降算法(Gradient descent algorithm)

考虑一个二元代价函数:

minw,bJ(w,b)\min_{w,b}J(w,b)

想求得满足条件的w,bw,b,则需要构建如下算法:

w=wαwJ(w,b)\begin{equation} w = w - \alpha \frac{ \partial }{ \partial w } J(w,b) \end{equation}

b=bαbJ(w,b)\begin{equation} b = b - \alpha \frac{ \partial }{ \partial b } J(w,b) \end{equation}

式中,α\alpha称作学习率,影响模型收敛的速度。α\alpha越大,梯度下降越快,也越容易过冲(发散),反之越慢,但可保证模型收敛。

举例:线性回归模型

model:

fw,b=wx+bf_{w,b} = wx + b

Cost func:

J(w,b)=12mi=1m(fw,b(x(i))y(i))2J(w,b) = \frac{1}{2m} \sum_{i=1}^{m} (f_{w,b}(x^{(i)}) - y^{(i)})^2

Gradient Descent Algorithm:

initialize w,bw,b, then repeat until convergence:{

w=wαwJ(w,b) w = w - \alpha \frac{ \partial }{ \partial w } J(w,b)

b=bαbJ(w,b) b = b - \alpha \frac{ \partial }{ \partial b } J(w,b)

(convex func: 凸函数)
}

Batch gradient descent: 用所有的数据来进行梯度下降(但其实很多时候是取子集)。

2. 从一元线性模型到多维特征——向量化

模型变化:

fw,b=wx+bf_{w,b} = wx + b

进化到

fW,b=i=1nwixi+bf_{\bold W,b} = \sum_{i = 1}^{n}w_ix_i + b

fW,b=wx+bf_{\bold W,b} = \bold w \centerdot \bold x + b

代价函数的变化:

minw,bJ(w,b)\min_{w,b}J(w,b)

w=wαwJ(w,b)\begin{equation} w = w - \alpha \frac{ \partial }{ \partial w } J(w,b) \end{equation}

b=bαbJ(w,b)\begin{equation} b = b - \alpha \frac{ \partial }{ \partial b } J(w,b) \end{equation}

进化到

minw,bJ(w,b)\min_{\bold w,b}J(\bold w,b)

wj=wjαwjJ(w,b)\begin{equation} w_j = w_j - \alpha \frac{ \partial }{ \partial w_j } J(\bold w,b) \end{equation}

b=bαbJ(w,b)\begin{equation} b = b - \alpha \frac{ \partial }{ \partial b } J(\bold w,b) \end{equation}

代码实现:

  1. 利用for循环实现矢量点积;
  2. 利用np.dot(vector_1, vector_2)实现

Normal Equation(正规方程):

针对线性回归问题的梯度下降替代算法

多元线性回归问题中的参数

  1. wjw_j:对于取值范围不同的特征,采取缩放的手段,有利于梯度下降算法运行。
  • 方式1:均值标准化

xi=xiμimaxxminxx_i = \frac{x_i - \mu_i}{max_x - min_x}

  • 方式2:z-score标准化

xi=xiμiσix_i = \frac{x_i - \mu_i}{\sigma_i}

(其实还有很多,详见《数据挖掘》理论与实践)

  • 方式三:最小最大值标准化

xi=ximinXmaxXminX(new_maxnew_min)+new_minx_i = \frac{x_i - min_X}{max_X - min_X}(new\_max - new\_min) + new\_min

  • 方式四:小数标准化

xi=xi10jx_i = \frac{x_i}{10^j}

  1. 学习率α\alpha:

迭代次数-损失函数图:也称学习曲线(learning curve)

自动收敛测试:
设置一个阈值ϵ=very small value\epsilon = very \space small \space value,检查J(w,b)J(\bold w,b)每次迭代的减少量,小于ϵ\epsilon认为模型收敛。(不如看learning curve)

学习率设定过大,对于二次函数型的代价函数,迭代多次可能损失函数越来越大,对于其他震荡函数,也很难得到一个真正的极小值。

经验:With a small enough α\alpha, $ J(\bold w, b)$should decrease on every iteration. (如果不是,大概率就是代码有bug了)

3. 从线性到非线性——Polynomial Regression

玄学:Feature Engineering (用你的直觉/想象力,通过之前模型中的特征,对他们进行变换、组合,从而得到新的特征的过程)

4. 分类问题

逻辑回归(logistic regression,西瓜书翻译为对数几率回归,怪怪的)

线性回归并不适合分类问题,因为分类问题的输出是有限的。

决策边界与逻辑回归:

逻辑回归的输出总是在0-1之间,逻辑回归虽然名字里有“回归”,但它更适合用到二元分类问题中(历史遗留问题)

举例:肿瘤大小判断发病与否(二元分类问题)

img01.Sigmoid Function/Logistic Fuction

img01.Sigmoid Function/Logistic Fuction

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

注意到g(0)=0.5g(0) = 0.5

利用Sigmoid函数建模分类问题:

f(x)=wx+bf(\bold x) = \bold w \centerdot \bold x + b

z=wx+bz = \bold w \centerdot \bold x + b

f(w,b)(x)=11+ez=11+e(wx+b)f_{(\bold w,b)}(\bold x) = \frac{1}{1+e^{-z}} = \frac{1}{1+e^{-(\bold w \centerdot \bold x + b)}}

输出为分到positive的概率,换言之:

f(w,b)(x)={P(f(x)=1)x;w,b}f_{(\bold w,b)}(\bold x) = \{P(f(\bold x)=1) | \bold x_;\bold w,b\}

决策边界定义为:

z=0z = 0

1699629188484.png

Ex.1:

z=wx+bz = \bold w \centerdot \bold x + b

fw,b(x)=g(z)=11+ezf_{\bold w, b}(\bold x) = g(z) = \frac{1}{1+e^{-z}}

decision_boundaryz=0wx+b=0decision\_boundary \rightarrow z = 0 \rightarrow \bold w \centerdot \bold x + b = 0

求出来的结果是关于xix_i的线性表达式,即一条直线;
Ex.2:

z=wx2+bz = \bold w \centerdot \bold x^2 + b

fw,b(x)=g(z)=11+ezf_{\bold w, b}(\bold x) = g(z) = \frac{1}{1+e^{-z}}

fw,b(x)=g(z)=11+ezf_{\bold w, b}(\bold x) = g(z) = \frac{1}{1+e^{-z}}

decision_boundaryz=0wx2+b=0decision\_boundary \rightarrow z = 0 \rightarrow \bold w \centerdot \bold x^2 + b = 0

求出来的结果是关于xi2x_i^2的线性表达式,即一个圆形边界;

更复杂的边界函数:引入交叉乘积项(椭圆边界),高次幂项(不规则边界)。。。

逻辑回归的代价函数

仿照线性回归问题构造。。。

J(w,b)=12mi=1m(fw,b(x(i))y(i))2J(w,b) = \frac{1}{2m} \sum_{i=1}^{m} (f_{\bold w,b}(\bold x^{(i)}) - y^{(i)})^2

数学上可证明,是非凸函数(non-convex function)

1699630576706.png

损失(Loss):

L(fw,b(x(i))y(i))L(f_{\bold w,b}(\bold x^{(i)}) - y^{(i)})

对于逻辑回归的损失函数:

L(fw,b(x(i)),y(i))={log(fw,b(x(i)))if y(i)=1log(1fw,b(x(i)))if y(i)=0L\big(f_{\vec{w},b}\big(\vec{x}^{(i)}\big),y^{(i)}\big)=\begin{cases}\quad-\log\big(f_{\vec{w},b}\big(\vec{x}^{(i)}\big)\big)&\quad\text{if} \space y^{(i)}=1\\-\log\big(1-f_{\vec{w},b}\big(\vec{x}^{(i)}\big)\big)&\quad\text{if} \space y^{(i)}=0\end{cases}

1699707771023.png

代价函数也因此为如下形式:

J(w,b)=1mi=1mL(fw,b(x(i)),y(i))J(\overrightarrow{\mathrm{w}},b)=\frac{1}{m}{\sum_{i=1}^{m}{L(f_{\vec{w}},b(\vec{\mathrm{x}}^{(i)}),y}^{(i)})}

太麻烦了。。。有什么办法简化一下吗?

L(fw,b(x(i)),y(i))=y(i)log(fw,b(x(i)))(1y(i))log(1fw,b(x(i)))L{\left(f_{\vec{w},b}\left(\vec{x}^{(i)}\right),y^{(i)}\right)}=-y^{(i)}\mathrm{log}\left(f_{\vec{w},b}\left(\vec{x}^{(i)}\right)\right)-(1-y^{(i)})\mathrm{log}\left(1-{f_{\vec{w},b}}(\vec{x}^{(i)})\right)

之所以采用如上的损失函数,是来自统计学中的最大似然估计

逻辑回归中利用梯度下降找到损失函数的极小值

步骤和线性回归相同:

wjJ(w,b)=1mi=1m(fw,b(x(i))y(i))xj(i)\frac{\partial}{\partial w_{j}}J(\vec{w},b)=\frac{1}{m}\sum_{i=1}^{m}(f_{\vec{w},b}(\vec{x}^{(i)})-y^{(i)})x_{j}^{(i)}

bJ(w,b)=1mi=1m(fw,b(x(i))y(i))\frac{\partial}{\partial b}J(\vec{\mathrm{w}},b)=\frac{1}{m}\sum_{i=1}^{m}(f_{\vec{w},b}(\vec{\mathrm{x}}^{(i)})-y^{(i)})

不同之处在于,线性回归中的f(x)=wx+bf(x) = wx + b, 逻辑回归中,f(x)=sigmoid funxtionf(x) = sigmoid \space funxtion

OVER-FITTING & UNDER-FITTING!!!

解决过拟合的方法:

  1. 收集更多的训练集数据
  2. 增加/减少训练特征
  3. 正则化(最实用)

正则化

指导思想:奥卡姆剃刀原理:“如无必要,勿增实体” (Entities should not be multiplied unnecessarily)

Numquam ponenda est pluralitas sine necessitate.(避重趋轻)

Pluralitas non est ponenda sine necessitate.(避繁逐简)

Frustra fit per plura quod potest fieri per pauciora.(以简御繁)

Entia non sunt multiplicanda praeter necessitatem.(避虚就实)

J(w,b)=12mi=1mL(fw,b(x(i)),y(i))+λ2mj=1nwj2+λ2mb2J(\overrightarrow{\mathrm{w}},b)=\frac{1}{2m}{\sum_{i=1}^{m}{L(f_{\vec{w}},b(\vec{\mathrm{x}}^{(i)}),y}^{(i)})} + \color{red}\frac{\lambda}{2m}\sum_{j=1}^n w_j^2 + \color{yellow}\frac{\lambda}{2m}b^2

式中,λ\lambda为正则系数,这个式子代表当模型中不知道要对哪个特征的权重值进行正则化的时候,损失函数对所有权重进行正则化/惩罚.

对b无论是否进行正则化,影响不是很大,所以最后一项可要可不要。

用于线性回归的正则化

wjJ(w,b)=1mi=1m(fw,b(x(i))y(i))xj(i)+λmwj\frac{\partial}{\partial w_{j}}J(\vec{w},b)=\frac{1}{m}\sum_{i=1}^{m}(f_{\vec{w},b}(\vec{x}^{(i)})-y^{(i)})x_{j}^{(i)} + \color{red}\frac{\lambda}{m}w_j

wj=wjα[1mi=1m(fw,b(x(i))y(i))xj(i)+λmwj]w_j = w_j - \alpha [\frac{1}{m}\sum_{i=1}^{m}(f_{\vec{w},b}(\vec{x}^{(i)})-y^{(i)})x_{j}^{(i)} + \frac{\lambda}{m}w_j]

其中,1αλm1-\alpha\frac{\lambda}{m}这一系数相比原始的迭代更新步骤,起到了每一步对wiw_i乘一个略小于一的数,即对wiw_i缩水

wj=(1αλm)wjα[1mi=1m(fw,b(x(i))y(i))xj(i)]w_j = (1-\alpha \frac{\lambda}{m})w_j - \alpha [\frac{1}{m}\sum_{i=1}^{m}(f_{\vec{w},b}(\vec{x}^{(i)})-y^{(i)})x_{j}^{(i)}]

bJ(w,b)=1mi=1m(fw,b(x(i))y(i))\frac{\partial}{\partial b}J(\vec{\mathrm{w}},b)=\frac{1}{m}\sum_{i=1}^{m}(f_{\vec{w},b}(\vec{\mathrm{x}}^{(i)})-y^{(i)})

用于逻辑回归的正则化

(跟线性回归完全一样~)

深度学习神经网络

神经元与大脑

Activation(激活):指神经元向下游的其他神经元发送的输出(来源于神经生物学的术语)

Layer:层,代表若干神经元

Multilayer Perception: 多层感知机(包含输入层、隐藏层、输出层的很简单的神经网络)

1699736661168.png

激活值aj[l]a_j^{[l]}与神经元的参数运算规律:第l层的第j个神经元输出为

aj[l]=g(wj[l]a[l1]+bj[l])a_j^{[l]} = g(\vec w_j^{[l]} \centerdot \vec a^{[l-1]} + b_j^{[l]})

在神经网络中,g()g()也被称作为激活函数。Sigmoid只是众多激活函数的一种。

神经网络进行推理和预测:前向传播算法

通常越接近输出,激活值越来越少,最终为一个标量值。(通常而言)

前向传播与训练过程中的反向传播形成对比。

向量化

Tensorflow 框架

tensorflow中,Logistic loss函数又称为BinaryCrossEntropy(二进制交叉熵,统计学概念,又由于强调是二元分类问题,故得此名。)

tensorflow框架中,梯度下降更新w,b的循环操作被称作“反向传播(back propagation)”

其他的激活函数

有时模型不支持二元化分类。。。

ReLU (Rectified linear unit) Function

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

Linear Activation Function

g(z)=zg(z) = z

该函数也等价于没有用到任何的激活函数。

输出层(output layer)的激活函数的选择标准?

问题描述 激活函数 输出
二元分类问题(非零即一) Sigmoid Function y = 1(positive)的概率
回归问题(输出有正有负) Linear Activation Function 预测结果
回归问题(输出只有正值) ReLU (Rectified linear unit) Function 预测结果(只有正值,例如预测房价)

隐藏层(hidden layer)的激活函数

ReLU函数更加广泛使用,原因有几点:

  1. ReLU相比Sigmoid计算更快

  2. ReLU仅仅把小于零的部分平坦化,使得神经网络训练速度更快

tanh-function

LeakyReLU function

P-ReLU function

swish activation function

为什么需要激活函数?

如果全部是线性激活(等于不激活),整个神经网络和线性回归并无差别。但很多情况下神经网络处理的问题往往比线性复杂很多。

多分类问题

输出:(两个以上的)少量的离散的类别

softmax回归算法——逻辑回归算法的推广

举例:当输出可能有四种类别时

计算:

z1=w1x+b1z_{1}=\vec{w}_{1}\cdot\vec{\mathrm{x}}+b_{1}

z2=w2x+b2z_{2}=\vec{w}_{2}\cdot\vec{\mathrm{x}}+b_{2}

z3=w3x+b3z_{3}=\vec{w}_{3}\cdot\vec{\mathrm{x}}+b_{3}

z4=w4x+b4z_{4}=\vec{w}_{4}\cdot\vec{\mathrm{x}}+b_{4}

其中,w1w2w3w4b1b2b3b4\vec{w}_{1}、\vec{w}_{2}、\vec{w}_{3}、\vec{w}_{4}、b_{1}、b_{2}、b_{3}、b_{4}为softmax回归算法的参数。

下面计算回归函数:

a1=P(y=1x)=ez1ez1+ez2+ez3+ez4a_1 = P(y=1|\vec{x}) = \frac{e^{z_1}}{e^{z_1} + e^{z_2}+ e^{z_3}+ e^{z_4}}

a2=P(y=2x)=ez2ez1+ez2+ez3+ez4a_2 = P(y=2|\vec{x}) = \frac{e^{z_2}}{e^{z_1} + e^{z_2}+ e^{z_3}+ e^{z_4}}

a3=P(y=3x)=ez3ez1+ez2+ez3+ez4a_3 = P(y=3|\vec{x}) = \frac{e^{z_3}}{e^{z_1} + e^{z_2}+ e^{z_3}+ e^{z_4}}

a4=P(y=4x)=ez4ez1+ez2+ez3+ez4a_4 = P(y=4|\vec{x}) = \frac{e^{z_4}}{e^{z_1} + e^{z_2}+ e^{z_3}+ e^{z_4}}

通式:对于N类分类问题

zj=wjx+bj,j=1,,Nz_{j}=\vec{w}_{j}\cdot\vec{\mathrm{x}}+b_{j},j=1,\dots,N

aj=P(y=jx)=ezjk=1Nezka_j = P(y=j|\vec{x}) = \frac{e^{z_j}}{\sum_{k=1}^{N}e^{z_k}}

softmax回归模型的损失函数

重新审视Logistic Regression的损失函数:

L(fw,b(x(i)),y(i))=y(i)log(fw,b(x(i)))(1y(i))log(1fw,b(x(i)))L{\left(f_{\vec{w},b}\left(\vec{x}^{(i)}\right),y^{(i)}\right)}=-y^{(i)}\mathrm{log}\left(f_{\vec{w},b}\left(\vec{x}^{(i)}\right)\right)-(1-y^{(i)})\mathrm{log}\left(1-{f_{\vec{w},b}}(\vec{x}^{(i)})\right)

如果定义a1=fw,b(x(i))a_1 = f_{\vec{w},b} (\vec{x}^{(i)}), 且a2=1a1=1fw,b(x(i))a_2 = 1-a_1 = 1-f_{\vec{w},b} (\vec{x}^{(i)}), 损失函数简写为:

L(a1,y(i))=y(i)log(a1)(1y(i))log(1a1)L{\left(a_1,y^{(i)}\right)}=-y^{(i)}\mathrm{log}(a_1)-(1-y^{(i)})\mathrm{log}(1-a_1)

L(a1,y(i))=y(i)log(a1)(1y(i))log(a2)L{\left(a_1,y^{(i)}\right)}=-y^{(i)}\mathrm{log}(a_1)-(1-y^{(i)})\mathrm{log}(a_2)

J(w,b)=average L()J(\vec w,b) = average \space L()

softmax回归算法中

loss(a1,...,aN,y)={loga1ify=1loga2ify=2logaNify=Nloss(a_1,...,a_N,y)=\begin{cases}-\log a_1&\mathrm{if}y=1\\-\log a_2&\mathrm{if}y=2\\\vdots\\-\log a_N&\mathrm{if}y=N\end{cases}

softmax部署到神经网络中

1699809789220.png

softmax与其他激活函数的区别:softmax函数的每一个输出和这一层的所有参数都有关。

tensorflow中部署softmax层

SparseCategoricalCrossEntropy(稀疏分类交叉熵),与intensive…对比,前者的损失函数要求输出y只是有限个种类中的一种。

改进实现

为了减少数值舍入误差,通常不计算中间值g(z)g(z),而是直接通过层前输入计算得到的z=w+bz = \vec w + b代入损失函数(二元分类是BinaryCrossEntropy,多分类问题是SparseCategoricalCrossEntropy)中计算loss

代码中体现为:

1
model.complie(loss=BinaryCrossEntropy(from_logits=True))

该行代码表示,output layer不使用任何激活函数(线性激活),把激活函数(二元分类为Sigmoid、多元分类为Softmax)和损失函数的标准一同作为一层进行计算。

Multi-label Classification(多标签分类问题)

和上面讨论的分类问题不同,多标签分类问题的输出是一个向量(多个输出),但针对每个标签,可能是二元分类问题,也可能是多元分类

高级优化算法

比梯度下降更好的。。。?

Adam Algorithm

梯度下降的固有问题,在于学习率的值不能根据实际优化问题而变化,这使得模型训练过程中速度/效率没有办法得到更大提升。因此,Adaptive Moment Estimation(Adam,自适应矩估计)算法应运而生。

Adam算法背后的直观理解是,当进行梯度下降时,wjw_j或者bb不断地在同一方向上进行更新,则增大学习率,反之减少。

在tensorflow框架中,体现为:

1
2
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True))

神经网络中的“层”的类型

Dense Layer

致密层中的每一个神经元的输出都是前一个层中所有的激活值的函数。

Convolutional Layer(卷积层)

1699813774118.png

卷积层的好处:

  1. 计算速度更快
  2. 使用更少的计算数据,模型更不容易过拟合。

反向传播算法(Back Propagation)

计算图

1699845706399.png

Debug自己的机器学习项目

1. 模型评估

分割训练集和测试集。注意:计算测试集的损失函数时,不包括对参数的正则化项。

2. 模型选择

training set:设定模型参数

cross validation set:为了更好的选出模型种类

test set:验证模型的泛化能力,不能参与参数的变更

3. Bias & Variance

high bias: 训练集的误差较大,交叉验证集的误差也较大。代表模型欠拟合

high variance: 训练集的误差较小,但是交叉验证集的误差较大。代表模型过拟合。

找baseline很重要!!!

正则化对偏差与方差的影响:

4. learning curve(学习曲线)

1699875694187.png

如果一个模型是高偏差的,那么一味增加数据只是徒劳,不会对训练效果有显著提升。

如果一个模型是高方差的,那么增加数据有可能对训练模型起到积极的作用。

5. 其他debug方法

  • 减少训练所需的特征——处理高方差问题
  • 增加训练所需的特征——处理高偏差问题
  • 增加高次幂特征/交叉积特征——处理高偏差问题
  • 减少λ\lambda(正则化参数)——处理高偏差问题
  • 增大λ\lambda(正则化参数)——处理高方差问题(防止过拟合)

bias & variance in NN

bias和var的权衡(tradeoff)问题:

大型神经网络一般都是低偏差模型

tensorflow中,对神经网络中的某一层进行正则化操作:

1
layer_1 =Dense(units=25, activation="relu", kernel_regularizer=L2(0.01))

说明:
kernel_regularizer:初看似乎有点费解,kernel代表什么呢?其实在旧版本的Keras中,该参数叫做weight_regularizer,即是对该层中的权值进行正则化,亦即对权值进行限制,使其不至于过大。

可以看出,之所以叫L2正则化,是因为它是平方项之和。所以从名字,就可以写出它们的表达式。

L1正则化可以产生稀疏权值矩阵,即产生一个稀疏模型,可以用于特征选择

L2正则化可以防止模型过拟合(overfitting);一定程度上,L1也可以防止过拟合

ref:https://zhuanlan.zhihu.com/p/352437358

误差分析:

数据增强操作(Data Augmentation)

引入失真(distortion),增加模型的泛化性。

数据合成。。。

迁移学习

本质:

把别人的网络copy过来,改一下输出层(x),或者重新训练输出层的权重值和偏置(因为维度变了,之前的权值不能用了)。或者重新训练所有层。

处理倾斜数据集(skewed dataset)

利用混淆矩阵:

Precision:

Prec.=TruePos.TotalPredictedPos.Prec. = \frac{True Pos.}{Total Predicted Pos.}

Recall:

Rec.=TruePos.TotalActualPos.Rec. = \frac{True Pos.}{Total Actual Pos.}

F1-Score:(Precision和Recall的调和平均)

F1=112(1P+1R)=2PRP+RF_1 = \frac{1}{\frac{1}{2}(\frac{1}{P}+\frac{1}{R})} = \frac{2PR}{P+R}

决策树

决策树的特征选取原则是“Maximize Purity”

Entropy(熵)用来衡量数据簇的不纯度:(p1p2p_1、p_2、\dots=某一类的比例)

H(p)=p1log2(p1)p0log2(p0),where p0=1p1H(p) = -p_1 \log_{2}(p_1) - p_0 \log_{2} (p_0), where \space p_0=1-p_1

注意:0logk(0)==0,kN0 \log_{k}(0) == 0, k \in N^*

(更多量度见《数据挖掘·理论与实践》)

深度神经网络的随机初始化

如果所有的初始权重都为0,将会发生什么?(b初始化为0问题不大)

以下面的神经网络为例子:
1699898673460.png

初始:w1=(0000)初始:\bold w_1 = \begin{pmatrix} 0 & 0 \\ 0 & 0 \end{pmatrix}

b=(00)\bold b = \begin{pmatrix} 0 \\ 0 \end{pmatrix}

w2=(00)\bold w_2 = \begin{pmatrix} 0 & 0 \end{pmatrix}

hidden layer中的两个神经元不断地在计算完全相同的激活函数。

正确的做法是:

1
2
3
w_1 = np.random.randn((2,2)) * 0.01 # 初始化为一个很小的随机值

b_1 = np.zeros((2,1))

之所以把权重值初始化为很小的值,是保证a=g(z)=g(wx+b)a=g(z)=g(wx+b)计算的值偏离较为平坦的区域,有利于学习速率提升。(sigmoid或者tanh激活函数等都存在此问题)

tips:通过隐藏层输出(z)的维度和输入维度(x/a),来确定权重矩阵的维度(w)

深度神经网路的可视化解释(以CNN为例)

Dropout用于防止模型过拟合

Inverted Dropout:

Vanishing Gradients

产生原因:网络过深,权重矩阵以指数速度影响(增大或减少)输出结果。

解决方法:

  1. 随机初始化参数
    对于单个神经元:

z=i=1nwixi+bz = \sum_{i=1}^{n}w_ix_i + b

当n足够大时,设w\bold w的 方差为1n\frac{1}{n}

规定:

w[l]=np.random.randn(shape)×1n[l1]w^{[l]} = np.random.randn(shape) \times \sqrt{\frac{1}{n^{[l-1]}}}

如果中间层使用的激活函数是ReLU函数,则w\bold w的 方差为2n\frac{2}{n}.

w[l]=np.random.randn(shape)×2n[l1]w^{[l]} = np.random.randn(shape) \times \sqrt{\frac{2}{n^{[l-1]}}}

如果使用的是tanh激活函数,则:(Xaiver Normalization)

w[l]=np.random.randn(shape)×1n[l1]w^{[l]} = np.random.randn(shape) \times \sqrt{\frac{1}{n^{[l-1]}}}

Yoshua Bengio等还提出另一种标准化的方法:

w[l]=np.random.randn(shape)×2n[l1]×n[l]w^{[l]} = np.random.randn(shape) \times \sqrt{\frac{2}{n^{[l-1]} \times n^{[l]}}}

Optimization Algs.

Mini-batch 梯度下降

Exponentially weighted averages(指数加权平均。EWA)

vt=βvt1+(1β)θtv_t=\beta v_{t-1}+(1-\beta)\theta_t

在计算资源和内存消耗上体现出明显优势。

bias correction in EWA

预测初期:

vt1βt=βvt1+(1β)θt\frac{v_t}{1- \beta ^t} = \beta v_{t-1}+(1-\beta)\theta_t

Gradient descent with momentum (动量梯度下降)

在第t次迭代:
在当前的批处理数据上计算dW,dbdW,db

vdW=βvdW+(1β)dWvdb=βvdb+(1β)dbW=WαvdW,b=bαvdb\begin{aligned} &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} \end{aligned}

Hyperparameter:α,β\alpha, \beta.

有无偏差修正一般不影响,加上也可以

RMSprop

在第t次迭代:
在当前的批处理数据上计算dW,dbdW,db

SdW=βSdW+(1β)dW2Sdb=βSdb+(1β)db2W=WαdWSdW,b=bαdbSdb\begin{aligned} &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}}} \end{aligned}

工程应用为了保证数值稳定(防止SdW\sqrt{S_{dW}}太小),通常会把SdW\sqrt{S_{dW}}改成SdW+ϵ\sqrt{S_{dW}} + \epsilon(ϵ\epsilon是个很小的值,通常取1e-8)

Adam = momentum + RMSprop

如何调参更有效

“Coarse to fine” principal

Batch Normalization

思想:借鉴输入归一化,将每一隐藏层的中间输出(激活值:a或z,工程中常用z归一化)归一化,以便更快速地训练出相应的w和b。

方法:

znorm[l][i]=z[l][i]μσ2+ϵz_{norm}^{[l][i]} = \frac{z^{[l][i]}- \mu}{\sqrt{\sigma^2 + \epsilon}}

(防止分母为0)

通过下列式子:

z~[l][i]=γznorm[l][i]+β\tilde z^{[l][i]} = \gamma z^{[l][i]}_{norm} + \beta

中的γ,β\gamma, \beta值,来自定义z的均值和偏置。不难发现,当γ=σ2+ϵ,β=μ\gamma = \sqrt{\sigma^2 + \epsilon}, \beta = \mu时,z~[l][i]=z[l][i]\tilde z^{[l][i]} = z^{[l][i]}

这么做的一大原因是,我们想更好地利用非线性激活函数的非线性部分(以sigmoid为例,近似线性的部分集中在0附近,而我们想要偏离这一区域,就需要再重新设定z的均值)。这也说明了,Batch Norm这一过程是发生在计算z和a之间的

batch norm也可以与Mini-batch结合在一起使用。b在归一化之后就没有意义了,取而代之的参数是β[l]\beta^{[l]}

batch norm还有略微提供一点正则化的效果,尤其是作用在mini-batch上,由于每次计算方差是在一小撮数据集,不代表整体数据集,因此计算得到的方差可以被看作加入了一点噪声(不准确因素),这与dropout的效果类似(使一个隐藏层的神经元有概率输出为0)

test set上运用batch norm的时候,由于test set是一个一个样本处理的,没有batch的概念,故需要从训练集(training set)中估计均值、方差。

Deep learning frameworks

  • Caffe/Caffe2
  • CNTK
  • DL4J
  • Keras
  • Lasagne
  • mxnet
  • PaddlePaddle
  • TensorFlow
  • Theano
  • Torch

正交化的调参思想

Convolutional Nerual Networks

Why Conv?

CNN的共性:

  • 多数参数集中在Full-Connection Layer(FC layer)
  • 从浅到深隐藏层的神经元数目逐渐递减
  • 基本包括卷积、池化、全连接三个步骤

CNN的好处:

  1. Parameter Sharing: 对于特征检测(比如边缘提取任务),一个对于图片中某一块有作用的特征探测单元,那么它对图片的其他区域也同样适用。

  2. Sparsity of connections: 在CNN的每一层中,每一个输出值都依赖于很少的一部分输入。

几个经典网络

LeNet-5(1998)

论文阅读:

Structured Risk Minimization(abbr.SRM)

EtestEtrain=k(hP)αE_{test} - E_{train} = k(\frac{h}{P})^\alpha

式中,PP为训练样本数,hh为模型的有效算力(复杂度),α\alpha为介于0.5到1.0的常数,kk为常系数,EtestE_{test}为测试样本的误差,EtrainE_{train}为训练样本的误差。

Feature Map: the set of outputs of the units in such a plane

(LeNet的一些分类策略还是太落后了~)

AlexNet(2012)

Local Response Norm:局部响应归一化,(但是用处不是很大)

VGG-16(2015)

简化CNN的架构

Residual Nerual Networks(Resnet)

Residual block

注意:加性操作是在下下一层激活之前

ResNet咋就这么好用?

a[l+2]=g(z+a[l])=g(wa[l+1]+b+a[l])\begin{aligned} a^{[l+2]} &= g(z + a^{[l]}) \\ &= g(\bold w a^{[l+1]} + \bold b + a^{[l]} ) \end{aligned}

如果在正则化的时候,导致w,b\bold w, \bold b很小(便于计算,假设都为0),则:

a[l+2]=g(a[l])a^{[l+2]} = g(a^{[l]})

再加一条前提假设,假如隐藏层使用的是ReLU激活函数,则输出一定是大于零的,则有

a[l+2]=a[l]a^{[l+2]} = a^{[l]}

这证明了加了一层residual block,不会使得训练结果变差。且假设很深的时候梯度消失了,残差块可以让网络回到梯度消失前的状态

1x1 conv?

1x1卷积对多通道输出进行有力的降维/升维打击,构建成bottleneck layer,减少inception的计算成本

如果不进行维度变换,1x1卷积也会增加ReLU的次数,网络会学习到更复杂的非线性关系。

Inception

不知道用哪种卷积块、或者要不要用池化层,inception说:好吧那就都用)

Computer vision tech.

Localization

Object Detecting

如何高效的滑窗?把全连接层变成卷积层

卷积核的大小等于一个通道的输入维度。

YOLO algorithm

output: [pc,bx,by,bh,bw,c1,c2,...,cx][p_c, b_x, b_y, b_h, b_w, c_1, c_2, ... , c_x]

交并比(Intersection over union)

评估对象检测任务,检测框框的质量 (框没框,如框)

一般认为,IoU0.5IoU \geq 0.5就认为是好的.

非极大值抑制(non-max suppression)

目的是防止一个物体触发多次检测。

Anchor Boxes:

对于重叠的物体,预先设定若干个形状相差很多的boxes(框框)。设定输出为

[pcbxbybhbwc1c2c3pcbxbybhbwc1c2c3]\begin{bmatrix} p_c \\ b_x \\ b_y \\ b_h \\ b_w \\ c_1 \\ c_2 \\ c_3 \\ p_c \\ b_x \\ b_y \\ b_h \\ b_w \\ c_1 \\ c_2 \\ c_3 \\ \end{bmatrix}

候选区域(region proposal) R-CNN

对象检测任务中,某些地方真的没有东西,但是CNN还要计算一遍。由此,Regions of CNN(R-CNN)应运而生。方法是运行图像分割算法

改进:Fast R-CNN

应用卷积滑窗

再改进:Faster R-CNN

利用卷积来实现图像分割

Face Recognition

Oen-shot Learning:

学习一个"相似度"函数:

d(img1, img2) = 两幅输入图片的不同程度。

if d τ\leq \tau, 判定为same, 反之判定为different.

Siamese Network

triplet loss

神经风格迁移

深度神经网络到底在学到些啥?

layer 1中随便取一个unit,找到九个图像块使得这个unit的激活值最大。

对风格迁移拟定代价函数

J(G)=αJcontent(C,G)+βJstyle(S,G)J(G) = \alpha J_{content}(C,G) + \beta J_{style}(S,G)

  1. 初始化(随机生成)一张图片

  2. Gradient Descent 最小化J(G)J(G)

ConvNet for 1D

怎么表征序列数据?

以NLP为例,想表征一个句子里的每一个单词,首先要有一张巨大的词库(Vocabulary),词库中的单词按照字母顺序排列并顺序编号。再用独热码表示每个单词。

Recurrent Neural Network

为什么对于序列信息不使用传统多层全连接的前馈神经网络?

  1. 输入输出在不同的应用案例中可能维度不同,这对于序列处理来说极其不方便。

  2. 文本序列不具有特征共享的属性。

通常a<0>a^{<0>}为一组零向量。

不难发现,单向的循环神经网络是没有之后的信息为当前预测做反馈的。这也是RNN的弊端之一。

RNN的Forward Prop

a<0>=0a<1>=g(waaa<0>+waxx<1>+ba)y^<1>=g(wyaa<1>+by)\begin{aligned} & a^{<0>} = \vec 0 \\ & a^{<1>} = g(w_{aa}a^{<0>} + w_{ax}x^{<1>} + b_a) \\ & \hat{y}^{<1>} = g(w_{ya}a^{<1>} + b_y) \end{aligned}

针对 a<i>a^{<i>} 的激活函数可以选择一系列非线性的激活函数,例如tanh,ReLU等等, 针对输出y^<i>\hat{y}^{<i>}的激活函数可以根据分类问题的需求选择sigmoid或者softmax等函数。

简化RNN的记号

RNN的损失函数与反向传播

用交叉熵定义某个单词/某个时间点的预测损失为

L<t>(y^<t>,y<t>)=y<t>logy^<t>(1y<t>)log(1y^<t>)L^{<t>}(\hat{y}^{<t>}, y^{<t>}) = -y^{<t>}\log\hat{y}^{<t>} - (1-y^{<t>})\log(1-\hat{y}^{<t>})

整个序列的损失函数:

L(y^<t>,y<t>)=t=1TyL<t>(y^<t>,y<t>)L(\hat{y}^{<t>}, y^{<t>}) = \sum_{t=1}^{T_y}L^{<t>}(\hat{y}^{<t>}, y^{<t>})

RNN的各种架构

  1. 输入输出长度相等(也可能不等,比如翻译任务):多对多架构

  2. 输入为一个序列,输出一个结果:多对单架构

  3. 输入为很短的序列或仅仅一个单词,输出很长:一对多架构(例如音乐生成)

已训练好的RNN模型可以通过采样的方式生成序列,过程和One-to-Many的RNN类似,将每次输出采样取概率最大值的对象作为下一步长的输入。

RNN的梯度消失问题

RNN的一大缺点就是,如果网络非常深,输出又很大程度依赖于很前面的单词/元素,那么网络性能会变差。

Gate Recurrent Unit for RNN (门控循环单元)

新概念:memory cell:cc

在GRU里,c<t>=a<t>c^{<t>} = a^{<t>};此外在每一个步长里,用候选值c~<t>\tilde{c}^{<t>}重写记忆细胞的值cc

别急,我知道屏幕前的你已经混了,没关系,我也混了

c~<t>=tanh(wc[c<t1>,x<t>]+bc)\tilde{c}^{<t>} = \tanh(w_c[c^{<t-1>},x^{<t>}] + b_c)

GRU的核心思想——建立一个门Γu\Gamma_u,下标uu是update的意思。GRU决定了记忆细胞的值要不要更新。请注意,Γu\Gamma_u输出范围为[0,1]。

Γu=sigmoid(wu[c<t1>,x<t>]+bu)\Gamma_u = \text{sigmoid}(w_u[c^{<t-1>},x^{<t>}] + b_u)

c<t>=Γu×c~<t>+(1Γu)×c<t1>c^{<t>} = \Gamma_u \times \tilde{c}^{<t>} + (1 - \Gamma_u) \times c^{<t-1>}

LSTM

LSTM中,不存在GRU里的c<t>=a<t>c^{<t>} = a^{<t>}

c~<t>=tanh(wc[a<t1>,x<t>]+bc)\tilde{c}^{<t>} = \tanh(w_c[a^{<t-1>},x^{<t>}] + b_c)

Γu=sigmoid(wu[a<t1>,x<t>]+bu)\Gamma_u = \text{sigmoid}(w_u[a^{<t-1>},x^{<t>}] + b_u)

新的来力,与GRU不同,LSTM在更新c<t>c^{<t>}的时候采用两个不同的门控函数:Γu,Γf\Gamma_u, \Gamma_f,前者代表更新,后者代表遗忘。

Γf=sigmoid(wf[a<t1>,x<t>]+bf)\Gamma_f = \text{sigmoid}(w_f[a^{<t-1>},x^{<t>}] + b_f)

还顶一个门控函数代表output:

Γo=sigmoid(wo[a<t1>,x<t>]+bo)\Gamma_o = \text{sigmoid}(w_o[a^{<t-1>},x^{<t>}] + b_o)

c<t>=Γu×c~<t>+Γf×c<t1>c^{<t>} = \Gamma_u \times \tilde{c}^{<t>} + \Gamma_f \times c^{<t-1>}

a<t>=Γo×c<t>a^{<t>} = \Gamma_o \times c^{<t>}

Bidirectional RNN

对于第t个步长,预测值为

y^<t>=g(wy[a<t>,a<t>]+by)\hat{y}^{<t>} = g(w_y[a^{\rightarrow<t>},a^{\leftarrow<t>}] + b_y)

式中,a<t>,a<t>a^{\rightarrow<t>},a^{\leftarrow<t>}分别代表前向传播计算出的a<t>a^{<t>}和逆向传播计算出的a<t>a^{<t>}

当然上图中的每一层都可以替换成GRU和LSTM单元。

BRNN也有它的缺点,数据量必须是完整的才可以。(比如对于一个语音处理应用,如果部署了BRNN,那么用户每次必须说完一整句话,程序才会进行处理。)

Deep RNN

a[i]<j>=g(wa[i][a[i]<j1>,a[i1]<j>]+ba[i])a^{[i]<j>} = g(w_a^{[i]}[a^{[i]<j-1>}, a^{[i-1]<j>}] + b_a^{[i]})

Attention Model

Attention是对BRNN(with or without GRU & LSTM)的一个大改进:

α<i,t>\alpha^{<i,t'>}是输出y<t>y^{<t>}应该对a<t>a^{<t'>}的注意力强度。

a<t>=(a<t>,a<t>)tα<i,t>=1c<i>=tα<i,t>a<t>\begin{aligned} & a^{<t'>} = (a^{\leftarrow <t'>}, a^{\rightarrow <t'>}) \\ & \sum_{t'} \alpha^{<i,t'>} = 1 \\ & c^{<i>} = \sum_{t'} \alpha^{<i,t'>} a^{<t'>} \end{aligned}

一切的核心就在如何计算注意力权重α<i,t>\alpha^{<i,t'>}

α<i,t>=exp(e<t,t>)t=1Txexp(e<t,t>)\alpha^{<i,t'>} = \frac{\exp{(e^{<t,t'>})}}{\sum_{t'=1}^{T_x} \exp{(e^{<t, t'>})}}

每个e<t,t>e^{<t, t'>}由一个简单的softmax层得到:

ConvNet for 3D

例如:CT断层扫描数据

(带天坑!!)