30行代码就可以实现看图识字!python使用tensorflow.keras搭建简单神经网络
文章目錄
- 搭建過(guò)程
- 1. 引入必需的庫(kù)
- 2. 引入數(shù)據(jù)集
- 3. 搭建神經(jīng)網(wǎng)絡(luò)層
- 4. 編譯神經(jīng)網(wǎng)絡(luò)模型
- 5. 訓(xùn)練模型
- 效果測(cè)試
大概幾個(gè)月前,神經(jīng)網(wǎng)絡(luò)、人工智能等概念在我心里仍高不可攀,直到自己親身上手之后,才發(fā)現(xiàn)搭建神經(jīng)網(wǎng)絡(luò)并不像自己想象的那么難。很幸運(yùn),我開(kāi)始學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)的時(shí)候 Tensorflow2.0已經(jīng)發(fā)布了。
Tensorflow2中內(nèi)置了Keras庫(kù),Keras是一個(gè)由Python編寫(xiě)的開(kāi)源人工神經(jīng)網(wǎng)絡(luò)庫(kù),可以作為T(mén)ensorflow、Microsoft-CNTK和Theano的高階應(yīng)用程序接口,進(jìn)行深度學(xué)習(xí)模型的設(shè)計(jì)、調(diào)試、評(píng)估、應(yīng)用和可視化。用Tensorflow2中自帶的Keras庫(kù),會(huì)使得搭建神經(jīng)網(wǎng)絡(luò)變得非常簡(jiǎn)單友好。
學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)需要的前置知識(shí)有:
- numpy(必需);
- pandas;
- matplotlib
搭建過(guò)程
接下來(lái),介紹用tensorflow.keras搭建基本神經(jīng)網(wǎng)絡(luò)模型的過(guò)程:
1. 引入必需的庫(kù)
import tensorflow as tf import numpy as np2. 引入數(shù)據(jù)集
這里的mnist數(shù)據(jù)集是tf.keras自帶的手寫(xiě)數(shù)據(jù)集,里面存有60000張28x28尺寸的黑白手寫(xiě)數(shù)字
#引入minst (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() #將讀到的每個(gè)灰度值除以255進(jìn)行歸一化,因?yàn)閗eras模型的輸入值要求在0~1之間 x_train, x_test= x_train / 255.0, x_test / 255.03. 搭建神經(jīng)網(wǎng)絡(luò)層
- Flatten層用于將二維數(shù)組展開(kāi),相當(dāng)于把圖片按照每一行鋪平;
- Dense層就是所謂的全連接神經(jīng)網(wǎng)絡(luò)層,第一個(gè)參數(shù)是神經(jīng)元的數(shù)量,第二個(gè)參數(shù)是激活函數(shù)的類型;
- relu函數(shù)是一種線性整流函數(shù),在神經(jīng)網(wǎng)絡(luò)中有廣泛的使用;
- softmax是一種邏輯回歸函數(shù),常用于多分類問(wèn)題,可以使輸出值符合概率分布,神經(jīng)元數(shù)量為10,代表會(huì)輸出10個(gè)元素的列表,列表的每個(gè)元素相加為1,列表中的每個(gè)元素正好符合對(duì)應(yīng)數(shù)字的概率(數(shù)字有0~9十種)
這就是softmax函數(shù),可以看到對(duì)于任意x,其對(duì)應(yīng)的y值都在-1~1之間,從而實(shí)現(xiàn)數(shù)據(jù)的歸一化。
4. 編譯神經(jīng)網(wǎng)絡(luò)模型
- 第一個(gè)參數(shù)指定優(yōu)化器為adam,adam結(jié)合了自適應(yīng)梯度算法和均方根傳播,是一個(gè)非常強(qiáng)大的優(yōu)化器
- 指定損失函數(shù)的計(jì)算方法為交叉熵,from_logits=False表示數(shù)據(jù)不是原始輸出,即數(shù)據(jù)滿足概率分布,因?yàn)槲覀儾捎胹oftmax作為輸出層,因此結(jié)果是概率分布的
- 指定準(zhǔn)確率計(jì)算方法為多分類準(zhǔn)確率
5. 訓(xùn)練模型
- 第一個(gè)參數(shù)表示輸入的訓(xùn)練集,第二個(gè)參數(shù)表示訓(xùn)練集本身對(duì)應(yīng)的結(jié)果,神經(jīng)網(wǎng)絡(luò)可以通過(guò)判斷自己得出的結(jié)果與原來(lái)給定的結(jié)果是否相同,來(lái)不斷優(yōu)化自己的判斷;
- batch_size表示每次喂入的數(shù)據(jù)量,mnist數(shù)據(jù)集中有60000張圖片,顯然不能一次喂入;
- epochs表示訓(xùn)練次數(shù);
- validation_data表示驗(yàn)證用的數(shù)據(jù)集,驗(yàn)證集并不參與訓(xùn)練,因此用驗(yàn)證集判斷模型的準(zhǔn)確率是客觀有效的;
- validation_freq表示驗(yàn)證頻率,即多少次訓(xùn)練會(huì)做一次驗(yàn)證
到這里,一個(gè)完整的簡(jiǎn)單神經(jīng)網(wǎng)絡(luò)就搭建完成了,我們可以欣賞一下輸出結(jié)果,這里只截取了第1次和最后2次訓(xùn)練的部分內(nèi)容,以節(jié)省篇幅。
可以看到,每次喂入數(shù)據(jù)之后,都顯示出了訓(xùn)練集的loss誤差和accuracy準(zhǔn)確率,而當(dāng)每次訓(xùn)練完成時(shí)會(huì)進(jìn)行一次驗(yàn)證,計(jì)算出驗(yàn)證集的誤差和準(zhǔn)確率。
我們還發(fā)現(xiàn)一個(gè)現(xiàn)象,第一次訓(xùn)練時(shí),每次喂入數(shù)據(jù)都使得loss誤差快速下降,正確率上升,而到最后幾次訓(xùn)練時(shí),由于準(zhǔn)確率已經(jīng)很高,想要繼續(xù)優(yōu)化模型變得困難,準(zhǔn)確率便上下波動(dòng),不再持續(xù)上升:
Epoch 1/101/1875 [..............................] - ETA: 0s - loss: 2.4223 - sparse_categorical_accuracy: 0.0625277/1875 [===>..........................] - ETA: 2s - loss: 0.5614 - sparse_categorical_accuracy: 0.8380567/1875 [========>.....................] - ETA: 1s - loss: 0.4153 - sparse_categorical_accuracy: 0.8792814/1875 [============>.................] - ETA: 1s - loss: 0.3604 - sparse_categorical_accuracy: 0.8956 1107/1875 [================>.............] - ETA: 1s - loss: 0.3189 - sparse_categorical_accuracy: 0.9070 1367/1875 [====================>.........] - ETA: 0s - loss: 0.2925 - sparse_categorical_accuracy: 0.9150 1592/1875 [========================>.....] - ETA: 0s - loss: 0.2761 - sparse_categorical_accuracy: 0.9197 1875/1875 [==============================] - 3s 2ms/step - loss: 0.2577 - sparse_categorical_accuracy: 0.9250 - val_loss: 0.1379 - val_sparse_categorical_accuracy: 0.9584 Epoch 9/101/1875 [..............................] - ETA: 0s - loss: 0.0043 - sparse_categorical_accuracy: 1.0000347/1875 [====>.........................] - ETA: 2s - loss: 0.0174 - sparse_categorical_accuracy: 0.9986634/1875 [=========>....................] - ETA: 1s - loss: 0.0173 - sparse_categorical_accuracy: 0.9965922/1875 [=============>................] - ETA: 1s - loss: 0.0176 - sparse_categorical_accuracy: 0.9945959/1875 [==============>...............] - ETA: 1s - loss: 0.0177 - sparse_categorical_accuracy: 0.9944 1286/1875 [===================>..........] - ETA: 0s - loss: 0.0182 - sparse_categorical_accuracy: 0.9943 1501/1875 [=======================>......] - ETA: 0s - loss: 0.0187 - sparse_categorical_accuracy: 0.9943 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0193 - sparse_categorical_accuracy: 0.9942 - val_loss: 0.0879 - val_sparse_categorical_accuracy: 0.9763 Epoch 10/101/1875 [..............................] - ETA: 0s - loss: 0.0164 - sparse_categorical_accuracy: 0.9995322/1875 [====>.........................] - ETA: 2s - loss: 0.0131 - sparse_categorical_accuracy: 0.9986610/1875 [========>.....................] - ETA: 1s - loss: 0.0138 - sparse_categorical_accuracy: 0.9976 999/1875 [==============>...............] - ETA: 1s - loss: 0.0146 - sparse_categorical_accuracy: 0.9970 1248/1875 [==================>...........] - ETA: 0s - loss: 0.0147 - sparse_categorical_accuracy: 0.9965 1285/1875 [===================>..........] - ETA: 0s - loss: 0.0148 - sparse_categorical_accuracy: 0.9959 1536/1875 [=======================>......] - ETA: 0s - loss: 0.0153 - sparse_categorical_accuracy: 0.9954 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0157 - sparse_categorical_accuracy: 0.9952 - val_loss: 0.0804 - val_sparse_categorical_accuracy: 0.9789到這里,我們的模型就輸入完成了,只需要提供一個(gè)輸入圖片的函數(shù),便可以完成看圖識(shí)別數(shù)字的任務(wù):
import PIL.Image #使用PIL庫(kù)處理圖片def judge_image(path): """輸入圖片的路徑,判斷圖片中的數(shù)字是什么"""#打開(kāi)圖片img = Image.open(path) #改變尺寸為28x28,因?yàn)橛?xùn)練集的圖片大小就是28x28img = img.resize((28, 28)) #img.convert用于處理圖像,L表示轉(zhuǎn)換成灰度圖#將灰度圖的像素信息排列成array存儲(chǔ)img_array = np.array(img.convert('L'))#遍歷每一個(gè)像素,進(jìn)行二值化處理,即把灰度圖轉(zhuǎn)換成純黑白圖,以便于模型判斷for row in range(28):for col in range(28):#如果像素偏白,就轉(zhuǎn)為純黑色if img_array[row][col] < 75:img_array[row][col] = 255#如果像素偏黑,就轉(zhuǎn)為純白色else:img_array[row][col] = 0#將輸入值歸一化,滿足模型輸入要求img_array = img_array / 255.0 #由于數(shù)據(jù)是以batch的形式喂入模型,我們需要給數(shù)據(jù)集添加一個(gè)維度#將img_array:(28,28)變?yōu)閤_predict:(1,28,28),1代表數(shù)據(jù)量為1張圖x_predict = img_array[tf.newaxis]result = model.predict(x_predict) #利用模型進(jìn)行預(yù)測(cè)#返回索引為1的值,result中索引為1剛好是預(yù)測(cè)結(jié)果predict = tf.argmax(result, axis=1)tf.print(predict)這樣,完整的代碼就完成了:
import tensorflow as tf import numpy as np import PIL(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() x_train, x_test= x_train / 255.0, x_test / 255.0model = tf.keras.Sequential([tf.keras.layers.Flatten(),tf.keras.layers.Dense(128, activation='relu'),tf.keras.layers.Dense(10, activation='softmax')])model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['sparse_categorical_accuracy'])model.fit(x_train, y_train, batch_size=32, epochs=10,validation_data=(x_test, y_test), validation_freq=1)def judge_image(path):img = PIL.Image.open(path)img = img.resize((28, 28))img_array = np.array(img.convert('L'))for row in range(28):for col in range(28):if img_array[row][col] < 75:img_array[row][col] = 255else:img_array[row][col] = 0img_array = img_array / 255x_predict = img_array[tf.newaxis]result = model.predict(x_predict)predict = tf.argmax(result, axis=1)tf.print(predict)效果測(cè)試
我們來(lái)試一下預(yù)測(cè)效果,我準(zhǔn)備了幾張手寫(xiě)數(shù)字的圖片:
img_2.gif
img_5.gif
img_8.gif
輸出結(jié)果為:
The recognized figure of img_2.gif: [2] The recognized figure of img_5.gif: [5] The recognized figure of img_8.gif: [8]可以看到,每張圖片所對(duì)應(yīng)的數(shù)字都被識(shí)別出來(lái)啦!
總結(jié)
以上是生活随笔為你收集整理的30行代码就可以实现看图识字!python使用tensorflow.keras搭建简单神经网络的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: zabbix微信告警HTML,ZABBI
- 下一篇: layui - 页面元素