深度学习与计算机视觉教程(7) | 神经网络训练技巧 (下)(CV通关指南·完结)

深度学习与计算机视觉(CV)介绍 深度学习与计算机视觉(CV)介绍 深度学习 学习⽬标 知道什么是深度学习 知道深度学习的应⽤场景 什么是深度学习 在介绍深度学习之前,我们先看下⼈⼯智能,机器学习和深度学习之间的关系: 机器学习是实现⼈⼯智能的⼀种途径,深度学习是机器学习的⼀个⼦集,也就是说深度学习是实现机器学习的⼀种⽅法。与机器学习算法的主要区别如下图所示: 传统机器学习算术依赖人工设计特征,并进行特征提取,而深度学习方法不需要人工,而是依赖算法自动提取特征。深度学习模仿人类大脑的运行方式,从经验中学习获取知识。这也是深度学习被 阅读详情

ShowMeAI研究中心


Training Neural Networks; 深度学习与计算机视觉; Stanford CS231n

本系列为 斯坦福CS231n 《深度学习与计算机视觉(Deep Learning for Computer Vision)》的全套学习笔记,对应的课程视频可以在 这里 查看。更多资料获取方式见文末。


引言

ShowMeAI在上一篇 深度学习与CV教程(6) | 神经网络训练技巧 (上) 介绍了激活函数选择, s i g m o i d sigmoid sigmoid 和 t a n h tanh tanh 都有饱和的问题;权重初始化不能太小也不能太大,最好使用Xavier初始化;数据预处理使用减去均值和归一化,线性分类中这两个操作会使分界线不那么敏感,即使稍微转动也可以,神经网络中也对权重的轻微改变没那么敏感,易于优化;也可以使用批量归一化,将输入数据变成单位高斯分布,或者缩放平移;学习过程跟踪损失、准确率;超参数体调优范围由粗到细,迭代次数逐渐增加,使用随机搜索。

本篇重点

  • 更好的优化
  • 正则化
  • 迁移学习
  • 模型集成

1.更好的优化(参数更新)

关于优化算法的详细知识也可以对比阅读ShowMeAI的 深度学习教程 | 吴恩达专项课程 · 全套笔记解读 中的文章 神经网络优化算法 的讲解。

1.1 批梯度下降(BGD)

批梯度下降即 batch gradient descent,在训练中每一步迭代都使用训练集的所有内容 { x 1 , ⋯   , x n } \{x_1, \cdots ,x_n\} {x1​,⋯,xn​} 以及每个样本对应的输出 y i y_i yi​,用于计算损失和梯度然后使用梯度下降更新参数。

当在整个数据集上进行计算时,只要学习率足够低,总是能在损失函数上得到非负的进展。参考代码如下(其中 learning_rate 是一个超参数):

# 普通梯度下降
while True:
    weights_grad = evaluate_gradient(loss_fun, data, weights)
    weights += -learning_rate * weights_grad  # 参数更新

如下图为只有两个参数的损失函数,经过不断更新,如果足够幸运,函数最终收敛在红色部分是最低点:

批量梯度下降BGD; 两个参数的损失函数

  • 优点:由于每一步都利用了训练集中的所有数据,因此当损失函数达到最小值以后,能够保证此时计算出的梯度为 0 0 0,能够收敛。因此,使用BGD时不需要逐渐减小学习率。
  • 缺点:随着数据集的增大,运行速度会越来越慢。

1.2 随机梯度下降(SGD)

这里的随机梯度下降(stochastic gradient descent)其实和之前介绍的MBGD(minibatch gradient descent)是一个意思,即每次迭代随机抽取一批样本 { x 1 , ⋯   , x m } \{x_1, \cdots ,x_m\} {x1​,⋯,xm​} 及 y i y_i yi​,以此来反向传播计算出梯度,然后向负梯度方向更新参数。

SGD的优点是训练速度快,对于很大的数据集,也能够以较快的速度收敛。但是实际应用SGD会有很多问题:

① 如果损失函数在一个参数方向下降的快另一个方向下降的慢,这样会导致 「 之字形 」下降到最低点,高维中很普遍。

随机梯度下降SGD; SGD之字形路线

  • 上图是一个山沟状的区域,损失最小点沿着蓝色的线方向。考虑表面上的一个点A梯度,该点的梯度可以分解为两个分量,一个沿着方向 w 1 w_1 w1​,另一个沿着 w 2 w_2 w2​。
  • 梯度在 w 1 w_1 w1​ 方向上的分量要大得多,因为在 w 1 w_1 w1​ 方向上每走一步都比在 w 2 w_2 w2​ 方向损失值下降的多,虽然最小值在 w 2 w_2 w2​ 方向上。这样实际走一步在 w 1 w_1 w1​ 方向走的多, w 2 w_2 w2​ 走得少,就会导致在这个沟里反复震荡,「之字形」前往最小值点。

② 如果损失函数有局部极小值和鞍点(既不是极大值也不是极小值的临界点)时,此时的梯度为 0 0 0,参数更新会卡住,或在极小值附近震荡。

随机梯度下降SGD; 鞍点 Saddle points

  • 在高维数据中,鞍点的存在是个更普遍也更大的问题,极小值每个梯度方向损失都会变大,而鞍点有的方向变大,有的减小,接近鞍点时更新缓慢。

③ SGD具有随机性,我们的梯度来自小批量数据(使用全部数据计算真实梯度速度太慢了),可能会有噪声,这样梯度下降的路线会很曲折,收敛的慢。

随机梯度下降SGD; 有噪声的SGD路线曲折

下面有一些「小批量梯度下降」基础上的优化算法。

1.3 动量(Momentum)更新

带动量的更新方法在深度网络上几乎总能得到更好的收敛速度。

损失值可以理解为是山的高度(因此高度势能是 U = m g h U=mgh U=mgh),用随机数字初始化参数等同于在某个位置给质点设定初始速度为 0 0 0 ,这样最优化过程可以看做是参数向量(即质点)在地形上滚动的过程。

质点滚动的力来源于高度势能 F = − ∇ U F = - \nabla U F=−∇U,即损失函数的负梯度(想象损失函数为凸函数,梯度为正时质点会向负方向滚动,对应参数减小;损失函数梯度为负时会向正方向滚动对应参数增大)。又因为 F = m a F=ma F=ma,质点的加速度和负梯度成正比,所以负梯度方向速度是逐渐增加的。

在 SGD 中,梯度直接影响质点的位置,在梯度为 0 0 0 的地方,位置就不会更新了;而在这里,梯度作为作用力影响的是速度,速度再改变位置,即使梯度为 0 0 0 ,但之前梯度累积下来的速度还在,一般而言,一个物体的动量指的是这个物体在它运动方向上保持运动的趋势,所以此时质点还是有动量的,位置仍然会更新,这样就可以冲出局部最小值或鞍点,继续更新参数。但是必须要给质点的速度一个衰减系数或者是摩擦系数,不然因为能量守恒,质点在谷底会不停的运动。

也就是说,参数更新的方向,不仅由当前点的梯度方向决定,而且由此前累积的梯度方向决定。

计算过程也是每次迭代随机抽取一批样本 x 1 , ⋯   , x m {x_1, \cdots ,x_m} x1​,⋯,xm​ 及 y i y_i yi​,计算梯度和损失,并更新速度和参数(假设质量为1,v即动量):

v=0
while True:
    dW =  compute_gradient(W, X_train, y_train)
    v = rho * v - learning_rate * dW
    W += v
  • rho 表示每回合速度 v 的衰减程度,每次迭代得到的梯度都是 dW 那么最后得到的 v 的稳定值为: − l e a r n i n g r a t e ∗ d w 1 − r h o \frac{-learning_{rate} \ast dw}{1-rho} 1−rho−learningrate​∗dw​
  • rho 为 0 0 0 时表示 SGD,rho 一般取值 0.5 0.5 0.5、 0.9 0.9 0.9、 0.99 0.99 0.99,对应学习速度提高两倍、10倍和100倍。

动量更新可以很好的解决上述 SGD 的几个问题:

  • 由于参数的更新要累积之前的梯度,所以如果我们分别累加这些梯度的两个分量,那么 w 1 w_1 w1​ 方向上的分量将互相抵消,而 w 2 w_2 w2​ 方向上的分量得到了加强。 但是由于衰减系数,不可能完全抵消,但是已经可以加速通过,很大程度缓解了「之字形」收敛慢的问题。这也是减少震荡的原理。

动量更新; 缓解之字形震荡

  • 局部最小值和鞍点由于还有之前的速度,会加速冲过去。

动量更新; 越过局部极小值点和鞍点

  • 面对梯度变化比较大的方向,即一些噪声,由于此时质点还有比较大的速度,这时的反方向需要先将速度减小为 0 0 0 才能改变参数更新方向,由于速度是累加的,所以个别的噪声的影响不会那么大,就可以平滑快速的收敛。

动量更新; 抑制噪声的影响

1.4 Nesterov动量

Nesterov动量与普通动量有些许不同,最近变得比较流行。在理论上对于凸函数它能得到更好的收敛,在实践中也确实比标准动量表现更好一些。

Nesterov 动量; 动量 V.S. Nesterov动量

  • 普通的动量更新在某一点处有一个速度,然后计算该点的梯度,实际的更新方向会根据速度方向和梯度方向做一个权衡。
  • Nesterov动量更新是既然我们知道动量将会将质点带到一个新的位置(即向前看),我们就不要在原来的位置计算梯度了,在这个「向前看」的地方计算梯度,更新参数。

这样代码变为:

v=0
while True:
    W_ahead = W + rho * v
    dW_ahead =  compute_gradient(W_ahead, X_train, y_train)
    v = rho * v - learning_rate * dW_ahead
    W += v

动量还是之前的动量,只是梯度变成将来的点的梯度。

而在实践中,人们更喜欢和普通SGD或普通的动量方法一样简单的表达式。通过对 W_ahead = W + rho * v 使用变量变换进行改写是可以做到的,然后用 W_ahead 而不是 W 来表示上面的更新。

也就是说,实际存储的参数总是向前一步的那个版本。 代码如下:

v=0
while True:
    pre_v = v
    dW =  compute_gradient(W, X_train, y_train)
    v = rho * v - learning_rate * dW
    W += -rho * pre_v + (1 + rho) * v

推导过程如下:

最初的 Nesterov 动量可以用下面的数学表达式代替:

v t + 1 = ρ v t − α ∇ f ( x t + ρ v t ) v_{t+1}=\rho v_t - \alpha \nabla f(x_t+\rho v_t) vt+1​=ρvt​−α∇f(xt​+ρvt​)

x t + 1 = x t + v t + 1 x_{t+1}=x_t+v_{t+1} xt+1​=xt​+vt+1​

现在令 x ~ t = x t + ρ v t \tilde{x}_t =x_t+\rho v_t x~t​=xt​+ρvt​,则:

v t + 1 = ρ v t − α ∇ f ( x t ~ ) v_{t+1}=\rho v_t-\alpha \nabla f(\tilde{x_t}) vt+1​=ρvt​−α∇f(xt​~​)

x ~ t + 1 = x t + 1 + ρ v t + 1 = x t + v t + 1 + ρ v t + 1 = x ~ t − ρ v t + v t + 1 + ρ v t + 1 \begin{aligned} \tilde{x}_{t+1} &=x_{t+1}+\rho v_{t+1}\\ &=x_{t}+v_{t+1}+\rho v_{t+1}\\ &=\tilde{x}_{t}-\rho v_{t}+v_{t+1}+\rho v_{t+1} \end{aligned} x~t+1​​=xt+1​+ρvt+1​=xt​+vt+1​+ρvt+1​=x~t​−ρvt​+vt+1​+ρvt+1​​

从而有:

x ~ t + 1 = x t ~ − ρ v t + ( ρ + 1 ) v t + 1 \tilde{x}_{t+1}=\tilde{x_t}-\rho v_t+(\rho+1)v_{t+1} x~t+1​=xt​~​−ρvt​+(ρ+1)vt+1​

  • 只更新 v t v_t vt​ 和 x ~ t \tilde{x}_t x~t​ 即可

示意图如下:

Nesterov 动量; 还原推导示意图

Nesterov 动量; SGD V.S. 动量 V.S. Nesterov 动量

1.5 自适应梯度算法(Adagrad)

上面提到的方法对于所有参数都使用了同一个更新速率,但是同一个更新速率不一定适合所有参数。如果可以针对每个参数设置各自的学习率可能会更好,根据情况进行调整,Adagrad是一个由 Duchi等 提出的适应性学习率算法。

代码如下:

eps = 1e-7
grad_squared =  $0$ 
while True:
    dW = compute_gradient(W)
    grad_squared += dW * dW
    W -= learning_rate * dW / (np.sqrt(grad_squared) + eps)

AdaGrad 其实很简单,就是将每一维各自的历史梯度的平方叠加起来,然后更新的时候除以该历史梯度值即可。

变量 grad_squared 的尺寸和梯度矩阵的尺寸是一样的,用于累加每个参数的梯度的平方和。这个将用来归一化参数更新步长,归一化是逐元素进行的。eps(一般设为 1e-4 到 1e-8 之间)用于平滑,防止出现除以 0 0 0 的情况。

  • 优点:能够实现参数每一维的学习率的自动更改,如果某一维的梯度大,那么学习速率衰减的就快一些,延缓网络训练;如果某一维的梯度小,那么学习速率衰减的就慢一些,网络训练加快。
  • 缺点:如果梯度累加的很大,学习率就会变得非常小,就会陷在局部极小值点或提前停( RMSProp 算法可以很好的解决该问题)。

1.6 均方根支柱算法(RMSProp)

RMSProp优化算法也可以自动调整学习率,并且RMSProp为每个参数选定不同的学习率。

RMSProp算法在AdaGrad基础上引入了衰减因子,RMSProp在梯度累积的时候,会对「过去」与「现在」做一个平衡,通过超参数 decay_rate 调节衰减量,常用的值是 [ 0.9 , 0.99 , 0.999 ] [0.9,0.99,0.999] [0.9,0.99,0.999]。其他不变,只是 grad_squared 类似于动量更新的形式:

grad_squared =  decay_rate * grad_squared + (1 - decay_rate) * dx * dx

相比于AdaGrad,这种方法很好的解决了训练过早结束的问题。和 Adagrad 不同,其更新不会让学习率单调变小。

均方根支柱算法; SGD V.S. 动量 V.S. RMSProp

1.7 自适应-动量优化(Adam)

动量更新在SGD基础上增加了一阶动量,AdaGrad和RMSProp在SGD基础上增加了二阶动量。把一阶动量和二阶动量结合起来,就得到了Adam优化算法:Adaptive + Momentum。

代码如下:

eps = 1e-8
first_moment = 0  # 第一动量,用于累积梯度,加速训练
second_moment = 0  # 第二动量,用于累积梯度平方,自动调整学习率
while True:
    dW = compute_gradient(W)
    first_moment = beta1 * first_moment + (1 - beta1) * dW  # Momentum
    second_moment = beta2 * second_moment + (1 - beta2) * dW * dW  # AdaGrad / RMSProp
    W -= learning_rate * first_moment / (np.sqrt(second_moment) + eps)

上述参考代码看起来像是 RMSProp 的动量版,但是这个版本的 Adam 算法有个问题:第一步中 second_monent 可能会比较小,这样就可能导致学习率非常大,所以完整的 Adam 需要加入偏置。

代码如下:

eps = 1e-8
first_moment = 0  # 第一动量,用于累积梯度,加速训练
second_moment = 0  # 第二动量,用于累积梯度平方,自动调整学习率

for t in range(1, num_iterations+1):
    dW = compute_gradient(W)
    first_moment = beta1 * first_moment + (1 - beta1) * dW  # Momentum
    second_moment = beta2 * second_moment + (1 - beta2) * dW * dW  # AdaGrad / RMSProp
    first_unbias = first_moment / (1 - beta1 ** t)  # 加入偏置,随次数减小,防止初始值过小
    second_unbias = second_moment / (1 - beta2 ** t)
    W -= learning_rate * first_unbias / (np.sqrt(second_unbias) + eps)

论文中推荐的参数值 eps=1e-8, beta1=0.9, beta2=0.999, learning_rate = 1e-3或5e-4,对大多数模型效果都不错。

在实际操作中,我们推荐 Adam 作为默认的算法,一般而言跑起来比 RMSProp 要好一点。

自适应动量优化; SGD V.S. 动量 V.S. RMSProp V.S. Adam

1.8 学习率退火

以上的所有优化方法,都需要使用超参数学习率。

在训练深度网络的时候,让学习率随着时间衰减通常是有帮助的。可以这样理解:

  • 如果学习率很高,系统的动能就过大,参数向量就会无规律地跳动,不能够稳定到损失函数更深更窄的部分去。
  • 知道什么时候开始衰减学习率是有技巧的:慢慢减小它,可能在很长时间内只能是浪费计算资源地看着它混沌地跳动,实际进展很少。但如果快速地减少它,系统可能过快地失去能量,不能到达原本可以到达的最好位置。

通常,实现学习率衰减有3种方式:

① 随步数衰减:每进行几个周期(epoch)就根据一些因素降低学习率。典型的值是每过 5 个周期就将学习率减少一半,或者每 20 个周期减少到之前的 10%。

这些数值的设定是严重依赖具体问题和模型的选择的。在实践中可能看见这么一种经验做法:使用一个固定的学习率来进行训练的同时观察验证集错误率,每当验证集错误率停止下降,就乘以一个常数(比如0.5)来降低学习率。

② 指数衰减:数学公式是 α = α 0 e − k t \alpha=\alpha_0e^{-kt} α=α0​e−kt,其中 α 0 , k \alpha_0,k α0​,k 是超参数, t t t 是迭代次数(也可以使用周期作为单位)。
③ 1/t 衰减:数学公式是 α = α 0 / ( 1 + k t ) \alpha=\alpha_0/(1+kt) α=α0​/(1+kt)),其中 α 0 , k \alpha_0,k α0​,k 是超参数, t t t 是迭代次数。

在实践中随步数衰减的随机失活(Dropout)更受欢迎,因为它使用的超参数(衰减系数和以周期为时间单位的步数)比k更有解释性。

如果你有足够的计算资源,可以让衰减更加缓慢一些,让训练时间更长些。

一般像SGD这种需要使用学习率退火,Adam等不需要。也不要一开始就使用,先不用,观察一下损失函数,然后确定什么地方需要减小学习率。

学习率退火; 损失函数

1.9 二阶方法(Second-Order)

在深度网络背景下,第二类常用的最优化方法是基于牛顿方法的,其迭代如下:

x ← x − [ H f ( x ) ] − 1 ∇ f ( x ) x \leftarrow x - [H f(x)]^{-1} \nabla f(x) x←x−[Hf(x)]−1∇f(x)

H f ( x ) H f(x) Hf(x) 是 Hessian 矩阵,由 f ( x ) f(x) f(x) 的二阶偏导数组成:

H = [ ∂ 2 f ∂ x 1 2 ∂ 2 f ∂ x 1 ∂ x 2 ⋯ ∂ 2 f ∂ x 1 ∂ x n ∂ 2 f ∂ x 2 ∂ x 1 ∂ 2 f ∂ x 2 2 ⋯ ∂ 2 f ∂ x 2 ∂ x n ⋮ ⋮ ⋱ ⋮ ∂ 2 f ∂ x n ∂ x 1 ∂ 2 f ∂ x n ∂ x 2 ⋯ ∂ 2 f ∂ x n 2 ] \mathbf{H}=\left[\begin{array}{cccc} \frac{\partial^{2} f}{\partial x_{1}^{2}} & \frac{\partial^{2} f}{\partial x_{1} \partial x_{2}} & \cdots & \frac{\partial^{2} f}{\partial x_{1} \partial x_{n}} \\ \frac{\partial^{2} f}{\partial x_{2} \partial x_{1}} & \frac{\partial^{2} f}{\partial x_{2}^{2}} & \cdots & \frac{\partial^{2} f}{\partial x_{2} \partial x_{n}} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial^{2} f}{\partial x_{n} \partial x_{1}} & \frac{\partial^{2} f}{\partial x_{n} \partial x_{2}} & \cdots & \frac{\partial^{2} f}{\partial x_{n}^{2}} \end{array}\right] H=⎣ ⎡​∂x12​∂2f​∂x2​∂x1​∂2f​⋮∂xn​∂x1​∂2f​​∂x1​∂x2​∂2f​∂x22​∂2f​⋮∂xn​∂x2​∂2f​​⋯⋯⋱⋯​∂x1​∂xn​∂2f​∂x2​∂xn​∂2f​⋮∂xn2​∂2f​​⎦ ⎤​

x x x 是 n n n 维的向量, f ( x ) f(x) f(x) 是实数,所以海森矩阵是 n ∗ n n \ast n n∗n 的。

∇ f ( x ) \nabla f(x) ∇f(x) 是 n n n 维梯度向量,这和反向传播一样。

这个方法收敛速度很快,可以进行更高效的参数更新。在这个公式中是没有学习率这个超参数的,这相较于一阶方法是一个巨大的优势。

然而上述更新方法很难运用到实际的深度学习应用中去,这是因为计算(以及求逆)Hessian 矩阵操作非常耗费时间和空间。这样,各种各样的拟-牛顿法就被发明出来用于近似转置 Hessian 矩阵。

在这些方法中最流行的是L-BFGS,该方法使用随时间的梯度中的信息来隐式地近似(也就是说整个矩阵是从来没有被计算的)。

然而,即使解决了存储空间的问题,L-BFGS应用的一个巨大劣势是需要对整个训练集进行计算,而整个训练集一般包含几百万的样本。和小批量随机梯度下降(mini-batch SGD)不同,让 L-BFGS 在小批量上运行起来是很需要技巧,同时也是研究热点。

1.10 实际应用

Tips:默认选择Adam;如果可以承担全批量更新,可以尝试使用L-BFGS。

2.正则化

关于正则化的详细知识也可以对比阅读ShowMeAI的深度学习教程 | 吴恩达专项课程 · 全套笔记解读中的文章深度学习的实用层面中关于正则化的讲解。

2.1 正则化的动机

当我们增加神经网络隐藏层的数量和尺寸时,网络的容量会上升,即神经元可以合作表达许多复杂函数。例如,如果有一个在二维平面上的二分类问题。我们可以训练 3 个不同的神经网络,每个网络都只有一个隐藏层,但是隐藏层的神经元数目不同,结果如下:

正则化; 隐藏层神经元数目不同

在上图中,可以看见有更多神经元的神经网络可以表达更复杂的函数。然而这既是优势也是不足:

  • 优势是可以分类更复杂的数据
  • 不足是可能造成对训练数据的过拟合。

过拟合(Overfitting) 是网络对数据中的噪声有很强的拟合能力,而没有重视数据间(假设)的潜在基本关系。比如上图中:

  • 有20个神经元隐层的网络拟合了所有的训练数据,但是其代价是把决策边界变成了许多不相连的红绿区域。
  • 有3个神经元的模型的表达能力只能用比较宽泛的方式去分类数据。它将数据看做是两个大块,并把个别在绿色区域内的红色点看做噪声。在实际中,这样可以在测试数据中获得更好的泛化(generalization)能力。

那是不是说 「如果数据不是足够复杂,则小一点的网络似乎更好,因为可以防止过拟合」?

不是的,防止神经网络的过拟合有很多方法(L2正则化,Dropout和输入噪音等)。在实践中,使用这些方法来控制过拟合比减少网络神经元数目要好得多。

不应该因为害怕出现过拟合而使用小网络。相反,应该尽可能使用大网络,然后使用正则化技巧来控制过拟合。

正则化; 改变正则化强度

上图每个神经网络都有 20 个隐藏层神经元,但是随着正则化强度增加,网络的决策边界变得更加平滑。所以,正则化强度是控制神经网络过拟合的好方法。

ConvNetsJS demo 上有一个小例子大家可以练练手。

2.2 正则化方法

有不少方法是通过控制神经网络的容量来防止其过拟合的:

L2正则化:最常用的正则化,通过惩罚目标函数中所有参数的平方实现。

  • 对于网络中的每个权重 w w w,向目标函数中增加一个 1 2 λ w 2 \frac{1}{2} \lambda w^2 21​λw2,1/2为了方便求导, λ \lambda λ 是正则强度。
  • L2 正则化可以直观理解为它对于大数值的权重向量进行严厉惩罚,倾向于更加分散的权重向量。使网络更倾向于使用所有输入特征,而不是严重依赖输入特征中某些小部分特征。

L1正则化:是另一个相对常用的正则化方法,对于每个 w w w 都向目标函数增加一个 λ ∣ w ∣ \lambda \mid w \mid λ∣w∣。

  • L1 正则化会让权重向量在最优化的过程中变得稀疏(即非常接近 0 0 0)。在实践中,如果不是特别关注某些明确的特征选择,一般说来 L2 正则化都会比 L1 正则化效果好。
  • L1 和 L2 正则化也可以进行组合: λ 1 ∣ w ∣ + λ 2 w 2 \lambda_1 \mid w \mid + \lambda_2 w^2 λ1​∣w∣+λ2​w2,称作 Elastic net regularization。

最大范式约束(Max norm constraints):要求权重向量 $w $ 必须满足 L2 范式 ∥ w ⃗ ∥ 2 < c \Vert \vec{w} \Vert_2 < c ∥w ∥2​<c, c c c 一般是 3 或 4。这种正则化还有一个良好的性质,即使在学习率设置过高的时候,网络中也不会出现数值「爆炸」,这是因为它的参数更新始终是被限制着的。

但是在神经网络中,最常用的正则化方式叫做 Dropout,下面我们详细展开介绍一下。

2.3 随机失活(Dropout)

1) Dropout概述

Dropout 是一个简单又极其有效的正则化方法,由 Srivastava 在论文 [Dropout: A Simple Way to Prevent Neural Networks from Overfitting](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) 中提出,与 L1 正则化、L2 正则化和最大范式约束等方法互为补充。

在训练的时候,随机失活的实现方法是让神经元以超参数 p p p (一般是 0.5 0.5 0.5)的概率被激活或者被设置为 0 0 0 。常用在全连接层。

Dropout 随机失活; 核心思路

一个三层的神经网络 Dropout 示例代码实现:

""" 普通版随机失活"""

p = 0.5   # 神经元被激活的概率。p值越高,失活数目越少

def train_step(X):
  """ X中是输入数据 """
  # 前向传播
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = np.random.rand(*H1.shape) < p # 第一个随机失活掩模
  # rand可以返回一个或一组服从“0~1”均匀分布的随机样本值
  # 矩阵中满足小于p的元素为True,不满足False
  # rand()函数的参数是两个或一个整数,不是元组,所以需要*H1.shape获取行列
  H1 *= U1 # U1中False的H1对应位置置零
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = np.random.rand(*H2.shape) < p # 第二个随机失活掩模
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3

  # 反向传播:计算梯度... (略)
  # 进行参数更新... (略)

在上面的代码中,train_step 函数在第一个隐层和第二个隐层上进行了两次随机失活。在输入层上面进行随机失活也是可以的,为此需要为输入数据 X X X 创建一个二值(要么激活要么失活)的掩模。反向传播几乎保持不变,只需回传梯度乘以掩模得到 Dropout 层的梯度。

2) Dropout的理解

为什么这个想法可取呢?一个解释是防止特征间的相互适应:

  • 比如每个神经元学到了猫的一个特征比如尾巴、胡须、爪子等,将这些特征全部组合起来可以判断是一只猫。
  • 加入随机失活后就只能依赖一些零散的特征去判断不能使用所有特征,这样可以一定程度上抑制过拟合。不然训练时正确率很高,测试时却很低。

Dropout 随机失活; 防止特征间的互相适应

另一个比较合理的解释是:

  • 在训练过程中,随机失活可以被认为是对完整的神经网络抽样出一些子集,每次基于输入数据只更新子网络的参数。
  • 每个二值掩模都是一个模型,有 n n n 个神经元的网络有 2 n 2n 2n 种掩模。Dropout 相当于数量巨大的网络模型(共享参数)在同时被训练。

Dropout 随机失活; 相当于抽样出一些子集

3) 测试时避免随机失活

在训练过程中,失活是随机的,但是在测试过程中要避免这种随机性,所以不使用随机失活,要对数量巨大的子网络们做模型集成(model ensemble),以此来计算出一个预测期望。

比如只有一个神经元 a a a:

Dropout 随机失活; 测试时避免随机失活

测试的时候由于不使用随机失活所以:

E ( a ) = w 1 x + w 2 y \text{E}(a)=w_1x+w_2y E(a)=w1​x+w2​y

假如训练时随机失活的概率为 0.5 0.5 0.5,那么:

E ( a ) = 1 4 ( w 1 x + w 2 y ) + 1 2 ( w 1 x + w 2 ⋅ 0 ) + 1 2 ( w 1 x ⋅ 0 + w 2 ) + 1 4 ⋅ 0 = 1 2 ( w 1 x + w 2 y ) \text{E}(a)=\frac{1}{4}(w_1x+w_2y)+\frac{1}{2}(w_1x+w_2\cdot 0)+\frac{1}{2}(w_1x\cdot 0+w_2)+\frac{1}{4}\cdot 0=\frac{1}{2}(w_1x+w_2y) E(a)=41​(w1​x+w2​y)+21​(w1​x+w2​⋅0)+21​(w1​x⋅0+w2​)+41​⋅0=21​(w1​x+w2​y)

所以一个不确切但是很实用的做法是在测试时承随机失活概率,这样就能保证预测时的输出和训练时的期望输出一致。所以测试代码:

def predict(X):
  # 前向传播时模型集成
  H1 = np.maximum(0, np.dot(W1, X) + b1) * p # 注意:激活数据要乘以p
  H2 = np.maximum(0, np.dot(W2, H1) + b2) * p # 注意:激活数据要乘以p
  out = np.dot(W3, H2) + b3

上述操作不好的地方是必须在测试时对激活数据按照失活概率 p p p 进行数值范围调整。测试阶段性能是非常关键的,因此实际操作时更倾向使用反向随机失活(inverted dropout)

  • 在训练时就进行数值范围调整,从而让前向传播在测试时保持不变。

反向随机失活还有一个好处,无论是否在训练时使用 Dropout,预测的代码可以保持不变。参考实现代码如下:

""" 
反向随机失活: 推荐实现方式.
在训练的时候drop和调整数值范围,测试时不做任何事.
"""
p = 0.5
def train_step(X):
  # 前向传播
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = (np.random.rand(*H1.shape) < p) / p # 第一个随机失活遮罩. 注意/p!
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = (np.random.rand(*H2.shape) < p) / p # 第二个随机失活遮罩. 注意/p!
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3

def predict(X):
  # 前向传播时模型集成
  H1 = np.maximum(0, np.dot(W1, X) + b1) # 不用数值范围调整了
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  out = np.dot(W3, H2) + b3

在更一般化的分类上,随机失活属于网络在前向传播中有随机行为的方法。这种在训练过程加入随机性,然后在测试过程中对这些随机性进行平均或近似的思想在很多地方都能见到:

  • 批量归一化:训练时的均值和方差来自随机的小批量;测试时使用的是整个训练过程中的经验方差和均值。

  • 数据增强(data augmentation) :比如一张猫的图片进行训练时,可以随机的裁剪翻转等操作再训练,然后测试过程再对一些固定的位置(四个角、中心及翻转)进行测试。也可以在训练的时候随机改变亮度对比度,色彩抖动PCA降维等。

  • DropConnect:另一个与 Dropout 类似的研究是 DropConnect,它在前向传播的时候,一系列权重被随机设置为 0 0 0 。

  • 部分最大池化(Fractional Max Pooling) :训练时随机区域池化,测试时固定区域或者取平均值。这个方法并不常用。

  • 随机深度(Stochastic Depth) :一个比较深的网络,训练时随机选取部分层去训练,测试时使用全部的层。这个研究非常前沿。

总之,这些方法都是在训练的时候增加随机噪声,测试时通过分析法(在使用随机失活的本例中就是乘以 p p p)或数值法(例如通过抽样出很多子网络,随机选择不同子网络进行前向传播,最后对它们取平均)将噪音边缘化。

4) 实践经验

一些常用的实践经验方法:

  • 可以通过交叉验证获得一个全局使用的 L2 正则化系数。
  • 使用 L2 正则化的同时在所有层后面使用随机失活

随机失活 p p p值一般默认设为 0.5 0.5 0.5,也可能在验证集上调参。

3.迁移学习(Transfer Learning)

关于迁移学习的详细知识也可以对比阅读ShowMeAI的 深度学习教程 | 吴恩达专项课程 · 全套笔记解读 中的文章 AI 应用实践策略(下) 中关于正则化的讲解。

另一个导致过拟合的原因可能是训练样本过少,这时可以使用迁移学习来解决这个问题,它允许使用很少的数据来训练 CNN。

3.1 迁移学习的思想

迁移学习; Transfer Learning

  • 第①步:在大量的数据集上训练一个 CNN,得到模型(比如使用 ImageNet,有 1000 个分类)
  • 第②步:使用一个少量的数据集,最后需要的得到的分类也不再是 1000 而是一个较小的值 C C C,比如10。这时最后一个全连接层的参数矩阵变成 4096 × C 4096 \times C 4096×C,初始化这个矩阵,重新训练这个线性分类器,保持前面的所有层不变,因为前面的层已经训练好了,有了泛化能力。
  • 第③步:当得到较多的训练集后,训练的层数可以增多,比如可以训练最后三个全连接层。可以使用较低的学习率微调参数。

迁移学习; Transfer Learning

3.2 应用

在目标检测和图像标记中都会使用迁移学习,图像处理部分都使用一个已经用 ImageNet 数据预训练好的 CNN 模型,然后根据具体的任务微调这些参数。

所以对一批数据集感兴趣但是数量不够时,可以在网上找一个数据很相似的有大量数据的训练模型,然后针对自己的问题微调或重新训练某些层。一些常用的深度学习软件包都含有已经训练好的模型,直接应用就好。

4.模型集成(Model Ensembles)

在实践的时候,有一个总是能提升神经网络几个百分点准确率的办法,就是在训练的时候训练几个独立的模型,然后在测试的时候平均它们预测结果。

集成的模型数量增加,算法的结果也单调提升(但提升效果越来越少)。

模型之间的差异度越大,提升效果可能越好。

进行集成有以下几种方法:

  • 同一个模型,不同的初始化。使用交叉验证来得到最好的超参数,然后用最好的参数来训练不同初始化条件的模型。这种方法的风险在于多样性只来自于不同的初始化条件。
  • 在交叉验证中发现最好的模型。使用交叉验证来得到最好的超参数,然后取其中最好的几个(比如10个)模型来进行集成。这样就提高了集成的多样性,但风险在于可能会包含不够理想的模型。在实际操作中,这样操作起来比较简单,在交叉验证后就不需要额外的训练了。
  • 一个模型设置多个记录点 ( checkpoints ) 。如果训练非常耗时,那就在不同的训练时间对网络留下记录点(比如每个周期结束),然后用它们来进行模型集成。很显然,这样做多样性不足,但是在实践中效果还是不错的,这种方法的优势是代价比较小。
  • 在训练的时候跑参数的平均值。和上面一点相关的,还有一个也能得到1-2个百分点的提升的小代价方法,这个方法就是在训练过程中,如果损失值相较于前一次权重出现指数下降时,就在内存中对网络的权重进行一个备份。这样你就对前几次循环中的网络状态进行了平均。你会发现这个「平滑」过的版本的权重总是能得到更少的误差。直观的理解就是目标函数是一个碗状的,你的网络在这个周围跳跃,所以对它们平均一下,就更可能跳到中心去。

5.拓展学习

可以点击 B站 查看视频的【双语字幕】版本

【字幕+资料下载】斯坦福CS231n | 面向视觉识别的卷积神经网络 (2017·全16讲)

6.要点总结

  • 优化方式:SGD、动量更新、Nesterov动量、Adagrad、RMSProp、Adam等,一般无脑使用Adam。此外还有学习率退火和二阶方法。
  • 正则化:L2比较常用,Dropout也是一个很好的正则方法。
  • 数据较少时可以使用迁移学习。
  • 模型集成。

ShowMeAI 斯坦福 CS231n 全套解读

ShowMeAI 系列教程推荐

showmeai用知识加速每一次技术成长

计算机视觉最全专栏教程总结 为方便更多CV方向学习者学习,本次新星计划活动学习内容不仅包括为本人博客专栏,还会涉及部分知识星球:CV技术指南内容 ,星球文章内容成专栏体系 ,会分享最新论文+ 部署实战+ 资源教程共享,方向很多,包括不限于2D/3D、缺陷检测、分割、Diffusion Model、AIGC、Transformer、点云、遥感图像、量化剪枝蒸馏、REID、医学图像、目标跟踪、车道线、行为、图神经网络、GAN等。 阅读详情

相关推荐

手把手教你用三菱PLC控制JET伺服原点:从硬件接线到GXWORKS3程序调试

本文详细介绍了如何使用三菱PLC控制JET伺服系统实现原点回归功能,涵盖硬件接线、参数配置到GX Works3程序调试的全流程。通过实战指南,帮助工程师快速掌握伺服控制技术,提升工业自动化项目的实施效率。

weixin_30642561的博客 536

Tensorflow入门

文章目录Tensorflow入门tensorflow和keras简介TensorFlow介绍TensorFlow的安装张量及其操作tf.keras介绍总结快速入门模型相关的库的导入数据展示和划分sklearn实现tf.keras实现总结 Tensorflow入门 tensorflow和keras简介 学习目标 了解Tensorflow2.0框架的用途及流程 知道tf2.0的张量及其操作 知道tf.keras中的相关模块及常用方法 TensorFlow介绍 深度学习框架TensorFlow一经发布,就受到

最白の白菜的博客 1520

光学设计进阶:Zemax中的坐标断点与离轴系统优化

本文深入解析了Zemax中坐标断点的核心原理与实战应用,它是实现离轴光学系统设计的关键。文章通过比喻和实例,详细阐述了如何利用坐标断点作为“方向盘”来精确控制光学元件的偏心和倾斜,实现“前断后接”的局部坐标系变换,从而构建并优化无中心遮拦的离轴反射系统,避免光线失控。

3a9bq4r8t2y的博客 528

深度学习与计算机视觉教程(4) | 神经网络与反向传播(CV通关指南·完结)

本文讲解了神经网络计算图、前向传播与反向传播、标量与向量化形式计算、求导链式法则应用、神经网络结构、 激活函数等内容【对应 CS231n Lecture 4】

ShowMeAI研究中心 8663

MATLAB仿真实战:双有源桥(DAB)变换器的扩展移相调制(EPS)全流程解析

本文提供了一份详细的MATLAB/Simulink仿真实战指南,手把手解析双有源桥(DAB)变换器在扩展移相调制(EPS)下的全流程建模。内容涵盖从核心原理、主功率电路搭建、EPS驱动信号生成,到仿真运行、波形分析及模型优化的完整步骤,旨在帮助工程师和研究者快速掌握DAB变换器的仿真与性能验证方法。

o4p5q6r7s的博客 505

FPGA学习之路—应用程序—原码二位乘法器及Verilog代码分析

FPGA学习之路——原码二位乘法器及Verilog代码分析 原理 原码乘法可以分为原码一位乘和原码二位乘,两者在实现规则上大同小异。原码一位乘每次判断乘数的最低位,对被乘数和部分积进行相应操作。而原码二位乘则是对乘数的低二位进行判断,并执行相关操作。 两位乘数的取值可以有四种可能组合,每种组合对应于以下操作: 00相当于0x,部分积Dresult右移2位,不进行其他运算; 01相当于1x,部分积D...

谦豫 3717

人工智能教程第一课 深度学习和计算机视觉TensorFlow入门

深度学习 学习目标 知道什么是深度学习 知道深度学习的应用场景 1.什么是深度学习 在介绍深度学习之前,我们先看下人工智能,机器学习和深度学习之间的关系: 机器学习是实现人工智能的一种途径,深度学习是机器学习的一个子集,也就是说深度学习是实现机器学习的一种方法。与机器学习算法的主要区别如下图所示: 传统机器学习算术依赖人工设计特征,并进行特征提取,而深度学习方法不需要人工,而是依赖算法自动提取特征。深度学习模仿人类大脑的运行方式,从经验中学习获取知识。这也是深度学习被看做黑盒子,可解释性差的原因

fegus的博客 2768

【UE5】VoskPlugin实战:离线语音识别与实时文本转换全流程解析

本文详细解析了如何在UE5中利用VoskPlugin实现离线实时语音转文字功能。从环境搭建、插件配置、核心代码编写到蓝图测试,提供了完整的实战教程。重点阐述了离线方案零延迟、数据私密的优势,并分享了模型选择、性能优化及常见问题的解决方案,帮助开发者快速构建稳定可靠的语音交互系统。

weixin_29001655的博客 622

BN、LN、dropout、神经元

一、过拟合、欠拟合 二、BN 三、LN 四、dropout

yanglee0 2003

3D Slicer隐藏技巧:这样玩转医学影像分割与3D建模(含DICOM处理)

本文深入探讨3D Slicer在医学影像分割与3D建模中的高级应用技巧,包括多模态分割策略、三维可视化优化及DICOM数据处理。通过专业配置和Python脚本示例,帮助医疗AI开发者和影像科医师提升工作效率,实现精准的医学图像分析与建模。

weixin_28559803的博客 435

【雷达】一维和二维自适应波束形成(DBF))DBF附matlab代码

1 简介 数字波束形成技术是天线波束形成原理与数字信号处理技术相结合的产物,其广泛应用于阵列信号处理领域.由于电磁工作环境的恶化和大量射频干扰的存在,在极低的信干噪比(SINR)条件下进行目标检测和信息提取十分困难.对于阵列系统,往往采用自适应数字波束形成(ADBF)技术,来抑制强干扰和方向性干扰对有用信号的影响.介绍了数字波束形成器的基本原理及其DSP的实现结构.​ 2 完整代码 clc;clear all;close all;%%%%%%%%%%%%%%%%%一维DBF%%%%%%%%%%%%%

qq_59747472的博客 7269

【详解】计算机视觉算法导读篇

1 深度学习发展史 起源:深度学习所需要的神经网络技术起源于20世纪50年代,叫做感知机。当时也通常使用单层感知机,尽管结构简单,但是能够解决复杂的问题。后来感知机被证明存在严重的问题,因为只能学习线性可分函数,连简单的异或(XOR)等线性不可分问题都无能为力,1969年Marvin Minsky写了一本叫做《Perceptrons》的书,他提出了著名的两个观点:1.单层感知机没用,我们需要多层感知机来解决复杂问题 2.没有有效的训练算法。 发展:20世纪90年代,各种各样的浅层机器学习模型相继被提出,.

一个内容严谨、方向前沿、极具实践价值的AI大模型技术分享站 2621

计算机视觉卷积神经网络(CNN)基础:从LeNet到ResNet

计算机视觉卷积神经网络(CNN)基础:从LeNet到ResNet,在计算机视觉领域,卷积神经网络(Convolutional Neural Network,CNN)已然成为推动众多任务发展的核心力量。从早期简单的图像识别,到如今复杂的目标检测、语义分割、图像生成等任务,CNN 都展现出了卓越的性能。CNN 的发展历程见证了一系列经典模型的诞生,其中 LeNet 作为开山之作,为 CNN 的发展奠定了基础,而 ResNet 则通过创新性的设计,突破了传统神经网络的限制,使得网络能够构建得更深、性能更优。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 14万+

深度学习与计算机视觉教程(6) | 神经网络训练技巧 (上)(CV通关指南·完结)

批量归一化是 loffe 和 Szegedy 最近才提出的方法,该方法一定程度解决了如何合理初始化神经网络这个棘手问题,其做法是让激活数据在训练开始前通过一个网络,网络处理数据使其服从标准高斯分布。归一化是一个简单可求导的操作,所以上述思路是可行的。在实现层面,应用这个技巧通常意味着全连接层(或者是卷积层,后续会讲)与激活函数之间添加一个BatchNorm层。在神经网络中使用批量归一化已经变得非常常见,在实践中使用了批量归一化的网络对于不好的初始值有更强的鲁棒性。激活函数选择折叶函数。

weixin_42907150的博客 996

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

深度学习与计算机视觉教程(5) | 卷积神经网络(CV通关指南·完结

卷积层是构建卷积神经网络的核心层,网络中大部分的计算量都由它产生。关于卷积层的动图讲解也可以参考ShowMeAI的的深度学习教程 | 吴恩达专项课程 · 全套笔记解读中的文章卷积神经网络解读卷积层的参数是由一些可学习的滤波器(filter)集合构成的。每个滤波器在宽度和高度上都比较小,但是深度和输入数据一致。比如卷积神经网络第一层的一个典型的滤波器的尺寸可以是 5×5×35 \times 5 \times 35×5×3(宽高都是 555 像素,深度是 333 是因为图像应为颜色通道,所以有3的深度)。

weixin_42907150的博客 1100

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

深度学习与计算机视觉教程(1) | 引言与知识基础(CV通关指南·完结)

CS231n 是顶级院校斯坦福出品的深度学习与计算机视觉方向专业课程,核心内容覆盖神经网络、CNN、图像识别、RNN、神经网络训练、注意力机制、生成模型、目标检测、图像分割等内容。课程最后一版公开课视频为2017版,需要最新进阶技术内容的同学可以关注ShowMeAI发布的cs231n进阶课程希望对于深度学习进行一个全面学习了解的同学,可以阅读学习ShowMeAI的深度学习教程 | 吴恩达专项课程 · 全套笔记解读课程引入与介绍KNN 和线性分类器Softmax 和 SVM 两种损失函数。

weixin_42907150的博客 1338

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

深度学习与计算机视觉教程:斯坦福CS231n · 全套笔记解读

本教程依托于 Stanford 斯坦福大学的《CS231n:深度学习与计算机视觉》,对深度学习与计算机视觉方向的图像分类、CNN、RNN、目标检测、图像分割、生成模型等各个主题做了体系化的梳理

ShowMeAI研究中心 1万+

深度学习与计算机视觉教程(8) | 常见深度学习框架介绍(CV通关指南·完结)

现在有很多种深度学习框架,目前最流行的是 TensorFlow。第一代框架大多由学术界编写的,比如 Caffe 就是伯克利大学开发的。第二代往往由工业界主导,比如 Caffe2 是由 Facebook 开发。这里主要讲解 PyTorch 和 TensorFlow。回顾之前计算图的概念,一个线性分类器可以用计算图表示,网络越复杂,计算图也越复杂。构建大的计算图很容易,可以快速的开发和测试新想法;这些框架都可以自动计算梯度只需写出前向传播的代码;

weixin_42907150的博客 1167

深度学习与计算机视觉教程(12) | 目标检测 (两阶段,R-CNN系列)(CV通关指南·完结)

图像分类对应将图像划分为单个类别的过程,它通常对应于图像中最突出的物体。实际现实世界的很多图像通常包含多个物体,如果仅仅使用图像分类模型分配单一标签是非常粗糙的,并不准确。而目标检测(object detection)模型可以识别一张图片的多个物体,并可以给出不同物体的具体位置(边界框)。目标检测在很多场景有用,如无人驾驶和安防系统。常见的经典目标检测算法如下图所示:目标检测的基本思路是:解决定位(localization) + 识别(Recognition)两个任务。

weixin_42907150的博客 1081

深度学习与计算机视觉教程(11) | 循环神经网络及视觉应用(CV通关指南·完结)

RNN 是一种输入输出都很灵活的网络结构;Vanilla RNNs 很简单,但是效果不好;比较普遍的是使用 LSTM 和 GRU,能有效的改善梯度流;RNN 反向传播梯度爆炸可以给梯度设置阈值,而梯度锐减可以使用复杂的网络,比如 LSTM;RNN 的应用:图像标注、视觉问答,都是将 CNN 与 RNN 结合起来;理解语言模型与注意力模型;ShowMeAI。

weixin_42907150的博客 809

深度学习与计算机视觉教程(14) | 图像分割 (FCN,SegNet,U-Net,PSPNet,DeepLab,RefineNet)(CV通关指南·完结)

图像语义分割是计算机视觉中十分重要的领域,它是指像素级地识别图像,即标注出图像中每个像素所属的对象类别。下图为语义分割的一个实例,它清晰地把图中的骑行人员、自行车和背景对应的像素标注出来了。图像分割有语义分割和实例分割的差别。语义分割不分离同一类的实例,我们只关心每个像素的类别,如果输入对象中有两个相同类别的对象,语义分割不将他们区分为单独的对象。实例分割是需要对对象个体进行区分的。

weixin_42907150的博客 963

MATLAB计算机视觉与深度学习实战

MATLAB是一个强大的工具,广泛用于工程和科学领域。它提供了丰富的工具箱来处理各种计算任务。在计算机视觉和深度学习领域,MATLAB也提供了很多方便的函数和工具箱,例如Computer Vision Toolbox和Deep Learning Toolbox。这篇文章将介绍如何使用MATLAB进行基本的计算机视觉任务,并结合深度学习进行图像分类。除了使用预训练的模型,你也可以使用MATLAB设计和训练自己的深度学习模型。以下是一个简单的卷积神经网络(CNN)用于图像分类。% 加载数据集。

努力是为了站在万人之中,成为别人的光 8985
上一篇: 深度学习与计算机视觉教程(6) | 神经网络训练技巧 (上)(CV通关指南·完结)
下一篇: 深度学习与计算机视觉教程(8) | 常见深度学习框架介绍(CV通关指南·完结)
ShowMeAI
博客等级 码龄5年 6514粉丝 672原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShowMeAI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值