MNIST手寫數字的識別+LeNet的網絡的實現+迭代8輪達到測試集98.78%

LeNet網絡:

  • LeNet分爲卷積層塊和全連接層塊兩個部分。下⾯我們分別介紹這兩個模塊。
    卷積層塊⾥的基本單位是卷積層後接最⼤池化層:卷積層⽤來識別圖像⾥的空間模式,如線條和物體局部,之後的最⼤池化層則⽤來降低卷積層對位置的敏感性。卷積層塊由兩個這樣的基本單位重複堆疊構成。在卷積層塊中,每個卷積層都使⽤5 × 5的窗口,並在輸出上使⽤sigmoid激活函數。第⼀個卷積層輸出通道數爲6,第⼆個卷積層輸出通道數則增加到16。這是因爲第⼆個卷
    積層⽐第⼀個卷積層的輸⼊的⾼和寬要小,所以增加輸出通道使兩個卷積層的參數尺⼨類似。卷積層塊的兩個最⼤池化層的窗口形狀均爲2 × 2,且步幅爲2。由於池化窗口與步幅形狀相同,池化窗口在輸⼊上每次滑動所覆蓋的區域互不重疊。卷積層塊的輸出形狀爲(批量⼤小, 通道, ⾼, 寬)。當卷積層塊的輸出傳⼊全連接層塊時,全連接層塊會將小批量中每個樣本變平(flatten) 。也就是說,全連接層的輸⼊形狀將變成⼆維,其中第⼀維是小批量中的樣本,第⼆維是每個樣本變平後的向量表⽰,且向量⻓度爲通道、⾼和寬的乘積。全連接層塊含3個全連接層。它們的輸出個數分別是120、84和10,其中10爲輸出的類別個數。
    本次實驗環境使用Tensorflow2.0版本框架搭建。

  • 網絡架構:
    在這裏插入圖片描述

  • 網絡結構代碼設置:

# 一、LeNet
# 添加捲積層1+relu1
model.add(layers.Conv2D(6,kernel_size=(5,5),activation='sigmoid',input_shape=(img_rows,img_cols,1)))
# 添加池化層1
model.add(layers.MaxPooling2D(pool_size=(2,2),strides=2))
# 添加捲積層2+relu2
model.add(layers.Conv2D(16,kernel_size=(5,5),activation='sigmoid',input_shape=(img_rows,img_cols,1)))
# 添加池化層1
model.add(layers.MaxPooling2D(pool_size=(2,2),strides=2))
# 全連接層
model.add(layers.Flatten())
model.add(layers.Dense(120, activation='relu'))
model.add(layers.Dense(84, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
  • 神經網絡的訓練過程+結果:
    在這裏插入圖片描述
    我們可以看到LeNet在訓練過程中效果呈現較好的形式,訓練集和測試集都滿足擬合狀態,在訓練迭代8輪之後達到了
    訓練集 98.88% 的準確率
    測試集 達到了 98.78% 的準確率
    在這裏插入圖片描述

總代碼:

#%%
import tensorflow as tf
import numpy as np
import os
from tensorflow.keras.datasets import mnist
import tensorflow.keras as keras
from tensorflow.keras import layers

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0  # 將樣本從整數轉換爲浮點數

# 利用tf.keras.Sequential容器封裝網絡層,前一層網絡的輸出默認作爲下一層的輸入
# 使用卷積神經網絡
# 1、首先把y值變爲one_hot
#%%
y_train = keras.utils.to_categorical(y_train,num_classes=10)
y_test = keras.utils.to_categorical(y_test,num_classes=10)
# 2、調整圖像維度
img_rows,img_cols=28,28
x_train = x_train.reshape(x_train.shape[0],img_rows,img_cols,1)
x_test = x_test.reshape(x_test.shape[0],img_rows,img_cols,1)
# 3、建立模型
# 來建立幾個經典的卷積神經網絡
model = keras.Sequential()
#%%
# 一、LeNet
# 添加捲積層1+relu1
model.add(layers.Conv2D(6,kernel_size=(5,5),activation='sigmoid',input_shape=(img_rows,img_cols,1)))
# 添加池化層1
model.add(layers.MaxPooling2D(pool_size=(2,2),strides=2))
# 添加捲積層2+relu2
model.add(layers.Conv2D(16,kernel_size=(5,5),activation='sigmoid',input_shape=(img_rows,img_cols,1)))
# 添加池化層1
model.add(layers.MaxPooling2D(pool_size=(2,2),strides=2))
# 全連接層
model.add(layers.Flatten())
model.add(layers.Dense(120, activation='relu'))
model.add(layers.Dense(84, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
print(model.summary())
#%%

# 爲訓練選擇優化器和損失函數:
model.compile(optimizer='adam',
              loss=keras.losses.categorical_crossentropy,
              metrics=['accuracy'])

log_dir = os.path.join("logs")
# print(log_dir)
if not os.path.exists(log_dir):
    os.mkdir(log_dir)
# 定義TensorBoard對象.histogram_freq 如果設置爲0,則不會計算直方圖。
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)

# TensorBoard對象作爲回調傳給model.fit方法
model.fit(x_train, y_train,
          epochs=8,
          validation_data=(x_test, y_test),
          callbacks=[tensorboard_callback])

model.save_weights("./save_model/LeNet_MNIST_save_weights", save_format='tf')  # 保存模型
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章