DL roam

来自Jack's Lab
跳转到: 导航, 搜索

目录

1 接触 Deep Learning

Jack 给我普及Deep learning已经是一两年前的事情了. 作为酒桌的谈资,自然是没往心里去. 直到我最爱的几个youtube频道相继开始聊起Deep learning的话题,才想起来探个究竟.

  • 3Blue1Brown on youtube [1]

2 直观印象

无论是jack给的连接还是youtube频道3Blue1Brown, 都是用下面这个例子来作为介绍deep learning.

直接跳到这个神经元结构示意图, 是下面的这个样子.

Deep learning hw fnn.png


什么意思呢, 就是假设每个手写数字都是28x28个像素的小图片, 总共784个点, 每个点的像素值按照一行行配列好,变成一个输入数组对应 input layer的784个神经元, 非常的直接和暴力.

神经元有四层, 中间两层称作 hidden layer.

最右边是输出层, 对应0到9 10个数字. 如果已经训练好了, 一个手写的'3'的图片,在输出层将会得到 3这个神经元的值最接近1(最大可能性), 其他神经元,理想状态, 可能性最接近0 (或-1).

而且,有一个事情必须提到,每个神经元有一个可能性的度量值, 从[-1, +1],或者从[0,1], 一层层传递下去,构成正向反馈.


好了, 一共有四层, 算是'深了', 所以叫 'deep learning', 而层数很少的呢叫 'shallow learning'.

每一层的每一个结点都全链接到下一层的所有神经元, 同样,靠右的神经元也全链接到上一层的所有神经元, 这样的结构叫 "FNN" 全链接神经网络.


那下一层的神经元怎么得到自己的 '可能性' 值, 有两个步骤. 第一步,线性影射值, Zl = wl-11al-11 1 + wl-12*al-12 + ... + b

这个式子的意思是有好几个:

  • 每个神经元都被上一层的神经元以某种权重激活 (activation). 权重值是w (weight)
  • 上一层的一个神经元, 贡献给下一层的某个神经元的线性值"z"(小写代表某一个神经元), 用z=a*w计算.
  • Z 是所有上一层的神经元对这层的一个神经元贡献的和, 加上一个bias值 (b)
  • 第一层的激活直接从数据, 这里是784个像素的值获得.


第二步是, 根据Z计算神经元的 "可能性" 值, Z可能是任何值, 但是可能性的值, 一般是[0,1] (或者[-1,1]), 这个步骤是非线性的, 也是最重要的, 神经元必须有非线性过程. 这个函数应该能把任意实数值影射到0-1这个区间( 或者 [-1,1]). 这样的函数有很多,最常见的是 σ

00.jpg


所谓训练神经网络,就是找到每一层每一个神经元里所有wi和b 的最合适的值.


3 最小值:cost函数

先从识别一个数字来说,比如"2", 上述神经元可以认为是一个复杂的函数, 用一个手写体28x28的"2"的图片作为输入(x), 输出a是此图片可能是2的可能性. 输入一个"2"的图片,当然希望输出是y(x)=[1] (一维向量), 期望值用y(x)来表示(这里有点反人类, 为毛不用y(x)作为神经网路输出值). 而神经网络输出值可以用a表示. 这里y(x)就是1, 写作y(x)方便扩展.


希望 "2" 作为输入, [1,]作为输出, 如果不是这个情况呢, 比如输出了 0.1, 那么就需要说明下我们和期望值的'距离', 一般用:

C(w,b)= |y(x)-a|2

而C(w,b)定义了我们距离我们期望值的"距离"或者说"价格" 也或者说 "损耗". 总之, 是希望通过调整w,b这些参数, 得到一个神经网络的输出,使得C(w,b)这个Cost函数, 取值最小,也就是得到了最好结果.

(直接相减行不? 应该是不行的. C(w,b)是一个函数, 如果这个函数在所有图片"2"为输入的值域上, C(w,b)可能是一条直线, 哪里是最好值, 好像没法子定义好. 而二次方程图像是一个抛物线, 有一个底, 有一个最小值)


Dl-grident-decendent.png


现在,我们考虑,我们要同时识别手写"2"和"3". 结果是期望值现在是一个二维向量了, "2" 期望值是 [1,0], "3":期望值是 [0, 1]. 神奇的是, 数学, 用向量来表示"2", "3"的期望值时, 有几个令人敬畏的性质.

首先, 向量里的每个值互相都是正交的, 也可以说是二维空间的, 大概可以这样说, 学习 "2" 和学习"3" 现在可以独立互不影响的展开了. 其次, 如果输入是"2"的图片, 你肯定希望向量对应3的可能性是0, 而输入图片"3",向量对应2的部分是0. 这对应了输出向量的"方向",很神奇的是, Cost取最小值的时候, 这个条件也是满足的.

二维情况下, Cost函数, 如果走了狗屎运,可能是这个样子:

Dl-good-cost.png

很明显, 如果Cost是这个样子的, 我们应该能找到, w,b的组合, 让我们走到谷底.


想一下, 一个点在这个二维曲面上的意义是什么. 一个点, 代表某个图片通过一组 w,b的值被影射到的位置. 调整神经网络的w,b, 这个影射点的位置将会改变, 我们希望所有"2"的输出都在底部,其输出值在2的维度(x)上投影最大, 所有"3"的输出也都在底部, 很幸运, 二维空间容许我们 "3"的输出也在底部 其输出值在3的维度上投影最大(y). 二维空间容许"2" "3"有"相当旷阔"的独立性,在w,b调整中可能可以实现把"2","3"的影射值放到这个曲面的底部,即, cost最小. 这段,几乎就是在想象,向量代表的多维度空间是什么意思. (不要相信我)


还有一个问题, 就是所有的输入图片可能不能都是"最佳", 那么, 最好其平均值最好. 所以cost函数实际上是:

Deep-learnign-full-cost-mean-squeare.jpg


这个函数可以看作是以w,b的组合作为变量的函数 (而不是那些"图片"), 学习就是通过调整w,b,找到这个函数的最小值.


4 如何找到最小值:gradient descent

目的很明确, 我们可以通过找到Cost函数的极值(最小值)优化网络, 达到目的. 一般情况下 Cost函数会很复杂, 不过还是假设Cost函数很简单, 只有两个变量, 二维情况来看看.

Dl-good-cost.png


通过函数导数(函数)可以知道哪个点的导数为0, 即可知道极值位置. 不幸的是, 这个方法对一个变量有用, 但是对于拥有如此大量的变量的函数,毫无作用( (第一个hidenlayer就有768*5个weight变量).

但是, 有个物理学非常常用的刻画场性质的数学量, 梯度,非常适合渐近的解决这个问题. 梯度是对函数每个变量求偏导数, 最后得到一个向量,在这个向量方向上,函数变化率最大.

梯度的作用是可以求得Cost函数 C(v) 在某点处的变化量 ΔC(v) 这里用v来代Cost函数的向量(对任意函数适用), v=[v1,v2,....], 用偏导数计算某点处的函数变化率如下:

Dl-cost-delta.jpg

这个式子用梯度来写就是如下形式:

ΔC≈∇C⋅Δv

  • ∇:梯度计算符号. 含义如下, 左上角的T是转置运算, 把向量变成矩阵(就是横向变成垂直)

Dl-grident.jpg

  • Δv 是变量的变化量, Δv≡(Δv1,Δv2)T


这不仅是能计算某点处的函数变化量ΔC, 同时是矩阵运算, 契合计算机.


有了这个工具, 就能够从任意一点开始(将所有w,b置为非零随机数), 通过下面方法逐步降低C(w,b)的取值. 既然

ΔC≈∇C⋅Δv

那么可以取一个Δv, 注意这里的Δv内含有所有维度上的一个值,对应各个w,b的调整量, 同时作为向量,在我们的简单的例子里, 即在三维表面上指明了一个方向.

Δv=−η∇C

则在Δv这个变化方向上

ΔC≈−η∇C⋅∇C=−η‖∇C‖2

因为‖∇C‖2≥0 保证了 ΔC≤0, 即 Cost函数永不升高.


既然数学保证了Cost永不上升, 就可以把随机点 v挪动到如下位置:

v→v′=v−η∇C

这个过程就是基于梯度的下降过程. η是比较小的一个正数, 叫做 learning rate (学习速率). 不断重复这个过程, 就有可能走到一个Cost的最小值区域.


第一个难题出来了. cost函数是定义在所有样本空间的一个平均值, 数量极大, 计算一个Δv估计就爆了. 数学又来救场子了. 可以在样本中任取m个, 来估算∇C. 叫做 随机梯度下降 法. 这随机的m个样本叫做mini-batch. 如果m足够大, 可以期望在这m个样本上的梯度基本上等于在所有样本上的∇C:

Dl-minibach-1.jpg


即:

Mini-bach-grident.jpg


如果Cost函数放大m倍, 可以忽略梯度的 1/m, 这样就可以对未知数量样本进行计算, 亦或这只是等价于η的调整.

5 卷积与图像处理

即便是像爱因斯坦这种宗师, 也被数学大牛诸如希尔伯特嘲笑. 比较有名的是一句玩笑说, "物理对于物理学家来说实在是太难了". 同样的事情还发生在模拟电子工程学, 数学家觉得工程师掌握的数学对数学家是一种侮辱, 工程师从来都不知道他们的领域需要什么样的数学. 至于程序员, 估计人家都懒得嘲笑你. 然后deep learning 突然火爆, 程序员可怜的数学...

像卷积这个东西, 至少电子工程非常需要, 因为爱好无线电, 首次看到这个东西是在一本非常昂贵的书<<Wide Band Amplifier>> 上看到的, 用来计算放大器,滤波器的时域响应. 看到CNN的卷积还是有点懵圈的. 卷积在哪里,卷积是微积分, 矩阵的这个卷积有点摸不到头脑.

感谢互联网.

我看到的卷积是这样的, 是时间的函数,只有一个变量:

Convolution.jpg


而图像处理/Deep learning的卷积其实是矩阵定义, 至于他们之间的数学怎么联系到一起, 我选择完全相信数学(就是不懂的意思).

两个变量的函数其卷积定义如下:

2var-convolution.jpg


同时, 有两个变量的卷积函数可以视为矩阵 Axy = f(x, y) , 则矩阵的卷积就是下述样子:

函数f,g 代表 n × m 的矩阵A 和 k × l 的矩阵 B, 卷积 f ∗ g 就是一个 (n + k − 1) × (m + l − 1) 的矩阵C:

Matrix-convolution.jpg


图像处理应用卷积一般是下面这个样子的, 定义一个矩阵,一般就是3x3(这个矩阵叫做kernel或者filter), 另一个矩阵来自图像(选取图像中相同大小的矩阵), 进行卷积运算, 而且不需要计算全部卷积,只取中心结点 [2,2]即可, 即:

Image-kernel-convolution.jpg


图像中和kernel做卷积运算的对应矩阵的选择方法如图所示, 对图片每一个像素作卷积,卷积后取中间值作为目标图像的像素值.

Image-convolution-1.JPG


对于边缘的图像, 填充0做成3x3矩阵.

Image-convolution-2.JPG

Image-convolution-3.JPG


这个卷积后的图像, 实际上是将图片中的点和周围的点的关系的一种度量, kernel就是具体这种关系是什么, 比如高斯模糊,边界检测 等等.

6 CNN

有了一般Deep Learning 学习网络的认识, 卷积和图像处理的概念. 就可以进一步看看 CNN 网络了. CNN 网络非常明确的限定了处理对象是图像. 如果都是FNN网络,处理全尺寸图片时, Cost函数仅在第一层就会有巨量的参数. CNN通过引入卷积,或者说kernel对图像进行处理, 能极大的减少参数数量. 其结构一般如下:

CNN-Lenet-5.png

  • 这里的每个convolutions处理都没有画出对应的kernel. 但是有几个feature map就有几个对应的kernels.
  • subsampling又称作pool, 最常见的是把图片分割为2x2的子图, 子图中四个值只取最大值, 或者平均值. 这样就逐步减小了图片.


convolution layer结构如下.

Lenet5-CONV-Layer.png

这些filters/kernels 不是预先定义好的, 而是通过对Cost函数进行梯度下降逐步学习而来, 这里才是神奇的地方. 如果图片尺寸是 Win X Hin X Cin, filters尺寸是 Fh X Fw, 输出的处理过的feature map尺寸根据对边缘点处理的不同有两种, 如果采用填0处理, 则尺寸不变, 如果丢弃周围点不够的行则变为: (Win - Fh +1) X (Hin - Fw +1), 而feature map的深度, 也就是处理过的图像个数等于kernels个数.




7 参考资料

个人工具
名字空间

变换
操作
导航
工具箱