新聞中心
【稿件】在這篇文章中,我們將展示如何建立一個深度神經(jīng)網(wǎng)絡(luò),能做到以 90% 的精度來對圖像進(jìn)行分類,而在深度神經(jīng)網(wǎng)絡(luò),特別是卷積神經(jīng)網(wǎng)絡(luò)興起之前,這還是一個非常困難的問題。

深度學(xué)習(xí)是目前人工智能領(lǐng)域里最讓人興奮的話題之一了,它基于生物學(xué)領(lǐng)域的概念發(fā)展而來,現(xiàn)如今是一系列算法的集合。
事實(shí)已經(jīng)證明深度學(xué)習(xí)在計算機(jī)視覺、自然語言處理、語音識別等很多的領(lǐng)域里都可以起到非常好的效果。
在過去的 6 年里,深度學(xué)習(xí)已經(jīng)應(yīng)用到非常廣泛的領(lǐng)域,很多最近的技術(shù)突破,都和深度學(xué)習(xí)相關(guān)。
這里僅舉幾個例子:特斯拉的自動駕駛汽車、Facebook 的照片標(biāo)注系統(tǒng)、像 Siri 或 Cortana 這樣的虛擬助手、聊天機(jī)器人、能進(jìn)行物體識別的相機(jī),這些技術(shù)突破都要?dú)w功于深度學(xué)習(xí)。
在這么多的領(lǐng)域里,深度學(xué)習(xí)在語言理解、圖像分析這種認(rèn)知任務(wù)上的表現(xiàn)已經(jīng)達(dá)到了我們?nèi)祟惖乃健?/p>
如何構(gòu)建一個在圖像分類任務(wù)上能達(dá)到 90% 精度的深度神經(jīng)網(wǎng)絡(luò)?
這個問題看似非常簡單,但在深度神經(jīng)網(wǎng)絡(luò)特別是卷積神經(jīng)網(wǎng)絡(luò)(CNN)興起之前,這是一個被計算機(jī)科學(xué)家們研究了很多年的棘手問題。
本文分為以下三個部分進(jìn)行講解:
- 展示數(shù)據(jù)集和用例,并且解釋這個圖像分類任務(wù)的復(fù)雜度。
- 搭建一個深度學(xué)習(xí)專用環(huán)境,這個環(huán)境搭建在 AWS 的基于 GPU 的 EC2 服務(wù)上。
- 訓(xùn)練兩個深度學(xué)習(xí)模型:***個模型是使用 Keras 和 TensorFlow 從頭開始端到端的流程,另一個模型使用是已經(jīng)在大型數(shù)據(jù)集上預(yù)訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)。
一個有趣的實(shí)例:給貓和狗的圖像分類
有很多的圖像數(shù)據(jù)集是專門用來給深度學(xué)習(xí)模型進(jìn)行基準(zhǔn)測試的,我在這篇文章中用到的數(shù)據(jù)集來自 Cat vs Dogs Kaggle competition,這份數(shù)據(jù)集包含了大量狗和貓的帶有標(biāo)簽的圖片。
和每一個 Kaggle 比賽一樣,這份數(shù)據(jù)集也包含兩個文件夾:
- 訓(xùn)練文件夾:它包含了 25000 張貓和狗的圖片,每張圖片都含有標(biāo)簽,這個標(biāo)簽是作為文件名的一部分。我們將用這個文件夾來訓(xùn)練和評估我們的模型。
- 測試文件夾:它包含了 12500 張圖片,每張圖片都以數(shù)字來命名。對于這份數(shù)據(jù)集中的每幅圖片來說,我們的模型都要預(yù)測這張圖片上是狗還是貓(1= 狗,0= 貓)。事實(shí)上,這些數(shù)據(jù)也被 Kaggle 用來對模型進(jìn)行打分,然后在排行榜上排名。
我們觀察一下這些圖片的特點(diǎn),這些圖片各種各樣,分辨率也各不相同。圖片中的貓和狗形狀、所處位置、體表顏色各不一樣。
它們的姿態(tài)不同,有的在坐著而有的則不是,它們的情緒可能是開心的也可能是傷心的,貓可能在睡覺,而狗可能在汪汪地叫著。照片可能以任一焦距從任意角度拍下。
這些圖片有著***種可能,對于我們?nèi)祟悂碚f在一系列不同種類的照片中識別出一個場景中的寵物自然是毫不費(fèi)力的事情,然而這對于一臺機(jī)器來說可不是一件小事。
實(shí)際上,如果要機(jī)器實(shí)現(xiàn)自動分類,那么我們需要知道如何強(qiáng)有力地描繪出貓和狗的特征,也就是說為什么我們認(rèn)為這張圖片中的是貓,而那張圖片中的卻是狗。這個需要描繪每個動物的內(nèi)在特征。
深度神經(jīng)網(wǎng)絡(luò)在圖像分類任務(wù)上效果很好的原因是,它們有著能夠自動學(xué)習(xí)多重抽象層的能力,這些抽象層在給定一個分類任務(wù)后又可以對每個類別給出更簡單的特征表示。
深度神經(jīng)網(wǎng)絡(luò)可以識別極端變化的模式,在扭曲的圖像和經(jīng)過簡單的幾何變換的圖像上也有著很好的魯棒性。讓我們來看看深度神經(jīng)網(wǎng)絡(luò)如何來處理這個問題的。
配置深度學(xué)習(xí)環(huán)境
深度學(xué)習(xí)的計算量非常大,當(dāng)你在自己的電腦上跑一個深度學(xué)習(xí)模型時,你就能深刻地體會到這一點(diǎn)。
但是如果你使用 GPUs,訓(xùn)練速度將會大幅加快,因為 GPUs 在處理像矩陣乘法這樣的并行計算任務(wù)時非常高效,而神經(jīng)網(wǎng)絡(luò)又幾乎充斥著矩陣乘法運(yùn)算,所以計算性能會得到令人難以置信的提升。
我自己的電腦上并沒有一個強(qiáng)勁的 GPU,因此我選擇使用一個亞馬遜云服務(wù) (AWS) 上的虛擬機(jī),這個虛擬機(jī)名為 p2.xlarge,它是亞馬遜 EC2 的一部分。
這個虛擬機(jī)的配置包含一個 12GB 顯存的英偉達(dá)GPU、一個 61GB 的 RAM、4 個 vCPU 和 2496 個 CUDA 核。
可以看到這是一臺性能巨獸,讓人高興的是,我們每小時僅需花費(fèi) 0.9 美元就可以使用它。當(dāng)然,你還可以選擇其他配置更好的虛擬機(jī),但對于我們現(xiàn)在將要處理的任務(wù)來說,一臺 p2.xlarge 虛擬機(jī)已經(jīng)綽綽有余了。
我的虛擬機(jī)工作在 Deep Learning AMI CUDA 8 Ubuntu Version 系統(tǒng)上,現(xiàn)在讓我們對這個系統(tǒng)有一個更清楚的了解吧。
這個系統(tǒng)基于一個 Ubuntu 16.04 服務(wù)器,已經(jīng)包裝好了所有的我們需要的深度學(xué)習(xí)框架(TensorFlow,Theano,Caffe,Keras),并且安裝好了 GPU 驅(qū)動(聽說自己安裝驅(qū)動是噩夢般的體驗)。
如果你對 AWS 不熟悉的話,你可以參考下面的兩篇文章:
- https://blog.keras.io/running-jupyter-notebooks-on-gpu-on-aws-a-starter-guide.html
- https://hackernoon.com/keras-with-gpu-on-amazon-ec2-a-step-by-step-instruction-4f90364e49ac
這兩篇文章可以讓你知道兩點(diǎn):
- 建立并連接到一個 EC2 虛擬機(jī)。
- 配置網(wǎng)絡(luò)以便遠(yuǎn)程訪問 jupyter notebook。
用 TensorFlow 和 Keras 建立一個貓/狗圖片分類器
環(huán)境配置好后,我們開始著手建立一個可以將貓狗圖片分類的卷積神經(jīng)網(wǎng)絡(luò),并使用到深度學(xué)習(xí)框架 TensorFlow 和 Keras。
先介紹下 Keras:Keras 是一個高層神經(jīng)網(wǎng)絡(luò) API,它由純 Python 編寫而成并基于Tensorflow、Theano 以及 CNTK 后端,Keras 為支持快速實(shí)驗而生,能夠把你的 idea 迅速轉(zhuǎn)換為結(jié)果。
從頭開始搭建一個卷積神經(jīng)網(wǎng)絡(luò)
首先,我們設(shè)置一個端到端的 pipeline 訓(xùn)練 CNN,將經(jīng)歷如下幾步:數(shù)據(jù)準(zhǔn)備和增強(qiáng)、架構(gòu)設(shè)計、訓(xùn)練和評估。
我們將繪制訓(xùn)練集和測試集上的損失和準(zhǔn)確度指標(biāo)圖表,這將使我們能夠更直觀地評估模型在訓(xùn)練中的改進(jìn)變化。
數(shù)據(jù)準(zhǔn)備
在開始之前要做的***件事是從 Kaggle 上下載并解壓訓(xùn)練數(shù)據(jù)集。
- %matplotlib inline
- from matplotlib import pyplot as plt
- from PIL import Image
- import numpy as np
- import os
- import cv2
- from tqdm import tqdm_notebook
- from random import shuffle
- import shutil
- import pandas as pd
我們必須重新組織數(shù)據(jù)以便讓 Keras 更容易地處理它們。我們創(chuàng)建一個 data 文件夾,并在其中創(chuàng)建兩個子文件夾:
- train
- validation
在上面的兩個文件夾之下,每個文件夾依然包含兩個子文件夾:
- cats
- dogs
***我們得到下面的文件結(jié)構(gòu):
data/
train/
dogs/
dog001.jpg
dog002.jpg
...
cats/
cat001.jpg
cat002.jpg
...
validation/
dogs/
dog001.jpg
dog002.jpg
...
cats/
cat001.jpg
cat002.jpg
這個文件結(jié)構(gòu)讓我們的模型知道從哪個文件夾中獲取到圖像和訓(xùn)練或測試用的標(biāo)簽。這里提供了一個函數(shù)允許你來重新構(gòu)建這個文件樹,它有 2 個參數(shù):圖像的總數(shù)目、測試集 r 的比重。
- def organize_datasets(path_to_data, n=4000, ratio=0.2):
- files = os.listdir(path_to_data)
- files = [os.path.join(path_to_data, f) for f in files]
- shuffle(files)
- files = files[:n]
- n = int(len(files) * ratio)
- val, train = files[:n], files[n:]
- shutil.rmtree('./data/')
- print('/data/ removed')
- for c in ['dogs', 'cats']:
- os.makedirs('./data/train/{0}/'.format(c))
- os.makedirs('./data/validation/{0}/'.format(c))
- print('folders created !')
- for t in tqdm_notebook(train):
- if 'cat' in t:
- shutil.copy2(t, os.path.join('.', 'data', 'train', 'cats'))
- else:
- shutil.copy2(t, os.path.join('.', 'data', 'train', 'dogs'))
- for v in tqdm_notebook(val):
- if 'cat' in v:
- shutil.copy2(v, os.path.join('.', 'data', 'validation', 'cats'))
- else:
- shutil.copy2(v, os.path.join('.', 'data', 'validation', 'dogs'))
- print('Data copied!')
我使用了:
- n:25000(整個數(shù)據(jù)集的大小)
- r:0.2
- ratio = 0.2
- n = 25000
- organize_datasets(path_to_data='./train/',n=n, ratio=ratio)
現(xiàn)在讓我們裝載 Keras 和它的依賴包吧:
- import keras
- from keras.preprocessing.image import ImageDataGenerator
- from keras_tqdm import TQDMNotebookCallback
- from keras.models import Sequential
- from keras.layers import Dense
- from keras.layers import Dropout
- from keras.layers import Flatten
- from keras.constraints import maxnorm
- from keras.optimizers import SGD
- from keras.layers.convolutional import Conv2D
- from keras.layers.convolutional import MaxPooling2D
- from keras.utils import np_utils
- from keras.callbacks import Callback
圖像生成器和數(shù)據(jù)增強(qiáng)
在訓(xùn)練模型時,我們不會將整個數(shù)據(jù)集裝載進(jìn)內(nèi)存,因為這種做法并不高效,特別是你使用的還是你自己本地的機(jī)器。
我們將用到 ImageDataGenerator 類,這個類可以***制地從訓(xùn)練集和測試集中批量地引入圖像流。在ImageDataGenerator 類中,我們將在每個批次引入隨機(jī)修改。
這個過程我們稱之為數(shù)據(jù)增強(qiáng)(dataaugmentation)。它可以生成更多的圖片使得我們的模型不會看見兩張完全相同的圖片。這種方法可以防止過擬合,也有助于模型保持更好的泛化性。
我們要創(chuàng)建兩個 ImageDataGenerator 對象。train_datagen 對應(yīng)訓(xùn)練集,val_datagen 對應(yīng)測試集,兩者都會對圖像進(jìn)行縮放,train_datagen 還將做一些其他的修改。
- batch_size = 32
- train_datagen = ImageDataGenerator(rescale=1/255.,
- shear_range=0.2,
- zoom_range=0.2,
- horizontal_flip=True
- )
- val_datagen = ImageDataGenerator(rescale=1/255.)
基于前面的兩個對象,我們接著創(chuàng)建兩個文件生成器:
- train_generator
- validation_generator
每個生成器在實(shí)時數(shù)據(jù)增強(qiáng)的作用下,在目錄處可以生成批量的圖像數(shù)據(jù)。這樣,數(shù)據(jù)將會***制地循環(huán)生成。
- train_generator = train_datagen.flow_from_directory(
- './data/train/',
- target_size=(150, 150),
- batch_size=batch_size,
- class_mode='categorical')
- validation_generator = val_datagen.flow_from_directory(
- './data/validation/',
- target_size=(150, 150),
- batch_size=batch_size,
- class_mode='categorical')
- ##Found 20000 images belonging to 2 classes.
- ##Found 5000 images belonging to 2 classes.
模型結(jié)構(gòu)
我將使用擁有 3 個卷積/池化層和 2 個全連接層的 CNN。3 個卷積層將分別使用 32,32,64 的 3 * 3的濾波器(fiter)。在兩個全連接層,我使用了 dropout 來避免過擬合。
- model = Sequential()
- model.add(Conv2D(32, (3, 3), input_shape=(150, 150, 3), padding='same', activation='relu'))
- model.add(MaxPooling2D(pool_size=(2, 2)))
- model.add(Conv2D(32, (3, 3), padding='same', activation='relu'))
- model.add(MaxPooling2D(pool_size=(2, 2)))
- model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
- model.add(MaxPooling2D(pool_size=(2, 2)))
- model.add(Dropout(0.25))
- model.add(Flatten())
- model.add(Dense(64, activation='relu'))
- model.add(Dropout(0.5))
- model.add(Dense(2, activation='softmax'))
我使用隨機(jī)梯度下降法進(jìn)行優(yōu)化,參數(shù) learning rate 為 0.01,momentum 為 0.9。
- epochs = 50
- lrate = 0.01
- decay = lrate/epochs
- sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
- model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
Keras 提供了一個非常方便的方法來展示模型的全貌。對每一層,我們可以看到輸出的形狀和可訓(xùn)練參數(shù)的個數(shù)。在開始擬合模型前,檢查一下是個明智的選擇。
model.summary()
下面讓我們看一下網(wǎng)絡(luò)的結(jié)構(gòu)。
結(jié)構(gòu)可視化
在訓(xùn)練模型前,我定義了兩個將在訓(xùn)練時調(diào)用的回調(diào)函數(shù) (callback function):
- 一個用于在損失函數(shù)無法改進(jìn)在測試數(shù)據(jù)的效果時,提前停止訓(xùn)練。
- 一個用于存儲每個時期的損失和精確度指標(biāo):這可以用來繪制訓(xùn)練錯誤圖表。
- ## Callback for loss logging per epoch
- class LossHistory(Callback):
- def on_train_begin(self, logs={}):
- self.losses = []
- self.val_losses = []
- def on_epoch_end(self, batch, logs={}):
- self.losses.append(logs.get('loss'))
- self.val_losses.append(logs.get('val_loss'))
- history = LossHistory()
- ## Callback for early stopping the training
- early_stopping = keras.callbacks.EarlyStopping(monitor='val_loss',
- min_delta=0,
- patience=2,
- verbose=0, mode='auto')
我還使用了 keras-tqdm,這是一個和 keras ***整合的非常棒的進(jìn)度條。它可以讓我們非常容易地監(jiān)視模型的訓(xùn)練過程。
要想使用它,你僅需要從 keras_tqdm 中加載 TQDMNotebookCallback 類,然后將它作為第三個回調(diào)函數(shù)傳遞進(jìn)去。
下面的圖在一個簡單的樣例上展示了 keras-tqdm 的效果。
關(guān)于訓(xùn)練過程,還有幾點(diǎn)要說的:
- 我們使用 fit_generator 方法,它是一個將生成器作為輸入的變體(標(biāo)準(zhǔn)擬合方法)。
- 我們訓(xùn)練模型的時間超過 50 個 epoch。
- fitted_model = model.fit_generator(
- train_generator,
- steps_per_epoch= int(n * (1-ratio)) // batch_size,
- epochs=50,
- validation_data=validation_generator,
- validation_steps= int(n * ratio) // batch_size,
- callbacks=[TQDMNotebookCallback(leave_inner=True, leave_outer=True), early_stopping, history],
- verbose=0)
這個模型運(yùn)行時的計算量非常大:
- 如果你在自己的電腦上跑,每個 epoch 會花費(fèi) 15 分鐘的時間。
- 如果你和我一樣在 EC2 上的 p2.xlarge 虛擬機(jī)上跑,每個 epoch 需要花費(fèi) 2 分鐘的時間。
分類結(jié)果
我們在模型運(yùn)行 34 個 epoch 后達(dá)到了 89.4% 的準(zhǔn)確率(下文展示訓(xùn)練/測試錯誤和準(zhǔn)確率),考慮到我沒有花費(fèi)很多時間來設(shè)計網(wǎng)絡(luò)結(jié)構(gòu),這已經(jīng)是一個很好的結(jié)果了。現(xiàn)在我們可以將模型保存,以備以后使用。
model.save(`./models/model4.h5)
下面我們在同一張圖上繪制訓(xùn)練和測試中的損失指標(biāo)值:
- losses, val_losses = history.losses, history.val_losses
- fig = plt.figure(figsize=(15, 5))
- plt.plot(fitted_model.history['loss'], 'g', label="train losses")
- plt.plot(fitted_model.history['val_loss'], 'r', label="val losses")
- plt.grid(True)
- plt.title('Training loss vs. Validation loss')
- plt.xlabel('Epochs')
- plt.ylabel('Loss')
- plt.legend()
當(dāng)在兩個連續(xù)的 epoch 中,測試損失值沒有改善時,我們就中止訓(xùn)練過程。
下面繪制訓(xùn)練集和測試集上的準(zhǔn)確度。
- losses, val_losses = history.losses, history.val_losses
- fig = plt.figure(figsize=(15, 5))
- plt.plot(fitted_model.history['acc'], 'g', label="accuracy on train set")
- plt.plot(fitted_model.history['val_acc'], 'r', label="accuracy on validation set")
- plt.grid(True)
- plt.title('Training Accuracy vs. Validation Accuracy')
- plt.xlabel('Epochs')
- plt.ylabel('Loss')
- plt.legend()
這兩個指標(biāo)一直是增長的,直到模型即將開始過擬合的平穩(wěn)期。
裝載預(yù)訓(xùn)練的模型
我們在自己設(shè)計的 CNN 上取得了不錯的結(jié)果,但還有一種方法能讓我們?nèi)〉酶叩姆謹(jǐn)?shù):直接載入一個在大型數(shù)據(jù)集上預(yù)訓(xùn)練過的卷積神經(jīng)網(wǎng)絡(luò)的權(quán)重,這個大型數(shù)據(jù)集包含 1000 個種類的貓和狗的圖片。
這樣的網(wǎng)絡(luò)會學(xué)習(xí)到與我們分類任務(wù)相關(guān)的特征。
我將加載 VGG16 網(wǎng)絡(luò)的權(quán)重,具體來說,我要將網(wǎng)絡(luò)權(quán)重加載到所有的卷積層。這個網(wǎng)絡(luò)部分將作為一個特征檢測器來檢測我們將要添加到全連接層的特征。
與 LeNet5 相比,VGG16 是一個非常大的網(wǎng)絡(luò),它有 16 個可以訓(xùn)練權(quán)重的層和 1.4 億個參數(shù)。要了解有關(guān) VGG16 的信息,請參閱此篇 pdf 鏈接:https://arxiv.org/pdf/1409.1556.pdf
- from keras import applications
- # include_top: whether to include the 3 fully-connected layers at the top of the network.
- model = applications.VGG16(include_top=False, weights='imagenet')
- datagen = ImageDataGenerator(rescale=1. / 255)
現(xiàn)在我們將圖像傳進(jìn)網(wǎng)絡(luò)來得到特征表示,這些特征表示將會作為神經(jīng)網(wǎng)絡(luò)分類器的輸入。
- generator = datagen.flow_from_directory('./data/train/',
- target_size=(150, 150),
- batch_size=batch_size,
- class_mode=None,
- shuffle=False)
- bottleneck_features_train = model.predict_generator(generator, int(n * (1 - ratio)) // batch_size)
- np.save(open('./features/bottleneck_features_train.npy', 'wb'), bottleneck_features_train)
- ##Found 20000 images belonging to 2 classes.
- generator = datagen.flow_from_directory('./data/validation/',
- target_size=(150, 150),
- batch_size=batch_size,
- class_mode=None,
- shuffle=False)
- bottleneck_features_validation = model.predict_generator(generator, int(n * ratio) // batch_size,)
- np.save('./features/bottleneck_features_validation.npy', bottleneck_features_validation)
- ##Found 5000 images belonging to 2 classes.
圖像在傳遞到網(wǎng)絡(luò)中時是有序傳遞的,所以我們可以很容易地為每張圖片關(guān)聯(lián)上標(biāo)簽。
- train_data = np.load('./features/bottleneck_features_train.npy')
- train_labels = np.array([0] * (int((1-ratio) * n) // 2) + [1] * (int((1 - ratio) * n) // 2))
- validation_data = np.load('./features/bottleneck_features_validation.npy')
- validation_labels = np.array([0] * (int(ratio * n) // 2) + [1] * (int(ratio * n) // 2))
現(xiàn)在我們設(shè)計了一個小型的全連接神經(jīng)網(wǎng)絡(luò),附加上從 VGG16 中抽取到的特征,我們將它作為 CNN 的分類部分。
- model = Sequential()
- model.add(Flatten(input_shape=train_data.shape[1:]))
- model.add(Dense(512, activation='relu'))
- model.add(Dropout(0.5))
- model.add(Dense(256, activation='relu'))
- model.add(Dropout(0.2))
- model.add(Dense(1, activation='sigmoid'))
- model.compile(optimizer='rmsprop',
- loss='binary_crossentropy', metrics=['accuracy'])
- fitted_model = model.fit(train_data, train_labels,
- epochs=15,
- batch_size=batch_size,
- validation_data=(validation_data, validation_labels[:validation_data.shape[0]]),
- verbose=0,
- callbacks=[TQDMNotebookCallback(leave_inner=True, leave_outer=False), history])
在 15 個 epoch 后,模型就達(dá)到了 90.7% 的準(zhǔn)確度。這個結(jié)果已經(jīng)很好了,注意現(xiàn)在每個 epoch 在我自己的電腦上跑也僅需 1 分鐘。
- fig = plt.figure(figsize=(15, 5))
- plt.plot(fitted_model.history['loss'], 'g', label="train losses")
- plt.plot(fitted_model.history['val_loss'], 'r', label="val losses")
- plt.grid(True)
- plt.title('Training loss vs. Validation loss - VGG16')
- plt.xlabel('Epochs')
- plt.ylabel('Loss')
- plt.legend()
- fig = plt.figure(figsize=(15, 5))
- plt.plot(fitted_model.history['acc'], 'g', label="accuracy on train set")
- plt.plot(fitted_model.history['val_acc'], 'r', label="accuracy on validation sete")
- plt.grid(True)
- plt.title('Training Accuracy vs. Validation Accuracy - VGG16')
- plt.xlabel('Epochs')
- plt.ylabel('Loss')
- plt.legend()
許多深度學(xué)習(xí)領(lǐng)域的大牛人物都鼓勵大家在做分類任務(wù)時使用預(yù)訓(xùn)練網(wǎng)絡(luò),實(shí)際上,預(yù)訓(xùn)練網(wǎng)絡(luò)通常使用的是在一個非常大的數(shù)據(jù)集上生成的非常大的網(wǎng)絡(luò)。
而 Keras 可以讓我們很輕易地下載像 VGG16、GoogleNet、ResNet 這樣的預(yù)訓(xùn)練網(wǎng)絡(luò)。想要了解更多關(guān)于這方面的信息,請參考這里:https://keras.io/applications/
有一句很棒的格言是:不要成為英雄!不要重復(fù)發(fā)明輪子!使用預(yù)訓(xùn)練網(wǎng)絡(luò)吧!
接下來還可以做什么?
如果你對改進(jìn)一個傳統(tǒng) CNN 感興趣的話,你可以:
- 在數(shù)據(jù)集層面上,引入更多增強(qiáng)數(shù)據(jù)。
- 研究一下網(wǎng)絡(luò)超參數(shù)(network hyperparameter):卷積層的個數(shù)、濾波器的個數(shù)和大小,在每種組合后要測試一下效果。
- 改變優(yōu)化方法。
- 嘗試不同的損失函數(shù)。
- 使用更多的全連接層。
- 引入更多的 aggressive dropout。
如果你對使用預(yù)訓(xùn)練網(wǎng)絡(luò)獲得更好的分類結(jié)果感興趣的話,你可以嘗試:
- 使用不同的網(wǎng)絡(luò)結(jié)構(gòu)。
- 使用更多包含更多隱藏單元的全連接層。
如果你想知道 CNN 這個深度學(xué)習(xí)模型到底學(xué)習(xí)到了什么東西,你可以:
- 將 feature maps 可視化。
- 可以參考:https://arxiv.org/pdf/1311.2901.pdf
如果你想使用訓(xùn)練過的模型:
- 可以將模型放到 Web APP 上,使用新的貓和狗的圖像來進(jìn)行測試。這也是一個很好地測試模型泛化性的好方法。
總結(jié)
這是一篇手把手教你在 AWS 上搭建深度學(xué)習(xí)環(huán)境的教程,并且教你怎樣從頭開始建立一個端到端的模型,另外本文也教了你怎樣基于一個預(yù)訓(xùn)練的網(wǎng)絡(luò)來搭建一個 CNN 模型。
用 Python 來做深度學(xué)習(xí)是讓人愉悅的事情,而 Keras 讓數(shù)據(jù)的預(yù)處理和網(wǎng)絡(luò)層的搭建變得更加簡單。
如果有一天你需要按自己的想法來搭建一個神經(jīng)網(wǎng)絡(luò),你可能需要用到其他的深度學(xué)習(xí)框架。
現(xiàn)在在自然語言處理領(lǐng)域,也有很多人開始使用卷積神經(jīng)網(wǎng)絡(luò)了,下面是一些基于此的工作:
使用了 CNN 的文本分類:
https://chara.cs.illinois.edu/sites/sp16-cs591txt/files/0226-presentation.pdf
自動為圖像生成標(biāo)題:
https://cs.stanford.edu/people/karpathy/sfmltalk.pdf
字級別的文本分類:
https://papers.nips.cc/paper/5782-character-level-convolutional-networks-fortext-classification.pdf
【原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請注明原文作者和出處為.com】
文章標(biāo)題:我用Python實(shí)現(xiàn)了12500張貓狗圖像的精準(zhǔn)分類
新聞來源:http://m.fisionsoft.com.cn/article/cdiopsh.html


咨詢
建站咨詢
