数据透视怎么弄(数据透视怎么做)
1153
2022-05-30
学习总结
(1)本次图像多分类中的最后一层网络不需要加激活,因为在最后的torch.nn.CrossEntropyLoss已经包括了激活函数softmax。这里注意softmax的dim参数问题,如下面这个是(3,2)的一个变量,dim = 0 实际上是对第一维的3个变量进行对数化,而dim = 1是对第二维进行操作。
a = torch.Tensor([[1,1],[2,2],[3,3]]) a.size() Out[89]: torch.Size([3, 2]) b = torch.nn.Softmax(dim=0)(a) b Out[91]: tensor([[0.0900, 0.0900], [0.2447, 0.2447], [0.6652, 0.6652]]) b = torch.nn.Softmax(dim=1)(a) b Out[93]: tensor([[0.5000, 0.5000], [0.5000, 0.5000], [0.5000, 0.5000]])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(2)本次pytorch在读图像时,将PIL图像(现在都用Pillow了)转为Tensor,神经网络一般希望input比较小,最好在-1到1之间,最好符合正态分布。三种主流图像处理库的比较:
文章目录
学习总结
一、多分类问题
二、分布和API
三、交叉熵代码实践
四、代码实践
Reference
一、多分类问题
注意验证/测试的流程基本与训练过程大体一致,不同点在于:
需要预先设置torch.no_grad,以及将model调至eval模式
不需要将优化器的梯度置零
不需要将loss反向回传到网络
不需要更新optimizer
二、分布和API
法一:把每一个类别的确定看作是一个二分类问题。利用交叉熵。
为了解决抑制问题,就不要输出每个类别的概率,且满足每个概率大于0和概率之和为1的条件。(二分类我们输出的是分布,求出一个然后用1减去即可,多分类虽然也可以这样,但是最后1减去其他所有概率的计算,还需要构建计算图有点麻烦)。
之前二分类中的交叉熵的两项中只能有一项为0.
(1)NLLLoss函数计算如下红色框:
(2)可以直接使用torch.nn.CrossEntropyLoss(将下列红框计算纳入)。注意右侧是由类别生成独热编码向量。
交叉熵,最后一层网络不需要激活,因为在最后的Torch.nn.CrossEntropyLoss已经包括了激活函数softmax。
(1)交叉熵手写版本
import numpy as np y = np.array([1, 0, 0]) z = np.array([0.2, 0.1, -0.1]) y_predict = np.exp(z) / np.exp(z).sum() loss = (- y * np.log(y_predict)).sum() print(loss) # 0.9729189131256584
1
2
3
4
5
6
7
(2)交叉熵pytorch栗子
交叉熵损失和NLL损失的区别(读文档):
https://pytorch.org/doc s/stable/nn.html#crossentropyloss
https://pytorch.org/docs/stable/nn.html#nllloss
搞懂为啥:CrossEntropyLoss <==> LogSoftmax + NLLLoss
三、交叉熵代码实践
前面是sigmoid,后面是softmax(使得概率大于0,概率值和为1)。 两点注意。
# -*- coding: utf-8 -*- """ Created on Mon Oct 18 22:48:55 2021 @author: 86493 """ # 用CrossEntropyLoss计算交叉熵 import torch # 注意1:设定的第0个分类 y = torch.LongTensor([0]) z = torch.Tensor([[0.2, 0.1, -0.1]]) # 注意2:CrossEntropyLoss criterion = torch.nn.CrossEntropyLoss() loss = criterion(z, y) print(loss.item()) # 0.9729189276695251 # 举栗子:mini-batch:batch_size = 3 import torch criterion = torch.nn.CrossEntropyLoss() # 三个样本 Y = torch.LongTensor([2, 0, 1]) # 第一个样本比较吻合,loss会较小 Y_pred1 = torch.Tensor([[0.1, 0.2, 0.9], # 2 该层为原始的线性层的输出 [1.1, 0.1, 0.2], # 0 [0.2, 2.1, 0.1]])# 1 # 第二个样本差的比较远,loss较大 Y_pred2 = torch.Tensor([[0.8, 0.2, 0.3], # 2 [0.2, 0.3, 0.5], # 0 [0.2, 0.2, 0.5]])# 1 l1 = criterion(Y_pred1, Y) l2 = criterion(Y_pred2, Y) print("Batch Loss1 = ", l1.data, "\nBatch Loss2 =", l2.data) # Batch Loss1 = tensor(0.4966) # Batch Loss2 = tensor(1.2389)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
四、代码实践
(1)pytorch在读图像时,将PIL图像(现在都用Pillow了)转为Tensor,神经网络希望input比较小,最好在-1到1之间,最好符合正态分布。
三种主流图像处理库的比较:
(2)transforms.Normalize,转为标准正态分布即是一种映射到(0, 1)函数。 Pixel norm = Pixel origin − mean std \text { Pixel }_{\text {norm }}=\frac{\text { Pixel }_{\text {origin }}-\text { mean }}{\text { std }} Pixel norm = std Pixel origin − mean
(3)激活层改用relu,最后一层不用加,因为交叉熵损失函数里面已经包括了。
(4)_, predicted = torch.max(outputs.data, dim = 1)求出每一行(样本)的最大值的下标,dim = 1即行的维度;返回最大值和最大值所在的下标。
# -*- coding: utf-8 -*- """ Created on Mon Oct 18 19:25:46 2021 @author: 86493 """ import torch from torchvision import transforms from torchvision import datasets from torch.utils.data import DataLoader # 使用relu激活函数 import torch.nn.functional as F import torch.optim as optim import torch.nn as nn import matplotlib.pyplot as plt losslst = [] batch_size = 64 transform = transforms.Compose([ # 将PIL图片转为Tensor transforms.ToTensor(), # 归一化,分别为均值和标准差 transforms.Normalize((0.1307, ), (0.3081, )) ]) # 训练集数据 train_dataset = datasets.MNIST(root = '../dataset/mnist/', train = True, download = True, transform = transform) train_loader = DataLoader(train_dataset, shuffle = True, batch_size = batch_size) # 测试集数据 test_dataset = datasets.MNIST(root = '../dataset/mnist/', train = False, download = True, transform = transform) test_loader = DataLoader(test_dataset, shuffle = False, batch_size = batch_size) # 模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.l1 = nn.Linear(784, 512) self.l2 = nn.Linear(512, 256) self.l3 = nn.Linear(256, 128) self.l4 = nn.Linear(128, 64) self.l5 = nn.Linear(64, 10) def forward(self, x): # -1位置会自动算出N,即变成(N, 784)矩阵 x = x.view(-1, 784) x = F.relu(self.l1(x)) x = F.relu(self.l2(x)) x = F.relu(self.l3(x)) x = F.relu(self.l4(x)) # 注意最后一层不用加上relu,因为交叉熵已经含有softmax return self.l5(x) model = Net() # 交叉熵作为loss criterion = torch.nn.CrossEntropyLoss() # 优化器SGD加上冲量以优化训练过程 optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum = 0.5) def train(epoch): running_loss = 0.0 for batch_idx, data in enumerate(train_loader, 0): # 1.准备数据 inputs, labels = data # data为元组 # 2.向前传递 outputs = model(inputs) loss = criterion(outputs, labels) losslst.append(loss) # print(losslst,"+++++++++++++") # 3.反向传播 optimizer.zero_grad() loss.backward() # 4.更新参数 optimizer.step() # 记得取loss值用item(),否则会构建计算图 running_loss += loss.item() losslst.append(loss.item()) # 每300个batch打印一次 if batch_idx % 300 == 299: print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300)) running_loss = 0.0 def test(): correct = 0 total = 0 # 加上with这句后面就不会产生计算图 with torch.no_grad(): for data in test_loader: images, labels = data outputs = model(images) # 求出每一行(样本)的最大值的下标,dim = 1即行的维度 # 返回最大值和最大值所在的下标 _, predicted = torch.max(outputs.data, dim = 1) # label矩阵为N × 1 total += labels.size(0) # 猜对的数量,后面算准确率 correct += (predicted == labels).sum().item() print('Accuracy on test set: %d %%' % (100 * correct / total)) # print("losslst的长度为:", len(losslst)) if __name__ == '__main__': for epoch in range(10): # if epoch % 10 == 9: # 每10个输出一次 train(epoch) test()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
代码打印的loss值:
[1, 300] loss: 2.216 [1, 600] loss: 0.872 [1, 900] loss: 0.423 Accuracy on test set: 89 % [2, 300] loss: 0.333 [2, 600] loss: 0.272 [2, 900] loss: 0.232 Accuracy on test set: 93 % [3, 300] loss: 0.189 [3, 600] loss: 0.176 [3, 900] loss: 0.160 Accuracy on test set: 95 % [4, 300] loss: 0.135 [4, 600] loss: 0.127 [4, 900] loss: 0.121 Accuracy on test set: 95 % [5, 300] loss: 0.104 [5, 600] loss: 0.096 [5, 900] loss: 0.097 Accuracy on test set: 96 % [6, 300] loss: 0.080 [6, 600] loss: 0.071 [6, 900] loss: 0.083 Accuracy on test set: 97 % [7, 300] loss: 0.062 [7, 600] loss: 0.062 [7, 900] loss: 0.062 Accuracy on test set: 97 % [8, 300] loss: 0.050 [8, 600] loss: 0.052 [8, 900] loss: 0.053 Accuracy on test set: 97 % [9, 300] loss: 0.034 [9, 600] loss: 0.045 [9, 900] loss: 0.043 Accuracy on test set: 97 % [10, 300] loss: 0.032 [10, 600] loss: 0.032 [10, 900] loss: 0.036 Accuracy on test set: 97 %
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Reference
(1)pytorch中with torch.no_grad()
(2)https://www.bilibili.com/video/BV1Y7411d7Ys?p=9
(3)pytorch学习(五)—图像的加载/读取方式
(4)解决Python报错:RuntimeError: Can’t call numpy() on Variable that requires grad. Use var.detach().numpy()
pytorch 网络
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。