基于pytorch訓(xùn)練神經(jīng)網(wǎng)絡(luò),實(shí)現(xiàn)非線性的分類模型

在平面上,包括了3組不同類別的訓(xùn)練數(shù)據(jù),分別使用紅色、藍(lán)色和綠色表示。
它們呈非線性的分布方式:

我們要基于Pytorch深度學(xué)習(xí)框架,訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)模型,將這三組數(shù)據(jù)分開。
并且,我們要將模型產(chǎn)生的分類決策邊界,使用橙色進(jìn)行標(biāo)記:

分類數(shù)據(jù)的生成
首先來看分類數(shù)據(jù)的生成:

定義函數(shù)make_data,函數(shù)傳入num,代表每種類別的數(shù)據(jù)個(gè)數(shù)。
在函數(shù)中,使用np.random.seed(0),設(shè)定隨機(jī)數(shù)生成器的種子,使隨機(jī)數(shù)序列,每次運(yùn)行時(shí)都是確定的。
定義red保存紅色數(shù)據(jù),數(shù)據(jù)使用make_blobs生成,它是以(0, 0)為中心的正太分布數(shù)據(jù)。
定義green保存綠色數(shù)據(jù),數(shù)據(jù)使用make_circles生成,它分布在紅色數(shù)據(jù)的周圍。
定義blue保存藍(lán)色數(shù)據(jù),數(shù)據(jù)分布在四個(gè)角落。函數(shù)返回三種數(shù)據(jù)。

在main函數(shù)中,調(diào)用make_data,每種類別生成100個(gè)數(shù)據(jù)。然后創(chuàng)建-4到4的平面畫板,并使用plt.scatter繪制出綠色、藍(lán)色和紅色三種數(shù)據(jù)。
神經(jīng)網(wǎng)絡(luò)模型的定義
為了解決該分類問題,我們要定義一個(gè)三層神經(jīng)網(wǎng)絡(luò)。

輸入層包括x1和x2兩個(gè)特征,它們表示平面上,數(shù)據(jù)點(diǎn)的橫坐標(biāo)和縱坐標(biāo)。
隱藏層有5個(gè)神經(jīng)元,它們是解決該分類問題的高級(jí)特征。
輸出層有3個(gè)神經(jīng)元,對(duì)應(yīng)3種不同的類別。
輸出層輸出的y1、y2、y3,會(huì)輸入至softmax函數(shù),轉(zhuǎn)換為三種類別的概率,p1、p2和p3。

代碼實(shí)現(xiàn)如下:

定義神經(jīng)網(wǎng)絡(luò)類Network,它繼承nn.Module類。
實(shí)現(xiàn)類的初始化函數(shù)init,函數(shù)傳入?yún)?shù)n_in, n_hidden, n_out,代表輸入層、隱藏層和輸出層中的神經(jīng)元數(shù)量。
在init函數(shù)中,調(diào)用了父類的初始化函數(shù)super.init。
然后定義兩個(gè)線性層layer1和layer2,layer1是輸入層與隱藏層之間的線性層,layer2是隱藏層與輸出層之間的線性層。
在forward函數(shù)中,實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)的前向傳播。
函數(shù)傳入輸入數(shù)據(jù)x,先計(jì)算layer1的結(jié)果,并進(jìn)行relu激活,再計(jì)算layer2的結(jié)果,并返回。
神經(jīng)網(wǎng)絡(luò)模型的訓(xùn)練
完成模型的定義后,訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型。

定義特征數(shù)n_features=2,隱藏層神經(jīng)元個(gè)數(shù),n_hidden=5,類別數(shù)n_classes=3。
定義迭代次數(shù)n_epochs=10000,學(xué)習(xí)速率learning_rate=0.001。
然后將綠色、藍(lán)色、紅色三種樣本,從numpy數(shù)組轉(zhuǎn)換為張量形式,一起組成訓(xùn)練數(shù)據(jù)data。
設(shè)置label保存三種樣本的標(biāo)簽。
接著創(chuàng)建神經(jīng)網(wǎng)絡(luò)模型實(shí)例model,交叉熵?fù)p失函數(shù)CrossEntropyLoss和Adam優(yōu)化器optimizer。
完成這些必要的變量聲明后,進(jìn)入神經(jīng)網(wǎng)絡(luò)的循環(huán)迭代。

在循環(huán)中,使用當(dāng)前的模型,預(yù)測(cè)訓(xùn)練數(shù)據(jù)data,結(jié)果保存在output中。這里即為前向傳播。
然后調(diào)用criterion,計(jì)算預(yù)測(cè)值output與真實(shí)值label之間的損失loss。
調(diào)用loss.backward,通過自動(dòng)微分計(jì)算損失函數(shù)關(guān)于模型參數(shù)的梯度。
調(diào)用optimizer.step,更新模型參數(shù),使得損失函數(shù)減小。調(diào)用zero_grad,將梯度清零,以便于下一次迭代。這實(shí)際上就是反向傳播。
模型的每一輪迭代,有前向傳播和反向傳播共同組成。

在迭代過程中,每1000次迭代,打印一次當(dāng)前的損失,共打印10次。
這里loss.item對(duì)應(yīng)損失的標(biāo)量值。
繪制決策邊界
定義draw_decision_boundary函數(shù),生成用于繪制決策邊界的等高線數(shù)據(jù)。

傳入的min-x1到max-x1是畫板的橫軸范圍,min-x2到max-x2是畫板的縱軸范圍。
model是訓(xùn)練好的模型。
在函數(shù)中,我們會(huì)根據(jù)已訓(xùn)練的model,計(jì)算對(duì)應(yīng)類別結(jié)果,不同類別結(jié)果會(huì)對(duì)應(yīng)不同的高度,從而基于數(shù)據(jù)點(diǎn)的坐標(biāo)與高度數(shù)據(jù),繪制等高線。

首先調(diào)用mesh-grid生成網(wǎng)格數(shù)據(jù)點(diǎn)。
每個(gè)點(diǎn)的距離是0.02,這樣生成的點(diǎn),可以覆蓋平面的全部范圍。
然后設(shè)置x1s、x2s和z分別表示數(shù)據(jù)點(diǎn)的橫坐標(biāo)、縱坐標(biāo)和類別的預(yù)測(cè)結(jié)果。
遍歷全部樣本,將樣本轉(zhuǎn)為張量后,使用model預(yù)測(cè)結(jié)果,選擇概率最大的類別,添加到高度z中。

這里相當(dāng)于將平面上的黑色點(diǎn),標(biāo)記為紅色、綠色、藍(lán)色三種顏色。
最后將z重新設(shè)置為和xx1相同的形式,然后返回xx1、xx2和z。

在main函數(shù)的最后,使用函數(shù)draw_decision_boundary,生成數(shù)據(jù),然后調(diào)用plt.contour繪制多分類的決策邊界。
運(yùn)行程序,在結(jié)果中可以看到橙色的決策邊界。
那么到這里,使用神經(jīng)網(wǎng)絡(luò),訓(xùn)練非線性的分類模型就講完了,感謝大家的觀看,我們下節(jié)課再會(huì)。