-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathFirst-homework.py
105 lines (100 loc) · 3.56 KB
/
First-homework.py
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
'''
@Project : wc
@File : First-homework.py
@IDE : PyCharm
@Author : 21-蒋喜喜
@Date : 2023/2/16 19:12
@Description : 第1课:设计正负样本,并更改模型结构,完成模型训练
规律:随机生成一个5维向量,如果第一个值加第二个值大于第三个值加第四个值,认为是正样本,反之为负样本
'''
# coding:utf8
import torch
import torch.nn as nn
import numpy as np
import random
import json
import matplotlib.pyplot as plt
class TorchModel(nn.Module):
def __init__(self, input_size):
super(TorchModel, self).__init__()
self.linear = nn.Linear(input_size, 1)
self.activation = torch.sigmoid
self.loss = nn.functional.mse_loss
def forward(self, x, y=None):
x = self.linear(x)
y_pred = self.activation(x)
if y is not None:
return self.loss(y_pred, y)
else:
return y_pred
def build_sample():
x = np.random.random(5)
if (x[0] + x[1]) > (x[2] + x[3]):
return x, 1
else:
return x, 0
def build_dataset(total_sample_num):
X = []
Y = []
for i in range(total_sample_num):
x, y = build_sample()
X.append(x)
Y.append([y])
return torch.FloatTensor(X), torch.FloatTensor(Y)
def evaluate(model):
model.eval()
test_sample_num = 100
x, y = build_dataset(test_sample_num)
print("本次预测集中共有%d个正样本,%d个负样本" % (sum(y), test_sample_num - sum(y)))
correct, wrong = 0, 0
with torch.no_grad():
y_pred = model(x)
for y_p, y_t in zip(y_pred, y):
if float(y_p) < 0.5 and int(y_t) == 0:
correct += 1
elif float(y_p) >= 0.5 and int(y_t) == 1:
correct += 1
else:
wrong += 1
print("正确预测个数:%d, 正确率:%f" % (correct, correct / (correct + wrong)))
return correct / (correct + wrong)
def main():
epoch_num = 10
batch_size = 20
train_sample = 5000
input_size = 5
learning_rate = 0.001
model = TorchModel(input_size)
optim = torch.optim.Adam(model.parameters(), lr=learning_rate)
log = []
train_x, train_y = build_dataset(train_sample)
for epoch in range(epoch_num):
model.train()
watch_loss = []
for batch_index in range(train_sample // batch_size):
x = train_x[batch_index * batch_size : (batch_index + 1) * batch_size]
y = train_y[batch_index * batch_size : (batch_index + 1) * batch_size]
optim.zero_grad()
loss = model(x, y)
loss.backward()
optim.step()
watch_loss.append(loss.item())
print("=========\n第%d轮平均loss:%f" % (epoch + 1, np.mean(watch_loss)))
acc = evaluate(model)
log.append([acc, float(np.mean(watch_loss))])
torch.save(model.state_dict(), "model.pth")
print(log)
plt.plot(range(len(log)), [l[0] for l in log], label="acc") # 画acc曲线
plt.plot(range(len(log)), [l[1] for l in log], label="loss") # 画loss曲线
plt.legend()
plt.show()
return
def predict(model_path, input_vec):
input_size = 5
model = TorchModel(input_size)
model.load_state_dict(torch.load(model_path))
model.eval()
with torch.no_grad():
result = model.forward(torch.FloatTensor(input_vec))
for vec, res in zip(input_vec, result):
print("输入:%s, 预测类别:%d, 概率值:%f" % (vec, round(float(res)), res))