CNN實現手寫數字識別並改變引數進行分析

ckxllf發表於2019-12-19

  1.網路層級結構概述

  Input layer: 輸入資料為原始訓練影像

  Conv1:6 個 5 * 5 的卷積核,步長 Stride 為 1

  Pooling1:卷積核 size 為 2 * 2,步長 Stride 為 2

  Conv2:12 個 5 * 5 的卷積核,步長 Stride 為 1

  Pooling2:卷積核 size 為 2 * 2,步長 Stride 為 2

  Output layer:輸出為 10 維向量

  2.實驗基本流程

  (1)獲取訓練資料和測試資料

  直接使用keras裡面的手寫資料集

  from keras.datasets import mnist

  (x_train, y_train), (x_test, y_test) = mnist.load_data()

  (2)定義網路層級結構

  程式碼:

  def get_model():

  model = Sequential()

  model.add(Conv2D(filters=6, kernel_size=(5, 5),strides=1,activation='relu',input_shape=(28, 28, 1)))

  model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

  model.add(Conv2D(filters=12, kernel_size=(5, 5),strides=1,activation='relu'))

  model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

  model.add(Flatten())

  #model.add(Conv2D(filters=120, kernel_size=(5, 5),activation='relu'))

  model.add(Dense(120, activation='relu'))

  model.add(Dense(84, activation='relu'))

  model.add(Dropout(0.5))

  model.add(Dense(10, activation='softmax'))

  # 編譯模型,採用多分類的損失函式,最佳化器是Adadelta

  model.compile(loss='categorical_crossentropy',

  optimizer='Adadelta',

  metrics=['accuracy'])

  return model

  (3)交叉驗證

  直接附上程式碼

  def k_cross(data,target,bsize,epoch,sp):

  print("------進行交叉驗證------")

  ans=0 #交叉驗證正確率的和

  kf = KFold(n_splits=sp, shuffle = True)

  for train, test in kf.split(data):

  model.fit(data[train], target[train],

  batch_size=bsize,

  epochs=epoch,

  verbose=0,

  validation_data=(data[test], target[test]))

  score = model.evaluate(data[test], target[test], verbose=0)

  ans+=score[1]

  return ans/sp

  3完整程式碼

  我這裡直接就3折了,太多了執行時間太長。

  最後完整程式碼:

  # -*- coding: utf-8 -*-

  """

  Created on Tue Dec 10 15:42:27 2019

  @author: pff

  """

  from __future__ import print_function

  import numpy as np

  import keras

  from keras.datasets import mnist

  from keras.models import Sequential

  from keras.layers import Dense, Dropout, Flatten

  from keras.layers import Conv2D, MaxPooling2D

  from sklearn.model_selection import KFold

  import matplotlib.pyplot as plt

  def getdata():

  #提取出訓練集和測試集

  (x_train, y_train), (x_test, y_test) = mnist.load_data()

  x_train = x_train.astype('float32')

  x_test = x_test.astype('float32')

  x_train /= 255

  x_test /= 255

  x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)

  x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)

  # 採用one-hot編碼

  y_train = keras.utils.to_categorical(y_train, 10)

  y_test = keras.utils.to_categorical(y_test, 10)

  #將測試集和訓練集合並,便於後面交叉驗證

  data = np.row_stack((x_train,x_test))

  target = np.row_stack((y_train,y_test))

  return data, target

  # 構建模型

  def get_model():

  model = Sequential() 鄭州做無痛人流手術費用

  model.add(Conv2D(filters=6, kernel_size=(5, 5),strides=1,activation='relu',input_shape=(28, 28, 1)))

  model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

  model.add(Conv2D(filters=12, kernel_size=(5, 5),strides=1,activation='relu'))

  model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

  model.add(Flatten())

  #model.add(Conv2D(filters=120, kernel_size=(5, 5),activation='relu'))

  model.add(Dense(120, activation='relu'))

  model.add(Dense(84, activation='relu'))

  model.add(Dropout(0.5))

  model.add(Dense(10, activation='softmax'))

  # 編譯模型,採用多分類的損失函式,用 Adadelta 演算法做最佳化方法

  model.compile(loss='categorical_crossentropy',

  optimizer='Adadelta',

  metrics=['accuracy'])

  return model

  def kcross(data,target,bsize,epoch,sp):

  print("------進行交叉驗證------")

  ans=0

  kf = KFold(n_splits=sp, shuffle = True)

  for train, test in kf.split(data):

  #print("第{}次開始".format(i+1))

  model.fit(data[train], target[train],

  batch_size=bsize,

  epochs=epoch,

  verbose=0,

  validation_data=(data[test], target[test]))

  score = model.evaluate(data[test], target[test], verbose=0)

  ans+=score[1]

  return ans/sp

  #畫結果圖

  def draw(batch_size,y,epoch):

  plt.figure()

  plt.rcParams['font.sans-serif']='SimHei'

  plt.ylabel('正確率')

  plt.xlabel('batch_size')

  plt.title('不同引數下卷積神經網路數字識別圖')

  for i in range(len(y)):

  plt.scatter(batch_size, y[i], s=30, c='r', marker='x', linewidths=1)

  plt.plot(batch_size,y[i],label="epoch:"+str(epoch[i]))

  plt.legend()

  plt.show()

  if __name__=="__main__":

  data,target=getdata()

  model=get_model()

  '''

  設定epoch和baitch_size引數

  y:儲存每一次的結果

  '''

  epoch=[1,3,5,7]

  size=[50,100,150,200,250]

  y=np.zeros([4,5])

  for i in range(len(epoch)):

  for j in range(len(size)):

  print("now:",i,j)

  y[i,j]=kcross(data,target,size[j],epoch[i],3)

  draw(size,y,epoch)

  最後得出執行結果


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2669410/,如需轉載,請註明出處,否則將追究法律責任。

相關文章