当前位置:   article > 正文

用PyTorch实现Logistic回归_pytorch logistic模型

pytorch logistic模型

目录

1、数据准备

2、线性方程

3、激活函数、损失函数

4、利用nn.Module来实现Logistic回归

1、数据准备

  1. #导包
  2. import torch
  3. from torch import nn
  4. import matplotlib.pyplot as plt
  5. # %matplotlib inline
  6. import numpy as np
  7. from torch.distributions import MultivariateNormal
  8. # 设置两组不同的均值向量和协方差矩阵
  9. # torch.eye()主要是为了生成对角线全是1,其余部分全0的二维数组
  10. mu1 = -3 * torch.ones(2)
  11. mu2 = 3 * torch.ones(2)
  12. sigma1 = torch.eye(2) * 0.5
  13. sigma2 = torch.eye(2) * 2
  14. # 各从两个多元高斯分布中生成100个样本
  15. # 此处定义的多元高斯是二维的
  16. m1 = MultivariateNormal(mu1, sigma1)
  17. m2 = MultivariateNormal(mu2, sigma2)
  18. x1 = m1.sample((100,))
  19. x2 = m2.sample((100,))
  20. #设置正负样本的标签
  21. y = torch.zeros((200, 1))
  22. y[100:] = 1
  23. # 组合、打乱样本
  24. x = torch.cat([x1, x2], dim=0)
  25. # np.random.permutation():1、产生一个随机序列 2、对一个随机序列x进行随机排序 3、如果x是一个多维数组,它只会按照第一个索引洗牌
  26. idx = np.random.permutation(len(x))
  27. x = x[idx]
  28. y = y[idx]
  29. # # 绘制样本
  30. plt.scatter(x1.numpy()[:,0], x1.numpy()[:,1])
  31. plt.scatter(x2.numpy()[:,0], x2.numpy()[:,1])
  32. plt.show()

结果:

从图中可以看出右上角的簇样本分布稀疏,而左下角分布紧凑。可以自行调整9-10行代码的参数,观察其变化。

2、线性方程

  1. # 线性方程
  2. # D_in为输入的特征数,D_out为输出的特征数
  3. D_in, D_out = 2, 1
  4. linear = nn.Linear(D_in, D_out, bias=True)
  5. output = linear(x)
  6. print(x.shape, linear.weight.shape, linear.bias.shape, output.shape)
  7. def my_linear(x, w, b):
  8. return torch.mm(x, w.t()) + b
  9. torch.sum((output - my_linear(x, linear.weight, linear.bias)))

3、激活函数、损失函数

  1. # 激活函数
  2. sigmoid = nn.Sigmoid()
  3. scores = sigmoid(output)
  4. def my_sigmoid(x):
  5. x = 1/(1 + torch.exp(-x))
  6. return x
  7. # 通过PyTorch验证我们的试验结果
  8. torch.sum(scores - my_sigmoid(output))
  9. # 损失函数
  10. # Logistic回归使用交叉熵作为损失函数
  11. loss = nn.BCELoss()
  12. loss(scores, y)
  13. # 下面自定义了二值交叉熵函数,将my_loss和PyTorch的BCELoss进行比较
  14. def my_loss(x, y):
  15. loss = - torch.mean(torch.log(x) * y + torch.log(1 - x) * (1 - y))
  16. return loss
  17. loss(scores, y) - my_loss(my_sigmoid(output), y)

4、利用nn.Module来实现Logistic回归

以上是我们使用的torch.nn包中的线性模型nn.Linear、激活函数,损失函数,它们都继承自nn.Module类。而在PyTorch中,我们继承nn.Module来构建我们自己的模型。接下来我们用nn.Module来实现Logistic回归。
  1. import torch.nn as nn
  2. class LogisticRegression(nn.Module):
  3. def __init__(self, D_in):
  4. super(LogisticRegression, self).__init__()
  5. self.linear = nn.Linear(D_in, 1)
  6. self.sigmoid = nn.Sigmoid()
  7. # forward方法是必须被子类覆写的,在forward内部应当定义每次调用模型时执行的计算
  8. def forward(self, x):
  9. x = self.linear(x)
  10. x = self.sigmoid(x)
  11. return x
  12. #nn.Module类的主要作用就是接收Tensor然后计算并返回结果
  13. lr_model = LogisticRegression(2)
  14. loss = nn.BCELoss()
  15. # print(loss(lr_model(x), y))
  16. # 优化算法
  17. '''
  18. Logistic回归通常采用梯度下降法优化目标函数。
  19. PyTorch的torch.optim包实现了大多数常用算法
  20. '''
  21. from torch import optim
  22. optimizer = optim.SGD(lr_model.parameters(), lr=0.03)
  23. '''
  24. 构建完优化器,就可以迭代地对模型进行训练,有两个步骤:
  25. 1、调用损失函数的backward方法计算模型的梯度
  26. 2、调用优化器的step方法更新模型的参数
  27. 需要注意的是,应当提前调用优化器zero_grad方法清空参数的梯度
  28. '''
  29. batch_size = 10
  30. iters = 10
  31. # for input, target in dataset:
  32. for _ in range(iters):
  33. for i in range(int(len(x)/batch_size)):
  34. input = x[i*batch_size:(i+1)*batch_size]
  35. target = y[i*batch_size:(i+1)*batch_size]
  36. optimizer.zero_grad()
  37. output = lr_model(input)
  38. l = loss(output, target)
  39. l.backward()
  40. optimizer.step()
  41. # 优化算法
  42. '''
  43. Logistic回归模型的判决边界在高维空间的一个超平面,而我们的数据集是二维,所以判决边界只是平面内的一条直线,
  44. 在线的一侧被预测为正类,另一侧则被预测为父类。
  45. draw_decision_boundary函数接收线性模型的参数w和b,以及数据集x。
  46. 绘制判决边界只需要计算一些数据在线模型的映射值,然后调用plt.plot绘制线条即可。
  47. '''
  48. pred_neg = (output <= 0.5).view(-1)
  49. pred_pos = (output > 0.5).view(-1)
  50. plt.scatter(x[pred_neg, 0], x[pred_neg, 1])
  51. plt.scatter(x[pred_neg, 0], x[pred_pos, 1])
  52. w = lr_model.linear.weight[0]
  53. b = lr_model.linear.bias[0]
  54. def draw_decision_boundary(w, b, x0):
  55. x1 = (-b - w[0] * x0) / w[1]
  56. plt.plot(x0.detach().numpy(), x1.detach().numpy(), 'r')
  57. plt.show()
  58. draw_decision_boundary(w, b, torch.linspace(x.min(), x.max(), 50))


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/709712
推荐阅读
相关标签
  

闽ICP备14008679号