上一小节通过学习时间判断通过考试与否,衡量的维度只有一个,就是学习时间,而在实际任务中,结构化数据集往往有多个衡量指标,即多维度输入。本小结主要介绍的一个数据糖尿病数据集,用八个维度来衡量是否患有糖尿病。也是一个二分类问题。
回顾上一小节
- 可以看到该数据集只有一个维度。
糖尿病数据集介绍
- 这就是很典型的结构化数据,一行为一个样本,一列为一个独立的特征。在现实情况下,往往还需要对输入特征进行相关性分析,有些特征之间关联性很强,就可以进行降维,有些特征与输出指标关联性很差,就舍去不考虑。
- 查看数据量,可以看到有759个样本。
1,数据集准备
import numpy as np
#第一个参数是数据集的路径,第二个参数是数据的分割方式,第三个参数是数据类型
xy = np.loadtxt('diabetes.csv.gz', delimiter=',', dtype=np.float32)
x_data = torch.from_numpy(xy[:,:-1])
y_data = torch.from_numpy(xy[:, [-1]])
y_data.shape #[-1]保证拿出来的是矩阵,不加[]拿出来的是向量
时刻要注意的是,维度的正确性,batch方式输入。其输出也是一个batch。
2,设计模型
本讲的设计模型如下图所示:使用三个线性层,线性层与线性层之间采用Sigmoid函数做非线性映射。
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() #torch.nn.Sigmoid()是一个模块,继承于nn.Module
def forward(self, x):
# 避免混乱,从到到位使用一个变量x
x = self.sigmoid(self.linear1(x))
x = self.sigmoid(self.linear2(x))
x = self.sigmoid(self.linear3(x))
return x
model = Model()
3,构建损失函数与优化器
损失函数与上一节相同,都是二分类损失。
criterion = torch.nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
4,循环训练
for epoch in range(100):
# Forward
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
print(epoch, loss.item())
# Backward
optimizer.zero_grad()
loss.backward()
# Update
optimizer.step()
完整代码
import numpy as np
import torch
import matplotlib.pyplot as plt
# 1,数据集准备
#第一个参数是数据集的路径,第二个参数是数据的分割方式,第三个参数是数据类型
xy = np.loadtxt('diabetes.csv.gz', delimiter=',', dtype=np.float32)
x_data = torch.from_numpy(xy[:,:-1])
y_data = torch.from_numpy(xy[:, [-1]])
# y_data.shape #[-1]保证拿出来的是矩阵,不加[]拿出来的是向量
# 2,设计模型
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() #torch.nn.Sigmoid()是一个模块,继承于nn.Module
def forward(self, x):
# 避免混乱,从到到位使用一个变量x
x = self.sigmoid(self.linear1(x))
x = self.sigmoid(self.linear2(x))
x = self.sigmoid(self.linear3(x))
return x
model = Model()
# 3,构建损失函数与优化器
criterion = torch.nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
# 4,训练循环
l = []
for epoch in range(100):
# Forward,一次训练使用所有样本
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
# print(epoch, loss.item())
l.append(loss.item())
# Backward
optimizer.zero_grad()
loss.backward()
# Update
optimizer.step()
plt.rc('legend', fontsize=14)
fig = plt.figure(figsize=(10,5.5),dpi=100)
plt.plot(l,marker='d',label='Multiple_Dimension_Input')
plt.xlabel('epoch',fontsize=14)
plt.ylabel('loss',fontsize=14)
plt.legend()
plt.show()
实验结果
作业
使用不同的激活函数对比损失情况
pytorch提供了很多的非线性激活函数
不论激活函数取什么,最后要接sigmoid函数。因为要保证输出的概率分布在0-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.activate = ['torch.nn.Sigmoid()','torch.nn.ReLU()','torch.nn.ELU()',
'torch.nn.Hardswish()','torch.nn.Tanh()']
def forward(self, x,i):
# 避免混乱,从到到位使用一个变量x
x = eval(self.activate[i])(self.linear1(x))
x = eval(self.activate[i])(self.linear2(x))
output = eval(self.activate[0])((self.linear3(x)))
return output
实验结果
- 可以看到采用前两层Tanh(),后一层sigmoid,损失下降得最快,效果最好。