在之前的文章中,我们学习了各种机器学习的算法。从这篇文章开始,我们将了解现在最流行的机器学习算法即神经网络。神经网络有很多种类型,这篇文章将介绍神经网络种最简单和基础的类型------多层感知机(MLP)
为什么需要神经网络
之前提到的机器学习算法,对于复杂的数据需要使用非线性的多项式项来拟合数据。假设我们有非常多的特征,例如大于100个变量,我们希望用这100个特征来构建一个非线性 的多项式模型,结果将是数量非常惊人的特征组合,即便我们只采用两两特征的组合(𝑥1𝑥2+ 𝑥1𝑥3 +𝑥1𝑥4+...+𝑥2𝑥3 +𝑥2𝑥4+...+𝑥99𝑥100)
,我们也会有接近 5000 个组合而成的特征。这对于一般的机器学习算法来说需要计算的特征太多了。
如果我们使用一般的逻辑回归算法来进行图片分类。假使我们采用的都是 50x50 像素的小图片,并且我们将所有的像素视为特征,则会有 2500 个特征,如果我们要进一步将两两特征组合构成一个多项式模型,则会有约2500^2/2个 (接近3百万个)特征。普通的逻辑回归模型,不能有效地处理这么多的特征,这时候我们需要神经网络。
神经网络原理
如下图所示,经典的MLP神经网络包括输入层、隐藏层和输出层三层结构,且MLP神经网络不同层之间是全连接的(全连接的意思就是:上一层的任何一个神经元与下一层的所有神经元都有连接)。

假设我们需要区分图片是狗还是猫,同时输入的图片大小为50 * 50,那么神经网络的输入层则为 2500(50 * 50),其输出层为 2(猫或者狗)。
神经网络主要有三个基本要素,分别为:权重、偏置和激活函数。
- 权重:神经元之间的连接强度由权重表示,权重的大小表示可能性的大小
- 偏置:偏置的设置是为了正确分类样本,是模型中一个重要的参数,即保证通过输入算出的输出值不能随便激活。
- 激活函数:起非线性映射的作用,其可将神经元的输出幅度限制在一定范围内,一般限制在
(-1~1)
或(0~1)
之间。最常用的激活函数是Sigmoid函数。

以上图为例,假设输入为 (x0,x1,x2,x3),那么对于隐藏层的节点1来说,其计算结果为 y0 = Sigmoid(a0 * x0 + a1 * x1 + a2 * x2 + a3 * x3 + bias) ,其中 bias 是偏置。依此类推, z0 = Sigmoid(b0 * y0 + b1 * y1 + b2 * y2 + bias)。
MLP的最经典例子就是数字识别,其识别过程如下图所示,图片来源这里

从本质上讲,神经网络能够通过学习得出其自身的一系列特征。在普通的逻辑回归中, 我们被限制为使用数据中的原始特征𝑥1,𝑥2,...,𝑥𝑛
,我们虽然可以使用一些二项式项来组合 这些特征,但是我们仍然受到这些原始特征的限制。在神经网络中,原始特征只是输入层, 在我们上面三层的神经网络例子中,第三层也就是输出层做出的预测利用的是第二层的特 征,而非输入层中的原始特征,我们可以认为第二层中的特征是神经网络通过学习后自己得 出的一系列用于预测输出变量的新特征。
MLP实现逻辑运算
神经网络中,单层神经元(无中间层)的计算可用来表示逻辑运算,比如逻辑与(AND)、 逻辑或(OR)。
- 逻辑与(AND)
当下图的神经元(三个权重c0、c1、c2分别为-30,20,20)可以被视为作用同于逻辑与(AND)

- 逻辑或(OR)
下图的神经元(三个权重c0、c1、c2分别为-10,20,20)可以被视为作用等同于逻辑或(OR)

- 逻辑非(NOT)
下图的神经元(两个权重c0、c1分别为 10,-20)可以被视为作用等同于逻辑非(NOT)

- XNOR 功能(输入的两个值必须一样,均为1或均为0)
我们可以利用神经元来组合来实现XNOR 功能。三个权重c0、c1、c2分别为-30,20,20;三个权重d0、d1、d2分别为10,-20,-10;三个权重e0、e1、e2分别为-10,20,20。

示例
keras 是使用 python 编写的用于神经网络开发的应用接口,调用该接口可以实现神经网络、卷积神经网络、循环神经网络等常用的深度学习算法的开发。
keras的特点如下:
- 集成了深度学习中各类成熟的算法,容易安装和使用,样例丰富,教程和文档也非常详细
- 能够以 tensorflow 或者 theano 作为后端运行
我们可以使用keras来实现数字识别,代码示例如下:
ini
#set up the model
from keras.models import Sequential
from keras.layers import Dense, Activation
mlp = Sequential()
mlp.add(Dense(units=392,activation='relu',input_dim=784))
mlp.add(Dense(units=392,activation='relu'))
mlp.add(Dense(units=10,activation='softmax'))
#configure the model
mlp.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['categorical_accuracy'])
#train the model
mlp.fit(X_train_normal,y_train_format,epochs=10)
# 可视化数据
import matplotlib as mlp
font2 = {'family' : 'SimHei',
'weight' : 'normal',
'size' : 20,
}
mlp.rcParams['font.family'] = 'SimHei'
mlp.rcParams['axes.unicode_minus'] = False
a = [i for i in range(1,10)]
fig4 = plt.figure(figsize=(5,5))
for i in a:
plt.subplot(3,3,i)
plt.tight_layout()
plt.imshow(X_test[i])
plt.title('predict:{}'.format(y_test_predict[i]),font2)
plt.xticks([])
plt.yticks([])
效果如下图所示:
