Repository navigation
Expand file tree
/
Copy pathModel.py
More file actions
131 lines (109 loc) · 4.92 KB
/
Copy pathModel.py
File metadata and controls
131 lines (109 loc) · 4.92 KB
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
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import sys
class Attn(nn.Module):
def __init__(self, h_dim, attn_num):
super(Attn, self).__init__()
self.h_dim = h_dim
self.main = nn.Sequential(
nn.Linear(h_dim, attn_num),
nn.ReLU(True),
nn.Linear(attn_num,1)
)
def forward(self, encoder_outputs):
b_size = encoder_outputs.size(0)
tmp = encoder_outputs.contiguous().view(-1, self.h_dim)
attn_ene = self.main(tmp) # (b, s, h) -> (b * s, 1)
return F.softmax(attn_ene.view(b_size, -1), dim=1).unsqueeze(2) # (b*s, 1) -> (b, s, 1)
class RNN(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, num_classes):
super(RNN, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, dropout=0.5, batch_first=True, bidirectional=True)
def forward(self, x):
# 璁剧疆鍒濆鐘舵€乭_0涓巆_0鐨勭姸鎬佹槸鍒濆鐨勭姸鎬侊紝涓€鑸缃负0锛屽昂瀵告槸,x.size(0)
h0 = (5 * torch.ones(self.num_layers * 2, x.size(0), self.hidden_size)).cuda()
c0 = (torch.zeros(self.num_layers * 2, x.size(0), self.hidden_size)).cuda()
# Forward propagate RNN
out, (h_n, c_n) = self.lstm(x, (h0, c0)) # 閫佸叆涓€涓垵濮嬬殑x鍊硷紝浣滀负杈撳叆浠ュ強(h0, c0)
# Decode hidden state of last time step
# out = self.fc(out[:, -1, :]) # output涔熸槸batch_first, 瀹為檯涓奾_n涓巆_n骞朵笉鏄痓atch_first
return out
class AttnClassifier(nn.Module):
def __init__(self, h_dim, c_num, attn_num):
super(AttnClassifier, self).__init__()
self.attn = Attn(h_dim, attn_num)
self.main = nn.Linear(h_dim, c_num)
def forward(self, encoder_outputs):
attns = self.attn(encoder_outputs) # (b, s, 1)
feats = (encoder_outputs * attns).sum(dim=1) # (b, s, h) -> (b, h)
# return F.log_softmax(self.main(feats)), attns
return self.main(feats), attns
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
global count
count = 0
global rnn, classifier
def predict(data, true_ids, class_num):
global count
global rnn
global classifier
if count == 0:
rnn, classifier = load_model(class_num)
count += 1
test_data = data_process(data, 20)
rnn.eval()
with torch.no_grad():
test_data = torch.FloatTensor(test_data).to(device)
encoder_outputs = rnn(test_data)
out, attn = classifier(encoder_outputs)
out_softmax = F.softmax(out, dim=1)
out_softmax_sum = out_softmax.sum(0)
t = [round(out_softmax_sum.cpu().numpy()[i], 4) for i in range(class_num)]
id = t.index(max(t))
return true_ids[id]
def load_model(num_class):
couple_length = 20
input_size = 3 # 杈撳叆鏁版嵁鐨勭壒寰佺淮搴?
hidden_size = 400 # 闅愯棌灞傜殑size
if num_class == 10:
num_layers = 2 # 鏈夊灏戝眰
attn_num = 64
encoder_dir = './encoder_10_attention_400.pkl'
rnn = RNN(input_size, hidden_size, num_layers, num_class).cuda()
rnn.load_state_dict(torch.load(encoder_dir))
atten_dir = './classifier_10_attention_400.pkl'
classifier = AttnClassifier(hidden_size * 2, num_class, attn_num).cuda()
classifier.load_state_dict(torch.load(atten_dir))
elif num_class == 107:
num_layers = 3 # 鏈夊灏戝眰
attn_num = 128
encoder_dir = './encoder_107_attention.pkl'
rnn = RNN(input_size, hidden_size, num_layers, num_class).cuda()
rnn.load_state_dict(torch.load(encoder_dir))
atten_dir = './classifier_107_attention.pkl'
classifier = AttnClassifier(hidden_size * 2, num_class, attn_num).cuda()
classifier.load_state_dict(torch.load(atten_dir))
else:
print('Please choose 10/107 classify Task')
sys.exit(0)
return rnn, classifier
def data_process(data, couple_length):
def flag(i, x, p):
t = data[i][x][p][:]
t.append(0) if p == 0 else t.append(1)
return t
S = []
[S.append(flag(i, x, p)) for i in range(len(data)) for x in range(len(data[i])) for p in range(len(data[i][x])) if len(data[i][x]) > 1 or len(data[i]) > 1]
delta_S = [[S[i+1][0]-S[i][0], S[i+1][1]-S[i][1], S[i+1][2]] for i in range(len(S) - 1)]
delta_S_len = len(delta_S)
seq_length = [100] * couple_length
test_data = []
index_all = []
for i in range(couple_length):
index = np.random.randint(0, delta_S_len - seq_length[i])
index_all.append(index)
test_data.append(delta_S[index: index + seq_length[i]])
return np.array(test_data)