markdown
#說明
這個題目是很多人拿來當作學習神經網路的第一課,其實這個例子真的可以學習到很多,網路上也有很多善心人士分享自己的 code,我想我也只是運用他們的code,加上一些註解,幫助學習,這個題目是辨識手寫的數字,其實手寫數字會是用神經網路來解決是有原因的,除了手寫數字還有另外一種,七段顯示器的數字,如果遇到的是七段顯示器數字可以用影像處理的方式去解答,但手寫數字每一個字長的沒有那麼規則,而也因此使用神經網路。
這裡先來一張Mnist 裡面的手寫數字圖
#操作流程
##CODE
```
# 導入函式庫
import numpy as np
from keras.models import Sequential
from keras.datasets import mnist
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.utils import np_utils # 用來後續將 label 標籤轉為 one-hot-encoding
from matplotlib import pyplot as plt
import cv2
# 載入 MNIST 資料庫的訓練資料,並自動分為『訓練組』及『測試組』
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print(X_test.shape)
print(y_test.shape)
#cv2.imwrite('C:/Users/User/Desktop/output.jpg', X_test[1])
# 建立簡單的線性執行的模型
model = Sequential()
# Add Input layer, 隱藏層(hidden layer) 有 256個輸出變數
model.add(Dense(units=256, input_dim=784, kernel_initializer='normal', activation='relu'))
# Add output layer
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
# 編譯: 選擇損失函數、優化方法及成效衡量方式
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 將 training 的 label 進行 one-hot encoding,例如數字 7 經過 One-hot encoding 轉換後是 0000001000,即第7個值為 1
y_TrainOneHot = np_utils.to_categorical(y_train)
y_TestOneHot = np_utils.to_categorical(y_test)
# 將 training 的 input 資料轉為2維
X_train_2D = X_train.reshape(60000, 28*28).astype('float32')
X_test_2D = X_test.reshape(10000, 28*28).astype('float32')
print("X_test_2D: ",X_test_2D.shape)
x_Train_norm = X_train_2D/255
x_Test_norm = X_test_2D/255
# 進行訓練, 訓練過程會存在 train_history 變數中
train_history = model.fit(x=x_Train_norm, y=y_TrainOneHot, validation_split=0.2, epochs=10, batch_size=800, verbose=2)
# 顯示訓練成果(分數)
scores = model.evaluate(x_Test_norm, y_TestOneHot)
print()
print("\t[Info] Accuracy of testing data = {:2.1f}%".format(scores[1]*100.0))
# 預測(prediction)
X = x_Test_norm[0:10,:]
predictions = model.predict_classes(X)
# get prediction result
print(predictions)
img=cv2.imread('C:/Users/User/Desktop/7.png', cv2.IMREAD_GRAYSCALE)
crop_size = (28, 28)
img = cv2.resize(img, crop_size, interpolation = cv2.INTER_CUBIC)
# 顯示圖片
cv2.imshow('My Image', img)
# 按下任意鍵則關閉所有視窗
cv2.waitKey(0)
cv2.destroyAllWindows()
img_2D = img.reshape(1,28*28).astype('float32')
img_norm=img_2D/255
img = img_norm
predictions = model.predict_classes(img)
# get prediction result
print(predictions)
```
##說明一
剛剛看的出來 圖片是 28 *28 的,接下來也要把我們要預測的圖片的大小也要是 28*28
##說明二
- 參考:https://blog.csdn.net/DocStorm/article/details/58593682
這裡它就是把它原本是正方形的壓平變成 長條狀的,這個在每一種題目當中不一定都要做這件事情,只是這裡作者選擇要這樣做,所以我們之後丟進來的圖片也要做這件事情
##說明四
還有做正規化,補充一下,這個選擇除以255,是因為255 就是陣列中會出現的最大值,所以它希望值變得相對簡單一點,變成 0~1之間,原本是 0~255
,所以我們新丟的資料也要正規化通通除以 255
##說明五
了解完上面那些,就是全部我們要做的事情了,接著就是讀進一張圖片,做上面的事情 之後做預測,就完成囉
##說明六
可以手寫其它的圖片進去試試看,這邊有測試幾張,有些會不準確,
所以去找不準確的原因,發現它的訓練圖片幾乎都是黑色底白色字,所以我自己重新寫一張黑色底白色字的它就預測正確
但是如果不是黑底白字 預測錯的機率很高
###參考:
- MNIST 手寫數字資料集
- 七段顯示器
- 撰寫第一支 Neural Network 程式 -- 阿拉伯數字辨識
請問我照您的做法 但是出現了 error: C:\ci\opencv_1512688052760\work\modules\imgproc\src\resize.cpp:3289: error: (-215) ssize.width > 0 && ssize.height > 0 in function cv::resize
回覆刪除請問是哪邊有錯呢