课程链接:《PyTorch深度学习实践》7.处理多维特征的输入
课上示例
示例程序源代码+注释(根据个人理解)
import torch
import numpy as np
xy = np.loadtxt('diabetes.csv.gz', delimiter=',', dtype=np.float32) # 读取数据集文件。参数:文件名(.csv或.csv.gz),分隔符,数据类型
x_data = torch.from_numpy(xy[:, :-1]) # 加载特征,Tensor类型。参数:所有行,第一列到倒数第二列
y_data = torch.from_numpy(xy[:, [-1]]) # 加载标签,Tensor类型。参数:所有行,最后一列(中括号[-1]意为矩阵,若无中括号,则意为向量)
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维
# 之前是用的torch.nn.Functional.sigmoid()函数,现在是用torch.nn.Sigmoid()模块
self.sigmoid = torch.nn.Sigmoid() # 可更换激活函数:self.activate = torch.nn.ReLU()
def forward(self, x):
x = self.sigmoid(self.linear1(x)) # 都用x,进行迭代
x = self.sigmoid(self.linear2(x)) # 更换激活函数后可使用:x = self.activate(self.linear2(x))
x = self.sigmoid(self.linear3(x)) # 使用ReLu时,>0的数值都为0,可能会计算ln0,需要改回:self.sigmoid()
return x
model = Model()
criterion = torch.nn.BCELoss(size_average=True)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
for epoch in range(100):
# Forward
y_pred = model(x_data) # 直接使用所有数据,Mini-Batch后面再讲(DataLoader)
loss = criterion(y_pred, y_data)
print(epoch, loss.item())
# Backward
optimizer.zero_grad()
loss.backward()
# Update
optimizer.step()
输出结果:
0 0.7210900783538818
1 0.7137091159820557
2 0.7070571184158325
3 0.7010629177093506
4 0.6956613659858704
5 0.6907935738563538
6 0.686406672000885
7 0.6824524998664856
8 0.6788880825042725
9 0.6756744384765625
10 0.6727766394615173
11 0.6701630353927612
12 0.6678054928779602
13 0.6656782627105713
14 0.6637586355209351
15 0.6620258688926697
16 0.6604613661766052
17 0.6590486168861389
18 0.6577724814414978
19 0.6566197276115417
20 0.6555778980255127
21 0.6546363234519958
22 0.6537850499153137
23 0.6530153751373291
24 0.6523191332817078
25 0.651689350605011
26 0.651119589805603
27 0.6506038308143616
28 0.6501370668411255
29 0.6497144103050232
30 0.64933180809021
31 0.6489852666854858
32 0.6486712694168091
33 0.6483867764472961
34 0.6481289267539978
35 0.6478952765464783
36 0.6476834416389465
37 0.6474913954734802
38 0.6473171710968018
39 0.6471591591835022
40 0.6470157504081726
41 0.6468855738639832
42 0.6467674970626831
43 0.646660327911377
44 0.6465629935264587
45 0.6464744210243225
46 0.6463941931724548
47 0.6463211178779602
48 0.6462547779083252
49 0.6461944580078125
50 0.6461396217346191
51 0.6460896730422974
52 0.6460441946983337
53 0.6460028886795044
54 0.6459652185440063
55 0.6459308862686157
56 0.6458995938301086
57 0.6458710432052612
58 0.6458449959754944
59 0.6458212733268738
60 0.6457995176315308
61 0.6457796692848206
62 0.6457614302635193
63 0.6457448601722717
64 0.645729660987854
65 0.6457157135009766
66 0.6457028388977051
67 0.6456912159919739
68 0.6456803679466248
69 0.6456704139709473
70 0.6456611752510071
71 0.645652711391449
72 0.6456448435783386
73 0.6456376910209656
74 0.6456308960914612
75 0.6456246972084045
76 0.6456188559532166
77 0.645613431930542
78 0.6456084251403809
79 0.6456037163734436
80 0.6455993056297302
81 0.645595133304596
82 0.6455912590026855
83 0.6455875635147095
84 0.6455840468406677
85 0.6455807685852051
86 0.645577609539032
87 0.6455746293067932
88 0.6455718278884888
89 0.6455691456794739
90 0.6455665230751038
91 0.6455639600753784
92 0.6455616354942322
93 0.6455592513084412
94 0.6455570459365845
95 0.6455548405647278
96 0.6455527544021606
97 0.6455506682395935
98 0.6455487012863159
99 0.6455467343330383
课后作业
使用不同的激活函数(如ReLU)
import torch
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]])
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.ReLU() # 中间层使用ReLU激活函数
self.sigmoid = torch.nn.Sigmoid()
def forward(self, x):
x = self.activate(self.linear1(x))
x = self.activate(self.linear2(x))
x = self.sigmoid(self.linear3(x)) # 最后一层防止出现ln0的情况,所以使用Sigmoid激活函数
# 因为<0时,使用ReLU函数结果全为0,而使用Sigmoid函数可生成0~1之间光滑的曲线
return x
model = Model()
criterion = torch.nn.BCELoss(size_average=True)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
for epoch in range(100):
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
print(epoch, loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()