前几天学习的是一个x数据对应一个y数据,今天学习多个x数据对应一个y数据的情况。
对于下面的数据集,每一行叫做 一个sample 样本,每一列叫做 feature 特征
在数据库里 每一行叫 一条记录 record, 每一列叫字段~
x1-x8为糖尿病人的八个指标,y是表示一年之后该病人是否病情会复发。
之前的1个x对应1个y,而现在的数据集是 8个维度的x对应一个y。
所以改变训练模型公式。
八个维度的X特征值,每一个都要和其权重相乘。 矩阵形式:
带入公式进行变换表示:
整体化为矩阵形式:
所以在输入的时候,记得改 输入为8维,输出是1维。
实际上Linear做了函数线性映射,将8维空间映射成1维空间。
但之前的神经网络都是一层的,现在构造多层神经网络,可以组多个上述模型进行维度的变化。非线性因子
也叫激活函数。激活因子。
数据准备:
np.loadtxt() 函数读取文件数据,参数delimiter表示数据的分割字符,dype表示数据类型,一般N卡都使用float32。
torch.from_numpy 会根据后面给的数据创造Tensor(数组变张量)。
由于我们的数据类型像上图一样,一行8个X数据1个Y数据,所以在读取X数据的时候使用切片[:,:-1]
表示取所有的行,但列不要最后一个列 (切片,左闭右开)
下面的y数据同理,但后面不能写成 [:,-1]
这样就是向量了,要保证xy数据都是矩阵格式。
本节课中 。数据从 8D到6D到i4D到1D:
加入激活因子:
后面的forward函数里尽量都使用x进行操作,实际上第一个X是第一层的输出值,要放到第二层作为输入。像下面这样:
x1 = self.sigmoid(self.linear1(x))
x2 = self.sigmoid(self.linear1(x1))
x3 = self.sigmoid(self.linear1(x2))
显然最后x3得到的就是y的预测值。
损失函数和优化器函数不变。
还是前馈+反馈+更新:
这里并没有使用minibatch,而是将所有没有处理的数据一起放进去了,
课程已经给出了一个数据集,但由于我们需要测试训练模式是否有效,所以抽出数据集的最后两行作为测试集。
进行了10W次训练后发现损失函数只能降低到0.4左右,于是尝试使用GPU加速将训练次数增加到100W,然后…电脑崩了,笔记本显存4G内存16G直接跑满了。。。。如果有空放到云上跑一下看看能不能降低到0.1的损失。
完整代码:
import numpy as np
import torch
import matplotlib.pyplot as plt
# 将数据放到GPU上计算
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 数据准备
# 训练数据
s = np.loadtxt("./diabetes.csv", delimiter=',', dtype=np.float32)
x_data = torch.from_numpy(s[:,:-1]).to(device) # 行方向每一行都要,列方向就最后一列不要。
y_data = torch.from_numpy(s[:, [-1]]).to(device) # 同理
# 测试数据
ss = np.loadtxt("./diabetes_text.csv",delimiter = ',',dtype=np.float32)
x_text_data = torch.from_numpy(ss[:,:-1]).to(device)
# 模型设计
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.sigmoid = torch.nn.Sigmoid()
def forward(self,x):
# 多层神经网络传递
x = self.sigmoid(self.linear1(x))
x = self.sigmoid(self.linear2(x))
x = self.sigmoid(self.linear3(x))
return x
model = Model()
model.to(device) # 将训练模型放到GPU
# 损失函数
criterion = torch.nn.BCELoss(reduction='mean')
# 优化器
optimizer = torch.optim.SGD(model.parameters(),lr=0.1)
time_ll = []
loss_ll = []
y_pre_ll = []
# 循环训练
for i in range(100000):
time_ll.append(i)
y_pre = model(x_data) # 预测值
y_pre_ll.append(y_pre)
loss = criterion(y_pre,y_data) # 损失函数
loss_ll.append(loss.item())
optimizer.zero_grad() # 梯度清零
loss.backward() # 反向传播
optimizer.step() # 更新梯度
print("循环次数",time_ll[-1])
print("损失值",loss_ll[-1])
print(next(model.parameters()).is_cuda) # 该函数返回模型是否在GPU上运行
#绘图
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.title("训练模型")
plt.plot(time_ll,loss_ll)
plt.xlabel("循环次数")
plt.ylabel("损失值loss")
plt.show()
# 测试数据
res = model(x_text_data)
print(res)
运行结果:
最后的两个测试集数据:
从上面的输出结果里可以看到,对于第一个测试集,真实值为1,训练出来的值是0.9796 已经无限接近了。而第二个真实值是0,训练出来的值是0.4821.差的还比较多。
晚上回去看看有没有空,放云上跑一下看能不能吧损失函数降低。
程序已经不是之前的单一层,本程序中有三层。
如果想要查看某一层的数据:
layer1_w = model.linear1.weight.data
layer1_bias = model.linear1.bias.data
更新一下后续:
我吧代码放到cola云上跑了一下,训练次数为100W次,损失也仅仅将到0.3左右。
课程地址为:B站 刘二大人
数据集地址:
百度云链接:https://pan.baidu.com/s/1vZ27gKp8Pl-qICn_p2PaSw
提取码:cxe4
github链接:https://github.com/shitbro6/-