UP:B站-刘二大人
原视频链接:07.处理多维特征的输入_哔哩哔哩_bilibili
提示:数据集在视频开头即给出下载方式。
import torch
import matplotlib.pyplot as plt
import numpy as np
# 准备数据
# diabetes数据集的输入是8列输出1列,即可以理解成输入8维,输出1维
# 数据集的意思是:X1~X8是糖尿病病人的八项指标,输出y的0,1代表一年后糖尿病患者的病情是否加重
# 指定数据类型为float32而不用double的原因是:在神经网络中的计算我们都习惯用32位的浮点数,因为GPU环境很多显卡比如1080都不支持double类型,只支持32位浮点数
xy = np.loadtxt("diabetes.csv", delimiter = ",", dtype = np.float32)
# 将数组转换成张量,所有行,列数是到最后一列为止(不包括最后一列)
# 划分出训练集和测试集
x_data = torch.from_numpy(xy[:-6, :-1])
# 将数组转换成张量,所有行,列数是最后一列
y_data = torch.from_numpy(xy[:-6, [-1]]) # 注意:这个-1外面需要加[],如果不加得到的是一个向量,加了得到的是矩阵
# 设计模型
class Model(torch.nn.Module):
# 构造函数
def __init__(self):
super(Model, self).__init__()
self.linear1 = torch.nn.Linear(8, 6)
self.linear2 = torch.nn.Linear(6, 4)
self.linear3 = torch.nn.Linear(4, 1)
self.active = torch.nn.ReLU()
self.sigmoid = torch.nn.Sigmoid()
# 前馈计算函数
def forward(self, x):
x = self.active(self.linear1(x))
x = self.active(self.linear2(x))
# 最后这个激活函数这里不能是relu,因为relu会把小于0的变成0,但是损失函数涉及到一个取log的过程,所以不能是0
x = self.sigmoid(self.linear3(x)) # 最后一步激活函数把输出转换到(0, 1)之间
return x
# 实例化模型
model = Model()
# 损失函数
criterion = torch.nn.BCELoss(reduction='mean')
# 优化器
optimizer = torch.optim.SGD(model.parameters(), lr = 0.1)
# 为画图做准备
loss_list = []
epoch_list = []
# 训练过程
for epoch in range(10000):
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
print("epoch:", epoch, "loss:", loss.data.item())
# 为画图做准备
epoch_list.append(epoch)
loss_list.append(loss.data.item())
# 梯度清零
optimizer.zero_grad()
# 反向传播
loss.backward()
# 权重更新
optimizer.step()
# 测试过程
# 划分测试集
x_test = torch.from_numpy(xy[-6:, :-1])
y_val = torch.from_numpy(xy[-6:, -1])
y_pred = model(x_test)
print("y_val:", y_val.data.tolist())
print("y_pred:", y_pred.data.tolist())
# 二维曲线图
plt.plot(epoch_list, loss_list)
plt.xlabel("epoch")
plt.ylabel("loss")
plt.show()