日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

TensorFlow 2.0 mnist手写数字识别(CNN卷积神经网络)

發(fā)布時(shí)間:2025/3/11 125 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TensorFlow 2.0 mnist手写数字识别(CNN卷积神经网络) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

TensorFlow 2.0 (五) - mnist手寫(xiě)數(shù)字識(shí)別(CNN卷積神經(jīng)網(wǎng)絡(luò))

源代碼/數(shù)據(jù)集已上傳到?Github - tensorflow-tutorial-samples

大白話講解卷積神經(jīng)網(wǎng)絡(luò)工作原理,推薦一個(gè)bilibili的講卷積神經(jīng)網(wǎng)絡(luò)的視頻,up主從youtube搬運(yùn)過(guò)來(lái),用中文講了一遍。

這篇文章是?TensorFlow 2.0 Tutorial?入門教程的第五篇文章,介紹如何使用卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,?CNN)來(lái)提高mnist手寫(xiě)數(shù)字識(shí)別的準(zhǔn)確性。之前使用了最簡(jiǎn)單的784x10的神經(jīng)網(wǎng)絡(luò),達(dá)到了?0.91?的正確性,而這篇文章在使用了卷積神經(jīng)網(wǎng)絡(luò)后,正確性達(dá)到了0.99

卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,?CNN)是一種前饋神經(jīng)網(wǎng)絡(luò),它的人工神經(jīng)元可以響應(yīng)一部分覆蓋范圍內(nèi)的周圍單元,對(duì)于大型圖像處理有出色表現(xiàn)。

卷積神經(jīng)網(wǎng)絡(luò)由一個(gè)或多個(gè)卷積層和頂端的全連通層(對(duì)應(yīng)經(jīng)典的神經(jīng)網(wǎng)絡(luò))組成,同時(shí)也包括關(guān)聯(lián)權(quán)重和池化層(pooling layer)。這一結(jié)構(gòu)使得卷積神經(jīng)網(wǎng)絡(luò)能夠利用輸入數(shù)據(jù)的二維結(jié)構(gòu)。與其他深度學(xué)習(xí)結(jié)構(gòu)相比,卷積神經(jīng)網(wǎng)絡(luò)在圖像和語(yǔ)音識(shí)別方面能夠給出更好的結(jié)果。這一模型也可以使用反向傳播算法進(jìn)行訓(xùn)練。相比較其他深度、前饋神經(jīng)網(wǎng)絡(luò),卷積神經(jīng)網(wǎng)絡(luò)需要考量的參數(shù)更少,使之成為一種頗具吸引力的深度學(xué)習(xí)結(jié)構(gòu)。

——維基百科

1. 安裝TensorFlow 2.0

Google與2019年3月發(fā)布了TensorFlow 2.0,TensorFlow 2.0 清理了廢棄的API,通過(guò)減少重復(fù)來(lái)簡(jiǎn)化API,并且通過(guò)Keras能夠輕松地構(gòu)建模型,從這篇文章開(kāi)始,教程示例采用TensorFlow 2.0版本。

1 pip install tensorflow==2.0.0-beta0

或者在這里下載whl包安裝:https://pypi.tuna.tsinghua.edu.cn/simple/tensorflow/

2. 代碼目錄結(jié)構(gòu)

1 2 3 4 5 6 7 8 9 10 11 12 13 data_set_tf2/ # TensorFlow 2.0的mnist數(shù)據(jù)集|--mnist.npz test_images/ # 預(yù)測(cè)所用的圖片|--0.png|--1.png|--4.png v4_cnn/|--ckpt/ # 模型保存的位置|--checkpoint|--cp-0005.ckpt.data-00000-of-00001|--cp-0005.ckpt.index|--predict.py # 預(yù)測(cè)代碼|--train.py # 訓(xùn)練代碼

3. CNN模型代碼(train.py)

模型定義的前半部分主要使用Keras.layers提供的Conv2D(卷積)與MaxPooling2D(池化)函數(shù)。

CNN的輸入是維度為 (image_height, image_width, color_channels)的張量,mnist數(shù)據(jù)集是黑白的,因此只有一個(gè)color_channel(顏色通道),一般的彩色圖片有3個(gè)(R,G,B),熟悉Web前端的同學(xué)可能知道,有些圖片有4個(gè)通道(R,G,B,A),A代表透明度。對(duì)于mnist數(shù)據(jù)集,輸入的張量維度就是(28,28,1),通過(guò)參數(shù)input_shape傳給網(wǎng)絡(luò)的第一層。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import os import tensorflow as tf from tensorflow.keras import datasets, layers, modelsclass CNN(object):def __init__(self):model = models.Sequential()# 第1層卷積,卷積核大小為3*3,32個(gè),28*28為待訓(xùn)練圖片的大小model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))model.add(layers.MaxPooling2D((2, 2)))# 第2層卷積,卷積核大小為3*3,64個(gè)model.add(layers.Conv2D(64, (3, 3), activation='relu'))model.add(layers.MaxPooling2D((2, 2)))# 第3層卷積,卷積核大小為3*3,64個(gè)model.add(layers.Conv2D(64, (3, 3), activation='relu'))model.add(layers.Flatten())model.add(layers.Dense(64, activation='relu'))model.add(layers.Dense(10, activation='softmax'))model.summary()self.model = model

model.summary()用來(lái)打印我們定義的模型的結(jié)構(gòu)。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 26, 26, 32) 320 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 11, 11, 64) 18496 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 3, 3, 64) 36928 _________________________________________________________________ flatten (Flatten) (None, 576) 0 _________________________________________________________________ dense (Dense) (None, 64) 36928 _________________________________________________________________ dense_1 (Dense) (None, 10) 650 ================================================================= Total params: 93,322 Trainable params: 93,322 Non-trainable params: 0 _________________________________________________________________

我們可以看到,每一個(gè)Conv2D和MaxPooling2D層的輸出都是一個(gè)三維的張量(height, width, channels)。height和width會(huì)逐漸地變小。輸出的channel的個(gè)數(shù),是由第一個(gè)參數(shù)(例如,32或64)控制的,隨著height和width的變小,channel可以變大(從算力的角度)。

模型的后半部分,是定義輸出張量的。layers.Flatten會(huì)將三維的張量轉(zhuǎn)為一維的向量。展開(kāi)前張量的維度是(3, 3, 64) ,轉(zhuǎn)為一維(576)的向量后,緊接著使用layers.Dense層,構(gòu)造了2層全連接層,逐步地將一維向量的位數(shù)從576變?yōu)?4,再變?yōu)?0。

后半部分相當(dāng)于是構(gòu)建了一個(gè)隱藏層為64,輸入層為576,輸出層為10的普通的神經(jīng)網(wǎng)絡(luò)。最后一層的激活函數(shù)是softmax,10位恰好可以表達(dá)0-9十個(gè)數(shù)字。

最大值的下標(biāo)即可代表對(duì)應(yīng)的數(shù)字,使用numpy很容易計(jì)算出來(lái):

1 2 3 4 5 6 import numpy as npy1 = [0, 0.8, 0.1, 0.1, 0, 0, 0, 0, 0, 0] y2 = [0, 0.1, 0.1, 0.1, 0.5, 0, 0.2, 0, 0, 0] np.argmax(y1) # 1 np.argmax(y2) # 4

4. mnist數(shù)據(jù)集預(yù)處理(train.py)

1 2 3 4 5 6 7 8 9 10 11 12 13 class DataSource(object):def __init__(self):# mnist數(shù)據(jù)集存儲(chǔ)的位置,如何不存在將自動(dòng)下載data_path = os.path.abspath(os.path.dirname(__file__)) + '/../data_set_tf2/mnist.npz'(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data(path=data_path)# 6萬(wàn)張訓(xùn)練圖片,1萬(wàn)張測(cè)試圖片train_images = train_images.reshape((60000, 28, 28, 1))test_images = test_images.reshape((10000, 28, 28, 1))# 像素值映射到 0 - 1 之間train_images, test_images = train_images / 255.0, test_images / 255.0self.train_images, self.train_labels = train_images, train_labelsself.test_images, self.test_labels = test_images, test_labels

因?yàn)閙nist數(shù)據(jù)集國(guó)內(nèi)下載不穩(wěn)定,因此數(shù)據(jù)集也同步到了Github倉(cāng)庫(kù)。

對(duì)mnist數(shù)據(jù)集的介紹,大家可以參考這個(gè)系列的第一篇文章TensorFlow入門(一) - mnist手寫(xiě)數(shù)字識(shí)別(網(wǎng)絡(luò)搭建)。

5. 開(kāi)始訓(xùn)練并保存訓(xùn)練結(jié)果(train.py)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Train:def __init__(self):self.cnn = CNN()self.data = DataSource()def train(self):check_path = './ckpt/cp-{epoch:04d}.ckpt'# period 每隔5epoch保存一次save_model_cb = tf.keras.callbacks.ModelCheckpoint(check_path, save_weights_only=True, verbose=1, period=5)self.cnn.model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])self.cnn.model.fit(self.data.train_images, self.data.train_labels, epochs=5, callbacks=[save_model_cb])test_loss, test_acc = self.cnn.model.evaluate(self.data.test_images, self.data.test_labels)print("準(zhǔn)確率: %.4f,共測(cè)試了%d張圖片 " % (test_acc, len(self.data.test_labels)))if __name__ == "__main__":app = Train()app.train()

在執(zhí)行python train.py后,會(huì)得到以下的結(jié)果:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Train on 60000 samples Epoch 1/5 60000/60000 [==============================] - 45s 749us/sample - loss: 0.1477 - accuracy: 0.9536 Epoch 2/5 60000/60000 [==============================] - 45s 746us/sample - loss: 0.0461 - accuracy: 0.9860 Epoch 3/5 60000/60000 [==============================] - 50s 828us/sample - loss: 0.0336 - accuracy: 0.9893 Epoch 4/5 60000/60000 [==============================] - 50s 828us/sample - loss: 0.0257 - accuracy: 0.9919 Epoch 5/5 59968/60000 [============================>.] - ETA: 0s - loss: 0.0210 - accuracy: 0.9930 Epoch 00005: saving model to ./ckpt/cp-0005.ckpt 60000/60000 [==============================] - 51s 848us/sample - loss: 0.0210 - accuracy: 0.9930 10000/10000 [==============================] - 3s 290us/sample - loss: 0.0331 - accuracy: 0.9901 準(zhǔn)確率: 0.9901,共測(cè)試了10000張圖片

可以看到,在第一輪訓(xùn)練后,識(shí)別準(zhǔn)確率達(dá)到了0.9536,5輪之后,使用測(cè)試集驗(yàn)證,準(zhǔn)確率達(dá)到了0.9901

在第五輪時(shí),模型參數(shù)成功保存在了./ckpt/cp-0005.ckpt。接下來(lái)我們就可以加載保存的模型參數(shù),恢復(fù)整個(gè)卷積神經(jīng)網(wǎng)絡(luò),進(jìn)行真實(shí)圖片的預(yù)測(cè)了。

6. 圖片預(yù)測(cè)(predict.py)

為了將模型的訓(xùn)練和加載分開(kāi),預(yù)測(cè)的代碼寫(xiě)在了predict.py中。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import tensorflow as tf from PIL import Image import numpy as npfrom train import CNN''' python 3.7 tensorflow 2.0.0b0 pillow(PIL) 4.3.0 '''class Predict(object):def __init__(self):latest = tf.train.latest_checkpoint('./ckpt')self.cnn = CNN()# 恢復(fù)網(wǎng)絡(luò)權(quán)重self.cnn.model.load_weights(latest)def predict(self, image_path):# 以黑白方式讀取圖片img = Image.open(image_path).convert('L')img = np.reshape(img, (28, 28, 1)) / 255.x = np.array([1 - img])# API refer: https://keras.io/models/model/y = self.cnn.model.predict(x)# 因?yàn)閤只傳入了一張圖片,取y[0]即可# np.argmax()取得最大值的下標(biāo),即代表的數(shù)字print(image_path)print(y[0])print(' -> Predict digit', np.argmax(y[0]))if __name__ == "__main__":app = Predict()app.predict('../test_images/0.png')app.predict('../test_images/1.png')app.predict('../test_images/4.png')

最終,執(zhí)行predict.py,可以看到:

1 2 3 4 5 6 7 8 9 10 $ python predict.py ../test_images/0.png [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]-> Predict digit 0 ../test_images/1.png [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]-> Predict digit 1 ../test_images/4.png [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]-> Predict digit 4

與TensorFlow1.0的區(qū)別總結(jié)

  • 數(shù)據(jù)集從tensorflow.examples.tutorials.mnist切換到了tensorflow.keras.datasets
  • Keras的接口成為了主力,datasets, layers, models都是從Keras引入的,而且在網(wǎng)絡(luò)的搭建上,代碼更少,更為簡(jiǎn)潔。
  • 附: 推薦

    • 一篇文章入門 Python

    總結(jié)

    以上是生活随笔為你收集整理的TensorFlow 2.0 mnist手写数字识别(CNN卷积神经网络)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。