赞
踩
下面的代码以二维输入为例,实现二分类的感知机算法
import matplotlib.pyplot as plt import torch import torch.utils.data as Data import numpy as np class Perceptron: # 注意,为了我们能看到训练的效果,特意将learning_rate设的很小 def __init__(self, X, y, learn_rate=0.00001, batch_size=16, epoch=100): # feature_num特征数,label_num标签数 self.feature_num = X_train.shape[1] self.label_num = 1 # 权重初始化为均值为1,方差为0.01的正态随机数 self.weight = torch.normal(1, 0.01, size=(self.feature_num,), requires_grad=True) # 偏差初始化为均值为0,方差为0.01的正态随机数 self.bias = torch.normal(0, 0.01, size=(1,), requires_grad=True) # 批数据生成器 self.train_iter = Data.DataLoader( Data.TensorDataset(torch.tensor(X, dtype=torch.float32), torch.tensor(y, dtype=torch.float32)), batch_size=batch_size, shuffle=True) self.batch_size = batch_size self.learn_rate = learn_rate self.epoch = epoch def loss(self, X, y): l = - torch.mul(y, (torch.matmul(X, self.weight) + self.bias)) # 损失函数只计算错误分类的样本,故l小于0时应当作做0处理,相当于使用ReLU做处理 return torch.nn.ReLU()(l) def train(self): # 训练函数 log = [] for j in range(self.epoch): all_l = 0 for X, y in self.train_iter: l = self.loss(X, y).sum() if l > 0: # 如果不使用pytorch的自动求导,那么就使用下方注释代码 # self.weight = self.weight + self.learn_rate * torch.matmul(y, X) # self.bias = self.bias + self.learn_rate * y.sum() # 反向传播,求导 l.backward() # 必须加上.data,否则梯度会被修改 self.weight.data = self.weight.data - self.learn_rate * self.weight.grad.data self.bias.data = self.bias.data - self.learn_rate * self.bias.grad.data # 梯度清零 self.weight.grad.data.zero_() self.bias.grad.data.zero_() all_l += l.data.item() log.append(all_l) # plot(X_test, y_test, self.weight, self.bias) return log def predict(self, X, y=None): X = torch.tensor(X, dtype=torch.float32) pred_num = X.shape[0] ans = [] for i in range(pred_num): ans.append(torch.sign(torch.dot(self.weight, X[i]))) if y is not None: y = torch.tensor(y, dtype=torch.float32) print("识别正确率:%s"%((torch.tensor(ans) == y).sum()/y.shape[0])) plot(X, y, self.weight, self.bias) return ans # 产生样本数据 def generate(): from sklearn.datasets import make_blobs X_data, y_data = make_blobs(n_samples=1000, n_features=2, centers=2) X_train, y_train = X_data[:800], y_data[:800] X_test, y_test = X_data[800:], y_data[800:] y_train = np.where(y_train == 0, -1, 1) y_test = np.where(y_test == 0, -1, 1) return X_train, y_train, X_test, y_test # 绘制样本和模型 def plot(X, y, w, b): with torch.no_grad(): plt.scatter(X[:, 0], X[:, 1], c=y) x = torch.linspace(-10, 10, 500) # 创建分类线上的点,以点构线。 y = -w[0] / w[1] * x - b / w[1] plt.scatter(x, y, c=torch.zeros(size=(500,))) plt.show() # 绘制损失曲线 def plot_history(history): plt.plot(np.arange(len(history)), history) plt.show() X_train, y_train, X_test, y_test = generate() model = Perceptron(X_train, y_train, epoch=100) log = model.train() plot_history(log) model.predict(X_test, y_test)
epoch为100的情况下
损失曲线如下
测试集与模型可视化如图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。