日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tensorflow 神经网络作业手写数字识别 训练、回测准确率

發布時間:2025/3/11 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Tensorflow 神经网络作业手写数字识别 训练、回测准确率 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

?

大白話講解卷積神經網絡工作原理,推薦一個bilibili的講卷積神經網絡的視頻,up主從youtube搬運過來,用中文講了一遍。

這篇文章是?TensorFlow 2.0 Tutorial?入門教程的第五篇文章,介紹如何使用卷積神經網絡(Convolutional Neural Network,?CNN)來提高mnist手寫數字識別的準確性。之前使用了最簡單的784x10的神經網絡,達到了?0.91?的正確性,而這篇文章在使用了卷積神經網絡后,正確性達到了0.99

卷積神經網絡(Convolutional Neural Network,?CNN)是一種前饋神經網絡,它的人工神經元可以響應一部分覆蓋范圍內的周圍單元,對于大型圖像處理有出色表現。

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

——維基百科

1. 安裝TensorFlow 2.0

Google與2019年3月發布了TensorFlow 2.0,TensorFlow 2.0 清理了廢棄的API,通過減少重復來簡化API,并且通過Keras能夠輕松地構建模型,從這篇文章開始,教程示例采用TensorFlow 2.0版本。

1

pip install tensorflow==2.0.0-beta0

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

2. 代碼目錄結構

1
2
3
4
5
6
7
8
9
10
11
12
13

data_set_tf2/ ?# TensorFlow 2.0的mnist數據集
????|--mnist.npz ?
test_images/ ??# 預測所用的圖片
????|--0.png
????|--1.png
????|--4.png
v4_cnn/
????|--ckpt/ ??# 模型保存的位置
????????|--checkpoint
????????|--cp-0005.ckpt.data-00000-of-00001
????????|--cp-0005.ckpt.index
????|--predict.py ?# 預測代碼
????|--train.py ???# 訓練代碼

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

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

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

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, models


class?CNN(object):
????def?__init__(self):
????????model = models.Sequential()
????????# 第1層卷積,卷積核大小為3*3,32個,28*28為待訓練圖片的大小
????????model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
????????model.add(layers.MaxPooling2D((2, 2)))
????????# 第2層卷積,卷積核大小為3*3,64個
????????model.add(layers.Conv2D(64, (3, 3), activation='relu'))
????????model.add(layers.MaxPooling2D((2, 2)))
????????# 第3層卷積,卷積核大小為3*3,64個
????????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()用來打印我們定義的模型的結構。

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
_________________________________________________________________

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

模型的后半部分,是定義輸出張量的。layers.Flatten會將三維的張量轉為一維的向量。展開前張量的維度是(3, 3, 64) ,轉為一維(576)的向量后,緊接著使用layers.Dense層,構造了2層全連接層,逐步地將一維向量的位數從576變為64,再變為10。

后半部分相當于是構建了一個隱藏層為64,輸入層為576,輸出層為10的普通的神經網絡。最后一層的激活函數是softmax,10位恰好可以表達0-9十個數字。

最大值的下標即可代表對應的數字,使用numpy很容易計算出來:

1
2
3
4
5
6

import?numpy as?np

y1 = [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數據集預處理(train.py)

1
2
3
4
5
6
7
8
9
10
11
12
13

class?DataSource(object):
????def?__init__(self):
????????# mnist數據集存儲的位置,如何不存在將自動下載
????????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萬張訓練圖片,1萬張測試圖片
????????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.0

????????self.train_images, self.train_labels = train_images, train_labels
????????self.test_images, self.test_labels = test_images, test_labels

5. 開始訓練并保存訓練結果(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("準確率: %.4f,共測試了%d張圖片 "?% (test_acc, len(self.data.test_labels)))


if?__name__ == "__main__":
????app = Train()
????app.train()

在執行python train.py后,會得到以下的結果:

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
準確率: 0.9901,共測試了10000張圖片

可以看到,在第一輪訓練后,識別準確率達到了0.9536,5輪之后,使用測試集驗證,準確率達到了0.9901

在第五輪時,模型參數成功保存在了./ckpt/cp-0005.ckpt。接下來我們就可以加載保存的模型參數,恢復整個卷積神經網絡,進行真實圖片的預測了。

6. 圖片預測(predict.py)

為了將模型的訓練和加載分開,預測的代碼寫在了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?np

from?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()
????????# 恢復網絡權重
????????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)

????????# 因為x只傳入了一張圖片,取y[0]即可
????????# np.argmax()取得最大值的下標,即代表的數字
????????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')

最終,執行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

?

總結

以上是生活随笔為你收集整理的Tensorflow 神经网络作业手写数字识别 训练、回测准确率的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。