一、简介Le-Net5
在之前文章可以看到TensorFlow1实现的Le-Net5代码。
二、TensorFlow2实现
1. 层说明
- 输入层
- 卷积层 Convolution #1. Input = 32x32x1. Output = 28x28x6 conv2d
- 下采样层 SubSampling #1. Input = 28x28x6. Output = 14x14x6. SubSampling is simply Average Pooling so we use avg_pool
- 卷积层 Convolution #2. Input = 14x14x6. Output = 10x10x16 conv2d
- 下采样层 SubSampling #2. Input = 10x10x16. Output = 5x5x16 avg_pool
- 全连接层 Fully Connected #1. Input = 5x5x16. Output = 120
- 全连接层 Fully Connected #2. Input = 120. Output = 84
- 输出层 Output 10
2. 核心代码:
model = keras.Sequential()
model.add(layers.Conv2D(filters=6, kernel_size=(3, 3), activation='relu', input_shape=(32,32,1)))
model.add(layers.AveragePooling2D())
model.add(layers.Conv2D(filters=16, kernel_size=(3, 3), activation='relu'))
model.add(layers.AveragePooling2D())
model.add(layers.Flatten())
model.add(layers.Dense(units=120, activation='relu'))
model.add(layers.Dense(units=84, activation='relu'))
model.add(layers.Dense(units=10, activation = 'softmax'))
3. 导入数据
from requests import get
def download_file(url, file_name):
with open(file_name, "wb") as file:
response = get(url)
file.write(response.content)
i. 安装 seaborn
# Update libraries
!pip install seaborn==0.9.0
ii. 导入数据
import gzip
import numpy as np
import pandas as pd
from time import time
from sklearn.model_selection import train_test_split
import tensorflow as tf
import keras
import keras.layers as layers
from keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator
from keras.utils.np_utils import to_categorical
from keras.callbacks import TensorBoard
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
def read_mnist(images_path: str, labels_path: str):
with gzip.open(labels_path, 'rb') as labelsFile:
labels = np.frombuffer(labelsFile.read(), dtype=np.uint8, offset=8)
with gzip.open(images_path,'rb') as imagesFile:
length = len(labels)
# Load flat 28x28 px images (784 px), and convert them to 28x28 px
features = np.frombuffer(imagesFile.read(), dtype=np.uint8, offset=16) \
.reshape(length, 784) \
.reshape(length, 28, 28, 1)
return features, labels
iii. 查看数据
print('# of training images:', train['features'].shape[0])
print('# of test images:', test['features'].shape[0])
显示一些图片:
def display_image(position):
image = train['features'][position].squeeze()
plt.title('Example %d. Label: %d' % (position, train['labels'][position]))
plt.imshow(image, cmap=plt.cm.gray_r)
display_image(0)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cxfn8nRG-1574813376859)(/uploads/20191125/b8cfb8b60ba4fad00b8afbbf984e6a88.png “在这里输入图片标题”)]
iv. 标出数据
train_labels_count = np.unique(train['labels'], return_counts=True)
dataframe_train_labels = pd.DataFrame({'Label':train_labels_count[0], 'Count':train_labels_count[1]})
dataframe_train_labels
v. 数据集拆分训练集和测试集
validation = {}
train['features'], validation['features'], train['labels'], validation['labels'] = train_test_split(train['features'], train['labels'], test_size=0.2, random_state=0)
print('# of training images:', train['features'].shape[0])
print('# of validation images:', validation['features'].shape[0])
4. 数据格式修正
# Pad images with 0s
train['features'] = np.pad(train['features'], ((0,0),(2,2),(2,2),(0,0)), 'constant')
validation['features'] = np.pad(validation['features'], ((0,0),(2,2),(2,2),(0,0)), 'constant')
test['features'] = np.pad(test['features'], ((0,0),(2,2),(2,2),(0,0)), 'constant')
print("Updated Image Shape: {}".format(train['features'][0].shape))
5. Le-Net5实现
i. 结构:
- ####1 卷积输出张量形状: 28x28x6
- Activation any activation function, we will relu
- ####1 池化输出 14x14x6.
- ####2 卷积输出 10x10x16.
- Activation any activation function, we will relu
- ####2 池化输出 5x5x16.
- Flatten Flatten the output shape of the final pooling layer
- ####1 全连接输出 outputs 120
- Activation any activation function, we will relu
- ####2 全连接输出 84Fully Connected #2 outputs 84
- Activation any activation function, we will relu
- ####3 全连接输出 10 Fully Connected (Logits) #3 outpute 10
ii. 构建层
model = keras.Sequential()
model.add(layers.Conv2D(filters=6, kernel_size=(3, 3), activation='relu', input_shape=(32,32,1)))
model.add(layers.AveragePooling2D())
model.add(layers.Conv2D(filters=16, kernel_size=(3, 3), activation='relu'))
model.add(layers.AveragePooling2D())
model.add(layers.Flatten())
model.add(layers.Dense(units=120, activation='relu'))
model.add(layers.Dense(units=84, activation='relu'))
model.add(layers.Dense(units=10, activation = 'softmax'))
model.summary()
iii. 编译
model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(), metrics=['accuracy'])
EPOCHS = 10
BATCH_SIZE = 128
iv. 训练
X_train, y_train = train['features'], to_categorical(train['labels'])
X_validation, y_validation = validation['features'], to_categorical(validation['labels'])
train_generator = ImageDataGenerator().flow(X_train, y_train, batch_size=BATCH_SIZE)
validation_generator = ImageDataGenerator().flow(X_validation, y_validation, batch_size=BATCH_SIZE)
v. 拟合
print('# of training images:', train['features'].shape[0])
print('# of validation images:', validation['features'].shape[0])
steps_per_epoch = X_train.shape[0]//BATCH_SIZE
validation_steps = X_validation.shape[0]//BATCH_SIZE
tensorboard = TensorBoard(log_dir="logs/{}".format(time()))
model.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=EPOCHS,
validation_data=validation_generator, validation_steps=validation_steps,
shuffle=True, callbacks=[tensorboard])
vi. 评估
score = model.evaluate(test['features'], to_categorical(test['labels']))
print('Test loss:', score[0])
print('Test accuracy:', score[1])