这个文章是用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))))