参考ImageNet Classification with Deep Convolutional Neural Network
LeNet又名Le-Net-5,因为其使用了5×5的卷积核。它由LeCun于1998年发表,用来解决图片分类问题。
下图是LeNet-5的基本结构:
Le-Net使用了经典的卷积+池化+全连接的结构。
INPUT:输入是32×32,channel为1的手写数字图。
C1:卷积层,输入为32×32,channel=1,卷积核大小为5×5,深度为6,strides=1,没有padding,输出为(32-5+1)/1=28,使用的激活函数为tanh。输出维度为28×28×6.神经元的个数=28×28×6=4704。加上偏置项,参数个数=(5×5+1)×6=146.
S2:下采样层,采用MaxPooling。输入为28×28×6,pool_size=2×2,strides也是2,这样,输出维度为14×14×6.神经元的个数=14×14×6=1176.
C3:卷积层,输入为14×14×6,卷积核大小为5×5,深度为16.strides=1,没有padding,输出为(14-5+1)/1=10,使用的激活函数为tanh。输出维度为10×10×16.神经元的个数=10×10×16=1600.加上偏置项,参数个数=(5×5×6+1)×16=2416.
S4:下采样层,同样采用MaxPooling。输入为10×10×16,pool_size=2×2,strides为2.输出维度为5×5×16.神经元的个数=5×5×16=400.
此处需要进行flatten操作,以进行下一步的全连接。
C5:全连接层,节点数为120,参数个数=120×(5×5×16+1)=30840.激活函数采用tanh。
F6:全连接层,节点数为84,参数个数=(120+1)×84=10164.激活函数采用tanh。
OUTPUT:10分类的输出层,参数个数=(84+1)×10=850.激活函数采用softmax。
使用keras实现,代码如下:
import keras
from keras.layers import Conv2D, MaxPool2D, Flatten, Dense
from keras.models import Sequential
from keras.datasets import mnist
from keras.optimizers import SGD # 随机梯度下降
from keras.utils import plot_model, to_categorical
import matplotlib.pyplot as plt
模型的构建
model = Sequential()
model.add(Conv2D(input_shape=(28, 28, 1), filters=6, kernel_size=(5,5), padding='valid', activation='tanh')) # C1
model.add(MaxPool2D(pool_size=(2, 2), strides=2)) # S2
model.add(Conv2D(input_shape=(14, 14, 6), filters=16, kernel_size=(5, 5), padding='valid', activation='tanh')) # C3
model.add(MaxPool2D(pool_size=(2, 2), strides=2)) #S4
model.add(Flatten()) #展平
# 全连接层:把分布式特征representation映射到样本标记空间,大大减少特征位置的影响
model.add(Dense(120, activation='tanh')) #C5
model.add(Dense(84, activation='tanh')) #F6
model.add(Dense(10, activation='softmax')) # OUTPUT
model.summary()
导入数据
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 28, 28, 1)
x_test = x_test.reshape(10000, 28, 28, 1)
#损失函数使用的是categorical_crossentropy,因此要将数据转化为二值序列
y_train = to_categorical(y_train, num_classes=10)
y_test = to_categorical(y_test, num_classes=10)
模型编译与训练
# categorical_crossentropy:亦称作多类的对数损失,注意使用该目标函数时,需要将标签转化为形如(nb_samples, nb_classes)的二值序列
model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01), metrics=['accuracy']) # 编译
history = model.fit(x_train, y_train, batch_size=128, epochs=30)
print(history.history.keys())
训练结果显示
plt.plot(history.history['loss'])
plt.plot(history.history['accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['loss', 'acc'], loc='upper left')
plt.show()
evaluate
score = model.evaluate(x_test, y_test)
print('Testing Loss:', score[0])
print('Testing Accuracy of:', score[1])
10000/10000 [==============================] - 2s 193us/step
Testing Loss: 0.06168263527527452
Testing Accuracy of: 0.980400025844574