《深度学习入门》的cpp实现-ch02: 感知机

定义
感知机(perceptron)是接受多个输入信号,输出一个信号的的算法。
以一个接受两个输入信号的感知机为例子

神经元接受两个输入值(x1, x2), 在不同的输入上具有不同的权重(w1, w2), 神经元会处理输入计算各路总和(w1*x1 + w2*x2),当值高于某个阈值(bias)的时候,神经元被激活。
以数学公式表达就是

实现
可以使用单层感知机实现AND, NAND, OR的门逻辑,只需要调整不同的 w1, w2和 bias.
w1、w2称为权重, 是控制着输入信号重要性的参数。bias称为偏置, 是调整神经元被激活的容易程度的参数。
bool perceptron(int a, int b, double x1, double x2, double bias) {
Eigen::Matrix<double, 1, 2> input;
input << a, b;
Eigen::Vector2d weight(x1, x2);
// std::cout << input * weight << std::endl;
return input.dot(weight) + bias > 0;
}
// [w1, w2] = [0.5, 0.5] bias = -0.7
bool and_neural(int a, int b) {
return perceptron(a, b, 0.5, 0.5, -0.7);
}
bool nand_neural(int a, int b) {
return perceptron(a, b, -0.5, -0.5, 0.7);
}
bool or_neural(int a, int b) {
return perceptron(a, b, 0.5, 0.5, -0.2);
}
需要注意的是,在这里决定w1, w2 和 bias 具体值的是人。而机器学习就是将这个决定参数值的过程,交给计算机自动进行。学习是指确定合适参数的过程,而人需要做的事思考整个感知集的构造(模型),并将数据集交给计算机,进行学习。
感知机的局限性
使用单层感知机无法实现 XOR 门,这是因为对于或门的逻辑,可以如下图表示

用一条直线将整个空间分为两部分,在一个空间输出1,在另一个空间输出0

而对于XOR门, 无法使用一条直线分割整个空间。
因此,感知机的局限在于它只能表示一条由直线分割的空间(对于两个输入的感知机,是一条直线;有三个输入的感知机是一个平面; 有n个输入的感知机,是一个n-1维度的“平面”),无法表示弯曲的曲线。
由曲线分割的空间称为非线性空间,由直线分割的空间称为线性空间。也可以理解为x1 和 x2 之间是线性关系,还是非线性关系。
多层感知机
虽然单层感知机无法表示 XOR 门,但是正如可以使用 NAND 来不断叠加,表示出任何逻辑电路一样。我们也可以使用多个感知机的叠加,来表示XOR逻辑。
/**
* Exclusive-or gate:
* out = not (a == b)
*/
CHIP Xor {
IN a, b;
OUT out;
PARTS:
// Put your code here:
// xor = (a || b) && !(a && b)
// = (a || b) && (!a || !b)
// = (a&&!b) || (!a&&b)
Not (in=b, out=Notb);
And (a=a, b=Notb, out=aAndNotb);
Not (in=a, out=Nota);
And (a=Nota, b=b, out=NotaAndb);
Or (a=aAndNotb, b=NotaAndb, out=out);
}
上面是我在 中的HDL电路设计作业。
bool xor_neural(int a, int b) {
bool s1 = nand_neural(a, b);
bool s2 = or_neural(a, b);
return and_neural(s1, s2);
}
多层感知机之所以可以在空间内,表示出曲线来分割出 非线形空间,原因是经过多层线性函数后,输入之间的关系转变为非线形的。
多层感知机的层数定义

图中的感知机总共由 3 层构成,但是因为拥有权重的层实质 上只有2层(第0层和第1层之间,第1层和第2层之间),所以称 为“2 层感知机”。
感知机构建计算机
理论上可以说 2 层感知机就能构建计算机。这是因为,已有研究证明, 2层感知机(严格地说是激活函数使用了非线性的sigmoid函数的感知机,具体请参照下一章)可以表示任意函数。
PS: 本文之前提到的感知机,激活函数均是阶跃函数。




