神经网络的前世今生

From Logistic regression to Neural netword

提纲:

  • 传统的机器学习来做分类问题

    1. Logistic/Softmax regression
    2. 上述算法的决策边界
    3. 用什么损失函数
  • 神经网络的本质剖析

    1. 从Logistic regression到神经网络
    2. 前向传播和反向传播
    3. 训练的注意事项(参数初始化、优化方法)
    4. 从神经网络的角度看Word2Vec
  • 卷积神经网络什么鬼
    ......

一、传统机器学习对付分类问题

1.Logistic Regression(二分类)和Softmax(多分类)

LR我们一般之前都接触过,就是一个用W、b对X进行线性表示,然后再通过一个非线性的激活函数输出预测值。
曾经我突然有一个问题:“不是有一个非线性的激活函数吗?为什么还是只能进行线性的分类?”
这个问题说明了我对Logistic regression 的理解十分肤浅,对分类问题的本质还是不了解。
所以我重新回顾了一下分类问题的本质是什么。

假设我们的两个类别在图上表示为:

classification1.jpg

思路是什么:

  1. 首先观察不同类别的点的分布情况
  2. 找到分割开不同类别的方法(寻找切平面)
  3. 拟合切平面

图上的两个类,可以大致用一条直线分隔开来,我们设这个直线可以表示为:

Z = W·X + b

我们希望能够求得这条直线,或者说,想求出W和b。这样的话,WX+b>0和WX+b<0就可以吧原来的两个类给区分开了。见下图:

classification2.jpg

怎么学习这条直线呢?我们可以使用所有训练样本的点到直线的距离作为衡量指标,让距离尽可能大。也就是我们的最小二乘法。

但是,如果我们希望得到的结果是一个概率,即预测一个点属于各个类别的概率分布式多少。拿我们应该怎么办呢?
这个时候,我们就可以采用sigmoid函数

sigmoid.jpg

从sigmoid函数的图像可以看出,它可以把一个输入压缩到0-1之间,并且是一个中心对称图形,可以很好地拟合一个概率分布。比方我们希望某个点,属于第一类的概率为0.7,属于第二类的概率为0.3.这样似乎更符合实际一些,没那么武断。

我们把上面的Z = W·X + b作为sigmoid的输入,输出为y,则当Z>0时,y>0.5;当Z<0时,y<0.5。我们可以发现这样的结构很合理:

对于那些靠近直线Z = W·X + b的点,本来类别就比较模糊,如果直接用Z的符号来判断类别,就不大好。但是,这些靠近直线的点,由于Z的值和接近0,所以通过sigmoid输出的概率值也接近0.5,我们就可以看出那些点的分类的把握不是很大,这样就十分合理。

上面说的这些,就是所谓的Logistic Regression,表达式就是:

Z = W·X + b
y = σ(Z)

这样,我们的输出就是一个概率分布了。

上面讲的问题是一个二分类问题,那对于多分类我们怎么办呢?

多分类,可以转化为多个二分类,即学习多条直线的W和b:

classification3.jpg

图中,每一条直线,都是用于把对应的类和其他所有的类分开,这样,有几类,就需要几条直线。
设类别为i,则每一条直线可以表示为:Zi = Wi·X + bi。这里的Wi和前面的W形状一样。

如何获得多个类别的概率分布呢?用sigmoid函数是肯定没办法了。这个时候,Softmax函数就闪亮登场了。

softmax.jpg

可以很容易地看到,每一类的pi加起来就是1,于是就形成了一个多类别的概率分布。

再回头看,为什么是决策边界都是线性的?因为我们预设分割边界就是线性的呀而sigmoid和Softmax这些非线性函数,只是起到概率分布转换的作用!所以,决策边界自然是线性的。那个问题不攻自破了。

传统机器学习的方法怎么解决非线性问题呢?————SVM

上面介绍了Logistic/Softmax Regression,但是问题还没完,损失函数还没设定呢,那么我们应该怎么设定损失函数呢?

2.损失函数

开门见山吧,这里我们使用“交叉熵(Cross-entropy)”。主要是我们要了解,这个交叉熵到底是什么玩意儿,为什么用这种形式,以及能否用其他的损失函数?

熵的概念来源于信息论,熵说白了就是信息量。在信息论中,一件事的信息量是怎么衡量的呢?

假设事件A发生的概率为p,则定义熵(信息量)为

可以发现,概率p越大,熵就越小,信息量就越小。为啥呢?细细想一想也很自然,概率很大的事情,就很确定,那就跟地球是圆的一样,没什么信息量。而概率小的事情,因为不确定性很大,有很多种可能,所以信息量就大,就比如说“地球是平的”,会蕴含很多的信息。

那现在我们有一堆样本X=[x1,x2,...,xn],概率分布是p(x1),p(x2),...,p(xn).那么这些样本蕴含的平均信息量/平均熵是多大呢?很简单,求平均:

明白了上面的内容,我们接下来看一下,如果有两个概率分布p和q,怎么衡量这两个概率分布之间的差异呢?这里就使用KL散度


把KL散度分解一下,可以得到:

可以看到,左边的部分就是前面的概率分布p的信息量,剩下的右边的部分,就是我们传说中的交叉熵

回到我们的机器学习中,假设我们样本的真实概率分布是p,我们通过模型预测出来的概率分布是q,那么我们的损失函数,就可以使用KL散度。而因为真实概率分布p是固定的,所以KL散度的第一项-H(p(x))是一个定值,可以省去,所以我们就可以只用交叉熵来作为损失函数了,它就是衡量了我们的预测分布q与真实分布p的差距。

所以,一般对于这种输出概率分布的模型,我们都采用交叉熵来作为损失函数。

Cross-entropy VS. MSE

有人问,不是还有一个著名的MSE(Mean Square Error)吗?也是经常作为回归问题的目标函数呀,它和ACE(Average Cross Entropy)比起来孰优孰劣呢?

它俩的差别其实不大,都是常用的损失函数。但是在Logistic regression以及神经网络中,我们更常使用的还是ACE。原因主要体现在求导、更新参数的过程中:

大家不妨手推一下使用MSE和ACE对参数W进行求导的公式,大致推一推便可以发现:

  • MSE对W的导数,正比于sigmoid的导数,而根据sigmoid的图像可知,随着我们的训练的进行,预测值y会越来越接近0或者1,sigmoid的导数越来越小,这样会导致在梯度下降法中参数更新的速度越来越慢,可能难以收敛
  • ACE对W的导数,正比于预测的误差,误差越大,导数越大,更容易收敛

二、神经网络登场

其实,理解了Logistic regression,也就基本理解了神经网络,也就大概知道了深度学习的大致思路。

我们首先用一个图表示一个Logistic regression:



图中x1-x4为X的各个维度,Z=WX+b,a就是把Z输入激活函数sigmoid得到的结果,称为激活值(activation),然后就得到预测值y^.

如果我们把图中的那个黄色球看做一个神经元的话,那么实际上神经网络就是多了几个或者几层的神经元:



每一个神经元,内部的原理都是一样的。所以说,Logistic regression就是神经网络的基础。

多层神经网络,因为它是多个非线性函数的叠加,理论上可以拟合任意复杂的函数,这就突破了Logistic regression的局限,可以对付各种非线性问题了。

神经网络的神秘之处在于,除了最开始的输入X是我们知道意义的,中间层的各种输入输出是我们无法理解的

但另一方面,这正是神经网络的强大之处。每一层的输入,都可以看做是对原数据提取的某些特征,然后再经过处理,提取另一些特征,再传给下一层,如此反复。这样经过学习,就可以学习到许多我们人无法定义或者不了解的特征,但是这些特征对于我们判断事务本身是有帮助的。

这样,实际上我们是让神经网络主动地从数据中发掘特征,从而减少了我们人工定义特征的工作,“让数据说话,而不是替数据说话”。这也正是“深度学习”的主要思想,让模型的深度赋予模型以力量,从而让模型去自动提取特征,完成我们的任务。

3.卷积神经网络

一、引子————边界检测

我们来看一个最简单的例子:“边界检测(edge detection)”,假设我们有这样的一张图片,大小8×8:

图片中的数字代表该位置的像素值,我们知道,像素值越大,颜色越亮,所以为了示意,我们把右边小像素的地方画成深色。图的中间两个颜色的分界线就是我们要检测的边界。

怎么检测这个边界呢?我们可以设计这样的一个 滤波器(filter,也称为kernel),大小3×3:

filter

然后,我们用这个filter,往我们的图片上“盖”,覆盖一块跟filter一样大的区域之后,对应元素相乘,然后求和。计算一个区域之后,就向其他区域挪动,接着计算,直到把原图片的每一个角落都覆盖到了为止。这个过程就是 “卷积”
(我们不用管卷积在数学上到底是指什么运算,我们只用知道在CNN中是怎么计算的。)
这里的“挪动”,就涉及到一个步长了,假如我们的步长是1,那么覆盖了一个地方之后,就挪一格,容易知道,总共可以覆盖6×6个不同的区域。

那么,我们将这6×6个区域的卷积结果,拼成一个矩阵:

边界检测

诶?!发现了什么?
这个图片,中间颜色浅,两边颜色深,这说明咱们的原图片中间的边界,在这里被反映出来了!

从上面这个例子中,我们发现,我们可以通过设计特定的filter,让它去跟图片做卷积,就可以识别出图片中的某些特征,比如边界。
上面的例子是检测竖直边界,我们也可以设计出检测水平边界的,只用把刚刚的filter旋转90°即可。对于其他的特征,理论上只要我们经过精细的设计,总是可以设计出合适的filter的。

我们的CNN(convolutional neural network),主要就是通过一个个的filter,不断地提取特征,从局部的特征到总体的特征,从而进行图像识别等等功能。

那么问题来了,我们怎么可能去设计这么多各种各样的filter呀?首先,我们都不一定清楚对于一大推图片,我们需要识别哪些特征,其次,就算知道了有哪些特征,想真的去设计出对应的filter,恐怕也并非易事,要知道,特征的数量可能是成千上万的。

其实学过神经网络之后,我们就知道,这些filter,根本就不用我们去设计,每个filter中的各个数字,不就是参数吗,我们可以通过大量的数据,来 让机器自己去“学习”这些参数嘛。这,就是CNN的原理。

二、CNN的基本概念

1.padding 填白
从上面的引子中,我们可以知道,原图像在经过filter卷积之后,变小了,从(8,8)变成了(6,6)。假设我们再卷一次,那大小就变成了(4,4)了。

这样有啥问题呢?
主要有两个问题:

  • 每次卷积,图像都缩小,这样卷不了几次就没了;
  • 相比于图片中间的点,图片边缘的点在卷积中被计算的次数很少。这样的话,边缘的信息就易于丢失。

为了解决这个问题,我们可以采用padding的方法。我们每次卷积前,先给图片周围都补一圈空白,让卷积之后图片跟原来一样大,同时,原来的边缘也被计算了更多次。

padding

比如,我们把(8,8)的图片给补成(10,10),那么经过(3,3)的filter之后,就是(8,8),没有变。

我们把上面这种“让卷积之后的大小不变”的padding方式,称为 “Same”方式,
把不经过任何填白的,称为 “Valid”方式。这个是我们在使用一些框架的时候,需要设置的超参数。

2.stride 步长
前面我们所介绍的卷积,都是默认步长是1,但实际上,我们可以设置步长为其他的值。
比如,对于(8,8)的输入,我们用(3,3)的filter,
如果stride=1,则输出为(6,6);
如果stride=2,则输出为(3,3);(这里例子举得不大好,除不断就向下取整)

3.pooling 池化
这个pooling,是为了提取一定区域的主要特征,并减少参数数量,防止模型过拟合。
比如下面的MaxPooling,采用了一个2×2的窗口,并取stride=2:

Maxpooling

除了MaxPooling,还有AveragePooling,顾名思义就是取那个区域的平均值。

4.对多通道(channels)图片的卷积
这个需要单独提一下。彩色图像,一般都是RGB三个通道(channel)的,因此输入数据的维度一般有三个:(长,宽,通道)
比如一个28×28的RGB图片,维度就是(28,28,3)。

前面的引子中,输入图片是2维的(8,8),filter是(3,3),输出也是2维的(6,6)。

如果输入图片是三维的呢(即增多了一个channels),比如是(8,8,3),这个时候,我们的filter的维度就要变成(3,3,3)了,它的 最后一维要跟输入的channel维度一致。
这个时候的卷积,是三个channel的所有元素对应相乘后求和,也就是之前是9个乘积的和,现在是27个乘积的和。因此,输出的维度并不会变化。还是(6,6)。

但是,一般情况下,我们会 使用多了filters同时卷积,比如,如果我们同时使用4个filter的话,那么 输出的维度则会变为(6,6,4)

我特地画了下面这个图,来展示上面的过程:

同时有4个filter

图中的输入图像是(8,8,3),filter有4个,大小均为(3,3,3),得到的输出为(6,6,4)。
我觉得这个图已经画的很清晰了,而且给出了3和4这个两个关键数字是怎么来的,所以我就不啰嗦了(这个图画了我起码40分钟)。

其实,如果套用我们前面学过的神经网络的符号来看待CNN的话,

  • 我们的输入图片就是X,shape=(8,8,3);
  • 4个filters其实就是第一层神金网络的参数W1,,shape=(3,3,3,4),这个4是指有4个filters;
  • 我们的输出,就是Z1,shape=(6,6,4);
  • 后面其实还应该有一个激活函数,比如relu,经过激活后,Z1变为A1,shape=(6,6,4);

所以,在前面的图中,我加一个激活函数,给对应的部分标上符号,就是这样的:

呕心沥血画的好图片,值得收藏

三、CNN的结构组成

上面我们已经知道了卷积(convolution)、池化(pooling)以及填白(padding)是怎么进行的,接下来我们就来看看CNN的整体结构,它包含了3种层(layer):

1. Convolutional layer(卷积层--CONV)
由滤波器filters和激活函数构成。
一般要设置的超参数包括filters的数量、大小、步长,以及padding是“valid”还是“same”。当然,还包括选择什么激活函数。

2. Pooling layer (池化层--POOL)
这里里面没有参数需要我们学习,因为这里里面的参数都是我们设置好了,要么是Maxpooling,要么是Averagepooling。
需要指定的超参数,包括是Max还是average,窗口大小以及步长。
通常,我们使用的比较多的是Maxpooling,而且一般取大小为(2,2)步长为2的filter,这样,经过pooling之后,输入的长宽都会缩小2倍,channels不变。

3. Fully Connected layer(全连接层--FC)
这个前面没有讲,是因为这个就是我们最熟悉的家伙,就是我们之前学的神经网络中的那种最普通的层,就是一排神经元。因为这一层是每一个单元都和前一层的每一个单元相连接,所以称之为“全连接”。
这里要指定的超参数,无非就是神经元的数量,以及激活函数。

接下来,我们随便看一个CNN的模样,来获取对CNN的一些感性认识:

一个CNN的例子

上面这个CNN是我随便拍脑门想的一个。它的结构可以用:
X-->CONV(relu)-->MAXPOOL-->CONV(relu)-->FC(relu)-->FC(softmax)-->Y
来表示。

这里需要说明的是,在经过数次卷积和池化之后,我们 最后会先将多维的数据进行“扁平化”,也就是把 (height,width,channel)的数据压缩成长度为 height × width × channel 的一维数组,然后再与 FC层连接,这之后就跟普通的神经网络无异了

可以从图中看到,随着网络的深入,我们的图像(严格来说中间的那些不能叫图像了,但是为了方便,还是这样说吧)越来越小,但是channels却越来越大了。在图中的表示就是长方体面对我们的面积越来越小,但是长度却越来越长了。


四、卷积神经网络 VS. 传统神经网络

其实现在回过头来看,CNN跟我们之前学习的神经网络,也没有很大的差别。
传统的神经网络,其实就是多个FC层叠加起来。
CNN,无非就是把FC改成了CONV和POOL,就是把传统的由一个个神经元组成的layer,变成了由filters组成的layer。

那么,为什么要这样变?有什么好处?
具体说来有两点:

1.参数共享机制(parameters sharing)
我们对比一下传统神经网络的层和由filters构成的CONV层:
假设我们的图像是8×8大小,也就是64个像素,假设我们用一个有9个单元的全连接层:

使用全连接

那这一层我们需要多少个参数呢?需要 64×9 = 576个参数(先不考虑偏置项b)。因为每一个链接都需要一个权重w。

那我们看看 同样有9个单元的filter是怎么样的:

使用filter

其实不用看就知道,有几个单元就几个参数,所以总共就9个参数

因为,对于不同的区域,我们都共享同一个filter,因此就共享这同一组参数。
这也是有道理的,通过前面的讲解我们知道,filter是用来检测特征的,那一个特征一般情况下很可能在不止一个地方出现,比如“竖直边界”,就可能在一幅图中多出出现,那么 我们共享同一个filter不仅是合理的,而且是应该这么做的。

由此可见,参数共享机制,让我们的网络的参数数量大大地减少。这样,我们可以用较少的参数,训练出更加好的模型,典型的事半功倍,而且可以有效地 避免过拟合
同样,由于filter的参数共享,即使图片进行了一定的平移操作,我们照样可以识别出特征,这叫做 “平移不变性”。因此,模型就更加稳健了。

2.连接的稀疏性(sparsity of connections)
由卷积的操作可知,输出图像中的任何一个单元,只跟输入图像的一部分有关系:

只跟输入的一部分有关

而传统神经网络中,由于都是全连接,所以输出的任何一个单元,都要受输入的所有的单元的影响。这样无形中会对图像的识别效果大打折扣。比较,每一个区域都有自己的专属特征,我们不希望它受到其他区域的影响。

正是由于上面这两大优势,使得CNN超越了传统的NN,开启了神经网络的新时代。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容