孤独腹地 2021-10-22 11:27 采纳率: 100%
浏览 39
已结题

感知机算法的pytorch实现代码

这是我的代码


import matplotlib.pyplot as plt
import torch
import torch.utils.data as Data
import numpy as np


class Perceptron:
    def __init__(self, X, y, learn_rate=0.01, batch_size=32, epoch=100):  # feature_num特征数,label_num标签数,dataMat训练数据矩阵
        self.feature_num = X_train.shape[1]
        self.label_num = 1
        self.weight = torch.normal(0, 0.01, size=(self.feature_num,), requires_grad=True) 
        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):  # 单次loss function的相反数
        return - torch.mul(y, (torch.matmul(X, self.weight) + self.bias))

    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()
                # 反向传播
                l.backward()
                # 梯度更新
                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 / 100000)
        plot_history(log)
        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)
            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)
model.train()
model.predict(X_test, y_test)

感觉有很多问题,pytorch也不熟悉,希望有人指点迷津

  • 写回答

1条回答 默认 最新

  • 孤独腹地 2021-10-22 19:40
    关注

    应该解决了

    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:
                        # self.weight = self.weight + self.learn_rate * torch.matmul(y, X)
                        # self.bias = self.bias + self.learn_rate * y.sum()
                        l.backward()
                        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)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 11月2日
  • 已采纳回答 10月25日
  • 创建了问题 10月22日

悬赏问题

  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3