个人原文:www.hijerry.cn/p/53364.htm…html
感知机(perceptron)于1957年由Rosenblatt提出,是一种二分类线性模型。感知机以样本特征向量做为输入,输出为预测类别,取正、负两类。感知机最终学习到的是将输入空间(特征空间)划分为正、负两类的分离超平面,属于判别模型。为此,使用误分类做为损失函数,利用梯度降低优化该函数,可求得感知机模型。感知机是神经网络与支持向量机的基础。git
第 个样本的预测值
,其中
称为激活函数,
,损失为
。单层感知机的目的就是习得合适的
与
,使得全部样本的损失之和
最小。github
若是咱们令 即感知机的输入。那么当
时,
;当
时,
。由于
是
线性组合,因此最终获得的是一个超平面
,超平面将输入样本分为了
和
-1两类。算法
当输入 是二维向量时,用红点表示
的数据,黑点表示
的数据,最终习得的是一条直线,将两个数据分离开,以下图所示。bash
由于单层感知机最终习得是超平面,因此只能用于解决线性可分问题。对于下面这样的数据,单层感知机无能为力。网络
多层感知机也叫MLP,能够看作是一个有向图。MLP由多层节点组成,每一层全链接到下一层,除输入节点外,每一个节点都是一个带有非线性激活函数的神经元(unit)。多层感知机可用于解决线性不可分问题。机器学习
由于神经网络的和多层感知器是一个意思,因此下面直接对单层前馈神经网络进行详细说明。函数
下图是一个输入层节点数为3,隐藏层节点数为2,输出层节点数为2的前馈神经网络,该网络可用于解决二分类问题。学习
单层前馈神经网络本质上是一个多层感知机,有如下几个特色:优化
权重
链接。单层
。前馈
。咱们拿出隐藏层的一个神经元(unit)放大来看:
神经元的任务就是接受输入,产生输出
。
z
表示神经元的输入,a
是神经元的输出。
输入怎么得来?就是上一层的神经元输出与权重
的乘积之和再加上偏置
。
输出怎么得来?把输入值带入激活函数
获得。
写成数学表达式就是:
是激活函数,常见的有sigmoid、tanh、ReLU。
Sigmoid的表达式为 ,定义域为
,值域为
在 处,函数值为
,其函数图像以下:
sigmoid函数有许多优美的性质,如:
是 的复合函数,
又名
天然常数
1阶导函数
为 。即函数在某一点的导数可由函数在这一点的函数值求得
曲线光滑,定义域内到处可导,且能够无限次求导
能够把任意输入压缩到 范围内
在反向传播算法(BP算法)中,性质二、3起到了极大的做用,性质4起到了防溢出的做用。
现考虑一个样本 ,其中
是输入数据,
是实际值。咱们如今来手动计算
预测值
。预测值
的计算过程是从输入层开始
从左往右计算
的,因此这个过程也叫做前向传播。
下图表示,为了获得 ,有哪些神经元被激活了。
为了方便表述,用 表示第
层的第
个神经元与第
层的第
个神经元相连的权重,用
表示第
层第
个神经元的偏置值。
注意。输入层没有激活函数,因此:
若是咱们把 做为类别为
的几率,将
做为类别为1的几率,则样本
的预测值能够写成
,因此为了让
,选用
做为输出层的激活函数。
令 ,
咱们令 ,
,那么
,同理设
神经网络能够明确的用数学语言表达,它的函数表达式,能够明确的写出来
复制代码
若是真的将这个数学表达式写出来,那么这个数学函数 是一个包含
个参数的函数,函数输入
可获得预测值
,这个表达式会很是长。
咱们如今来优化网络中这10个权重参数和4个偏置参数。
定义输出层的节点 的偏差,可用的损失函数有:
使用梯度降低算法来优化损失函数,则须要求出损失函数对全部参数的导数
,这个过程在计算上是从输出层开始从右往左计算
的,由于与计算预测值 的过程恰巧相反,因此也叫做反向传播。
以计算权重 的偏导数为例,根据链式法则不可贵到:
∵ ,又
,
∴ (注:这是二分类问题特有的交叉熵表示方式)
∴
又
且
故原偏导数可写成:
更通用化的表达,如何计算 ?依葫芦画瓢得:
令 表示输出层节点
的偏差值
则上式可写成:
如何理解?用 表示为隐藏层节点的位置,
表示为输出层节点的位置,那么权重
的导数为
该权重前一层第i个节点的激活值与后一层第j个节点的偏差值的乘积
。
下图是反向传播的示意图,损失函数产生的偏差顺着红线一直往左边传,每通过一条红线就求一次导数,直到要求的权重也覆盖在红线为止。下图有三条红线,也就是损失函数 对
的导数须要用三个偏导数乘积造成的链式求导才能获得,且最后一个偏导数值为
。
如何计算 呢?继续使用链式法则 + 依葫芦画瓢可得:
令 为
的
偏差值
,那么上式能够写成:
观察能够发现:
如何理解?若是用 表示输入层节点位置,
表示隐藏层节点位置,那么权重
的导数为
该权重前一层第i个节点的激活值与后一层第j个节点的偏差值的乘积
。每一个节点的偏差值 等于 链接权重 与 权重另外一端所连节点的偏差值 的乘积之和 与 本节点激活值的导数 的乘积
。
详细的推导过程读者能够本身琢磨一下,这里有个关键点须要注意:
如何求 的导数?根据以前的逻辑推导便可:
如何求 的导数?链条太长,这里直接给出答案:
与权重导数不一样的地方就是,在求导过程当中的最后一项 。
若是加入偏置单元,也能够理解为偏置单元 的值为1,以下图所示:
正则化(regularation)是防止机器学习过拟合的一种手段。一种常见的手段是经过将权重的平方之和加入到损失函数来实现。那么损失函数变为:
全部权重、偏置之和称为 正则项
, 是
正则项系数
,也叫 惩罚系数
。
加入正则化项后, 的导数要多算一个平方项的导数,以
为例
咱们假设输入值 、 实际值
都是列向量。
观察 、
的表达式,进而发现能够用矩阵形式书写为:
不失通常性,设第 层的前向传播:
,其中
、
、
均为列向量,
为矩阵
激活值 ,因此激活值也是列向量。
损失函数向量化为:
表示把矩阵
的全部元素之和
*
表示求哈达马积
,即两个矩阵对应位置的元素的乘积所造成的一个新矩阵
输出层偏差值向量化:
隐藏层偏差向量化:
参数 导数向量化:
不失通常性,有:
上述全部过程都是假设只有一个样本。
当参与计算的样本数量大于1时:
你不用写一个for循环来计算上述值,使用矩阵乘法会更为方便,这里留给读者思考。
github:github.com/JerryCheese…
ann.py
是面向过程版本实现,且隐藏层数只能为1。
NN.py
是面向对象版本实现,支持多层隐藏层。