Tensorflow2.0笔记34——LeNet
Tensorflow2.0笔记
本博客为Tensorflow2.0学习笔记,感谢北京大学微电子学院曹建老师
4.CNN经典网络
在卷积神经网络的发展历程中,出现过许多经典的网络结构,这些 CNN 经典网络的提出都曾极大地促进了领域的发展,这里对 5 个经典的 CNN 网络结构做一个介绍,从 1998 年由 Yann LeCun 提出的 LeNet 直至 2015 年由何恺明提出的 ResNet,如图 5-20 所示。
值得一提的是,除了卷积网络的“开篇之作”LeNet 以外,AlexNet、VGGNet、InceptionNet 以及ResNet 这四种经典网络全部是在当年的 ImageNet 竞赛中问世的,它们作为深度学习的经典代表,使得 ImageNet 数据集上的错误率逐年降低。下面将会对这五种经典网络逐一进行介绍。
4.1 LeNet
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
from tensorflow.keras import Model
np.set_printoptions(threshold=np.inf)
cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
class LeNet5(Model):
def __init__(self):
super(LeNet5, self).__init__()
self.c1 = Conv2D(filters=6, kernel_size=(5, 5),
activation='sigmoid')
self.p1 = MaxPool2D(pool_size=(2, 2), strides=2)
self.c2 = Conv2D(filters=16, kernel_size=(5, 5),
activation='sigmoid')
self.p2 = MaxPool2D(pool_size=(2, 2), strides=2)
self.flatten = Flatten()
self.f1 = Dense(120, activation='sigmoid')
self.f2 = Dense(84, activation='sigmoid')
self.f3 = Dense(10, activation='softmax')
def call(self, x):
x = self.c1(x)
x = self.p1(x)
x = self.c2(x)
x = self.p2(x)
x = self.flatten(x)
x = self.f1(x)
x = self.f2(x)
y = self.f3(x)
return y
model = LeNet5()
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
checkpoint_save_path = "./checkpoint/LeNet5.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):
print('-------------load the model-----------------')
model.load_weights(checkpoint_save_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
save_weights_only=True,
save_best_only=True)
history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,
callbacks=[cp_callback])
model.summary()
# print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:
file.write(str(v.name) + '\n')
file.write(str(v.shape) + '\n')
file.write(str(v.numpy()) + '\n')
file.close()
############################################### show ###############################################
# 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
借鉴点:共享卷积核,减少网络参数。
LeNet 即 LeNet5,由 Yann LeCun 在 1998 年提出,做为最早的卷积神经网络之一,是许多神经网络架构的起点,其网络结构如图 5-21 所示。
根据以上信息,就可以根据上一节所总结出来的方法,在Tensorflow框架下利用tf. Keras来构建LeNet5模型,如图5- 22所示。
图中紫色部分为卷积层,红色部分为全连接层,模型图与代码一一对应,模型搭建具体流程如下(各步骤的实现函数在5.2节中均有介绍):
A)输入图像大小为32 * 32 * 3,三通道彩色图像输入;
B)进行卷积,卷积核大小为5 * 5,个数为6,步长为1,不进行全零填充;
C)将卷积结果输入sigmoid激活函数(非线性函数)进行激活;
D)进行最大池化,池化核大小为2 * 2,步长为2;
self.c1 = Conv2D(filters=6, kernel_size=(5, 5),
activation='sigmoid')
self.p1 = MaxPool2D(pool_size=(2, 2), strides=2)
E)进行卷积,卷积核大小为5 * 5,个数为16,步长为1,不 进行全零填充;
F)将卷积结果输入sigmoid激活函数进行激活;
G)进行最大池化,池化核大小为2 * 2,步长为2;
self.c2 = Conv2D(filters=16, kernel_size=(5, 5),
activation='sigmoid')
self.p2 = MaxPool2D(pool_size=(2, 2), strides=2)
H)输入三层全连接网络进行10分类。
self.flatten = Flatten()
self.f1 = Dense(120, activation='sigmoid')
self.f2 = Dense(84, activation='sigmoid')
self.f3 = Dense(10, activation='softmax')
与最初的LeNet5网络结构相比,这里做了一点微调,输入图像尺寸为32 * 32 * 3,以适应cifar10数据集(此数据集在5.2节中也有具体介绍)。模型中采用的激活函数有sigmoid和softmax,池化层均采用最大池化,以保留边缘特征。总体上看,诞生于1998年的LeNet5与如今一些主流的CNN网络相比,其结构可以说是相当简单,不过它成功地利用“卷积提取特征→全连接分类”的经典思路解决了手写数字识别的问题,对神经网络研究的发展有着很重要的意义。