「幾分鐘建立一個深度學習模型?訓練要花幾個小時!我甚至沒有一台足夠好的機器。」無數從事數據科學研究的人都這樣說,他們總是試圖迴避在自己的機器上構建深度學習模型。

其實,你不需要為谷歌或其他大型科技公司工作就可以使用深度學習數據集,在幾分鐘內從零開始建立起你自己的神經網絡,而不需要租用谷歌的服務器也不再只是一個夢。Fast.ai的學生在Imagenet數據集上僅用18分鐘就設計出了一個模型,本文將展示與其類似的模型構建過程。

深度學習是一個很廣泛的領域,因此本文我們將把重點主要放在解決圖像分類項目上。此外,我們將使用一個非常簡單的深度學習體系結構來提高準確度。

你可以考慮將本文中看到的python代碼作為構建圖像分類模型的參考。一旦你對這個概念有了很好的理解,就可以試着參加比賽了!

什麼是圖像分類?

觀察下面這張圖:

你會立刻意識到這是一輛(豪華的)汽車。後退一步,分析你是如何得出這個結論的——你看到了一張圖片並對它的所屬類別進行了分類(本例中是一輛車)。簡言之,這就是關於圖像分類的一切。

對給定的圖像進行分類,圖像中可能有n個類別。手動檢查和分類圖像是一個非常繁瑣的過程。當我們面對大量的圖片,比如10000張甚至100000張時,這個任務幾乎不可能完成。如果整個過程能夠實現自動化,並根據相應的類快速標記圖像,這將有多大的用處?

自動駕駛汽車是一個理解圖像分類在現實世界中的應用的很好的例子。為了實現自動駕駛,我們可以建立一個圖像分類模型來識別道路上的各種物體,例如汽車、人、移動物體等。在本文後面我們將會看到幾個用例,周圍還有更多的應用。

既然我們已經掌握了主題,那麼讓我們深入研究一下如何構建圖像分類模型,它的先決條件是什麼以及其如何在Python中實現。

設置圖像數據的結構

為了解決圖像分類問題,我們的數據需要採用特定的格式。我們將在幾個部分中看到這一點,但在這之前,請記住這些指示。

你需要兩個文件夾,一個用於訓練集,另一個用於測試集。訓練集文件夾中又包含一個.csv文件和一個圖像文件夾:

  • csv文件包含所有訓練圖像的名稱及其相應的標籤
  • 圖像文件夾包含所有的訓練圖像

測試集中的.csv文件與訓練集中的不同。測試集中的.csv文件包含所有測試圖像的名稱,但不包含其相應的標籤。你能猜到為什麼嗎?我們的模型將在訓練集中的圖像上進行訓練,標籤預測將在測試集中的圖像上進行。

如果你的數據不是上面描述的格式,你需要相應地對其進行轉換(否則預測將會是錯誤的、無用的)。

 分解模型構建過程

在深入研究Python代碼之前,讓我們花點時間了解一下圖像分類模型通常是如何設計的。我們可以把這個過程大致分為4個階段。每個階段都需要一定的時間來執行:

  1. 加載和預處理數據——30%的時間
  2. 定義模型架構——10%的時間
  3. 訓練模型——50%的時間
  4. 性能評估——10%的時間

現在我們更詳細地解釋一下上面的每一個步驟。這一部分非常重要,因為並非所有模型都是一下子構建起來的。你需要在每次迭代之後返回,對步驟進行微調,然後再次運行。對基礎概念有一個紮實的理解,對於加速整個過程將有很大的幫助。

階段1:數據的加載和預處理

就深度學習模型而言,數據就是黃金。如果訓練集中有大量的圖像,你的圖像分類模型將更有可能表現良好。此外,數據的形狀根據我們使用的體系結構/框架而變化。

因此,強烈建議你學習「Python中圖像處理的基礎知識」,以進一步了解預處理如何處理圖像數據。但我們目前還不用這麼深入。為了了解我們的模型如何處理未見過的數據(以及在將其公開給測試集之前),我們需要創建一個驗證集。這是通過劃分訓練集數據來完成的。

簡言之,在訓練集上訓練模型,並在驗證數據上加以驗證。一旦我們對模型在驗證集上的性能感到滿意,就可以用其對測試數據進行預測。

此步驟所需時間:大約2-3分鐘。

階段2:定義模型架構

這是我們深度學習模型構建過程中的另一個關鍵步驟。我們必須定義模型的外觀,這需要回答以下問題:

  • 需要多少卷積層?
  • 每層的激活功能是什麼?
  • 每層有多少隱藏單元?

還有很多問題,在此不再一一列舉。這些本質上是模型的超參數,它們在決定預測有多準確方面起着重要作用。

我們如何決定這些值?好問題!一個好想法是根據現有的研究選擇這些值。另一個想法是不斷嘗試這些值直到找到最佳匹配,但這可能是一個非常耗時的過程。

此步驟所需時間:大約1分鐘。

階段3:訓練模型

 為了訓練數據,我們需要:

  • 訓練圖像及其相應的正確標籤
  • 驗證圖像及其相應的正確標籤(我們僅使用這些標籤來驗證模型,而不在訓練階段使用)

我們還明確了這個步驟中的時期數。首先,我們將運行10個時期的模型(你可以稍後更改時期的數量)。

此步驟所需時間:由於訓練需要模型學習結構,我們需要大約5分鐘來完成此步驟。

是時候做預測了!

階段4:評估模型的性能

最後,我們加載測試數據(圖像)並在此完成預處理步驟。然後我們使用訓練模型為這些圖像預測類。

此步驟所需時間:不超過1分鐘。

 建立問題陳述並理解數據

我們將接受一個非常酷的挑戰來理解圖像分類。建立一個模型,根據服裝(襯衫、褲子、鞋子、襪子等)對給定的一組圖像進行分類。這實際上是許多電子商務零售商面臨的一個問題,這使其成為一個更有趣的計算機視覺問題。

這個挑戰被稱為「識別服裝」,是DataHack平台上遇到的實踐問題之一。

我們總共有70000張圖像(28 x 28維),其中60000張來自訓練集,10000張來自測試集。根據服裝類型預先標記訓練圖像,共10個類別。當然,測試圖像沒有標籤。挑戰在於識別所有測試圖像中的服裝類型。

我們將在Google Colab上構建模型,因為其可為我們訓練模型提供免費的GPU。

建立圖像分類模型的步驟

是時候激發Python技能了。最終到達了動手實踐部分了!

  1. 安裝Google Colab
  2. 導入庫
  3. 加載和預處理數據(3分鐘)
  4. 創建驗證集
  5. 定義模型結構(1分鐘)
  6. 訓練模型(5分鐘)
  7. 預測(1分鐘)

讓我們一步一步來:

步驟 1:安裝Google Colab

因為要從Google Drive鏈接導入數據,所以我們需要在Google Colabnotebook中添加幾行代碼。創建新的python 3notebook並編寫以下代碼塊:

!pip install PyDrive

這將安裝 PyDrive. 現在我們將導入一些必需的庫:

import os

from pydrive.auth import GoogleAuth

from pydrive.drive import GoogleDrive

from google.colab import auth

from oauth2client.client import GoogleCredentials

接下來我們將創建一個驅動器變量來訪問GoogleDrive:

auth.authenticate_user()

gauth = GoogleAuth()

gauth.credentials = GoogleCredentials.get_application_default()

drive = GoogleDrive(gauth)

為了下載數據集,我們將使用Google Drive上上傳文件的ID:

download = drive.CreateFile({'id': '1BZOv422XJvxFUnGh-0xVeSvgFgqVY45q'})

將上述代碼中的「id」替換為文件的id。現在,我們將下載此文件並解壓縮:

download.GetContentFile('train_LbELtWX.zip')

!unzip train_LbELtWX.zip

每次啟動notebook時都必須運行這些代碼塊。 

步驟 2:導入模型構建階段需要的庫。

import keras

from keras.models import Sequential

from keras.layers import Dense, Dropout, Flatten

from keras.layers import Conv2D, MaxPooling2D

from keras.utils import to_categorical

from keras.preprocessing import image

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split

from keras.utils import to_categorical

from tqdm import tqdm

步驟 3:回想一下我們前面討論過的預處理步驟。我們將在加載數據後在這裡重複以上步驟。

train = pd.read_csv('train.csv')

接下來,我們將讀取所有訓練圖像,將它們存儲在一個列表中,最後將該列錶轉換為一個numpy數組。

# We have grayscale images, so while loading the images we will keep grayscale=True, if you have RGB images, you should set grayscale as False

train_image = []

for i in tqdm(range(train.shape[0])):

    img = image.load_img('train/'+train['id'][i].astype('str')+'.png', target_size=(28,28,1), grayscale=True)

    img = image.img_to_array(img)

    img = img/255

    train_image.append(img)

X = np.array(train_image)

由於這是一個多類分類問題(10個類),我們將對目標變量進行one-hot編碼。

y=train['label'].values
y = to_categorical(y)

步驟 4:從訓練數據中創建驗證集

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=0.2)

步驟 5:定義模型結構

將創建一個具有兩個卷積層、一個隱藏層和一個輸出層的簡單架構。

model = Sequential()

model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=(28,28,1)))

model.add(Conv2D(64, (3, 3), activation='relu'))

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

model.add(Dropout(0.25))

model.add(Flatten())

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

model.add(Dropout(0.5))

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

接下來,編譯創建的模型。

model.compile(loss='categorical_crossentropy',optimizer='Adam',metrics=['accuracy'])

步驟 6:訓練模型。

在這一步中將在訓練集圖像上訓練模型,並使用(你猜到的)驗證集對其進行驗證。

model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test))

步驟 7: 預測!

我們將首先遵循處理訓練數據時執行的步驟。使用model.predict_classes()函數加載測試圖像並預測其類別。

download = drive.CreateFile({'id': '1KuyWGFEpj7Fr2DgBsW8qsWvjqEzfoJBY'})

download.GetContentFile('test_ScVgIM0.zip')

!unzip test_ScVgIM0.zip

導入測試文件:

test = pd.read_csv('test.csv')

現在,讀入和存儲所有的測試圖像:

test_image = []

for i in tqdm(range(test.shape[0])):

    img = image.load_img('test/'+test['id'][i].astype('str')+'.png', target_size=(28,28,1), grayscale=True)

    img = image.img_to_array(img)

    img = img/255

    test_image.append(img)

test = np.array(test_image)

# making predictions

prediction = model.predict_classes(test)

我們還將創建一個提交文件,將其上傳到Datahack平台頁面(查看結果如何在排行榜上顯示)。

download = drive.CreateFile({'id': '1z4QXy7WravpSj-S4Cs9Fk8ZNaX-qh5HF'})

download.GetContentFile('sample_submission_I5njJSF.csv')

# creating submission file

sample = pd.read_csv('sample_submission_I5njJSF.csv')

sample['label'] = prediction

sample.to_csv('sample_cnn.csv', header=True, index=False)

下載此樣本_cnn.csv文件,並將其上傳到競賽頁面,已生成成績並檢查在排行榜上的排名。這將為你提供一個開始處理任何圖像分類問題的參考解決方案!

你可以嘗試超參數調整和正則化技術來進一步提高模型的性能。

接受另一個挑戰

讓我們在不同的數據集上測試學習效果。我們將在本節中解決「識別數字」練習問題,下載數據集。在繼續之前,試着自己解決這個問題。你已經有了解決問題的工具——你只需要應用它們就行了!回來檢查一下你的結果,或者如果你在某個時刻被卡住了。

在這個挑戰中,我們需要識別給定圖像中的數字。總共有70000張圖片–在訓練集中有49000張貼有標籤的圖片,在測試集中有21000張(測試圖片沒有標籤)。我們需要識別/預測這些未標記圖像的類別。

準備好開始了嗎?棒極了!創建新的python 3 notebook並運行以下代碼:

# Setting up Colab

!pip install PyDrive

import os

from pydrive.auth import GoogleAuth

from pydrive.drive import GoogleDrive

from google.colab import auth

from oauth2client.client import GoogleCredentials

auth.authenticate_user()

gauth = GoogleAuth()

gauth.credentials = GoogleCredentials.get_application_default()

drive = GoogleDrive(gauth)

# Replace the id and filename in the below codes

download = drive.CreateFile({'id': '1ZCzHDAfwgLdQke_GNnHp_4OheRRtNPs-'})

download.GetContentFile('Train_UQcUa52.zip')

!unzip Train_UQcUa52.zip

# Importing libraries

import keras

from keras.models import Sequential

from keras.layers import Dense, Dropout, Flatten

from keras.layers import Conv2D, MaxPooling2D

from keras.utils import to_categorical

from keras.preprocessing import image

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split

from keras.utils import to_categorical

from tqdm import tqdm

train = pd.read_csv('train.csv')

# Reading the training images

train_image = []

for i in tqdm(range(train.shape[0])):

    img = image.load_img('Images/train/'+train['filename'][i], target_size=(28,28,1), grayscale=True)

    img = image.img_to_array(img)

    img = img/255

    train_image.append(img)

X = np.array(train_image)

# Creating the target variable

y=train['label'].values

y = to_categorical(y)

# Creating validation set

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=0.2)

# Define the model structure

model = Sequential()

model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=(28,28,1)))

model.add(Conv2D(64, (3, 3), activation='relu'))

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

model.add(Dropout(0.25))

model.add(Flatten())

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

model.add(Dropout(0.5))

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

# Compile the model

model.compile(loss='categorical_crossentropy',optimizer='Adam',metrics=['accuracy'])

# Training the model

model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test))

download = drive.CreateFile({'id': '1zHJR6yiI06ao-UAh_LXZQRIOzBO3sNDq'})

download.GetContentFile('Test_fCbTej3.csv')

test_file = pd.read_csv('Test_fCbTej3.csv')

test_image = []

for i in tqdm(range(test_file.shape[0])):

    img = image.load_img('Images/test/'+test_file['filename'][i], target_size=(28,28,1), grayscale=True)

    img = image.img_to_array(img)

    img = img/255

    test_image.append(img)

test = np.array(test_image)

prediction = model.predict_classes(test)

download = drive.CreateFile({'id': '1nRz5bD7ReGrdinpdFcHVIEyjqtPGPyHx'})

download.GetContentFile('Sample_Submission_lxuyBuB.csv')

sample = pd.read_csv('Sample_Submission_lxuyBuB.csv')

sample['filename'] = test_file['filename']

sample['label'] = prediction

sample.to_csv('sample.csv', header=True, index=False)

在練習題頁面上提交這個文件,得到一個相當不錯的準確數字。這是一個好的開端,但總有改進的餘地。繼續調整超參數值,看看你是否可以改進基本模型。

本文轉自公眾號 讀芯術,原文地址