一、准備工作
1.打開本鏈接,其中代碼可以直接粘貼使用。
conda install scikit-learn
conda install tensorflow
pip install keras
import numpy as np #數據庫 import keras import tensorflow as tf from keras.models import Sequential #序貫模型 from keras.layers.core import Dense,Dropout,Activation #構建 keras網絡結構 from keras.optimizers import SGD #SGD隨機梯度下降 import matplotlib.pyplot as plt #畫圖
二、基於keras手寫數字識別基本步驟
2.1導入數據-》2.2構建模型-》2.3訓練模型-》2.4評估模型
2.1、讀取mnist數據集(詳見PPT),並格式轉換
第一種方法:聯網下載mnist數據集
from keras.datasets import mnist #網上下載minist數據集,若聯網使用數據集
(x_train, y_train), (x_test, y_test) = mnist.load_data() # 使用Keras自帶的mnist工具讀取數據,由於網址會被隔斷,需要翻牆。
第二種方法:本地下載mnist數據集
path='./mnist.npz' f = np.load(path) x_train, y_train = f['x_train'], f['y_train'] #x_train存儲的是圖像的像素點組成的list數據類型,這里面又由一個二維的list(28 x 28的像素點值)和一個對應的標簽list組成 #y_train存儲的是對應圖像的標簽,也就是該圖像代表什么數字 x_test, y_test = f['x_test'], f['y_test'] f.close()
格式轉換:
x_train=x_train.reshape(x_train.shape[0],28*28).astype('float32') x_test=x_test.reshape(x_test.shape[0],28*28).astype('float32') #x_train.shape會發現它是(60000,28,28),即一共60000個數據,每個數據是28*28的圖片。通過reshape轉換為(60000,784)的線性張量。 num_classes=10 y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) #如果我們打印y_train會發現它是一組表示每張圖片的表示數字的數組,每個數字轉換為一組長度為10的張量,代表的數字的位置是1,其它位置為0.
2.2 、構建模型:Sequential()序貫模型
#通常有兩種模型,序貫模型和函數式模型,序貫模型是多個網絡蹭的線性堆疊,是函數式模型的簡略版,為最簡單的線性,從頭到尾的結構順序,不發生分叉。是多個網絡層的線性堆疊。
#參考:https://www.cnblogs.com/wj-1314/p/9967480.html
#選擇模型 model = Sequential() ##選擇Sequetial 序貫模型 #構建網絡層 #第1層 隱藏層 model.add(Dense(500,input_shape=(784,)))#這是第一個隱藏層,並附帶定義了輸入層,該隱含層有500個神經元。輸入則是 784個節點 model.add(Activation('tanh')) # 激活函數是tanh 為雙曲正切 model.add(Dropout(0.5)) # 隨機取一半進行訓練 ##第2層 隱藏層 model.add(Dense(200)) #隱藏節點200 model.add(Activation('tanh')) #激活函數 正切函數 model.add(Dropout(0.5)) #隨機丟掉百分之五十的權值,作用相當於對參數進行正則化來防止模型過擬合 ##第3層 輸出層 model.add(Dense(10))#輸出結果是10個類別,所以維度是10 model.add(Activation('softmax')) #激活函數 歸一化softmax model.summary()
通過model.add()增加模型的層數。其中Dense()設定該層的結構,第一個參數表示輸出的個數,第二個參數是接受的輸入數據的格式。第一層中需要指定輸入的格式,在之后的增加的層中輸入層節點數默認是上一層的輸出個數。Activation()指定激活函數,Dropout()指定每層要丟掉的權值信息百分比。輸出層激活函數一般為softmax,不需要丟棄節點。
編譯模型:
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) # 優化函數,設定學習率(lr)等參數 # lr:學習率 # momentum:動量參數 # decay:每次更新后的學習率衰減值 # nesterov:確定是否使用Nesterov動量(指數1e-9) #有通過了編譯,model才真正的建立起來,這時候才能夠被使用 model.compile(optimizer=sgd,loss='categorical_crossentropy', metrics=['accuracy']) # 使用交叉熵作為loss函數
2.3、訓練模型:
#訓練 print("start model training(fitting)") model.fit(x_train,y_train,batch_size=500,epochs=50,shuffle=True,verbose=0,validation_split=0.3) #fit的一些參數 # batch_size:對總的樣本數進行分組,每組包含的樣本數量 # epochs :訓練次數 #shuffle:是否把數據隨機打亂之后再進行訓練 #verbose:屏顯模式 0:不輸出 1:輸出進度 2:輸出每次的訓練結果 #validation_split:拿出百分之多少用來做交叉驗證 print("model training(fitting) finished, save model") model.save('./now_model.h5')
2.4 、評估模型
print("calculating model accuracy") loss, accuracy = model.evaluate(x_test,y_test,batch_size=500,verbose=0) #evaluate是在每個batch后得到一個值,而predict是在k個batch后得到的一個均值。 print('Test loss:', loss) print('Accuracy:', accuracy)
三、用戶測評
3.1 導入相應的函數
import keras from keras.models import load_model #加載模型 from keras.optimizers import SGD #優化函數 from PIL import Image import numpy as np #數據庫 import matplotlib.pyplot as plt #畫圖
# 准備待識別的圖片數據 testImage=Image.open("test3.jpg") testImage=testImage.convert("L") testImageForModel=np.array(testImage) plt.subplot(221) #subplot函數的作用是確定圖像的位置以及圖像的個數,總共放置2*2個圖片,放在第一個位置 plt.imshow(testImage, cmap=plt.get_cmap('gray')) testImageForModelFinal=testImageForModel.reshape(1,28*28).astype('float32') #轉成可以輸入到模型中的格式x_test_input,x_test是可以直接使用cv2顯示處理
3.2加載模型,識別數字結果
#加載模型,使用該模型識別數字圖片 model=load_model('./now_model.h5') sgd=SGD(lr=0.01,momentum=0.9,decay=1e-9,nesterov=True)#優化函數,參數有學習率,學習衰退率 ,指數1e-9這樣寫 model.compile(optimizer=sgd,loss='categorical_crossentropy') # 使用交叉熵作為loss函數 print("finshing loading model,starting application")
ans=model.predict(testImageForModelFinal) #輸入該數據到模型,得到預測結果的概率 print(ans) ansmax=np.argmax(ans) #找到每行最大的序號 print(ansmax)