Keras中實現mnist神經網絡訓練與模型保存(採用LeNet-5模型)

需要安裝cv2

http://blog.csdn.net/gjq246/article/details/71554157


安裝模型圖片導出模塊

sudo pip install pydot

sudo pip install graphviz

sudo pip install pydot-ng

sudo apt-get install graphviz


安裝h5py的命令如下(模型保存模塊):
sudo pip install cython
sudo apt-get install libhdf5-dev

sudo pip install h5py


# -*- coding: UTF-8 -*-

#mnist神經網絡訓練,採用LeNet-5模型

import os  
import cv2  
import numpy as np 

from keras.models import Sequential  
from keras.layers import Conv2D, MaxPooling2D, Flatten  
from keras.layers.core import Dense, Dropout, Activation, Flatten  
from keras.layers.advanced_activations import PReLU  
from keras.optimizers import SGD, Adadelta, Adagrad
  
from keras.utils import np_utils  
from keras.utils.vis_utils import plot_model  

import h5py 
from keras.models import model_from_json

def loadData(path,number):  
    data =  np.empty((number,1,28,28),dtype="float32")   #empty與ones差不多原理,但是數值隨機,類型隨後面設定 
    labels = np.empty((number,),dtype="uint8")   
    listImg = os.listdir(path) 
    count=0 
    for img in listImg:  
       imgData=cv2.imread(path+'/'+img, 0) #數據
       l=int(img.split('-')[0]) #答案
       arr = np.asarray(imgData,dtype="float32")  #將img數據轉化爲數組形式  
       data[count,:,:,:] = arr   #將每個三維數組賦給data  
       labels[count] = l   #取該圖像的數值屬性作爲標籤  
       count=count+1
       print path," loaded ",count
       if count>=number:
          break
    return data, labels  

 
#從圖片文件加載數據 
trainData, trainLabels = loadData('./mnisttrain',60000)  
testData, testLabels = loadData('./mnisttest',10000)  
trainLabels = np_utils.to_categorical(trainLabels, 10)
#label爲0~9共10個類別,keras要求格式爲binary class matrices,轉化一下,直接調用keras提供的這個函數  
testLabels = np_utils.to_categorical(testLabels, 10)  

# tf或th爲後端,採取不同參數順序
#th
#if K.image_data_format() == 'channels_first':
    # -x_train.shape[0]=6000
 #   x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    # -x_train.shape:(60000, 1, 28, 28)
  #  x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    # x_test.shape:(10000, 1, 28, 28)
    # 單通道灰度圖像,channel=1
   # input_shape = (1, img_rows, img_cols)
#else:    #tf
 #   x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
  #  x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
   # input_shape = (img_rows, img_cols, 1)

#tensorflow後端
trainData = trainData.reshape(trainData.shape[0], 28, 28, 1)
testData = testData.reshape(testData.shape[0], 28, 28, 1)

#建立一個Sequential模型  
model = Sequential()  
  
#model.add(Conv2D(4, 5, 5, border_mode='valid',input_shape=(28,28,1)))    
#第一個卷積層,4個卷積核,每個卷積核5*5,卷積後24*24,第一個卷積核要申明input_shape(通道,大小) ,激活函數採用“tanh”  
model.add(Conv2D(filters=4, kernel_size=(5,5), padding='valid', input_shape=(28,28,1), activation='tanh')) 
 
  
#model.add(Conv2D(8, 3, 3, subsample=(2,2), border_mode='valid'))   
#第二個卷積層,8個卷積核,不需要申明上一個卷積留下來的特徵map,會自動識別,下采樣層爲2*2,卷完且採樣後是11*11  
model.add(MaxPooling2D(pool_size=(2,2)))  
model.add(Conv2D(filters=8, kernel_size=(3,3), padding='valid', activation='tanh'))
#model.add(Activation('tanh'))  
  
#model.add(Conv2D(16, 3, 3, subsample=(2,2), border_mode='valid'))   
#第三個卷積層,16個卷積核,下采樣層爲2*2,卷完採樣後是4*4  
model.add(Conv2D(filters=16, kernel_size=(3,3), padding='valid', activation='tanh'))
model.add(MaxPooling2D(pool_size=(2,2)))  
#model.add(Activation('tanh'))  
  
model.add(Flatten())   
#把多維的模型壓平爲一維的,用在卷積層到全連接層的過度
  
#model.add(Dense(128, input_dim=(16*4*4), init='normal'))   
#全連接層,首層的需要指定輸入維度16*4*4,128是輸出維度,默認放第一位 
model.add(Dense(128, activation='tanh'))  

#model.add(Activation('tanh'))  
  
#model.add(Dense(10, input_dim= 128, init='normal'))   
#第二層全連接層,其實不需要指定輸入維度,輸出爲10維,因爲是10類 
model.add(Dense(10, activation='softmax')) 
#model.add(Activation('softmax'))   
#激活函數“softmax”,用於分類  
  
#訓練CNN模型   
  
sgd = SGD(lr=0.05, momentum=0.9, decay=1e-6, nesterov=True)   
#採用隨機梯度下降法,學習率初始值0.05,動量參數爲0.9,學習率衰減值爲1e-6,確定使用Nesterov動量  
model.compile(loss='categorical_crossentropy', optimizer=sgd,metrics=['accuracy'])   
#配置模型學習過程,目標函數爲categorical_crossentropy:亦稱作多類的對數損失,注意使用該目標函數時,需要將標籤轉化爲形如(nb_samples, nb_classes)的二值序列,第18行已轉化,優化器爲sgd  

model.fit(trainData, trainLabels, batch_size=100,epochs=20,shuffle=True,verbose=1,validation_split=0.2)   
#訓練模型,訓練nb_epoch次,bctch_size爲梯度下降時每個batch包含的樣本數,驗證集比例0.2,verbose爲顯示日誌,shuffle是否打亂輸入樣本的順序  

#輸出模型圖片
plot_model(model, to_file='model2.png', show_shapes=True, show_layer_names=False)  

print model.metrics_names
# 對測試數據進行測試
print model.evaluate(testData, testLabels,
          verbose=0,
          batch_size=500);

#保存model
json_string = model.to_json()  
open('my_model_architecture.json','w').write(json_string)  
model.save_weights('my_model_weights.h5') 






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章