當前位置:
首頁 > 知識 > 教你使用Keras on Google Colab微調深度神經網路

教你使用Keras on Google Colab微調深度神經網路

作者:LONG ANG

翻譯:閆曉雨

校對:丁楠雅

本文約2300字,建議閱讀7分鐘。

本文將指導您如何使用Google上的Keras微調VGG-16網路。

簡介

在CPU上訓練深度神經網路很困難。本教程將指導您如何使用Google Colaboratory上的Keras微調VGG-16網路,這是一個免費的GPU雲平台。如果您是Google Colab的新手,這是適合您的地方,您將了解到:

如何在Colab上創建您的第一個Jupyter筆記本並使用免費的GPU。

如何在Colab上上傳和使用自定義數據集。

如何在前景分割域中微調Keras預訓練模型(VGG-16)。

現在,讓我們開始!

1. 創建您的第一個Jupyter筆記本

假定您已登錄自己的Google帳戶。請按以下步驟操作:

恭喜!!!您已經在Colab上創建了您的第一個筆記本


2. 為筆記本設置GPU加速器

在筆記本中,選擇Runtime > Change runtime type。將彈出一個窗口。然後選擇您的運行時間類型,從硬體加速器下拉菜單中選擇GPU並保存您的設置,如下圖所示:


3. 將您的自定義數據集上傳到Colab

您已將筆記本設置為在GPU上運行。現在,讓我們將您的數據集上傳到Colab。在本教程中,我們處理前景分割,其中前景對象是從背景中提取的,如下圖所示:

圖像來自changedetection.net

將數據集上傳到Colab有幾種選擇,但是,我們在本教程中考慮兩個選項;首先,我們上傳到GitHub並從中克隆到Colab,其次,我們上傳到Google雲端硬碟並直接在我們的筆記本中使用它。您可以選擇任一選項 a選項b如下:

步驟a. 從GitHub克隆

讓我們將數據集克隆到創建的筆記本上。在您的筆記本中運行:

!git clone https://github.com/lim-eren/CDnet2014.git.

您會看到這樣的東西:

完成!讓我們列出訓練集,看它是否有效:

開始了!訓練集包含25個輸入幀和25個地面真實幀。如果您已完成此步驟,可略過步驟b並跳轉到第4節。

步驟b. 從Google雲盤下載

另一種方法是將數據集上傳到Google雲端硬碟並從中進行克隆。假設您已經壓縮了上面的培訓集,比如說CDnet2014.zip,並上傳到Google Drive中與myNotebook.ipynb相同的目錄。現在,右鍵單擊CDnet2014net.zip > 獲取可共享鏈接。複製文件的ID並將其存儲在某個地方(稍後我們將使用它)。

然後,讓我們將CDnet2014net.zip文件內容下載到我們的Jupyter筆記本中(替換 YOUR_FILE_ID 為上面步驟中獲得的id)並通過運行以下代碼解壓縮它:

完成!您已將數據集從Google雲端硬碟下載到Colab。讓我們繼續第4節,使用這個數據集構建一個簡單的神經網路。


4. 微調您的神經網路

將數據集下載到Colab後,現在讓我們在前景分割域中對Keras預訓練模型進行微調。請按照以下步驟操作:

步驟a.首先,在筆記本上添加此代碼段,以獲得跨機器的可重現結果(請在筆記本的單元格中運行代碼段):

# Run it to obtain reproducible results across machines (from keras.io)

from__future__import print_function

import numpy as np

import tensorflow as tf

import random as rn

import os

os.environ["PYTHONHASHSEED"] ="0"

rn.seed(12345)

session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)

from keras import backend as K

tf.set_random_seed(1234)

sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)

K.set_session(sess)

步驟b.創建一個從Colab載入數據的函數。此函數返回具有相應基礎事實(Y)的輸入圖像(X):

# load data func

import glob

from keras.preprocessing import image as kImage

defgetData(dataset_dir):

X= []

Y= []

for i inrange(len(X_list)):

# Load input image

x = kImage.load_img(X_list[i])

x = kImage.img_to_array(x)

X.append(x)

# Load ground-truth label and encode it to label 0 and 1

x = kImage.load_img(Y_list[i], grayscale=True)

x = kImage.img_to_array(x)

x /=255.0

x = np.floor(x)

Y.append(x)

X = np.asarray(X)

Y = np.asarray(Y)

# Shuffle the training data

idx =list(range(X.shape[0]))

X = X[idx]

Y = Y[idx]

return X, Y

步驟c.最初是一個vanilla編碼器——解碼器模型。我們將VGG-16預訓練模型作為編碼器進行調整,其中所有完全連接的層都被移除,只有最後一個卷積層(block5_conv3)被微調,其餘層被凍結。我們使用轉置卷積層來恢復解碼器部分中的特徵解析度。

由於它是二分類問題,binary_crossentropy因此使用並且來自網路的輸出將是0和1之間的概率值。這些概率值需要被閾值化以獲得二進位標籤0或1,其中標籤0表示背景和標籤1代表前景。

import keras

from keras.models import Model

from keras.layers import Deconv2D, Input

definitModel():

### Encoder

net_input = Input(shape=(240,320,3))

vgg16 = keras.applications.vgg16.VGG16(include_top=False, weights="imagenet", input_tensor=net_input)

for layer in vgg16.layers[:17]:

layer.trainable =False

x = vgg16.layers[-2].output # 2nd layer from the last, block5_conv3

### Decoder

x = Deconv2D(256, (3,3), strides=(2,2), activation="relu", padding="same")(x)

x = Deconv2D(128, (3,3), strides=(2,2), activation="relu", padding="same")(x)

x = Deconv2D(64, (3,3), strides=(2,2), activation="relu", padding="same")(x)

x = Deconv2D(32, (3,3), strides=(2,2), activation="relu", padding="same")(x)

x = Deconv2D(1, (1,1), activation="sigmoid", padding="same")(x)

model = Model(inputs=vgg16.input, outputs=x)

return model

步驟d.我們將學習率設置為5e-4,batch_size為1,validation_split為0.2,max-epochs為100,當驗證損失連續5次迭代沒有改善時將學習率降低10倍,並在驗證損失連續10次迭代沒有改善時提前停止訓練。現在,讓我們訓練模型吧。

# load data

X, Y = getData(dataset_path)

# init the model

model = initModel()

early = keras.callbacks.EarlyStopping(monitor="val_loss", min_delta=1e-4, patience=10)

reduce= keras.callbacks.ReduceLROnPlateau(monitor="val_loss", factor=0.1, patience=5)

model.fit(X, Y, batch_size=1, epochs=100, verbose=2, validation_split=0.2, callbacks=[reduce, early], shuffle=True)

model.save("my_model.h5")

使用GPU進行訓練

一次迭代大約需要1秒鐘,賊快!驗證集的最大精度高於98%。還不錯,對吧?現在,讓我們暫停一下。讓我們比較使用和不使用GPU的訓練速度(如果需要,可以跳過此比較並跳轉到測試部分)。要在沒有GPU的情況下進行訓練,請將硬體加速器設置為無(參見上面的第2節)。這是培訓日誌。沒有GPU,一次迭代需要大約30秒,而使用GPU訓練只需要1秒(大約快30倍)。

不使用GPU進行訓練

現在,讓我們使用ColabGPU在測試集上測試模型(您可以運行!ls */test/*以查看具有相應基礎事實的測試幀)。

好棒!!!只需使用25個vanilla網路的例子,我們就可以在測試集+驗證集上達到98.94%的精度。請注意,由於訓練示例的隨機性,您可能會得到與我相似的結果(不完全相同但只有很小的精度差異)。

注意一個問題:我們的模型過度擬合了訓練數據,您接下來的工作是解決這個問題。提示:使用正規化技術,如Dropout,L2,BatchNormalization。

步驟e.讓我們通過運行以下代碼繪製分段掩碼:

import matplotlib.pyplot as plt

idx =1#image index that you want to display

img =np.empty(3, dtype=object)

img[0] = X[idx]

img[1] =Y[idx].reshape(Y[idx].shape[0],Y[idx].shape[1])

img[2] =pred[idx].reshape(pred[idx].shape[0],pred[idx].shape[1])

title = ["input","ground-truth", "result"]

for iinrange(3):

plt.subplot(1, 3, i+1)

if i==0:

plt.imshow(img[i].astype("uint8"))

else:

plt.imshow(img[i], cmap="gray")

plt.axis("off")

plt.title(title[i])

plt.show()

好了!細分結果一點都不差!大多數對象邊界被錯誤分類了,該問題主要是由於訓練期間在損失計算中考慮空標籤(對象邊界周圍的模糊像素)引起的。我們可以通過在損失中省略這些void標籤來更好地提高性能。您訪問以下兩個鏈接參考如何執行此操作:

https://github.com/lim-anggun/FgSegNet

https://github.com/lim-anggun/FgSegNet_v2

CDnet2014數據集上的測試結果(changedetection.net)

GitHub中提供了本教程的完整源代碼:

https://github.com/lim-anggun/tutorials/blob/master/myNotebook.ipynb

總結

在本教程中,您學習了如何使用Google Colab GPU並快速訓練網路。您還學習了如何在前景分割域中微調Keras預訓練模型,您可能會發現它在您未來的研究中很有趣。

如果您喜歡這篇文章,請隨時分享或鼓掌。祝愉快!

原文標題:

A comprehensive guide on how tofine-tune deep neural networks using Keras on Google Colab (Free GPU)

https://towardsdatascience.com/a-comprehensive-guide-on-how-to-fine-tune-deep-neural-networks-using-keras-on-google-colab-free-daaaa0aced8f

譯者簡介

閆曉雨,本科畢業於北京林業大學,即將就讀於南加州大學應用生物統計與流行病碩士項目。繼續在生統道路上摸爬滾打,熱愛數據,期待未來。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 數據派THU 的精彩文章:

初學者的問題:在神經網路中應使用多少隱藏層/神經元?
假期專屬論文清單:把國慶長假安排得明明白白!

TAG:數據派THU |