问题1.1: 什么是神经网络?
神经网络是由神经元构成的网络,这个网络能够把很多神经元以一种网络的形式交织起来,每个神经元都有自己的处理能力。
问题1.2: 什么是神经元?
在神经网络中,神经元代表了一个基本处理单元。每个神经元由输入(
x
j
∈
{
0
,
1
}
x_j\in\{0, 1\}
xj∈{0,1},也就是说
x
j
x_j
xj是一个比特)、权重(
w
j
w_j
wj)、阈值(
t
h
r
e
s
h
o
l
d
threshold
threshold)和输出(
o
u
t
p
u
t
output
output)组成。这几个概念之间的关系是:
o
u
t
p
u
t
=
{
0
:
∑
j
w
j
x
j
≤
t
h
r
e
s
h
o
l
d
1
:
∑
j
w
j
x
j
>
t
h
r
e
s
h
o
l
d
output = \left\{ \begin{array}{lr} 0 & : \sum_j w_jx_j \leq threshold\\ 1 & : \sum_j w_jx_j > threshold \end{array} \right.
output={01:∑jwjxj≤threshold:∑jwjxj>threshold
通常,会把输入
x
j
x_j
xj和权重
w
j
w_j
wj的多个分量改写为不加下标的
x
x
x和
w
w
w来代替用偏置(
b
=
−
t
h
r
e
s
h
o
l
d
b=-threshold
b=−threshold)代替阈值,所以上式可以改写为
o
u
t
p
u
t
=
{
0
:
w
⋅
x
+
b
≤
0
1
:
w
⋅
x
+
b
>
0
output = \left\{ \begin{array}{lr} 0 & : w\cdot x + b \leq 0\\ 1 & : w\cdot x + b > 0 \end{array} \right.
output={01:w⋅x+b≤0:w⋅x+b>0
备注:显然利用神经元可以实现各种逻辑门(AND,XOR,NOT等),以此可以实现通用的运算(基于逻辑门组合的效果)。也就是说神经元表达计算的能力是不需要担心的。
问题1.3:神经网络是如何学习的?
既然神经元那么厉害,能够实现很通用的运算,神经网络和普通的函数或者算法有什么区别呢?其实,神经网络可以自动调整神经元的参数(权重和偏置),也就是我们说的神经网络可以自己学习如何调整这些参数。神经网络的学习过程其实就是根据不同的训练样本来对神经元参数进行一系列调整以使得整个网络预测的准确性不断提高的过程。
问题1.4: 神经元的初始化参数如何确定?
对于一个神经网络,如果我们按照问题1.2的方法随意选择参数,那么当神经网络中的一个神经元改变参数的时候,有可能会使得神经网络的输出产生非常大的波动。比如说,一个参数可能从0.5调整到0.4,然而整个网络输出可能从100变动到100000。这样大的幅度显然是非常不利于神经网络学习的。因此,有了S神经元这个黑科技来处理这个问题。
S神经元:
x
j
∈
[
0
,
1
]
x_j\in[0, 1]
xj∈[0,1](
x
j
x_j
xj是0,1之间的实数),
w
j
w_j
wj是权重,
b
b
b是偏置,输出是
s
i
g
m
o
i
d
(
x
)
=
1
1
+
e
−
w
⋅
x
−
b
∈
(
0
,
1
)
sigmoid(x) = \frac{1}{1 + e^{-w\cdot x - b}}\in(0, 1)
sigmoid(x)=1+e−w⋅x−b1∈(0,1)
备注:为什么选择sigmoid函数呢?根据经验选的,当然你也可以根据你的需求选择对应的。然而,后来在求代价函数的时候发现sigmoid求偏导数比较容易,所以坚定了很多学者选sigmoid的信念。(代价函数会在后面介绍)
问题1.5: 神经网络的结构
神经网络的层次可以分为输入层,输出层和多个隐藏层。一般情况下,神经网络是没有回路的,被称为前馈神经网络,有回路的是递归神经网络。在以后的章节中,我们只考虑前馈神经网络。
问题1.6: 神经网络的学习方法-梯度下降
神经网络的结构我们已经研究清楚了,而且其中的神经元的输入输出也搞定了。那么剩下来的就是研究如何来用神经网络进行学习了。对于神经网络的学习准则,最常用的就是梯度下降法。
介绍梯度下降之前,我们要知道什么样的一组神经网络参数才是这个网络想要最终学到的目标。为此,我们选择一个代价函数:
C
(
w
,
b
)
=
1
2
n
∑
x
∣
∣
y
(
x
)
−
a
∣
∣
2
C(w, b)=\frac{1}{2n}\sum_x ||y(x)-a||^2
C(w,b)=2n1x∑∣∣y(x)−a∣∣2
上面的
x
x
x代表输入向量,
w
w
w是权重的向量,
b
b
b是偏置值,
n
n
n是训练样本的输入,
a
a
a代表输入是
x
x
x时的真实值,
y
y
y代表神经网络的输出。这样,
C
C
C就是二次代价函数或者均方误差。显然,当
C
C
C越小,我们离目标越近(预测值
y
y
y和真实值
a
a
a越接近)。
备注:代价函数是怎么选的?目前我觉得是根据经验来选的。其实任何一个最小值是0的非负函数应该都可以作为代价函数。但是由于计算导数的方便,所以选择了这个简单的均方误差形式。
那要怎么应用梯度下降法呢?其实很简单,那就是利用
C
C
C对自变量的偏导确定移动方向(下降最快的方向)以使得下面一小步的移动沿着这个方向前进来使得
C
C
C尽可能快的减小。那么这个移动的步长就是我们通常说的学习率 (
η
=
−
Δ
C
∣
∣
∇
C
∣
∣
2
\eta=-\frac{\Delta C}{||\nabla C||^2}
η=−∣∣∇C∣∣2ΔC)。然后迭代这个过程不断更新
w
w
w和
b
b
b:
w
k
=
w
k
−
η
∂
C
∂
w
k
w_k = w_k - \eta\frac{\partial C}{\partial w_k}
wk=wk−η∂wk∂C
b
l
=
b
l
−
η
∂
C
∂
b
l
b_l = b_l - \eta\frac{\partial C}{\partial b_l}
bl=bl−η∂bl∂C
但是,如果训练样本量太大的时候,完成每一次的计算显然是非常耗时的,所以,可以把样本随机抽样成小批量数据(mini-batch)来逐批次的完成一个迭代的学习任务。
备注:学习率怎么选的?根据经验,其实学习率的选择没有一个很好的方法。所以,有些人可能会先选择一个大一些的学习率进行100次迭代,然后调整到一个较小的学习率进行100次迭代这种方法。