监督学习神经网络
感知器神经网络是一种典型的前馈神经网络,具有分层结构,信息从输入层进入网络,逐层向前传递至输出层。根据感知器神经元激活函数、隐层数以及权值调整规则的不同,可以形成具有各种功能特点的神经网络。
单层感知器(perceptron)
单层感知器的结构与功能都非常简单,以至于目前在解决实际问题时很少被采用,但由于它在神经网络研究中具有重要意义,是研究其他网络的基础,而且较易学习和理解,适合作为学习神经网络的起点。
感知器模型
单层感知器是指只有一层处理单元的感知器,如果包括输入层在内,应为两层。其拓扑结构如下图所示:
图中输入层也成为感知层,有n个神经元节点,这些节点只负责引入外部信息,自身无信息处理能力,每个节点接收一个输入信号,n个输入信号构成输入列向量X。输出层也称为处理层,有m个神经元节点,每个节点具有信息处理能力,m个节点向外部输出处理信息,构成输出列向量O。两层之间的连接权值用权值列向量
w
j
w_j
wj表示,m个权向量构成单层感知器的权值矩阵W。
3种列向量分别表示为:
X
=
(
x
1
,
x
2
,
.
.
.
,
x
i
,
.
.
.
,
x
n
)
T
O
=
(
o
1
,
o
2
,
.
.
.
,
o
i
,
.
.
.
,
o
m
)
T
W
j
=
(
w
1
j
,
w
2
j
,
.
.
,
w
i
j
,
.
.
.
,
w
n
j
)
T
X = (x_1,x_2,...,x_i,...,x_n)^T\\ O = (o_1,o_2,...,o_i,...,om)^T\\ W_j = (w_{1j},w{2j},..,w{ij},...,w_{nj})^T
X=(x1,x2,...,xi,...,xn)TO=(o1,o2,...,oi,...,om)TWj=(w1j,w2j,..,wij,...,wnj)T
由神经元数学模型知,对于处理层中任一节点,其净输入
n
e
t
j
net_j
netj为来自输入层各节点的输入加权和:
n
e
t
j
′
=
∑
i
=
1
n
w
i
j
x
j
net^{'}_j = \sum_{i = 1} ^nw_{ij}x_j
netj′=i=1∑nwijxj
输出
o
j
o_j
oj由节点的激活函数决定,离散型单计算层感知器的转移函数一般采用阶跃函数(sgn)(或单极性阈值函数)。
o
j
=
s
g
n
(
n
e
t
j
′
−
T
j
)
=
s
g
n
(
∑
i
=
1
n
w
i
j
x
j
)
=
s
g
n
(
W
j
T
X
)
(1.1)
o_j = sgn(net_j^{'} - T_j) = sgn(\sum_{i = 1} ^nw_{ij}x_j)=sgn(W_j^TX) \tag{1.1}
oj=sgn(netj′−Tj)=sgn(i=1∑nwijxj)=sgn(WjTX)(1.1)
其中大写字母代表矩阵形式。
这里介绍一下阶跃函数,也叫sgn函数。该函数输入值大于等于0时,输出为1,小于零时,函数值为-1.
数学表达式为:
f
(
x
)
=
{
−
1
:
x
<
0
1
:
x
≥
0
f(x) = \left\{ \begin{array}{lr} -1 & : x < 0\\ 1 & : x \ge 0 \end{array} \right.
f(x)={−11:x<0:x≥0
函数图像为:
用python简单绘制sgn函数图像:
import numpy as np
import matplotlib.pyplot as plt
def sgn(data): #定义sgn函数,大于0的数输出1,小于等于0的数输出-1
x = data.copy()
temp = x>0
x[temp] = 1
x[~temp] = -1
return x
x = np.random.normal(-10,10,100) #按照正态分布随机100个数
x = np.sort(x) #将随机的数排序
y = sgn(x) #进行sgn计算
plt.plot(x , y , "r",linewidth = 5) #绘图
#修改坐标轴位置,将原点放在零点处。
ax = plt.gca() #gca:get current axis
ax.xaxis.set_ticks_position("bottom")
ax.yaxis.set_ticks_position("left")
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))
plt.show()
单节点感知器的功能分析
单节点感知器实际上就是一个M-P神经元模型,由于采用了sgn函数,又称为符号单元。式(1.1)可进一步表达为:
o
j
=
{
−
1
:
W
j
T
X
<
0
1
:
W
j
T
X
≥
0
o_j = \left\{ \begin{array}{lr} -1 & : W_j^TX< 0\\ 1 & : W_j^TX\ge 0 \end{array} \right.
oj={−11:WjTX<0:WjTX≥0
分下面三种情况讨论单节点感知器的功能。
(1)设输入向量
X
=
(
x
1
,
x
2
)
T
X=(x_1,x_2)^T
X=(x1,x2)T,则两个输入分量在几何上构成一个二维平面,输入样本可以用该平面上的一个点表示。节点
j
j
j的输出为:
o
j
=
{
−
1
:
w
1
j
x
1
+
w
2
j
x
2
−
T
j
<
0
1
:
w
1
j
x
1
+
w
2
j
x
2
−
T
j
≥
0
o_j = \left\{ \begin{array}{lr} -1 & :w_{1j}x_1+w_{2j}x_2 - T_j< 0\\ 1 & : w_{1j}x_1+w_{2j}x_2 - T_j\ge 0 \end{array} \right.
oj={−11:w1jx1+w2jx2−Tj<0:w1jx1+w2jx2−Tj≥0
则由以下方程确定的直线称为二维输入样本空间上的一条分界线:
w
1
j
x
1
+
w
2
j
x
2
−
T
j
=
0
(1.2)
w_{1j}x_1+w_{2j}x_2 - T_j = 0\tag{1.2}
w1jx1+w2jx2−Tj=0(1.2)
线上方的样本用紫色的点表示,它们使
n
e
t
j
>
0
net_j>0
netj>0,从而使输出为1;线下方的样本用黄色的点表示,它们使
n
e
t
j
<
0
net_j<0
netj<0,从而使输出为-1.见上图。显然,由感知器权值和偏置值确定的直线方程规定了分界线的分界线在样本空间的位置,从而也体现了如何输入样本分为两类的分类知识与确定规则。假如分界线的初始位置不能将两类样本点正确的区分开,需要改变权值和偏置值,分界线也会随之改变,直到可以正确的区分两类样本点。
(2)输入向量
X
=
(
x
1
,
x
2
,
x
3
)
T
X = (x_1,x_2,x_3)^T
X=(x1,x2,x3)T,则3个输入分量在几何上构成了一个三维空间。节点
j
j
j的输出为:
o
j
=
{
−
1
:
w
1
j
x
1
+
w
2
j
x
2
+
w
3
j
x
3
−
T
j
<
0
1
:
w
1
j
x
1
+
w
2
j
x
2
+
w
3
j
x
3
−
T
j
≥
0
o_j = \left\{ \begin{array}{lr} -1 & :w_{1j}x_1+w_{2j}x_2+w_{3j}x_3 - T_j< 0\\ 1 & : w_{1j}x_1+w_{2j}x_2+w_{3j}x_3 - T_j\ge 0 \end{array} \right.
oj={−11:w1jx1+w2jx2+w3jx3−Tj<0:w1jx1+w2jx2+w3jx3−Tj≥0
则由以下方程确定的平面成为三维输入样本空间上的一个分解平面
w
1
j
x
1
+
w
2
j
x
2
+
w
3
j
x
3
−
T
j
=
0
w_{1j}x_1+w_{2j}x_2+w_{3j}x_3 - T_j = 0
w1jx1+w2jx2+w3jx3−Tj=0
如图:
(3)将上述两个特例推广到n维输入空间的一般情况,设输入向量
X
=
(
x
1
,
x
2
,
x
3
)
T
X = (x_1,x_2,x_3)^T
X=(x1,x2,x3)T,则n个输入分量在几何上构成了一个n维空间。由如下方程可以定于一个n维空间上的超平面:
w
1
j
x
1
+
w
2
j
x
2
+
.
.
.
+
w
n
j
x
n
−
T
j
=
0
w_{1j}x_1+w_{2j}x_2+...+w_{nj}x_n - T_j = 0
w1jx1+w2jx2+...+wnjxn−Tj=0
此平面可以将输入样本分为两类。
通过以上分析可以看出,一个最简单的单计算节点感知器具有分类功能。其分类原理使将分类知识存储于感知器的权向量(包含了偏置值)中,由权向量确定的分类判决界面将输入模式分为两类。
总结:
感知器(perceptron)由两层神经元组成,输入层接受外界信号后传递给输出层,输出层使M-P神经元,亦称“阈值逻辑单元”(threshold logic unit)
感知器能容易的实现逻辑与、或、非运算.注意到
y
=
f
(
∑
i
w
i
x
i
−
T
i
)
y = f(\sum_iw_ix_i - T_i)
y=f(∑iwixi−Ti)
- “与”:
x_1 | x_2 | y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
可得到分类判决的方程为:
y
=
f
(
0.5
x
1
+
0.5
x
2
−
0.75
)
y = f(0.5x_1 + 0.5x_2 - 0.75)
y=f(0.5x1+0.5x2−0.75)
- “或”
x_1 | x_2 | y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
可得到分类判决的方程为:
y
=
f
(
x
1
+
x
2
+
0.5
)
y = f(x_1 + x_2 + 0.5)
y=f(x1+x2+0.5)
- “非”
易得到分类判决的方程为:
y = f ( − 0.6 ∗ x 1 + 0 ∗ x 2 + 0.5 ) y = f(-0.6 *x_1 +0 * x_2 + 0.5) y=f(−0.6∗x1+0∗x2+0.5)
更一般的,给定训练数据集,权重
w
i
(
i
=
0
,
1
,
2
,
.
.
.
,
n
)
w_i(i= 0,1,2,...,n)
wi(i=0,1,2,...,n)以及偏置值
T
i
T_i
Ti可以通过学习得到。偏置值
T
i
T_i
Ti可以看作一个固定输入为1的“哑节点”(即输入值始终为1,利于矩阵运算),所对应的连接权重
w
n
+
1
w_{n+1}
wn+1。这样,权重和偏置值的学习就可以统一为权重的学习。感知器的学习规则非常简单,对训练样本
(
x
,
y
)
(x ,y)
(x,y),若当前感知器的输出为
t
t
t,则感知器权重应该这样调整:
w
i
←
w
i
+
△
w
i
,
△
w
i
=
η
(
y
−
t
)
x
i
w_i \leftarrow w_i + \triangle w_i,\\ \triangle w_i = \eta (y - t)x_i
wi←wi+△wi,△wi=η(y−t)xi
其中
η
∈
(
0
,
1
)
\eta \in (0,1)
η∈(0,1)成为学习率(learning rate).从上式可以得出。若感知器对训练样例
(
x
,
y
)
(x,y)
(x,y)预测正确,即
y
=
t
y = t
y=t,则感知器不发生变化,否则将根据错误的成都进行权重的调整。
感知器学习规则
t
=
f
(
∑
i
=
1
n
x
i
∗
w
i
)
△
w
i
=
η
(
y
−
t
)
x
i
w
i
=
w
i
+
△
w
i
t = f(\sum_{i = 1}^n x_i * w_i)\\ \triangle w_i = \eta (y - t)x_i \\ w_i = w_i + \triangle w_i
t=f(i=1∑nxi∗wi)△wi=η(y−t)xiwi=wi+△wi
其中
i
=
0
,
1
,
2
,
.
.
.
i = 0,1,2,...
i=0,1,2,...,
t
t
t是网络输出,
f
f
f是激活函数,
η
\eta
η表示学习率,
y
y
y表示正确的标签。
根据以上总结,我利用python,对单层感知器进行了简单的建模:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
def sgn(data):
x = data.copy()
temp = x>0
x[temp] = 1
temp = x<=0
x[temp] = 0
return x
def update(x,y,w,lr=0.03,epoches=50000):
for i in range(epoches):
t = sgn(np.dot(w , x))
w_gard = y - t
w += lr * np.dot(w_gard,x.T)
return w
#数据产生
x_data = np.random.normal(-10,10,(3,10))
x_data = np.sort(x_data)
y_data = np.random.randint(0,2,(1,10))
y_data = np.sort(y_data)
#数据预处理
x_data = np.r_[x_data,np.ones(x_data.shape[1]).reshape((1,10))]
w = np.ones(x_data.shape[0])
w = w[np.newaxis,:]
print(x_data)
print(y_data)
print(w)
w = update(x_data,y_data,w)
print(w)
'''
#2dim绘图
#计算分解线的斜率和截距
k = -w[0,0]/w[0,1]
b = -w[0,2]/w[0,1]
#随机样本
x_test = np.random.normal(-10,10,(2,10))
x_test = np.sort(x_test)
y_test = x_test[0,:]*k + b
print(x_test)
print(y_test)
plt.scatter(x_data[0,:],x_data[1,:],c = y_data[0,:])
plt.plot(x_test[0,:],y_test,'r')
plt.show()
'''
#3dim绘图
fig = plt.figure()
ax = Axes3D(fig)
k1 = -w[0,0]/w[0,2]
k2 = -w[0,1]/w[0,2]
b = -w[0,3]/w[0,2]
#随机样本
x_test = np.random.normal(-10,10,(3,10))
x_test = np.sort(x_test)
print(x_test)
ax.scatter3D(x_data[0,:],x_data[1,:],x_data[2,:] , c = y_data[0,:])
X,Y = np.meshgrid(x_test[0,:],x_test[1,:])
Z = X*k1 + Y * k2 + b
ax.plot_surface(X,Y,Z,color = 'blue')
plt.show()
改变x_data的行数,可以对不同维度的数据进行简单的单层感知器分类。
这里特别说明一下绘制分界线方程的方法。
分界线方程为:
w
1
j
x
1
+
w
2
j
x
2
+
.
.
.
+
w
n
j
x
n
−
T
j
=
0
w_{1j}x_1+w_{2j}x_2+...+w_{nj}x_n - T_j = 0
w1jx1+w2jx2+...+wnjxn−Tj=0
这里拿2维的方程举例:
w
1
j
x
1
+
w
2
j
x
2
−
T
j
=
0
w_{1j}x_1+w_{2j}x_2 - T_j = 0
w1jx1+w2jx2−Tj=0
将偏置值
T
j
T_j
Tj设置为输入始终为-1的“哑节点”,并给与一个权值
w
3
w_3
w3,则方程变为
w
1
j
x
1
+
w
2
j
x
2
+
w
3
j
=
0
w_{1j}x_1+w_{2j}x_2 +w_{3j} = 0
w1jx1+w2jx2+w3j=0
令
x
1
=
x
,
x
2
=
y
x_1 = x,x_2 = y
x1=x,x2=y,将方程转化为截距式为
y
=
−
w
3
j
w
2
j
−
w
1
j
w
2
j
x
y = -\frac {w_{3j}}{w_{2j}}-\frac {w_{1j}}{w_{2j}}x
y=−w2jw3j−w2jw1jx
利用上式便可画出2维数据分类的分界线。
单层感知器的局限性
以上的例子说明单计算节点感知器可具有逻辑“与,或,非”的功能,但他是否具有“异或”功能呢?请看图:
表中的4个样本可以分为两类,但在坐标系中可以发现,任何直线不可能把两类样本分开,称这种样本为线性不可分。 事实上,感知器须有输出层神经元进行激活函数处理,即只拥有一层功能神经元(functional neuron),其学习能力也是非常有限。可以证明,若两类模式是线性可分的,即存在一个线性超平面能将他们分开,则感知器的学习过程一定会收敛(converge)而求得适当权向量
w
=
(
w
1
;
w
2
;
w
3
;
.
.
.
;
w
n
+
1
)
w = (w_1;w_2;w_3;...;w_{n+1})
w=(w1;w2;w3;...;wn+1)否则感知器学习过程将会发生振荡(fluctuation),
w
w
w很难稳定下来,不能求得合适解,例如感知器甚至不能解决上图的异或这样简单的问题。
要解决非线性问题,需考虑使用多层功能神经元。如图:
这个简单的两层感知器就能解决异或问题。在上图中,输出层与输入层之间的一层神经元,被称为隐层或隐含层(hidden layer),隐含层和输出层神经元都是拥有激活函数的神经元。
更一般的,常见的神经网络是如下图所示的层级结构,每层神经元与下一层神经元互连,这样的神经网络结构通常成为“多层前馈神经网络”(multi-layer feedforward neural network)。
其中输入层神经元接收外界输入,隐层与输出层神经元对信号进行加工,最终结果由输出层神经元输出;换言之,输入层神经元仅是接受输入,不进行函数处理,隐层与输出层包含功能神经元。因此,上图同城被称为“两层网络”,为避免歧义,称之为“单隐层网络”。只需包含隐层,即可成为多层网络。神经网络的学习过程,就是根据训练数据来调整神经元之间的“连接权”(connection weight)以及每个功能神经元之间的偏置值;换言之,神经网络“学”到的东西,蕴含在连接权与阈值中。
线性单元和梯度下降法
前面学习到了当激活函数为 s g n sgn sgn函数时,单层感知器具有简单的分类功能(classification)。若我们需要处理回归(regression)问题时,需要怎么办呢?
我们可以设置激活函数为purelin函数:
f
(
x
)
=
x
f(x)=x
f(x)=x,这样我们的单层感知器变为如下:
替换了激活函数后,神经网络的输出不再是0,1类,而是一个预测值,这便可以解决回归问题。
事实上,这种用一个可导的线性函数来代替感知器的sgn函数,这种感知器叫做线性单元。线性单元在面对线性不可分的数据集时,会收敛到一个最佳的近似上。而将激活函数替换成purelin函数,是最简单的线性单元。(purelin = pure liner function,纯线性函数)
pureline函数图像:
线性单元模型分析
当我们说模型时,我们实际上在谈论根据输入
x
x
x预测输出的算法。比如,
x
x
x可以是一个人的工作年限,
y
y
y可以是他的月薪,我们可以用某种算法来根据一个人的工作年限来预测他的收入。比如:
y
=
h
(
x
)
=
k
∗
x
+
b
y = h(x) = k *x + b
y=h(x)=k∗x+b
函数
h
(
x
)
h(x)
h(x)叫做假设,而
k
k
k、
b
b
b是它的参数。我们假设参数k = 1000,参数b = 500,如果一个人的工作年限是5年的话,我们的模型会预测他的月薪为
y
=
h
(
x
)
=
1000
∗
5
+
500
=
5500
y = h(x) = 1000 * 5 + 500 =5500
y=h(x)=1000∗5+500=5500
那当我们拥有更多的考虑因素时,模型应该怎么样改变呢?这里,我们可以把一个人影响他工资的因素用一个特征向量表示:
x = (年份,职业,公司,岗位,…)
例如一个在阿里干了3年的,目前是p8这样的人
x = (3,IT,阿里,p8)
这些信息,称为特征,此时输入x是一个具有4个特征的向量,我们同样需要4个参数k,来分别控制每个特征的权值,此时模型变成了:
y
=
h
(
x
)
=
k
1
∗
x
1
+
k
2
∗
x
2
+
k
3
∗
x
3
+
k
4
∗
x
4
+
b
y = h(x) = k_1 *x_1+k_2 *x_2+k_3*x_3+k_4 *x_4+b
y=h(x)=k1∗x1+k2∗x2+k3∗x3+k4∗x4+b
其中,
x
1
x1
x1是年份,
x
2
x2
x2是职业,
x
3
x3
x3是公司,
x
4
x4
x4是岗位。而当我们令
x
5
=
1
x_5 = 1
x5=1时,我们的最后一项
b
b
b,可以改写成
b
=
x
5
∗
k
5
b = x_5 * k_5
b=x5∗k5,模型此时每一项都由
k
k
k与
x
x
x组成。
y
=
h
(
x
)
=
k
1
∗
x
1
+
k
2
∗
x
2
+
k
3
∗
x
3
+
k
4
∗
x
4
+
k
5
∗
x
5
y = h(x) = k_1 *x_1+k_2 *x_2+k_3*x_3+k_4 *x_4+k_5*x_5
y=h(x)=k1∗x1+k2∗x2+k3∗x3+k4∗x4+k5∗x5
为了便于计算,上式便可以改写成向量的形式
y
=
h
(
x
)
=
K
T
X
y = h(x) = K^TX
y=h(x)=KTX
形如上式的模型,便是线性模型,输出y就是输入特征
x
1
,
x
2
.
x
3
,
.
.
.
x_1,x_2.x_3,...
x1,x2.x3,...的线性组合。
线性单元模型的训练
线性单元模型的训练,与机器学习中线性回归的算法完全相同,可参考线性回归的方法。
代码实现
import numpy as np
import matplotlib.pyplot as plt
def purelin(x):
return x
def update(x,y,w,lr,epochs):
for i in range(epochs):
t = purelin(np.dot(x,w))
y_gard = y - t
w = w + lr * np.dot(x.T,y_gard)/x.shape[0] #这里一定要除以样本数量,以平均误差
return w
#训练数据
x_data = np.linspace(-10,10,20).reshape(20,1)
nosie = np.random.normal(-0.1,0.1,20).reshape(20,1)
y_data = x_data * 0.2 + 2 + nosie
#绘制训练数据的散点图
plt.scatter(x_data,y_data,c = 'r')
#数据准备
x_data = np.c_[x_data,np.ones(x_data.shape)]
w = np.ones((1,x_data.shape[1])).reshape(2,1)
w = update(x_data , y_data , w , 0.01 , 500000)
print(w)
x_test = np.linspace(-10,10,10).reshape(10,1)
x_test = np.c_[x_test,np.ones(x_test.shape)]
y_test = np.dot(x_test , w)
plt.plot(x_test[:,0],y_test,'b')
plt.show()
用以上算法,可以简单的完成对一元线性的回归问题,如图:
小结
事实上,一个机器学习算法其实只有两部分
模型 从输入特征预测输入的那个函数
目标函数 目标函数取最小(最大)值时所对应的参数值,就是模型的参数的最优值。很多时候我们只能获得目标函数的局部最小(最大)值,因此也只能得到模型参数的局部最优值。
因此,如果你想最简洁的介绍一个算法,列出这两个函数就行了。
接下来,你会用优化算法去求取目标函数的最小(最大)值。[随机]梯度{下降|上升}算法就是一个优化算法。针对同一个目标函数,不同的优化算法会推导出不同的训练规则。我们后面还会讲其它的优化算法。
其实在机器学习中,算法往往并不是关键,真正的关键之处在于选取特征。选取特征需要我们人类对问题的深刻理解,经验、以及思考。而神经网络算法的一个优势,就在于它能够自动学习到应该提取什么特征,从而使算法不再那么依赖人类,而这也是神经网络之所以吸引人的一个方面。
基于误差反向传播的多层感知器——BP神经网络
BP算法的基本思想时,学习过程由信号的正向传播与误差的反向传播两个过程组成。正向传播时,输入样本从输入层传入,经各隐层逐层逐层处理后,传向输出层。若输出层的实际输出与期望的输出不符,则转入误差的反向传播阶段。误差反传时将输出误差以某种形式通过隐层向输入层逐层反传,并将误差分摊给各层的所有单元,从而获得更曾单元的误差信号,此误差信号即作为修正各个单元权值的依据。这种信号正向传播与误差反向传播的各层权值调整过程是周而复始的进行的。权值不断调整的过程,也就是网络的学习训练过程。此过程一直进行到网络输出的误差减少到可接受的程度,或进行到预先设定的学习次数为止。
在学习BP神经网络之前,先需要了解一下
s
i
g
m
o
i
d
sigmoid
sigmoid函数:
f
(
x
)
=
1
1
+
e
−
x
f(x) = \frac {1}{1 + e^{-x}}
f(x)=1+e−x1
函数图像如下:
python实现:
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
y = 1 / (1 + np.exp(-x))
return y
x_data = np.linspace(-5,5,50)
y_data = sigmoid(x_data)
plt.plot(x_data , y_data , 'r')
ax = plt.gca() #gca:get current axis
ax.xaxis.set_ticks_position("bottom")
ax.yaxis.set_ticks_position("left")
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))
plt.show()
这个 s i g m o i d sigmoid sigmoid函数非常有趣,它可以用自身表示自己的倒数。这样只要计算出sigmoid函数的值,它的倒数也就随之计算出来了。
y = s i g m o i d ( x ) y ′ = y ( 1 − y ) y = sigmoid(x)\\y'=y(1-y) y=sigmoid(x)y′=y(1−y)
神经网络是啥?
神经网络其实就是按照一定规则连接起来的多个神经元。上图展示了一个全连接(full connected, FC)神经网络,通过观察上面的图,我们可以发现它的规则包括:
- 神经元按照层来布局。最左边的层叫做输入层,负责接收输入数据;最右边的层叫输出层,我们可以从这层获取神经网络输出数据。输入层和输出层之间的层叫做隐藏层,因为它们对于外部来说是不可见的。
- 同一层的神经元之间没有连接。
- 第N层的每个神经元和第N-1层的所有神经元相连(这就是full connected的含义),第N-1层神经元的输出就是第N层神经元的输入。
- 每个连接都有一个权值。
上面这些规则定义了全连接神经网络的结构。事实上还存在很多其它结构的神经网络,比如卷积神经网络(CNN)、循环神经网络(RNN),他们都具有不同的连接规则。
神经网络实际上就是一个输入向量
X
X
X到输出向量
Y
Y
Y的函数,即:
Y
=
f
n
e
t
w
o
r
k
(
X
)
Y = f_{network}(X)
Y=fnetwork(X)
根据输入计算神经网络的输出,需要首先将输入向量
X
X
X的每个元素
x
i
x_i
xi的值赋给神经网络的输入层的对应神经元,然后根据
Y
=
s
i
g
m
o
i
d
(
W
T
⋅
X
)
Y = sigmoid(W^T · X)
Y=sigmoid(WT⋅X)依次向前计算每一层的每个神经元的值,直到最后一层输出层的所有神经元的值计算完毕。最后,将输出层每个神经元的值串在一起就得到了输出向量
Y
Y
Y。
接下来举一个例子来说明这个过程,我们先给神经网络的每个单元写上编号。
参考资料
https://www.zybuluo.com/hanbingtao/note/448086