山东大学类脑计算实验四 LSTM的实现
实验内容
根据 LSTM 模型的相关知识,使用 Python 语言实现一个简单 LSTM 模
型。
实验要求
(1) 随机产生 0-127 之间的两个八位的二进制整数,作为一组输
入数据,将这两个数的和作为一个标签,这三个数据组成一
组训练数据,训练数据的组数应尽可能多。
(2) 创建 LSTM 网络。
(3) 实现两个八位的二进制整数的加法运算,网络能够输出正确
的加法运算结果。
requirements:
复制代码
1
2
3numpy=1.20 torch=1.7.1
(用最新的版本应该也行但是不一定未来会不会有大更新)
复制代码
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170import math import numpy as np import torch from torch import nn from torch.utils.data import Dataset, DataLoader np.random.seed(1) # 1.生成训练数据 def convert(x): """ 格式转换函数,自动双向转换 :param x: :return: """ if np.array(x).shape == (): x_ = np.array([[x]], dtype=np.uint8) return np.unpackbits(x_) else: res = 0 for idx, _ in enumerate(np.array(x)): res += (2 ** (7 - idx)) * _ return res data = [] labels = [] data_test = [] labels_test = [] for i in range(500): a_ = np.random.randint(63) b_ = np.random.randint(63) c_ = convert(a_ + b_) x_ = list(zip(list(convert(a_)), list(convert(b_)))) if i < 400: data.append(x_) labels.append(c_) else: data_test.append(x_) labels_test.append(c_) data = torch.tensor(data, dtype=torch.float32) labels = torch.tensor(labels, dtype=torch.float32) data_test = torch.tensor(data_test, dtype=torch.float32) labels_test = torch.tensor(labels_test, dtype=torch.float32) # 2.创建网络 class LSTM(nn.Module): def __init__(self, input_sz, hidden_sz): super().__init__() # self.m = nn.LSTM(input_size=input_sz,hidden_size=hidden_sz) # self.hidden_out = nn.Linear(hidden_sz,127) self.input_size = input_sz self.hidden_size = hidden_sz self.U_i = nn.Parameter(torch.Tensor(input_sz, hidden_sz)) self.V_i = nn.Parameter(torch.Tensor(hidden_sz, hidden_sz)) self.b_i = nn.Parameter(torch.Tensor(hidden_sz)) # f_t self.U_f = nn.Parameter(torch.Tensor(input_sz, hidden_sz)) self.V_f = nn.Parameter(torch.Tensor(hidden_sz, hidden_sz)) self.b_f = nn.Parameter(torch.Tensor(hidden_sz)) # c_t self.U_c = nn.Parameter(torch.Tensor(input_sz, hidden_sz)) self.V_c = nn.Parameter(torch.Tensor(hidden_sz, hidden_sz)) self.b_c = nn.Parameter(torch.Tensor(hidden_sz)) # o_t self.U_o = nn.Parameter(torch.Tensor(input_sz, hidden_sz)) self.V_o = nn.Parameter(torch.Tensor(hidden_sz, hidden_sz)) self.b_o = nn.Parameter(torch.Tensor(hidden_sz)) self.init_weights() def init_weights(self): stdv = 1.0 / math.sqrt(self.hidden_size) for weight in self.parameters(): weight.data.uniform_(-stdv, stdv) def forward(self, x, init_states=None): # return self.m(x) bs, seq_sz, _ = x.size() hidden_seq = [] if init_states is None: h_t, c_t = ( torch.zeros(bs, self.hidden_size).to(x.device), torch.zeros(bs, self.hidden_size).to(x.device) ) else: h_t, c_t = init_states for t in range(seq_sz): x_t = x[:, t, :] i_t = torch.sigmoid(x_t @ self.U_i + h_t @ self.V_i + self.b_i) f_t = torch.sigmoid(x_t @ self.U_f + h_t @ self.V_f + self.b_f) g_t = torch.tanh(x_t @ self.U_c + h_t @ self.V_c + self.b_c) o_t = torch.sigmoid(x_t @ self.U_o + h_t @ self.V_o + self.b_o) c_t = f_t * c_t + i_t * g_t h_t = o_t * torch.tanh(c_t) hidden_seq.append(h_t.unsqueeze(0)) hidden_seq = torch.cat(hidden_seq, dim=0) hidden_seq = hidden_seq.transpose(0, 1).contiguous() return hidden_seq, (h_t, c_t) class data_set(Dataset): def __init__(self, flag="train"): if flag == "train": self.data_ = data self.data_labels_ = labels else: self.data_ = data_test self.data_labels_ = labels_test def __len__(self): return len(self.data_) def __getitem__(self, item): return self.data_[item], self.data_labels_[item] train_dataset = data_set(flag='train') train_dataloader = DataLoader(dataset=train_dataset, batch_size=1, shuffle=True) test_dataset = data_set(flag='test') test_dataloader = DataLoader(dataset=test_dataset, batch_size=1, shuffle=True) lstm = LSTM(2, 8) optimizer = torch.optim.Adam(lstm.parameters(), lr=0.01) criterion = torch.nn.MSELoss() training_loss = [] training_acc = [] for epoch in range(200): print("epoch ====================", epoch) lstm.train() # 训练 epoch_loss = [] for idx, (data_x, data_y) in enumerate(train_dataloader): outputs, (h, c) = lstm(data_x) optimizer.zero_grad() loss = criterion(data_y, outputs[:,-1]) epoch_loss.append(loss.detach()) loss.backward() optimizer.step() training_loss.append(np.mean(epoch_loss)) # 测试 acc = 0 for idx, (data_x, data_y) in enumerate(test_dataloader, 0): outputs, (h, c) = lstm(data_x) res = np.round(outputs[-1][-1].tolist()) print(round(convert(data_y.squeeze().tolist())), "pred >", round(convert(res))) if round(convert(data_y.squeeze().tolist())) == round(convert(res)): acc += 1 acc /= 100 training_acc.append(acc) print("epoch ", epoch, " acc :", acc) import matplotlib.pyplot as plt plt.figure() plt.plot(training_loss) plt.plot(training_acc) plt.legend(["training_loss","acc"]) plt.show()
最后
以上就是满意眼睛最近收集整理的关于山东大学类脑计算实验四 LSTM的实现山东大学类脑计算实验四 LSTM的实现的全部内容,更多相关山东大学类脑计算实验四内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复