1. 简介
神经网络由若干神经元组成,这些神经元负责对输入数据进行相似的计算操作。神经网络如下图所示:
上图中每个圆圈都是一个神经元,每条线表示神经元之间的连接。我们可以看到,上面的神经元被分成了多层,层与层之间的神经元有连接,而层内之间的神经元没有连接。最左边的层叫做输入层,这层负责接收输入数据;最右边的层叫输出层,我们可以从这层获取神经网络输出数据。输入层和输出层之间的层叫做隐藏层。
隐藏层>2的神经网络叫做深度神经网络。而深度学习就是使用深层架构(如深度神经网络)的机器学习方法。
2. 感知机(Perceptions)基础
感知机是神经网络的组成单元,又叫神经元。感知机算法在上世纪50-70年代流行,可以说是最简单的神经网络,它用N个二进制输入模拟了一个单个的神经元。而这个神经元的作用,笔者用一句话来概括就是通过调整其中公式的参数来实现我们想要的功能。
感知机组成如下:
输入权值:每个感知机可以接受多个输入,即上图中x1~xn,每个输入上有一个权值wi,此外还有一个偏置项bias,即上图中的w0.到这里,有的同学可能会纳闷图中的input 1和w0是怎么回事,这一点我们一会儿会讲到。
激活函数:激活函数可有多种选择,比如我们可以选择如下阶跃函数f作为激活函数。
输出:感知机的输出由如下公式计算。
其基本原理为:计算输入数据的权重和,若权重和>=0,它将“fires”(计算超过了阈值)。
将上述公式用python代码实现如下:
from scratch.linear_algebra import Vector, dot
def step_function(x: float) -> float:
"""阶越函数"""
return 1.0 if x >= 0 else 0.0
def perceptron_output(weights: Vector, bias: float, x: Vector) -> float:
"""
Returns 1 if the perceptron 'fires', 0 if not
"""
# y=f(w·x+b)
calculation = dot(weights, x) + bias
return step_function(calculation)
从上述公式我们可以看出,偏置项是b,那么为什么要写成w0呢?输入1又是怎么回事?
这个实际上是为了简化运算而进行的操作。通常,我们将b看做权重系数的一个维度,也就是上文中的w0,同时,将x扩展一个维度为1,这样,我们就实现了公式的简化。如下:
s
c
o
r
e
s
=
∑
i
N
w
i
x
i
+
b
scores=\sum_i^Nw_ix_i+b
scores=i∑Nwixi+b
简化为:
s
c
o
r
e
s
=
∑
i
N
+
1
w
i
x
i
scores=\sum_i^{N+1}w_ix_i
scores=i∑N+1wixi
上文提到,感知机通过修改参数来解决我们要解决的问题,那它究竟是如何做到的呢?通过上述公式我们可以猜到,这里讲的参数就是weight(w)和bias(b)。比如,我们可以通过将w1与w2赋值为0.5,将b赋值为-0.8实现与门(AND Gate)。举例说明,当输入为0,0时,输出当为0,公式验证如下:
注意:实现同一种功能的参数未必是唯一固定的,比如,w1=w2=2,b=-3时,也可实现上述功能。代码实现如下:
AND Gate
and_weights = [2., 2]
and_bias = -3.
assert perceptron_output(and_weights, and_bias, [1, 1]) == 1
assert perceptron_output(and_weights, and_bias, [0, 1]) == 0
assert perceptron_output(and_weights, and_bias, [1, 0]) == 0
assert perceptron_output(and_weights, and_bias, [0, 0]) == 0
其余输入,读者可自行测试。
同样的,我们还可以通过改变参数值实现或门(OR Gate),**非门(Not Gate)**等一系列功能。或门,非门实现代码如下:
OR Gate:
or_weights = [2., 2]
or_bias = -1.
assert perceptron_output(or_weights, or_bias, [1, 1]) == 1
assert perceptron_output(or_weights, or_bias, [0, 1]) == 1
assert perceptron_output(or_weights, or_bias, [1, 0]) == 1
assert perceptron_output(or_weights, or_bias, [0, 0]) == 0
NOT Gate:
not_weights = [-2.]
not_bias = 1.
assert perceptron_output(not_weights, not_bias, [0]) == 1
assert perceptron_output(not_weights, not_bias, [1]) == 0
3. 感知机实现二分类问题
除了上文提到的门,感知机还可以用于实现更为有用的功能,比如二分类问题。
在介绍基本原理之前,需要提醒大家的一点是:感知机二分类需要遵循**+1为正例**,-1为负例的前提。
其基本原理如下:
- 首先在超平面(因为输入可能是多维的,所以是超平面)上随意取一条分类面,统计分类错误的点;
- 然后随机对某个错误点就行修正,即变换直线的位置,使该错误点得以修正;
- 接着再随机选择一个错误点进行纠正,分类面不断变化,直到所有的点都完全分类正确了,就得到了最佳的分类面。
(未完…)
References:
[1] Data Science from Scratch
[2] 一看就懂的感知机算法PLA
[3] 零基础入门深度学习(1) - 感知器