用TensorFlow搭建卷積神經網路識別數字0~9

外出的霍位元人發表於2020-11-27

入門深度學習,用TensorFlow搭建卷積神經網路識別數字0~9,採用mnist資料集,參考了其它兩三篇部落格的內容。
一些相關內容我寫在程式碼註釋裡面了:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, optimizers, datasets

# 下面一行是線上載入方式獲取mnist資料
# mnist = tf.keras.datasets.mnist
# 下面兩行是載入本地的資料集(提前從網上下載好)
datapath  = r'F:\MyDownloads\PyCharm 5.0.3\mnist.npz'
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(datapath)

# 資料預處理,原來x_train是60000*28*28的資料
# 處理之後x_train是60000*28*28*1的資料(黑白單通道)
# y_train是0~9
x_train = x_train.reshape(x_train.shape[0],28,28,1).astype('float32')
x_test = x_test.reshape(x_test.shape[0],28,28,1).astype('float32')
# 歸一化
x_train = tf.keras.utils.normalize(x_train, axis=1)
x_test = tf.keras.utils.normalize(x_test, axis=1)   

'''
建立卷積神經網路結構模型:
    建立兩層卷積層和兩層池化層
    第一層卷積核個數為16,大小為5*5,same的填充是指輸出影像大小與輸入一致
    第二層卷積核個數為36,以提取更高維度的資訊,大小為5*5
    一般來說,最大池化層比平均池化層在分類上表現更好
卷積——>ReLU——>池化(以上3層可以疊加多層)——>全連線(可以疊加多層)

一個卷積核可以提取影像的部分特徵,選取若干個卷積核。
反向傳播:計算卷積核的引數和全連線的權重
'''

'''
Sequential用於建立序列模型
Flatten層展開張量,把feature map都展開
Dense層是全連線層,輸出128個神經元,啟用函式用relu
Dropout層使用0.5的失活率
再來一個全連線層,輸出10個神經元(對應0~9),啟用函式使用softmax,得到對各個類別預測的概率
'''

model = keras.models.Sequential([
    layers.Conv2D(filters=16, kernel_size=(5,5), padding='same',
                 input_shape=(28,28,1),  activation='relu'),   
    layers.MaxPooling2D(pool_size=(2, 2)), 
    layers.Conv2D(filters=36, kernel_size=(5,5), padding='same',
    			 activation='relu'),
    layers.MaxPooling2D(pool_size=(2, 2)),   
    layers.Dropout(0.25),
    layers.Flatten(),
    layers.Dense(128, activation='relu'),
    layers.Dropout(0.5),
    layers.Dense(10,activation='softmax')
])
#列印模型
print(model.summary())

#模型編譯及訓練
#損失函式使用交叉熵損失函式,優化器使用adam,訓練10個epoch和128的batch_size
'''
隨機梯度下降:
batch:更新內部模型引數之前處理的樣本數,訓練資料集可以劃分成一個或者多個batch
1個epoch:訓練資料集中的所有樣本都有機會參與更新內部模型引數,epoch由一個或者多個batch組成

小例子:
訓練資料集有200個樣本,令batch_size=5,即每個batch有5個樣本,則有40個batch。
處理完一個batch的5個樣本之後,更新內部模型引數。
1個epoch由40個batch組成,執行完一次epoch,引數更新40次。
epoch數量一般比較大,允許演算法執行直到模型的誤差非常小
'''
#訓練配置
model.compile(loss='sparse_categorical_crossentropy',
              optimizer='adam', metrics=['accuracy'])
#開始訓練
model.fit(x=x_train, y=y_train, validation_split=0.2,	# validation_split是指將一部分作為驗證集使用,0.2代表80%的資料作為訓練集,20%作為驗證集
                        epochs=10, batch_size=128, verbose=1)   # verbose=1代表顯示訓練過程

# 測試集驗證來評估模型,model.evaluate輸出計算的損失值和準確度
val_loss, val_acc = model.evaluate(x_test, y_test)
print('Test Loss:{:.6f}'.format(val_loss))
print('Test Acc:{:.6f}'.format(val_acc))

'''
# 繪製影像,檢視loss和accr
import matplotlib.pyplot as plt
history = model.fit(...)
plt.plot(history.epoch,history.history['loss'],color='red',label='loss')
plt.plot(history.epoch,history.history['accr'],color='blur',label='accr')
plt.legend()
plt.show()
'''

相關文章