3. 多层感知机

3.1 神经网络图

多层感知机 vs 单层神经网络:
在单层神经网络的基础上,引入了一到多个隐藏层(hidden layer)。
隐藏层位于输入层和输出层之间。

如下图所示:
输入和输出个数分别为4和3,中间的隐藏层包含5个隐藏单元(hidden unit)。
多层感知机的层数为2,且隐藏层和输出层都为全连接层。



用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归

多层感知机



3.2 矢量计算表达式

给定一个小批量样本用多层感知机替代线性回归 多层感知机例题_多层感知机_02,其批量大小为用多层感知机替代线性回归 多层感知机例题_函数定义_03,输入个数为用多层感知机替代线性回归 多层感知机例题_函数定义_04
若仅有一个隐藏层,且隐藏单元个数为用多层感知机替代线性回归 多层感知机例题_多层感知机_05。记隐藏层的输出(隐藏变量)为用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_06,有用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_07
设隐藏层的权重参数和偏差参数分别为用多层感知机替代线性回归 多层感知机例题_函数定义_08用多层感知机替代线性回归 多层感知机例题_函数定义_09,输出层的权重和偏差参数分别为用多层感知机替代线性回归 多层感知机例题_多层感知机_10用多层感知机替代线性回归 多层感知机例题_函数定义_11

则,有输出用多层感知机替代线性回归 多层感知机例题_仿射变换_12的计算为:
用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_13

用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_14

即,将隐藏层的输出直接作为输出层的输入。

若将(1)式代入(2)式,可得:

用多层感知机替代线性回归 多层感知机例题_函数定义_15

由此可以发现,虽然引入了隐藏层,却依然等价于一个单层神经网络(输出层权重参数为用多层感知机替代线性回归 多层感知机例题_多层感知机_16,偏差参数为用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_17)。




3.3 激活函数

上述问题根源:
全连接层只对数据做仿射变换(affine transformation),多个仿射变换的叠加仍然是一个仿射变换。
—— 仿射变换:线性变换+平移(变换前是直线的,变换后依然是直线;直线比例保持不变)

解决方法之一:引入非线性变换
如,对隐藏变量使用按元素运算的非线性函数进行变换,然后再作为下一个全连接层的输入。
那么,这个非线性函数称为激活函数(activation function)。



3.3.1 ReLU函数

给定元素用多层感知机替代线性回归 多层感知机例题_仿射变换_18,ReLU(rectified linear unit)函数定义为:
用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_19

即,只保留正数元素,并将负数元素归零。

可直观地绘图如下:

%matplotlib inline
import tensorflow as tf
import matplotlib.pyplot as plt 

def use_svg_display():
    # 用矢量图显示
    %config InlineBackend.figure_format='svg'

def xyplot(x,y,name):
    use_svg_display()
    fig,ax = plt.subplots(figsize=(5,2.5))
    plt.plot(x.numpy(),y.numpy())
    plt.xlabel('x')
    plt.ylabel(name+'(x)')
x = tf.Variable(tf.range(-8,8,0.1),dtype=tf.float32)
y = tf.nn.relu(x)
xyplot(x,y,'relu')



用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_20



3.3.2 Sigmoid函数

给定元素用多层感知机替代线性回归 多层感知机例题_仿射变换_18,Sigmoid函数定义为:
用多层感知机替代线性回归 多层感知机例题_函数定义_22

即,将元素值变换到0至1之间。

可直观地绘图如下:

y = tf.nn.sigmoid(x)
xyplot(x,y,'sigmoid')



用多层感知机替代线性回归 多层感知机例题_仿射变换_23



3.3.3 tanh函数

给定元素用多层感知机替代线性回归 多层感知机例题_仿射变换_18,tanh函数定义为:
用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_25

即,将元素值变换到-1至1之间。

可直观地绘图如下:

y = tf.nn.tanh(x)
xyplot(x,y,'tanh')



用多层感知机替代线性回归 多层感知机例题_用多层感知机替代线性回归_26




3.4 多层感知机

多层感知机,是含有至少一个隐藏层的由全连接层组成的神经网络,且每个隐藏层的输出通过激活函数进行变换。

以单隐藏层为例,沿用3.2小节定义的符号,多层感知机的输出可计算如下:

用多层感知机替代线性回归 多层感知机例题_多层感知机_27

用多层感知机替代线性回归 多层感知机例题_函数定义_28

其中,用多层感知机替代线性回归 多层感知机例题_多层感知机_29表示激活函数。




3.5 代码实现

与softmax回归区别:
增加了一个全连接层作为隐藏层。隐藏单元个数为256,并使用ReLU函数作为激活函数。

import tensorflow as tf
from tensorflow import keras

model = keras.models.Sequential(
[keras.layers.Flatten(input_shape=(28,28)),
keras.layers.Dense(256,activation='relu'),
keras.layers.Dense(10,activation='softmax')]
)

fashion_mnist = keras.datasets.fashion_mnist
(x_train,y_train),(x_test,y_test) = fashion_mnist.load_data()
x_train = x_train/255.0
x_test = x_test/255.0

model.compile(
optimizer=keras.optimizers.SGD(0.5),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)

model.fit(x_train,
          y_train,
          batch_size=256,
          epochs=5,
          validation_data=(x_test,y_test)
          ,validation_freq=1)

输出:

Train on 60000 samples, validate on 10000 samples
Epoch 1/5
60000/60000 [==============================] - 1s 24us/sample - loss: 0.7909 - accuracy: 0.7127 - val_loss: 0.7150 - val_accuracy: 0.7203
Epoch 2/5
60000/60000 [==============================] - 1s 16us/sample - loss: 0.4734 - accuracy: 0.8257 - val_loss: 0.5336 - val_accuracy: 0.8011
Epoch 3/5
60000/60000 [==============================] - 1s 15us/sample - loss: 0.4192 - accuracy: 0.8453 - val_loss: 0.4297 - val_accuracy: 0.8404
Epoch 4/5
60000/60000 [==============================] - 1s 15us/sample - loss: 0.3895 - accuracy: 0.8572 - val_loss: 0.4431 - val_accuracy: 0.8303
Epoch 5/5
60000/60000 [==============================] - 1s 15us/sample - loss: 0.3680 - accuracy: 0.8648 - val_loss: 0.4280 - val_accuracy: 0.8481