Pytorch学习之线性回归分类
2019-01-05 本文已影响0人
骆旺达
pytorch学习之回归分类
引用库
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
import numpy as np
数据导出
with open("G:\大四\pytorch学习\learning_pyTorch_with_SherlockLiao-master\Chapter_3\logistRegression/data.txt",'r') as f:
# 读每行数据
data_list = f.readlines()
# 通过换行分割数据
data_list = [i.split('\n')[0] for i in data_list]
# 通过,分割数据![image.png](https://img.haomeiwen.com/i15573329/3e616f8ebe559e53.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
data_list = [i.split(',') for i in data_list]
# 获得数据中[0],[1],[2]的数据
data = [(float(i[0]),float(i[1]),float(i[2])) for i in data_list]
数据展示
# 获得标记为0的点坐标
x0 = list(filter(lambda x:x[-1] == 0.0 ,data))
# 获得标记为1的点坐标
x1 = list(filter(lambda x:x[-1] == 1.0 ,data))
# 分别获得点坐标的x和y轴
plot_x0_0 = [i[0] for i in x0]
plot_x0_1 = [i[1] for i in x0]
plot_x1_0 = [i[0] for i in x1]
plot_x1_1 = [i[1] for i in x1]
# 显示
plt.plot(plot_x0_0,plot_x0_1,'ro',label='x_0',color="blue")
plt.plot(plot_x1_0,plot_x1_1,'ro',label='x_1')
plt.legend(loc='best')
image.png
获得数据
# 分别获得标注为0和1的数据的点坐标(x,y)
label0 = np.array([(float(row[0]), float(row[1])) for row in data if row[2] == 0])
label1 = np.array([(float(row[0]), float(row[1])) for row in data if row[2] == 1])
# 将点坐标合并连接起来
x = np.concatenate((label0,label1), axis = 0)
x_data = torch.from_numpy(x).float()
# 分别获得对应的标注(既0或者1,将其连接起来)
y = [[0] for i in range(label0.shape[0])]
y += [[1] for i in range(label1.shape[0])]
y_data = torch.FloatTensor(y)
设置模型
# 建立回归模型
class LogisticRegression(nn.Module):
# 建立一层线程神经网络层和激活函数
def __init__(self):
super().__init__()
self.lr = nn.Linear(2, 1)
self.sm = nn.Sigmoid()
# 前向传播,通过学习率和sigmod函数激活x
def forward(self,x):
x = self.lr(x)
x = self.sm(x)
return x
# 建立模型对象
logistic_model = LogisticRegression()
if torch.cuda.is_available():
logistic_model.cuda()
设置损失函数和优化器
# 交叉熵损失函数
criterion = nn.BCELoss()
# 带动量的随机梯度下降优化器
optimizer = torch.optim.SGD(logistic_model.parameters(),lr=1e-3,momentum=0.9)
image.png
模型训练
# 训练50000次
for epoch in range(50000):
# 将数据转换为tensor变量
if torch.cuda.is_available():
x = Variable(x_data).cuda()
y = Variable(y_data).cuda()
else:
x = Variable(x_data)
y = Variable(y_data)
# 向前传播,计算输出及损失函数
out = logistic_model(x)
loss = criterion(out,y)
print_loss = loss.data[0]
# 判断输出结果如果大于0.5就等于1,小于0.5就等于0
mask = out.ge(0.5).float()
correct = (mask==y).sum()
acc = correct.data[0].item()/ x.size(0)
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1) %1000 ==0:
print('*'*10)
print('epoch {}'.format(epoch+1))
print('loss is {:.4f}'.format(print_loss))
print('acc is {:.4f}'.format(acc))
可视化分类结果
# 获得权值
weight = logistic_model.lr.weight[0]
w0, w1 = weight[0], weight[1]
b = logistic_model.lr.bias.data[0]
plt.plot(plot_x0_0,plot_x0_1,'ro',label='x_0',color="blue")
plt.plot(plot_x1_0,plot_x1_1,'ro',label='x_1')
plt.legend(loc = 'best')
plot_x = np.arange(30, 100, 0.1)
plot_y = (-w0.item() * plot_x - b.item()) / w1.item()
plt.plot(plot_x, plot_y)
plt.show()
image.png
总结
本实验是训练一个线性回归分类问题
目的是为了训练
w0*x + w1*y + b =0
则
y = (-w0*x-b)/w1