這個文章是用pytorch和matplotlib實現一個二元分類器而且可視化。python
定義網絡、訓練網絡主要沒什麼好說的啦其實,畢竟有pytorch這麼好的框架,已經提供瞭如此簡單的代碼工做。網絡
主要是可視化的技巧。框架
主要是matplotlib中有個contourf,自己是畫等高線用的,就是地理中那個三維圖投射到二維圖的那種圖。函數
咱們能夠把這個用到可視化上來(固然只是3維的,若是是更高維度就無法用這個可視化了)。spa
首先,先本身生成200個訓練數據(這步對應getData函數),而後把屬於不一樣類別的數據染上不一樣顏色;
而後,進行網絡的訓練(對應run函數);
而後,用一樣的數據讓網絡進行預測。由於二元分類器最後預測的結果要麼是0,要麼是1,因此能夠利用matplotlib中的畫等高線的函數,來近似畫出決策邊界。這一步主要對應showBoundary函數。code
這個函數我本身在用的時候有點懵逼,使用這個要先meshgrid,mesh合併的意思,grid網格的意思,要把兩個列表先合成一個網格,這個形式我也不是很喜歡。
勉勉強強參考了一些博客才寫了出來。具體我也沒辦法一一講述,還請各位原諒。
不過其中,cmap是畫出來的圖的風格參數,能夠是camp=plt.cm.hot等等,alpha是透明度。orm
用了conturf這個函數,就能夠有顏色的區別了。blog
import torch import torch.nn.modules import torch.nn import numpy as np from torch.autograd import Variable #torch的基本變量 import torch.nn.functional as F #裏面有不少torch的函數 import matplotlib.pyplot as plt #定義自帶forward propagation的神經網絡。 class Net(torch.nn.Module): def __init__(self,n_features,n_hiddens,n_outputs): super(Net,self).__init__() self.hidden=torch.nn.Linear(n_features,n_hiddens) self.predict=torch.nn.Linear(n_hiddens,n_outputs) def forward(self, x): x=F.relu(self.hidden(x)) predict=F.softmax(self.predict(x)) return predict class MyNet: def __init__(self,n_features,n_hiddens,n_outputs,times): self.NeuronalNet=Net(n_features,n_hiddens,n_outputs) self.realX=None self.realY=None self.opitimizer=None self.lossFunc=None self.times=times #訓練集 def getData(self): temp = torch.ones(100, 2) B = torch.normal(2 * temp, 1) By = torch.ones(100) A = torch.normal(-2 * temp, 1) Ay = torch.zeros(100) self.realX = Variable(torch.cat([A, B], 0)) self.realY = Variable(torch.cat([Ay, By]).type(torch.LongTensor)) # plt.scatter(realX.data.numpy()[:,0],realX.data.numpy()[:,1],c=realY) # plt.show() def run(self): self.opitimizer=torch.optim.SGD(self.NeuronalNet.parameters(),lr=0.01) self.lossFunc=torch.nn.CrossEntropyLoss() for i in range(self.times): out=self.NeuronalNet(self.realX) loss=self.lossFunc(out,self.realY) self.opitimizer.zero_grad() loss.backward() self.opitimizer.step() #可視化 def showBoundary(self): x_min, x_max = self.realX[:, 0].min() - 0.1, self.realX[:, 0].max() + 0.1 y_min, y_max = self.realX[:, 1].min() - 0.1, self.realX[:, 1].max() + 0.1 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 101), np.linspace(y_min, y_max, 101)) cmap = plt.cm.Spectral X_test = torch.from_numpy(np.c_[xx.ravel(), yy.ravel()]).float() y_pred = self.NeuronalNet(X_test) _, y_pred = y_pred.max(dim=1) y_pred = y_pred.reshape(xx.shape) plt.contourf(xx, yy, y_pred, cmap=plt.cm.Spectral, alpha=0.8) plt.scatter(self.realX[:, 0], self.realX[:, 1], c=self.realY, s=40, cmap=plt.cm.RdYlBu) plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) plt.title("binary classifier") plt.show() def predict(self,inputData): #inputData should be a 1x2 matrix data=torch.from_numpy(np.array(inputData)).int() return self.NeuronalNet(data.float()) if __name__=="__main__": myNet =MyNet(2,18,2,1000) myNet.getData() myNet.run() myNet.showBoundary() probabilitys=list(myNet.predict([3, 3]).data.numpy()) print("是第{0}類".format(1+probabilitys.index(max(probabilitys))))