forked from miracleyoo/Poisson-Equation-Solving-with-DL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdl_solver.py
135 lines (114 loc) · 4.15 KB
/
dl_solver.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
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
# coding: utf-8
# Author: Zhongyang Zhang
# Email : [email protected]
import torch
import os
import threading
import numpy as np
from torch.autograd import Variable
from models import miracle_net, miracle_wide_net, miracle_weight_wide_net, miracle_lineconv_net
lock = threading.Lock()
def save_models(opt, net, epoch, train_loss, best_loss, test_loss):
# Save a temp model
train_loss = float(train_loss)
best_loss = float(best_loss)
test_loss = float(test_loss)
if opt.SAVE_TEMP_MODEL:
net.save(epoch, train_loss / opt.NUM_TRAIN, "temp_model.dat")
# Save the best model
if test_loss / opt.NUM_TEST < best_loss:
best_loss = test_loss / opt.NUM_TEST
net.save(epoch, train_loss / opt.NUM_TRAIN, "best_model.dat")
return best_loss
class MyThread(threading.Thread):
def __init__(self, opt, net, epoch, train_loss, best_loss, test_loss):
threading.Thread.__init__(self)
self.opt = opt
self.net = net
self.epoch = epoch
self.train_loss = train_loss
self.best_loss = best_loss
self.test_loss = test_loss
def run(self):
lock.acquire()
try:
self.best_loss = save_models(self.opt, self.net, self.epoch, self.train_loss, self.best_loss,
self.test_loss)
finally:
lock.release()
class Config(object):
def __init__(self):
self.USE_CUDA = torch.cuda.is_available()
self.NET_SAVE_PATH = "./source/trained_net/"
self.MODEL = 'MiracleWeightWideNet'
self.NUM_CHANNEL = 2
self.PROCESS_ID = 'PADDING_LOSS1-2_WEI4-2-1-1-For-Paper'
self.LINER_HID_SIZE = 1024
self.LENGTH = 41
self.WIDTH = 9
self.NUM_CLASSES = 369
self.LEARNING_RATE = 0.001
def dl_init():
opt = Config()
try:
if opt.MODEL == 'MiracleWeightWideNet':
net = miracle_weight_wide_net.MiracleWeightWideNet(opt)
elif opt.MODEL == 'MiracleWideNet':
net = miracle_wide_net.MiracleWideNet(opt)
elif opt.MODEL == 'MiracleNet':
net = miracle_net.MiracleNet(opt)
elif opt.MODEL == 'MiracleLineConvNet':
net = miracle_lineconv_net.MiracleLineConvNet(opt)
except KeyError('Your model is not found.'):
exit(0)
else:
print("==> Model initialized successfully.")
net_save_prefix = opt.NET_SAVE_PATH + opt.MODEL + '_' + opt.PROCESS_ID + '/'
temp_model_name = net_save_prefix + "best_model.dat"
if os.path.exists(temp_model_name):
net, *_ = net.load(temp_model_name)
print("Load existing model: %s" % temp_model_name)
if opt.USE_CUDA:
net.cuda()
print("==> Using CUDA.")
else:
raise FileNotFoundError()
return opt, net
def border_loss(matrix_a, matrix_b, opt):
batch = len(matrix_a)
vec_sim = (torch.sum(torch.pow(matrix_a - matrix_b, 2))).sqrt()
std = Variable(torch.Tensor(np.zeros([batch, opt.LENGTH, opt.WIDTH])))
std[:, 0, :] = 1
std[:, -1, :] = 1
if opt.USE_CUDA:
std = std.cuda()
matrix_a = matrix_a.resize(batch, opt.LENGTH, opt.WIDTH)
matrix_b = matrix_b.resize(batch, opt.LENGTH, opt.WIDTH)
a_border = matrix_a * std
b_border = matrix_b * std
return vec_sim + 2 * (torch.sum(torch.pow(a_border - b_border, 2))).sqrt()
def online_training(model_input, net, opt, labels):
net.train()
optimizer = torch.optim.Adam(net.parameters(), lr=opt.LEARNING_RATE)
if opt.USE_CUDA:
inputs = Variable(torch.Tensor(model_input).cuda())
else:
inputs = Variable(torch.Tensor(model_input))
optimizer.zero_grad()
# forward + backward + optimize
outputs = net(inputs)
loss = border_loss(outputs, labels, opt)
# loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
def dl_solver(model_input, net, opt):
net.eval()
if opt.USE_CUDA:
inputs = Variable(torch.Tensor(model_input).cuda())
outputs = net(inputs)
outputs = outputs.cpu()
else:
inputs = Variable(torch.Tensor(model_input))
outputs = net(inputs)
outputs = outputs.data.numpy()
return outputs