PyBrain官方Tutorial翻譯(二)
3.Classification with Feed-Forward Neural Networks
本節會手把手教你為分類建立一個數據集,訓練相應的網路並且線上公佈視覺化訓練結果。
首先我們需要從PyBrain匯入必要的元件。
frompybrain.datasetsimport ClassificationDataSet
frompybrain.utilitiesimport percentError
frompybrain.tools.shortcutsimport buildNetwork
frompybrain.supervised.trainersimport BackpropTrainer
frompybrain.structure.modulesimport SoftmaxLayer
進一步,需要匯入pylab進行圖形化輸出。
frompylabimport ion, ioff, figure, draw, contourf, clf, show, hold, plot
fromscipyimport diag, arange, meshgrid, where
fromnumpy.randomimport multivariate_normal
為了視覺化展示效果好,我們生成一組2D的從屬於三個不同型別的點。同時,需要一個將資料從一個檔案中讀入的工具,e.g. 使用pylab.load()。
means= [(-1,0),(2,4),(3,1)]
cov= [diag([1,1]), diag([0.5,1.2]), diag([1.5,0.7])]
alldata= ClassificationDataSet(2,1, nb_classes=3)
for n inxrange(400):
for klass inrange(3):
input= multivariate_normal(means[klass],cov[klass])
alldata.addSample(input, [klass])
隨機將資料集分為75%的訓練集和25%的測試集。當然,我們也可以在一開始建立不同的資料集。
tstdata, trndata = alldata.splitWithProportion(0.25 )
對神經網路分類而言,十分建議編譯類別時,每一個輸出神經元對應一個類別。注意這個操作複製原先的目標,並存到一個名為‘class’的(整數)場。(?Forneural network classification, it is highly advisable to encode classes withone output neuron per class. Note that this operation duplicates the originaltargets and stores them in an (integer) field named ‘class’.)
trndata._convertToOneOfMany( )
tstdata._convertToOneOfMany( )
通過列印部分資訊來測試我們的資料集。
print"Number of training patterns: ",len(trndata)
print"Input and output dimensions: ", trndata.indim, trndata.outdim
print"First sample (input, target, class):"
print trndata['input'][0], trndata['target'][0], trndata['class'][0]
現在搭建一個有5個隱藏單元的向前傳遞網路。我們用快捷鍵buildNetwork()來實現。輸入和輸出的層大小必須和資料集輸入和目標維數保持一致。你可以在給定層大小的基礎上加入更多的隱藏層。
我們在解決分類問題,所以輸出層使用一個softmax函式。PyBrain提供更多的選擇,e.g.試著將隱藏層的轉換函式從sigmoid(預設的)變為linear的。
fnn= buildNetwork( trndata.indim,5, trndata.outdim, outclass=SoftmaxLayer )
建立一個訓練器基本上可以說是以網路和資料集作為輸入。檢視trainers可以看到訓練器列表。這裡我們使用BackpropTrainer。
trainer= BackpropTrainer( fnn, dataset=trndata, momentum=0.1, verbose=True, weightdecay=0.01)
現在生成一個數據點的正方形網格,並放入資料集中,從而在視覺化分類結果時可以得到更好的等值線圖。因此,這個資料集的目標值可以被忽略。
ticks= arange(-3.,6.,0.2)
X, Y = meshgrid(ticks, ticks)
# need column vectors in dataset, not arrays
griddata= ClassificationDataSet(2,1, nb_classes=3)
for i inxrange(X.size):
griddata.addSample([X.ravel()[i],Y.ravel()[i]], [0])
griddata._convertToOneOfMany()# this is still needed to make the fnn feel comfy
開始迭代訓練。對網路訓練一定時間。通常你會設定為5,但是為了視覺化目的,我們一次只做一個epoch。
for i in range(20):
trainer.trainEpochs( 1 )
網路在訓練集和測試集上進行評估。有許多種方法來做,例如可以檢視pybrain.tools.validation模組。 這裡我們讓訓練器來做這個測試。
...
trnresult = percentError( trainer.testOnClassData(),
trndata['class'] )
tstresult = percentError( trainer.testOnClassData(
dataset=tstdata ), tstdata['class'] )
print "epoch: %4d" % trainer.totalepochs, \
" train error: %5.2f%%" % trnresult, \
" test error: %5.2f%%" % tstresult
在FNN上執行我們的grid data,得到最近似的分類並且將它們再次組合成一個正方形陣列。
...
out = fnn.activateOnDataset(griddata)
out = out.argmax(axis=1) # the highest output activation gives the class
out = out.reshape(X.shape)
現在plot測試資料和填充顏色等值線作為背景。
...
figure(1)
ioff() # interactive graphics off
clf() # clear the plot
hold(True) # overplot on
for c in [0,1,2]:
here, _ = where(tstdata['class']==c)
plot(tstdata['input'][here,0],tstdata['input'][here,1],'o')
if out.max()!=out.min(): # safety check against flat field
contourf(X, Y, out) # plot the contour
ion() # interactive graphics on
draw() # update the plot
最後,會一直展示圖直到使用者停止。
ioff()
show()