cs231n笔记

第一课:李飞飞授课

cs231a —— 更宽泛、涵盖更全面的计算机视觉课程。cs231n专门讨论cnn。

CVPR, ICCV —— 重要的计算机视觉会议

Block world (Larry Roberts, 1963)

David Marr's book: VISION

Normalized Cut (Shi & Malik, 1997) 将图像分割为有意义的块

Face Detection (Viola & Jones, 2001)

SIFT & Object Recognition, David Lowe, 1999

Spatial Pyramid Matching, Lazebnik, Schmid & Ponce, 2006

总体梗概

课程描述

计算机视觉在我们的生活中随处可见,其应用包括搜索、图像解译、app、地理制图、医学、无人驾驶飞行器、以及自动驾驶汽车。许多这些应用的核心任务是图像识别,例如图像分类、定位和检测。神经网络技术的最近进展(即深度学习)极大的提升了这些最先进图像识别系统的性能。

重点关注:

如何建立图像识别问题,学习算法(例如反向传播法),训练并精细调整网络的工程应用技巧,通过上手操作的作业和最终的一个课程工程项目来指导训练学生。

课前具备的条件:

精通Python;高度熟悉C/C++

大学微积分;线性代数

基本概率统计

CS229的等效知识(机器学习)[将使用代价函数、求导数、使用梯度下降法求最优]

课程鼓励外部学习者:

作业、课程笔记、讲座视频、幻灯片可以在线获得。

完成作业需要掌握的工具:Python,and a few polular libraries(numpy, scipy, matplotlib)

knn分类器、线性分类器

knn分类器原理不复杂,笔记掠过。

线性分类器与CS229的部分内容一样。要点有:score function, loss function, gradient descend.

SVM loss,也是hinge loss;

softmax loss,可以从两个角度解读:1 信息论角度,真实分布与预测分布的交叉熵,或者KL散度;2 概率论角度,最大似然(叠加正则项时,是最大后验概率)

为什么正则项可以防止过拟合?因为正则项限制模型参数的大小,使模型保持简单。

为什么要用L1、L2正则项?从概率论的角度解释,使假定模型参数服从某种分布(L1对应拉普拉斯分布、L2对应高斯分布),这时再求最大后验概率,就推导出正则项。

实际编程时注意:

初始化W为接近与0的随机数时,应当检验Multi-SVM损失函数 / softMax损失函数是否符合预期。具体为Multi-SVM损失函数C -1,而softMax损失函数为log(C),C为分类数。

寻优过程与CS 229类似。同样,计算梯度时,需要注意:

用数值法求得的梯度来检验解析公式得出的梯度。(所谓的Gradient Check)

图像特征提取:神经网络兴起之前,往往不直接将图像作为分类器的输入,而是先提取特征,再输入分类器。

常用的特征有:Color Histgram,Hisgram of Oriented Gradient (HoG),Bag of Words

反向传播

Computational Graph: 可以近似任何函数

用于计算前向传播,得到函数值;或计算反向传播,计算梯度。

(由于神经网络很复杂时,很难得到梯度的解析式,因此用Computational Graph来计算)

课程反向传播的notes部分,某个函数分解成计算图后,正向传播计算如下:

x = 3 # example values
y = -4

# forward pass
sigy = 1.0 / (1 + math.exp(-y)) # sigmoid in numerator   #(1)
num = x + sigy # numerator                               #(2)
sigx = 1.0 / (1 + math.exp(-x)) # sigmoid in denominator #(3)
xpy = x + y                                              #(4)
xpysqr = xpy**2                                          #(5)
den = sigx + xpysqr # denominator                        #(6)
invden = 1.0 / den                                       #(7)
f = num * invden # done! 

反向传播如下:

# backprop f = num * invden
dnum = invden # gradient on numerator                             #(8)
dinvden = num                                                     #(8)
# backprop invden = 1.0 / den 
dden = (-1.0 / (den**2)) * dinvden                                #(7)
# backprop den = sigx + xpysqr
dsigx = (1) * dden                                                #(6)
dxpysqr = (1) * dden                                              #(6)
# backprop xpysqr = xpy**2
dxpy = (2 * xpy) * dxpysqr                                        #(5)
# backprop xpy = x + y
dx = (1) * dxpy                                                   #(4)
dy = (1) * dxpy                                                   #(4)
# backprop sigx = 1.0 / (1 + math.exp(-x))
dx += ((1 - sigx) * sigx) * dsigx # Notice += !! See notes below  #(3)
# backprop num = x + sigy
dx += (1) * dnum                                                  #(2)
dsigy = (1) * dnum                                                #(2)
# backprop sigy = 1.0 / (1 + math.exp(-y))
dy += ((1 - sigy) * sigy) * dsigy                                 #(1)
# done! phew

其中,dnum的意思是 $$ \partial f / \partial num $$

同理 dx 意思是 $$\partial f / \partial x$$

其他的都类似。

卷积神经网络总体

Convolutional Neural Network 与 Fully Connected Neural Networks 相对。

设计CNN的结构、选择超参数是很费事费力的事情。90%的情况下,我们都从ImageNet中选择表现最好的网络结构,下载下来,再针对自己的具体数据精确调参。

对于Fully Connected Neural Networks,三层比两层表现更好,但是更深的网络则不然。而对于CNN,几乎越深的神经网络效果越好。

为了防止过拟合,一般不是通过降低层数,二是通过 L2 regularization, dropout, input noise等方法。小网络容易陷入较差的局部最优解,对初值依赖很强;而大网络则往往不会得到很差的解,对初值依赖性也不强

一些实现细节

数据预处理:Zero Centering, Normalization。注意:这些操作在计算均值和方差时都是使用 training set,而不能用 validation set 和 test set。

权值初值:初始化为较小的随机数。初始化为标准的高斯分布,然后以1/sqrt(n)做校正(n是神经元的输入的维度),使得神经元的输出为标准高斯分布,这样可以提高收敛的概率。对于采用ReLU的神经网络,应当乘以sqrt(2/n)。

bias初值:一般都设置为0。

检验程序的正确性 Sanity Check

检查初始的损失函数,是否符合预期

检验梯度。在 gradient checking 时使用双精度,而不是单精度,否则会因溢出出现较大的相对误差。分开对 data loss和 regularization loss 进行梯度检验,防止一方的梯度过大吞噬掉另一方,从而检查不出另一方的错误。

再对大量数据进行学习前,把regularization调成0,学习少数几个随机样本(例如20个),使得网络对这几个数据过拟合。此时,理论上loss function应当为0。若不为零,说明学习过程中有错误。

照看学习的过程

第一个需要监督的量是损失函数。 先设定很小的regularization,然后观察loss function是否会快速下降。如果不下降,说明learning rate 太低了;如果loss function 急剧增大,则learning rate 太大了

第二是训练集的分类精度和检验集的训练精度 Train/Val accuracy

第三是每一步的权值的更新量与权值本身的比值,Ratio of weights:updates,大小应当为1e-3左右

第四,输出每一层的Activation / Gradient distributions,以排除不正确的initialization

最后,得到学习的结果时,将第一层神经网络可视化(对于处理图像的网络)

迭代寻优的方法

普通的梯度下降法

动量更新法

Nesterov动量法

超参数调优

learning rate 的调优: 使用cross validation,先选择部分数据、执行少量迭代,观察loss function是否下降,变化情况如何,以确定learning rate 的大致范围。(过大则loss fucntion可能出现NaN,过小则loss function 无变化)

对超参数的采样使用随机抽样,而不是等间隔抽样,这样更容易找到更好的组合

迁移学习

使用大型数据的学习结果,只对最后几层做进一步调优。

CPU or GPU

GPU编程:

  • CUDA

类c语言代码,有很多技巧,很复杂

高阶API:cuBLAS, cuFFT, cuDNN(用于卷积神经网络、反向传播),等等

  • OpenCL

与CUDA类似,通常计算速度更慢一些

  • Udacity:并行编程导论

一般使用现有库即可。

你可能感兴趣的:(他山之石,cnn)