?博客主頁(yè):王樂(lè)予??
?年輕人要:Living for the moment(活在當(dāng)下)!??
??推薦專欄:【圖像處理】【千錘百煉Python】【深度學(xué)習(xí)】【排序算法】
?? 本來(lái)想著多更新一些關(guān)于深度學(xué)習(xí)的文章,但這方面知識(shí)專業(yè)度很高,如果作者本身都掌握不好,又怎么能寫(xiě)出好文章分享呢?
??距離第一篇關(guān)于深度學(xué)習(xí)的文章:深度學(xué)習(xí)筆記1——激活函數(shù),已經(jīng)過(guò)去了9個(gè)多月,在沉淀了9個(gè)月后,這次寫(xiě)出了第二篇關(guān)于深度學(xué)習(xí)的文章,而且出于快速上手代碼編寫(xiě)的目的,這次直接進(jìn)行手寫(xiě)數(shù)字識(shí)別的實(shí)戰(zhàn),且看下文:
??一、準(zhǔn)備工作
設(shè)備\庫(kù) | 型號(hào)\版本 |
---|---|
顯卡 | GTX1650 |
驅(qū)動(dòng)程序版本 | 457.49 |
tensorflow-gpu版本 | 2.4.0 |
keras版本 | 2.4.3 |
Python版本 | 3.7.3 |
??二、下載MNIST數(shù)據(jù)集
Keras已經(jīng)對(duì)MNIST數(shù)據(jù)集做了集成,可以直接通過(guò)API下載與使用。
??2.1 導(dǎo)入所需的庫(kù)與模塊
from keras.datasets import mnist
import matplotlib.pyplot as plt
??2.2 下載數(shù)據(jù)集
# x_train_original和y_train_original代表訓(xùn)練集的圖像與標(biāo)簽, x_test_original與y_test_original代表測(cè)試集的圖像與標(biāo)簽
(x_train_original, y_train_original), (x_test_original, y_test_original) = mnist.load_data()
下載好的數(shù)據(jù)集系統(tǒng)會(huì)存放在C盤(pán)用戶下的.keras中的datasets文件夾下:
C:\Users\Lenovo\.keras\datasets
??三、數(shù)據(jù)集可視化
??3.1 單張圖像可視化
def mnist_visualize_single(mode, idx):
if mode == 0:
plt.imshow(x_train_original[idx], cmap=plt.get_cmap('gray'))
title = 'label=' + str(y_train_original[idx])
plt.title(title)
plt.xticks([])
plt.yticks([])
plt.show()
else:
plt.imshow(x_test_original[idx], cmap=plt.get_cmap('gray'))
title = 'label=' + str(y_test_original[idx])
plt.title(title)
plt.xticks([])
plt.yticks([])
plt.show()
我們調(diào)用這個(gè)函數(shù)
mnist_visualize_single(mode=0, idx=0)
可以看到,訓(xùn)練數(shù)據(jù)的第一張圖像是5。
??3.2 多張圖像可視化
def mnist_visualize_multiple(mode, start, end, length, width):
if mode == 0:
for i in range(start, end):
plt.subplot(length, width, 1 + i)
plt.imshow(x_train_original[i], cmap=plt.get_cmap('gray'))
title = 'label=' + str(y_train_original[i])
plt.title(title)
plt.xticks([])
plt.yticks([])
plt.show()
else:
for i in range(start, end):
plt.subplot(length, width, 1 + i)
plt.imshow(x_test_original[i], cmap=plt.get_cmap('gray'))
title = 'label=' + str(y_test_original[i])
plt.title(title)
plt.xticks([])
plt.yticks([])
plt.show()
我們調(diào)用這個(gè)函數(shù)
mnist_visualize_multiple(mode=0, start=0, end=4, length=2, width=2)
可以看到,訓(xùn)練數(shù)據(jù)的前四張圖像分別是5、0、4、1。
??3.3 原始數(shù)據(jù)量可視化
print('訓(xùn)練集圖像的尺寸:', x_train_original.shape)
print('訓(xùn)練集標(biāo)簽的尺寸:', y_train_original.shape)
print('測(cè)試集圖像的尺寸:', x_test_original.shape)
print('測(cè)試集標(biāo)簽的尺寸:', y_test_original.shape)
程序運(yùn)行結(jié)果:
訓(xùn)練集圖像的尺寸: (60000, 28, 28)
訓(xùn)練集標(biāo)簽的尺寸: (60000,)
測(cè)試集圖像的尺寸: (10000, 28, 28)
測(cè)試集標(biāo)簽的尺寸: (10000,)
從這里可以知道,MNIST數(shù)據(jù)集是(28×28)的灰度圖像
??四、數(shù)據(jù)預(yù)處理
??4.1 驗(yàn)證集分配
我們從訓(xùn)練集的60000張圖像中,分離出10000張圖像用作驗(yàn)證集。
x_val = x_train_original[50000:]
y_val = y_train_original[50000:]
x_train = x_train_original[:50000]
y_train = y_train_original[:50000]
# 打印驗(yàn)證集數(shù)據(jù)量
print('驗(yàn)證集圖像的尺寸:', x_val.shape)
print('驗(yàn)證集標(biāo)簽的尺寸:', y_val.shape)
程序運(yùn)行結(jié)果:
驗(yàn)證集圖像的尺寸: (10000, 28, 28)
驗(yàn)證集標(biāo)簽的尺寸: (10000,)
??4.2 圖像數(shù)據(jù)預(yù)處理
我們需要先將圖像轉(zhuǎn)換為四維矩陣用于網(wǎng)絡(luò)訓(xùn)練,且需要把圖像類型從Uint8轉(zhuǎn)化為float32,提高訓(xùn)練精度。
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32')
x_val = x_val.reshape(x_val.shape[0], 28, 28, 1).astype('float32')
x_test = x_test_original.reshape(x_test_original.shape[0], 28, 28, 1).astype('float32')
原始圖像數(shù)據(jù)的像素灰度值范圍是0-255,為了提高模型的訓(xùn)練精度,通常將數(shù)值歸一化至0-1。
x_train = x_train / 255
x_val = x_val / 255
x_test = x_test / 255
我們打印一下數(shù)據(jù)集傳入網(wǎng)絡(luò)的尺寸:
print('訓(xùn)練集傳入網(wǎng)絡(luò)的圖像尺寸:', x_train.shape)
print('驗(yàn)證集傳入網(wǎng)絡(luò)的圖像尺寸:', x_val.shape)
print('測(cè)試集傳入網(wǎng)絡(luò)的圖像尺寸:', x_test.shape)
打印結(jié)果為:
訓(xùn)練集傳入網(wǎng)絡(luò)的圖像尺寸: (50000, 28, 28, 1)
驗(yàn)證集傳入網(wǎng)絡(luò)的圖像尺寸: (10000, 28, 28, 1)
測(cè)試集傳入網(wǎng)絡(luò)的圖像尺寸: (10000, 28, 28, 1)
??五、構(gòu)建網(wǎng)絡(luò)
??5.1 導(dǎo)入所需的庫(kù)與模塊
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix
import seaborn as sns
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.utils import np_utils
from keras.utils.vis_utils import plot_model
??5.2 定義網(wǎng)絡(luò)模型
我們使用CNN模型做手寫(xiě)數(shù)字的分類,當(dāng)然也可以使用感知機(jī)。
模型的構(gòu)建采用序貫?zāi)P?/strong>結(jié)構(gòu),網(wǎng)絡(luò)由卷積層-池化層-卷積層-池化層-平鋪層-全連接層-全連接層組成。最后一層的全連接層采用softmax
激活函數(shù)做10分類。
def CNN_model():
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(100, activation='relu'))
model.add(Dense(10, activation='softmax'))
print(model.summary())
return model
model = CNN_model()
??5.3 網(wǎng)絡(luò)模型參數(shù)可視化
我們使用print(model.summary())
得到神經(jīng)網(wǎng)路的每一層參數(shù)。
print(model.summary())
輸出結(jié)果為:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 24, 24, 16) 416
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 12, 12, 16) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 8, 8, 32) 12832
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 4, 4, 32) 0
_________________________________________________________________
flatten (Flatten) (None, 512) 0
_________________________________________________________________
dense (Dense) (None, 100) 51300
_________________________________________________________________
dense_1 (Dense) (None, 10) 1010
=================================================================
Total params: 65,558
Trainable params: 65,558
Non-trainable params: 0
_________________________________________________________________
??5.4 網(wǎng)絡(luò)結(jié)構(gòu)可視化
為了更直觀的展示網(wǎng)絡(luò)的結(jié)構(gòu),我們可以通過(guò)圖的方式了解網(wǎng)絡(luò)各層之間的關(guān)系:
plot_model(model, to_file='CNN_model.png', show_shapes=True, show_layer_names=True, rankdir='TB')
plt.figure(figsize=(10, 10))
img = plt.imread('CNN_model.png')
plt.imshow(img)
plt.axis('off')
plt.show()
網(wǎng)絡(luò)結(jié)構(gòu)圖可以更加直觀的看出網(wǎng)絡(luò)各層關(guān)系以及張量流的傳遞路徑,此外每個(gè)網(wǎng)絡(luò)層的輸入輸出尺寸都能很好的體現(xiàn)。
??六、編譯訓(xùn)練網(wǎng)絡(luò)
??6.1 編譯網(wǎng)絡(luò)
Keras通過(guò)model.compile()
編譯網(wǎng)絡(luò),其可以定義損失函數(shù)、優(yōu)化器、評(píng)估指標(biāo)等參數(shù)。
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
這里使用交叉熵categorical_crossentropy
作為損失函數(shù),這是最常用的多分類任務(wù)的損失函數(shù),常搭配softmax
激活函數(shù)使用。
優(yōu)化器我們使用自適應(yīng)矩估計(jì):Adam
,Adam簡(jiǎn)直不要太好用?。?!
評(píng)價(jià)指標(biāo)我們使用精度:accuracy
。
??6.2 訓(xùn)練網(wǎng)絡(luò)
Keras可以通過(guò)多種函數(shù)訓(xùn)練網(wǎng)絡(luò),這里我們使用model.fit()
訓(xùn)練網(wǎng)絡(luò)模型,函數(shù)中可以定義訓(xùn)練集數(shù)據(jù)與訓(xùn)練集標(biāo)簽,驗(yàn)證集數(shù)據(jù)與驗(yàn)證集標(biāo)簽、訓(xùn)練批次、批處理大小等。
train_history = model.fit(x_train, y_train, validation_data=(x_val, y_val), epochs=20, batch_size=32, verbose=2)
這里返回值train_history
中包含了訓(xùn)練過(guò)程的許多信息,例如訓(xùn)練損失和訓(xùn)練精度等。
接下來(lái)網(wǎng)絡(luò)就會(huì)開(kāi)始訓(xùn)練,訓(xùn)練過(guò)程如下:
Epoch 1/20
1563/1563 - 9s - loss: 0.1665 - accuracy: 0.9486 - val_loss: 0.0610 - val_accuracy: 0.9821
Epoch 2/20
1563/1563 - 6s - loss: 0.0524 - accuracy: 0.9833 - val_loss: 0.0473 - val_accuracy: 0.9849
Epoch 3/20
1563/1563 - 6s - loss: 0.0353 - accuracy: 0.9891 - val_loss: 0.0416 - val_accuracy: 0.9873
Epoch 4/20
1563/1563 - 6s - loss: 0.0293 - accuracy: 0.9908 - val_loss: 0.0354 - val_accuracy: 0.9900
Epoch 5/20
1563/1563 - 6s - loss: 0.0195 - accuracy: 0.9939 - val_loss: 0.0372 - val_accuracy: 0.9898
Epoch 6/20
1563/1563 - 6s - loss: 0.0180 - accuracy: 0.9940 - val_loss: 0.0416 - val_accuracy: 0.9876
Epoch 7/20
1563/1563 - 6s - loss: 0.0150 - accuracy: 0.9953 - val_loss: 0.0425 - val_accuracy: 0.9884
Epoch 8/20
1563/1563 - 6s - loss: 0.0108 - accuracy: 0.9961 - val_loss: 0.0365 - val_accuracy: 0.9908
Epoch 9/20
1563/1563 - 6s - loss: 0.0120 - accuracy: 0.9957 - val_loss: 0.0406 - val_accuracy: 0.9890
Epoch 10/20
1563/1563 - 6s - loss: 0.0087 - accuracy: 0.9970 - val_loss: 0.0437 - val_accuracy: 0.9893
Epoch 11/20
1563/1563 - 6s - loss: 0.0081 - accuracy: 0.9973 - val_loss: 0.0487 - val_accuracy: 0.9884
Epoch 12/20
1563/1563 - 6s - loss: 0.0067 - accuracy: 0.9978 - val_loss: 0.0470 - val_accuracy: 0.9906
Epoch 13/20
1563/1563 - 6s - loss: 0.0075 - accuracy: 0.9976 - val_loss: 0.0388 - val_accuracy: 0.9905
Epoch 14/20
1563/1563 - 6s - loss: 0.0068 - accuracy: 0.9977 - val_loss: 0.0554 - val_accuracy: 0.9897
Epoch 15/20
1563/1563 - 6s - loss: 0.0056 - accuracy: 0.9981 - val_loss: 0.0512 - val_accuracy: 0.9908
Epoch 16/20
1563/1563 - 6s - loss: 0.0058 - accuracy: 0.9981 - val_loss: 0.0479 - val_accuracy: 0.9914
Epoch 17/20
1563/1563 - 6s - loss: 0.0056 - accuracy: 0.9980 - val_loss: 0.0482 - val_accuracy: 0.9912
Epoch 18/20
1563/1563 - 6s - loss: 0.0057 - accuracy: 0.9982 - val_loss: 0.0528 - val_accuracy: 0.9904
Epoch 19/20
1563/1563 - 6s - loss: 0.0046 - accuracy: 0.9985 - val_loss: 0.0538 - val_accuracy: 0.9895
Epoch 20/20
1563/1563 - 6s - loss: 0.0038 - accuracy: 0.9986 - val_loss: 0.0581 - val_accuracy: 0.9900
??6.3 訓(xùn)練過(guò)程可視化
我們可以通過(guò)圖的方式展示神經(jīng)網(wǎng)路在訓(xùn)練時(shí)的損失與精度的變化,我們定義函數(shù):
def show_train_history(train_history, train, validation):
plt.plot(train_history.history[train])
plt.plot(train_history.history[validation])
plt.title('Train History')
plt.ylabel(train)
plt.xlabel('Epoch')
plt.legend(['train', 'validation'], loc='best')
plt.show()
我們調(diào)用該函數(shù):
show_train_history(train_history, 'accuracy', 'val_accuracy')
show_train_history(train_history, 'loss', 'val_loss')
上圖分別表示網(wǎng)絡(luò)訓(xùn)練過(guò)程中在訓(xùn)練集與驗(yàn)證集上的精度與損失的變化折現(xiàn)圖。通過(guò)折線圖我們可以判斷網(wǎng)絡(luò)是否發(fā)生過(guò)擬合等情況。
??6.4 保存訓(xùn)練好的網(wǎng)絡(luò)模型
Keras有多種保存網(wǎng)絡(luò)模型的函數(shù),這里我們使用model.save()
。
model.save('handwritten_numeral_recognition.h5')
.h5模型中包含模型結(jié)構(gòu)、模型權(quán)重、模型編譯信息等。
??七、網(wǎng)絡(luò)預(yù)測(cè)
??7.1 測(cè)試集預(yù)測(cè)結(jié)果
Keras通過(guò)函數(shù)model.evaluate()
測(cè)試神經(jīng)網(wǎng)路在測(cè)試集上的情況。
score = model.evaluate(x_test, y_test)
score中包含了測(cè)試集上的損失與精度信息,我們打印一下:
print('Test loss:', score[0])
print('Test accuracy:', score[1])
輸出打印結(jié)果:
Test loss: 0.0538315623998642
Test accuracy: 0.9905999898910522
從結(jié)果我們可知,我們的神經(jīng)網(wǎng)路在測(cè)試集上的精度可以達(dá)到99%,說(shuō)明網(wǎng)絡(luò)還是不錯(cuò)的。
我們通過(guò)model.predict()
對(duì)測(cè)試集圖像進(jìn)行預(yù)測(cè):
predictions = model.predict(x_test)
predictions = np.argmax(predictions, axis=1)
print('前20張圖片預(yù)測(cè)結(jié)果:', predictions[:20])
前20張圖像的預(yù)測(cè)結(jié)果如下:
前20張圖片預(yù)測(cè)結(jié)果: [7 2 1 0 4 1 4 9 5 9 0 6 9 0 1 5 9 7 3 4]
??7.2 測(cè)試集預(yù)測(cè)結(jié)果圖像可視化
我們可以像第三部分那樣,構(gòu)造一個(gè)函數(shù)可以既顯示圖片,又能顯示圖像預(yù)測(cè)的結(jié)果,定義以下函數(shù):
def mnist_visualize_multiple_predict(start, end, length, width):
for i in range(start, end):
plt.subplot(length, width, 1 + i)
plt.imshow(x_test_original[i], cmap=plt.get_cmap('gray'))
title_true = 'true=' + str(y_test_original[i])
title_prediction = ',' + 'prediction' + str(model.predict_classes(np.expand_dims(x_test[i], axis=0)))
title = title_true + title_prediction
plt.title(title)
plt.xticks([])
plt.yticks([])
plt.show()
調(diào)用該函數(shù):
mnist_visualize_multiple_predict(start=0, end=9, length=3, width=3)
我們可以得到測(cè)試集上圖像的真實(shí)標(biāo)簽與預(yù)測(cè)標(biāo)簽。
第9張圖像已經(jīng)很抽象了,網(wǎng)絡(luò)仍能精準(zhǔn)判別出數(shù)字是5。
??7.3 顯示混淆矩陣
通過(guò)建立混淆矩陣可以更直觀的感知每一種類別的誤差。
首先構(gòu)造混淆矩陣:
cm = confusion_matrix(y_test_original, predictions)
cm = pd.DataFrame(cm)
然后我們構(gòu)造一個(gè)類名:
class_names = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
最后我們定義混淆矩陣可視化函數(shù):
def plot_confusion_matrix(cm):
plt.figure(figsize=(10, 10))
sns.heatmap(cm, cmap='Oranges', linecolor='black', linewidth=1, annot=True, fmt='', xticklabels=class_names, yticklabels=class_names)
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.title("Confusion Matrix")
plt.show()
我們調(diào)用這個(gè)函數(shù):
plot_confusion_matrix(cm)
可視化結(jié)果如圖:
??八、完整程序
from keras.datasets import mnist
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix
import seaborn as sns
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.utils import np_utils
from keras.utils.vis_utils import plot_model
import tensorflow as tf
import os
import keras
config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.compat.v1.Session(config=config)
# 設(shè)定隨機(jī)數(shù)種子,使得每個(gè)網(wǎng)絡(luò)層的權(quán)重初始化一致
# np.random.seed(10)
# x_train_original和y_train_original代表訓(xùn)練集的圖像與標(biāo)簽, x_test_original與y_test_original代表測(cè)試集的圖像與標(biāo)簽
(x_train_original, y_train_original), (x_test_original, y_test_original) = mnist.load_data()
"""
數(shù)據(jù)可視化
"""
# 單張圖像可視化
def mnist_visualize_single(mode, idx):
if mode == 0:
plt.imshow(x_train_original[idx], cmap=plt.get_cmap('gray'))
title = 'label=' + str(y_train_original[idx])
plt.title(title)
plt.xticks([]) # 不顯示x軸
plt.yticks([]) # 不顯示y軸
plt.show()
else:
plt.imshow(x_test_original[idx], cmap=plt.get_cmap('gray'))
title = 'label=' + str(y_test_original[idx])
plt.title(title)
plt.xticks([]) # 不顯示x軸
plt.yticks([]) # 不顯示y軸
plt.show()
# 多張圖像可視化
def mnist_visualize_multiple(mode, start, end, length, width):
if mode == 0:
for i in range(start, end):
plt.subplot(length, width, 1 + i)
plt.imshow(x_train_original[i], cmap=plt.get_cmap('gray'))
title = 'label=' + str(y_train_original[i])
plt.title(title)
plt.xticks([])
plt.yticks([])
plt.show()
else:
for i in range(start, end):
plt.subplot(length, width, 1 + i)
plt.imshow(x_test_original[i], cmap=plt.get_cmap('gray'))
title = 'label=' + str(y_test_original[i])
plt.title(title)
plt.xticks([])
plt.yticks([])
plt.show()
# 原始數(shù)據(jù)量可視化
print('訓(xùn)練集圖像的尺寸:', x_train_original.shape)
print('訓(xùn)練集標(biāo)簽的尺寸:', y_train_original.shape)
print('測(cè)試集圖像的尺寸:', x_test_original.shape)
print('測(cè)試集標(biāo)簽的尺寸:', y_test_original.shape)
"""
數(shù)據(jù)預(yù)處理
"""
# 從訓(xùn)練集中分配驗(yàn)證集
x_val = x_train_original[50000:]
y_val = y_train_original[50000:]
x_train = x_train_original[:50000]
y_train = y_train_original[:50000]
# 打印驗(yàn)證集數(shù)據(jù)量
print('驗(yàn)證集圖像的尺寸:', x_val.shape)
print('驗(yàn)證集標(biāo)簽的尺寸:', y_val.shape)
print('======================')
# 將圖像轉(zhuǎn)換為四維矩陣(nums,rows,cols,channels), 這里把數(shù)據(jù)從unint類型轉(zhuǎn)化為float32類型, 提高訓(xùn)練精度。
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32')
x_val = x_val.reshape(x_val.shape[0], 28, 28, 1).astype('float32')
x_test = x_test_original.reshape(x_test_original.shape[0], 28, 28, 1).astype('float32')
#原始圖像的像素灰度值為0-255,為了提高模型的訓(xùn)練精度,通常將數(shù)值歸一化映射到0-1。
x_train = x_train / 255
x_val = x_val / 255
x_test = x_test / 255
print('訓(xùn)練集傳入網(wǎng)絡(luò)的圖像尺寸:', x_train.shape)
print('驗(yàn)證集傳入網(wǎng)絡(luò)的圖像尺寸:', x_val.shape)
print('測(cè)試集傳入網(wǎng)絡(luò)的圖像尺寸:', x_test.shape)
# 圖像標(biāo)簽一共有10個(gè)類別即0-9,這里將其轉(zhuǎn)化為獨(dú)熱編碼(One-hot)向量
y_train = np_utils.to_categorical(y_train)
y_val = np_utils.to_categorical(y_val)
y_test = np_utils.to_categorical(y_test_original)
"""
定義網(wǎng)絡(luò)模型
"""
def CNN_model():
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(100, activation='relu'))
model.add(Dense(10, activation='softmax'))
print(model.summary())
return model
"""
訓(xùn)練網(wǎng)絡(luò)
"""
model = CNN_model()
# 模型網(wǎng)絡(luò)結(jié)構(gòu)圖輸出
plot_model(model, to_file='CNN_model.png', show_shapes=True, show_layer_names=True, rankdir='TB')
plt.figure(figsize=(10, 10))
img = plt.imread('CNN_model.png')
plt.imshow(img)
plt.axis('off')
plt.show()
# 編譯網(wǎng)絡(luò)(定義損失函數(shù)、優(yōu)化器、評(píng)估指標(biāo))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 開(kāi)始網(wǎng)絡(luò)訓(xùn)練(定義訓(xùn)練數(shù)據(jù)與驗(yàn)證數(shù)據(jù)、定義訓(xùn)練代數(shù),定義訓(xùn)練批大小)
train_history = model.fit(x_train, y_train, validation_data=(x_val, y_val), epochs=20, batch_size=32, verbose=2)
# 模型保存
model.save('handwritten_numeral_recognition.h5')
# 定義訓(xùn)練過(guò)程可視化函數(shù)(訓(xùn)練集損失、驗(yàn)證集損失、訓(xùn)練集精度、驗(yàn)證集精度)
def show_train_history(train_history, train, validation):
plt.plot(train_history.history[train])
plt.plot(train_history.history[validation])
plt.title('Train History')
plt.ylabel(train)
plt.xlabel('Epoch')
plt.legend(['train', 'validation'], loc='best')
plt.show()
show_train_history(train_history, 'accuracy', 'val_accuracy')
show_train_history(train_history, 'loss', 'val_loss')
# 輸出網(wǎng)絡(luò)在測(cè)試集上的損失與精度
score = model.evaluate(x_test, y_test)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
# 測(cè)試集結(jié)果預(yù)測(cè)
predictions = model.predict(x_test)
predictions = np.argmax(predictions, axis=1)
print('前20張圖片預(yù)測(cè)結(jié)果:', predictions[:20])
# 預(yù)測(cè)結(jié)果圖像可視化
def mnist_visualize_multiple_predict(start, end, length, width):
for i in range(start, end):
plt.subplot(length, width, 1 + i)
plt.imshow(x_test_original[i], cmap=plt.get_cmap('gray'))
title_true = 'true=' + str(y_test_original[i])
title_prediction = ',' + 'prediction' + str(model.predict_classes(np.expand_dims(x_test[i], axis=0)))
title = title_true + title_prediction
plt.title(title)
plt.xticks([])
plt.yticks([])
plt.show()
mnist_visualize_multiple_predict(start=0, end=9, length=3, width=3)
# 混淆矩陣
cm = confusion_matrix(y_test_original, predictions)
cm = pd.DataFrame(cm)
class_names = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
def plot_confusion_matrix(cm):
plt.figure(figsize=(10, 10))
sns.heatmap(cm, cmap='Oranges', linecolor='black', linewidth=1, annot=True, fmt='', xticklabels=class_names, yticklabels=class_names)
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.title("Confusion Matrix")
plt.show()
plot_confusion_matrix(cm)
??九、總結(jié)
??到此,深度學(xué)習(xí)的第二篇博文就完成了,這也是我寫(xiě)的第一個(gè)keras實(shí)戰(zhàn)博文,從構(gòu)思到跑程序再到完成這篇博文用了整整4個(gè)小時(shí),肩膀已經(jīng)巨酸,要去休息加干飯。
??其實(shí)有很多知識(shí)點(diǎn)限于篇幅原因沒(méi)有詳細(xì)介紹。例如Adam優(yōu)化器為什么常用?為什么使用獨(dú)熱編碼等,如果有不懂的小伙伴可以私聊我,或者有機(jī)會(huì)我會(huì)繼續(xù)介紹相關(guān)知識(shí)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-466799.html
??博主水平有限,如果有不對(duì)的地方還望多多指教,最后希望這篇文章可以幫助到任何一位想進(jìn)入深度學(xué)習(xí)的伙伴?。?!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-466799.html
到了這里,關(guān)于【深度學(xué)習(xí)實(shí)戰(zhàn)—1】:基于Keras的手寫(xiě)數(shù)字識(shí)別(非常詳細(xì)、代碼開(kāi)源)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!