通过前几期视频的学习,我们知道了关于一维特征的输入(也就是只有一个x)应该如何处理?但事情往往并不那么简单。比如下图这个预测一个人在一年之后得糖尿病的概率的例子,这个时候我们的输入将会有很多的指标。你可以把它看成是我们体检的各种值。最后一排的外代表了他是否会得糖尿病。

pytorch 输入h w pytorch多输入_python


那么多维的特征输入应该怎么办呢?我们就需要把每一个特征x付以相应的权重。在进行逻辑回归时,把每一个维度的x乘相应的权值的和加上一个偏置量,送入sigema函数进行二分类,就像这样:

pytorch 输入h w pytorch多输入_人工智能_02


当然在真正编程的时候是以矩阵乘法的形式进行运算的,也就是一次能算多个样本的值,具体的推导过程大家可以看刘老师的教学视频,这里就不写了。根据数据集,我们需要构造一个从八维到一维的计算图,就是这样:

pytorch 输入h w pytorch多输入_深度学习_03

代码实现:

import  torch
import  torch.nn.functional as F
import  numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets

xy=np.loadtxt('./data/Diabetes_class.csv.gz',delimiter=',',dtype=np.float32)#加载训练集合
x_data = torch.from_numpy(xy[:,:-1])#取前八列
y_data = torch.from_numpy(xy[:,[-1]])#取最后一列

test =np.loadtxt('./data/test_class.csv.gz',delimiter=',',dtype=np.float32)#加载测试集合,这里我用数据集的最后一个样本做测试,训练集中没有最后一个样本
test_x = torch.from_numpy(test)

class Model(torch.nn.Module):
    def __init__(self):#构造函数
        super(Model,self).__init__()
        self.linear1 = torch.nn.Linear(8,6)#8维到6维
        self.linear2 = torch.nn.Linear(6, 4)#6维到4维
        self.linear3 = torch.nn.Linear(4, 1)#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()#实例化模型

criterion = torch.nn.BCELoss(size_average=False)
#model.parameters()会扫描module中的所有成员,如果成员中有相应权重,那么都会将结果加到要训练的参数集合上
optimizer = torch.optim.SGD(model.parameters(),lr=0.1)#lr为学习率,因为0.01太小了,我改成了0.1

for epoch in range(1000):
    #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()

y_pred = model(x_data)

print(y_pred.detach().numpy())

y_pred2 = model(test_x)
print(y_pred2.data.item())

结果(因为训练了1000次,太长了,我省略了一些):
0 6.900471210479736
1 6.431941509246826
2 6.269504547119141
3 6.213807106018066
4 6.194538116455078
5 6.187747001647949
6 6.185264587402344
7 6.184279441833496
8 6.183816909790039
9 6.183538913726807
10 6.18332576751709
……
290 3.877141237258911
291 3.8444809913635254
292 3.8125956058502197
293 3.781493663787842
294 3.7511816024780273
295 3.7216618061065674
296 3.6929337978363037
297 3.6649935245513916
298 3.6378355026245117
299 3.611449718475342
300 3.585826873779297
……
390 2.6110944747924805
391 2.6028544902801514
392 2.594512939453125
393 2.5860655307769775
394 2.5775086879730225
395 2.5688369274139404
396 2.560046672821045
397 2.5511317253112793
398 2.542088270187378
399 2.532912015914917
400 2.5235979557037354
……
491 0.7130656838417053
492 0.6981781125068665
493 0.683821976184845
494 0.6699725389480591
495 0.6566075682640076
496 0.6437036395072937
497 0.6312403082847595
498 0.6191967725753784
499 0.6075533032417297
500 0.5962917804718018
……
690 0.10917279124259949
691 0.10864472389221191
692 0.10812131315469742
693 0.10760248452425003
694 0.10708855092525482
695 0.10657861083745956
696 0.10607350617647171
697 0.10557280480861664
698 0.1050761491060257
699 0.10458431392908096
700 0.10409623384475708
……
990 0.042595554143190384
991 0.0425054207444191
992 0.042415354400873184
993 0.04232564941048622
994 0.04223642498254776
995 0.04214755818247795
996 0.042058996856212616
997 0.04197085648775101
998 0.04188307374715805
999 0.04179559648036957
[[6.5274360e-03]
[9.9645293e-01]
[8.1841857e-04]
[9.9169475e-01]
[3.7710081e-04]
[9.9676043e-01]
[8.9814300e-03]
[9.9347234e-01]
[3.2491339e-03]]
0.9983044862747192

问题总结:
从结果的倒数第10行到倒数第2行可以看出,基本上已经和我们的标准输出一样了,说明模型训练的挺成功的。但是当我们用最后一个样本做测试的时候发现结果与我们预期的恰恰相反,标准输出为0,程序输出为0.99也就是1。这是为什么呢?于是我想看看测试集输出的变化情况,我把每次训练后的模型都测试一次,然后输出图像。

代码如下:

out =[]

for epoch in range(1000):
    #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()
    y_pred2 = model(test_x)
    out.append(y_pred2.data.item())

out_in=np.arange(1,1001,1)
plt.plot(out_in,out)
plt.ylabel('change of output')
plt.xlabel('times')
plt.grid()
plt.show()

输出的图像如下:

pytorch 输入h w pytorch多输入_pytorch 输入h w_04

可见输出是在训练200次以后显著提升的。当时的loss为5.8,还是很大的。如果有小伙伴知道为什么会出现这个现象,请在下方留言,万分感谢。