基于nolear建立的ConvNet體系結(jié)構(gòu)并用它去訓(xùn)練一個特征提取器
摘要:本文展示了如何基于nolearn使用一些卷積層和池化層來建立一個簡單的ConvNet體系結(jié)構(gòu),以及如何使用ConvNet去訓(xùn)練一個特征提取器,然后在使用如SVM、LogisTIc回歸等不同的模型之前使用它來進行特征提取。
卷積神經(jīng)網(wǎng)絡(luò)(ConvNets)是受生物啟發(fā)的MLPs(多層感知器),它們有著不同類別的層,并且每層的工作方式與普通的MLP層也有所差異。如果你對ConvNets感興趣,這里有個很好的教程CS231n – ConvoluTIonal Neural Newtorks for Visual RecogniTIon。CNNs的體系結(jié)構(gòu)如下所示:
常規(guī)的神經(jīng)網(wǎng)絡(luò)
ConvNet網(wǎng)絡(luò)體系結(jié)構(gòu)
如你所見,ConvNets工作時伴隨著3D卷積并且在不斷轉(zhuǎn)變著這些3D卷積。我在這篇文章中不會再重復(fù)整個CS231n的教程,所以如果你真的感興趣,請在繼續(xù)閱讀之前先花點時間去學(xué)習(xí)一下。
Lasagne 和 nolearn
Lasagne和nolearn是我最喜歡使用的深度學(xué)習(xí)Python包。Lasagne是基于Theano的,所以GPU的加速將大有不同,并且其對神經(jīng)網(wǎng)絡(luò)創(chuàng)建的聲明方法也很有幫助。nolearn庫是一個神經(jīng)網(wǎng)絡(luò)軟件包實用程序集(包含Lasagne),它在神經(jīng)網(wǎng)絡(luò)體系結(jié)構(gòu)的創(chuàng)建過程上、各層的檢驗等都能夠給我們很大的幫助。
在這篇文章中我要展示的是,如何使用一些卷積層和池化層來建立一個簡單的ConvNet體系結(jié)構(gòu)。我還將向你展示如何使用ConvNet去訓(xùn)練一個特征提取器,在使用如SVM、LogisTIc回歸等不同的模型之前使用它來進行特征提取。大多數(shù)人使用的是預(yù)訓(xùn)練ConvNet模型,然后刪除最后一個輸出層,接著從ImageNets數(shù)據(jù)集上訓(xùn)練的ConvNets網(wǎng)絡(luò)提取特征。這通常被稱為是遷移學(xué)習(xí),因為對于不同的問題你可以使用來自其它的ConvNets層,由于ConvNets的第一層過濾器被當(dāng)做是一個邊緣探測器,所以它們可以用來作為其它問題的普通特征探測器。
加載MNIST數(shù)據(jù)集
MNIST數(shù)據(jù)集是用于數(shù)字識別最傳統(tǒng)的數(shù)據(jù)集之一。我們使用的是一個面向Python的版本,但先讓我們導(dǎo)入需要使用的包:
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from urllib import urlretrieve
import cPickle as pickle
import os
import gzip
import numpy as np
import theano
import lasagne
from lasagne import layers
from lasagne.updates import nesterov_momentum
from nolearn.lasagne import NeuralNet
from nolearn.lasagne import visualize
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
正如你所看到的,我們導(dǎo)入了用于繪圖的matplotlib包,一些用于下載MNIST數(shù)據(jù)集的原生Python模塊,numpy, theano,lasagne,nolearn 以及 scikit-learn庫中用于模型評估的一些函數(shù)。
然后,我們定義一個加載MNIST數(shù)據(jù)集的函數(shù)(這個功能與Lasagne教程上使用的非常相似)
def load_dataset():
url = 'http://deeplearning.net/data/mnist/mnist.pkl.gz'
filename = 'mnist.pkl.gz'
if not os.path.exists(filename):
print("Downloading MNIST dataset...")
urlretrieve(url, filename)
with gzip.open(filename, 'rb') as f:
data = pickle.load(f)
X_train, y_train = data[0]
X_val, y_val = data[1]
X_test, y_test = data[2]
X_train = X_train.reshape((-1, 1, 28, 28))
X_val = X_val.reshape((-1, 1, 28, 28))
X_test = X_test.reshape((-1, 1, 28, 28))
y_train = y_train.astype(np.uint8)
y_val = y_val.astype(np.uint8)
y_test = y_test.astype(np.uint8)
return X_train, y_train, X_val, y_val, X_test, y_test
正如你看到的,我們正在下載處理過的MNIST數(shù)據(jù)集,接著把它拆分為三個不同的數(shù)據(jù)集,分別是:訓(xùn)練集、驗證集和測試集。然后重置圖像內(nèi)容,為之后的Lasagne輸入層做準(zhǔn)備,與此同時,由于GPU/theano數(shù)據(jù)類型的限制,我們還把numpy的數(shù)據(jù)類型轉(zhuǎn)換成了uint8。
隨后,我們準(zhǔn)備加載MNIST數(shù)據(jù)集并檢驗它:
X_train, y_train, X_val, y_val, X_test, y_test = load_dataset()
plt.imshow(X_train[0][0], cmap=cm.binary)
這個代碼將輸出下面的圖像(我用的是IPython Notebook)
一個MNIST數(shù)據(jù)集的數(shù)字實例(該實例是5)
ConvNet體系結(jié)構(gòu)與訓(xùn)練