keras 人工智能之VGGNet神經網絡模型訓練

上期文章我們分享瞭如何使用LetNet體系結構來搭建一個圖片識別的神經網絡:

本期我們基於VGGNet神經網絡來進行圖片的識別,且增加圖片的識別種類,當然你也可以增加更多的種類,本期代碼跟往期代碼有很大的相識處,可以參考

VGGNet基礎

keras 人工智能之VGGNet神經網絡模型訓練

VGG16結構圖

  1. 輸入是大小為224*224的RGB圖像,預處理(preprocession)時計算出三個通道的平均值,在每個像素上減去平均值
  2. 圖像經過一系列卷積層處理,在卷積層中使用了非常小的3*3卷積核,在有些卷積層裡則使用了1*1的卷積核。
  3. 卷積層步長(stride)設置為1個像素,3*3卷積層的填充(padding)設置為1個像素。池化層採用max pooling,共有5層,在一部分卷積層後,max-pooling的窗口是2*2,步長設置為2。
  4. 卷積層之後是三個全連接層(fully-connected layers,FC)。前兩個全連接層均有4096個通道,第三個全連接層有1000個通道,用來分類。所有網絡的全連接層配置相同。
  5. 全連接層後是Softmax,用來分類。
  6. 所有隱藏層(每個conv層中間)都使用ReLU作為激活函數。VGGNet不使用局部響應標準化(LRN),這種標準化並不能在ILSVRC數據集上提升性能,卻導致更多的內存消耗和計算時間(LRN:Local Response Normalization,局部響應歸一化,用於增強網絡的泛化能力)。

VGGNet keras 神經網絡搭建

使用VGGNet基礎知識,我們使用keras來搭建一個小型的神經網絡,新建一個smallervggnet.py文件

<code>from keras.models import Sequentialfrom keras.layers.normalization import BatchNormalizationfrom keras.layers.convolutional import Conv2Dfrom keras.layers.convolutional import MaxPooling2Dfrom keras.layers.core import Activationfrom keras.layers.core import Flattenfrom keras.layers.core import Dropoutfrom keras.layers.core import Densefrom keras import backend as Kclass SmallerVGGNet:@staticmethoddef build(width, height, depth, classes):# initialize the model along with the input shape to be# "channels last" and the channels dimension itselfmodel = Sequential()inputShape = (height, width, depth)chanDim = -1# if we are using "channels first", update the input shape# and channels dimensionif K.image_data_format() == "channels_first":inputShape = (depth, height, width)chanDim = 1# CONV => RELU => POOLmodel.add(Conv2D(32, (3, 3), padding="same",input_shape=inputShape))model.add(Activation("relu"))model.add(BatchNormalization(axis=chanDim))model.add(MaxPooling2D(pool_size=(3, 3)))model.add(Dropout(0.25))# (CONV => RELU) * 2 => POOLmodel.add(Conv2D(64, (3, 3), padding="same"))model.add(Activation("relu"))model.add(BatchNormalization(axis=chanDim))model.add(Conv2D(64, (3, 3), padding="same"))model.add(Activation("relu"))model.add(BatchNormalization(axis=chanDim))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Dropout(0.25))# (CONV => RELU) * 2 => POOLmodel.add(Conv2D(128, (3, 3), padding="same"))model.add(Activation("relu"))model.add(BatchNormalization(axis=chanDim))model.add(Conv2D(128, (3, 3), padding="same"))model.add(Activation("relu"))model.add(BatchNormalization(axis=chanDim))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Dropout(0.25))# first (and only) set of FC => RELU layersmodel.add(Flatten())model.add(Dense(1024))model.add(Activation("relu"))model.add(BatchNormalization())model.add(Dropout(0.5))# softmax classifiermodel.add(Dense(classes))model.add(Activation("softmax"))# return the constructed network architecturereturn model/<code>

搭建圖片識別訓練模型

導入第三方庫

<code>import matplotlibmatplotlib.use("Agg")from keras.preprocessing.image import ImageDataGeneratorfrom keras.optimizers import Adamfrom keras.preprocessing.image import img_to_arrayfrom sklearn.preprocessing import LabelBinarizerfrom sklearn.model_selection import train_test_splitfrom smallervggnet import SmallerVGGNetfrom keras.utils import to_categoricalimport matplotlib.pyplot as pltfrom imutils import pathsimport numpy as npimport randomimport pickleimport cv2import os/<code>

初始化數據

<code>EPOCHS = 100  #學習的步數INIT_LR = 1e-3 #學習效率BS = 32# 每步學習個數IMAGE_DIMS = (96, 96, 3) # 圖片尺寸data = [] # 保存圖片數據labels = [] # 保存圖片label# 加載所有圖片imagePaths = sorted(list(paths.list_images("dataset\\\")))random.seed(42)random.shuffle(imagePaths)/<code>

遍歷圖片蒐集圖片信息

<code>for imagePath in imagePaths:    # 加載所有圖片    image = cv2.imread(imagePath)    image = cv2.resize(image, (IMAGE_DIMS[1], IMAGE_DIMS[0]))    image = img_to_array(image)    data.append(image)# 蒐集圖片data 與label    label = imagePath.split(os.path.sep)[-2]    print(label)    labels.append(label)/<code>

處理圖片

<code># 處理數據到0-1data = np.array(data, dtype="float") / 255.0labels = np.array(labels# 標籤二值化lb = LabelBinarizer()labels = lb.fit_transform(labels)#labels = to_categorical(labels) #多類刪除這個,當然本期代碼完全可以使用在介紹lenet網絡上/<code>

搭建神經網絡模型

<code>(trainX, testX, trainY, testY) = train_test_split(data,                                                  labels, test_size=0.2, random_state=42)#分開測試數據#創建一個圖像生成器對象,該對象在圖像數據集上執行隨機旋轉,平移,翻轉,修剪和剪切。#這使我們可以使用較小的數據集,但仍然可以獲得較高的結果aug = ImageDataGenerator(rotation_range=25, width_shift_range=0.1,                         height_shift_range=0.1, shear_range=0.2, zoom_range=0.2,                         horizontal_flip=True, fill_mode="nearest")# 初始化模型model = SmallerVGGNet.build(width=IMAGE_DIMS[1], height=IMAGE_DIMS[0],                            depth=IMAGE_DIMS[2], classes=len(lb.classes_))opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)model.compile(loss="categorical_crossentropy", optimizer=opt,              metrics=["accuracy"])/<code> 

訓練神經網絡

<code>H = model.fit_generator(    aug.flow(trainX, trainY, batch_size=BS),    validation_data=(testX, testY),    steps_per_epoch=len(trainX) // BS,    epochs=EPOCHS, verbose=1)/<code>

保存訓練模型

<code>model.save("VGGNet.model")f = open("labelbin.pickle", "wb")f.write(pickle.dumps(lb))f.close()/<code>

顯示訓練結果


keras 人工智能之VGGNet神經網絡模型訓練

訓練結果

<code>plt.style.use("ggplot")plt.figure()N = EPOCHSplt.plot(np.arange(0, N), H.history["loss"], label="train_loss")plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")plt.plot(np.arange(0, N), H.history["acc"], label="train_acc")plt.plot(np.arange(0, N), H.history["val_acc"], label="val_acc")plt.title("Training Loss and Accuracy")plt.xlabel("Epoch #")plt.ylabel("Loss/Accuracy")plt.legend(loc="upper left")plt.savefig("plot1.JPG")/<code>


keras 人工智能之VGGNet神經網絡模型訓練

識別圖片

下期我們將使用預訓練好的模型對圖片進行識別


分享到:


相關文章: