tools 1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tools/torch/model.py ADDED
@@ -0,0 +1,397 @@
1
+ from copy import deepcopy as dcopy
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.functional as F
5
+ import torch.optim as optim
6
+
7
+ class FNN(nn.Module):
8
+ '''
9
+ basic FNN module
10
+
11
+ Parameters
12
+ ----------
13
+ n_input: number of input (int)
14
+ if n_input is None, then the LazyLinear() is set in the first layer.
15
+ n_hidden_list: list of hidden neurons (list of int)
16
+ activation_list: torch.nn activation function instances (nn object or list of nn object)
17
+
18
+ Example
19
+ -------
20
+ >>> model = FNN(n_input=10, n_hidden_list=[8,6,5], activation_list=[nn.Sigmoid(), nn.ReLU(), nn.Tanh()])
21
+ # n_hidden_list, activation_list corresponds to [h1, h2, output]
22
+ >>> print(model)
23
+ FNN(
24
+ (fc): Sequential(
25
+ (0): Linear(in_features=10, out_features=8, bias=True)
26
+ (1): Sigmoid()
27
+ (2): Linear(in_features=8, out_features=6, bias=True)
28
+ (3): ReLU()
29
+ (4): Linear(in_features=6, out_features=5, bias=True)
30
+ (5): Tanh()
31
+ )
32
+ )
33
+ '''
34
+ def __init__(self, n_hidden_list, activation_list, n_input=None):
35
+ # def __init__(self, n_input, n_hidden_list, activation_list):
36
+ super().__init__()
37
+ if type(activation_list) is not list:
38
+ activation_list = [dcopy(activation_list)]*len(n_hidden_list)
39
+ assert len(activation_list)==len(n_hidden_list), 'length of layers and activations must match. If you want no activation, use nn.Identity'
40
+
41
+ # 1st layer - Select Lazy if n_input is not specified
42
+ if n_input is None:
43
+ layers = [nn.Flatten(1), nn.LazyLinear(n_hidden_list[0]), activation_list[0]]
44
+ else:
45
+ layers = [nn.Flatten(1), nn.Linear(n_input, n_hidden_list[0]), activation_list[0]]
46
+ # Hidden layers ~ Output layer
47
+ for i in range(len(n_hidden_list) - 1):
48
+ layers.extend([nn.Linear(n_hidden_list[i], n_hidden_list[i+1]), activation_list[i+1]])
49
+
50
+ self.fc = nn.Sequential(*layers)
51
+
52
+ def forward(self, x):
53
+ '''x.shape()==(batch_size, feature_dim)'''
54
+ return self.fc(x)
55
+
56
+ class FNN_Resnet(nn.Module):
57
+ '''
58
+ Resnet module
59
+
60
+ Parameters
61
+ ----------
62
+ n_input : int
63
+ number of input
64
+ n_hidden_list : list of int
65
+ list of hidden neurons
66
+ activation : nn activation instance or list
67
+ torch.nn activation function instances
68
+ skip: int
69
+ number of layers to skip. Interval for skipping
70
+ ex) skip=2, then add skip layer every other 2 layers
71
+
72
+ Example
73
+ -------
74
+ >>> model = Resnet(n_input=10, n_hidden_list=[8,6,5], activation=[nn.Sigmoid(), nn.ReLU(), nn.tanh()], skip=2)
75
+ # activation corresponds to [h1, h2, output]
76
+ >>> print(model)
77
+
78
+ '''
79
+ def __init__(self, n_hidden_list, activation_list, n_input=None, skip=2):
80
+ # def __init__(self, n_input, n_hidden_list, activation_list, skip=2):
81
+ super().__init__()
82
+ if type(activation_list) is not list:
83
+ activation_list = [dcopy(activation_list)]*len(n_hidden_list)
84
+ assert len(activation_list)==len(n_hidden_list), 'length of layers and activations must match. If you want no activation, use nn.Identity'
85
+ assert len(n_hidden_list) >= skip, 'number of layers must be equal or greater than skip. len(n_hidden_list): %s, skip: %s'%(len(n_hidden_list), skip)
86
+ assert skip >= 2, 'skip needs to be: skip >= 2, given: %s'%(skip)
87
+
88
+ # 1st layer
89
+ if n_input is None:
90
+ layers = [nn.LazyLinear(n_hidden_list[0])]
91
+ else:
92
+ layers = [nn.Linear(n_input, n_hidden_list[0])]
93
+ # Hidden layers ~ Output layer
94
+ layers.extend([nn.Linear(n_hidden_list[i], n_hidden_list[i+1]) for i in range(len(n_hidden_list)-1)])
95
+ self.fc = nn.ModuleList(layers)
96
+ self.activation_list = nn.ModuleList(activation_list)
97
+
98
+ # Skip layers
99
+ # Bias already present at original layers
100
+ self.skip = skip
101
+ if n_input is None:
102
+ n_skip_hidden_list = [n_hidden_list[i] for i in range(skip-1, len(n_hidden_list), skip)]
103
+ skip_layers = [nn.LazyLinear(n_skip_hidden_list[0], bias=False)] + [nn.Linear(n_skip_hidden_list[i], n_skip_hidden_list[i+1], bias=False) for i in range(len(n_skip_hidden_list)-1)]
104
+ else:
105
+ n_skip_hidden_list = [n_input] + [n_hidden_list[i] for i in range(skip-1, len(n_hidden_list), skip)]
106
+ skip_layers = [nn.Linear(n_skip_hidden_list[i], n_skip_hidden_list[i+1], bias=False) for i in range(len(n_skip_hidden_list)-1)]
107
+ self.skip_layers = nn.ModuleList(skip_layers) # Need ModuleList, not list, so that the model can recognize this layers
108
+ self.n_skip = len(n_hidden_list) // skip # number of skip layers
109
+ # assert self.n_skip == len(self.skip_layers), 'something\'s wrong'
110
+
111
+ def forward(self, x):
112
+ x = x.flatten(1)
113
+ last_x = x
114
+ skip_layers = iter(self.skip_layers)
115
+ for i, (layer, activation) in enumerate(zip(self.fc, self.activation_list)):
116
+ if (i+1) % self.skip == 0:
117
+ skip_layer = next(skip_layers)
118
+ x = activation(layer(x)+skip_layer(last_x))
119
+ last_x = x
120
+ else:
121
+ x = activation(layer(x))
122
+ return x
123
+ '''To do:
124
+ - weight initialization? modify?
125
+ - optimize using nn.Sequential() and itertools in forward. compute layers in group
126
+ '''
127
+
128
+ class FNN_Densenet(nn.Module):
129
+ def __init__(self, n_hidden_list, activation_list, n_input=None, skip=2):
130
+ # def __init__(self, n_input, n_hidden_list, activation_list, skip=2):
131
+ super().__init__()
132
+ if type(activation_list) is not list:
133
+ activation_list = [dcopy(activation_list)]*len(n_hidden_list)
134
+ assert len(activation_list)==len(n_hidden_list), 'length of layers and activations must match. If you want no activation, use nn.Identity'
135
+ assert len(n_hidden_list) >= skip, 'number of layers must be equal or greater than skip. len(n_hidden_list): %s, skip: %s'%(len(n_hidden_list), skip)
136
+ assert skip >= 2, 'skip needs to be: skip >= 2, given: %s'%(skip)
137
+
138
+ # 1st layer
139
+ if n_input is None:
140
+ layers = [nn.LazyLinear(n_hidden_list[0])]
141
+ else:
142
+ layers = [nn.Linear(n_input, n_hidden_list[0])]
143
+ # Hidden layers ~ Output layer
144
+ layers.extend([nn.Linear(n_hidden_list[i], n_hidden_list[i+1]) for i in range(len(n_hidden_list)-1)])
145
+ self.fc = nn.ModuleList(layers)
146
+ self.activation_list = nn.ModuleList(activation_list)
147
+
148
+ # Skip layers
149
+ self.skip = skip
150
+ if n_input is None:
151
+ n_skip_hidden_list = [None] + [n_hidden_list[i] for i in range(skip-1, len(n_hidden_list), skip)]
152
+ skip_layers = nn.ModuleDict()
153
+ for i in range(1, len(n_skip_hidden_list)):
154
+ for j in range(i):
155
+ if j==0:
156
+ skip_layers[str(j)+'_'+str(i)]=nn.LazyLinear(n_skip_hidden_list[i], bias=False)
157
+ else:
158
+ skip_layers[str(j)+'_'+str(i)]=nn.Linear(n_skip_hidden_list[j], n_skip_hidden_list[i], bias=False)
159
+ else:
160
+ n_skip_hidden_list = [n_input] + [n_hidden_list[i] for i in range(skip-1, len(n_hidden_list), skip)]
161
+ skip_layers = nn.ModuleDict()
162
+ for i in range(1, len(n_skip_hidden_list)):
163
+ for j in range(i):
164
+ skip_layers[str(j)+'_'+str(i)]=nn.Linear(n_skip_hidden_list[j], n_skip_hidden_list[i], bias=False)
165
+ self.skip_layers = skip_layers
166
+
167
+ n = len(n_skip_hidden_list)-1
168
+ self.n_skip = int(n*(n+1)/2)
169
+ assert self.n_skip == len(skip_layers), f'something wrong: n_skip({self.n_skip}), skip_layers({len(skip_layers)})'
170
+
171
+ def forward(self, x):
172
+ x_history = [x]
173
+ dest = 1 # Destination index of skip layers
174
+ for i, (layer, activation) in enumerate(zip(self.fc, self.activation_list)):
175
+ if (i+1) % self.skip == 0:
176
+ assert dest == len(x_history), f'Length of x_history{len(x_history)} and destination number{dest} must match'
177
+ skip_x = torch.stack([self.skip_layers[str(src)+'_'+str(dest)](x_) for src, x_ in enumerate(x_history)], dim=-1).sum(dim=-1)
178
+ x = activation(layer(x)+skip_x)
179
+ x_history.append(x)
180
+ dest += 1
181
+ else:
182
+ x = activation(layer(x))
183
+
184
+ return x
185
+
186
+ class CNN(nn.Module):
187
+ def __init__(self, in_channel, n_channel_list, activation_list, kernel_size=3):
188
+ super().__init__()
189
+ if type(activation_list) is not list:
190
+ activation_list = [dcopy(activation_list)]*len(n_channel_list)
191
+ assert len(activation_list)==len(n_channel_list), 'length of layers and activations must match. If you want no activation, use nn.Identity'
192
+
193
+ # 1st layer
194
+ padding = kernel_size // 2
195
+ layers = [nn.Conv2d(in_channels=in_channel, out_channels=n_channel_list[0], kernel_size=kernel_size, stride=1, padding=padding), activation_list[0]]
196
+ # Hidden layers ~ Output layer
197
+ for i in range(len(n_channel_list) - 1):
198
+ layers.extend([nn.Conv2d(in_channels=n_channel_list[i], out_channels=n_channel_list[i+1], kernel_size=kernel_size, stride=1, padding=padding), activation_list[i+1]])
199
+ self.layers = nn.Sequential(*layers)
200
+
201
+ def forward(self, x):
202
+ return self.layers(x)
203
+
204
+ class CNN_Resnet(nn.Module):
205
+ def __init__(self, in_channel, n_channel_list, activation_list, kernel_size=3, skip=2):
206
+ super().__init__()
207
+ if type(activation_list) is not list:
208
+ activation_list = [dcopy(activation_list)]*len(n_channel_list)
209
+ assert len(activation_list)==len(n_channel_list), 'length of layers and activations must match. If you want no activation, use nn.Identity'
210
+ assert kernel_size % 2 == 1, f'kernel size must be odd number, Got: ({kernel_size})'
211
+
212
+ # 1st layer
213
+ padding = kernel_size // 2
214
+ layers = [nn.Conv2d(in_channels=in_channel, out_channels=n_channel_list[0], kernel_size=kernel_size, stride=1, padding=padding)]
215
+ # Hidden layers ~ Output layer
216
+ layers.extend([nn.Conv2d(in_channels=n_channel_list[i], out_channels=n_channel_list[i+1], kernel_size=kernel_size, stride=1, padding=padding) for i in range(len(n_channel_list)-1)])
217
+ self.layers = nn.ModuleList(layers)
218
+ self.activation_list = nn.ModuleList(activation_list)
219
+
220
+ # Skip layers
221
+ self.skip = skip
222
+ n_skip_channel_list = [in_channel]+[n_channel_list[i] for i in range(skip-1, len(n_channel_list), skip)]
223
+ skip_layers = [nn.Conv2d(in_channels=n_skip_channel_list[i], out_channels=n_skip_channel_list[i+1], kernel_size=kernel_size, stride=1, padding=padding, bias=False) for i in range(len(n_skip_channel_list)-1)] # Bias already present at original layers
224
+ self.skip_layers = nn.ModuleList(skip_layers) # Need ModuleList, not list, so that the model can recognize this layers
225
+ self.n_skip = len(n_channel_list) // skip # number of skip layers
226
+ # assert self.n_skip == len(self.skip_layers), 'something\'s wrong'
227
+
228
+ def forward(self, x):
229
+ last_x = x
230
+ skip_layers = iter(self.skip_layers)
231
+ for i, (layer, activation) in enumerate(zip(self.layers, self.activation_list)):
232
+ if (i+1) % self.skip == 0:
233
+ skip_layer = next(skip_layers)
234
+ x = activation(layer(x)+skip_layer(last_x))
235
+ last_x = x
236
+ else:
237
+ x = activation(layer(x))
238
+ return x
239
+
240
+ class CNN_Densenet(nn.Module):
241
+ def __init__(self, in_channel, n_channel_list, activation_list, kernel_size=3, skip=2):
242
+ super().__init__()
243
+ if type(activation_list) is not list:
244
+ activation_list = [dcopy(activation_list)]*len(n_channel_list)
245
+ assert len(activation_list)==len(n_channel_list), 'length of layers and activations must match. If you want no activation, use nn.Identity'
246
+ assert kernel_size % 2 == 1, f'kernel size must be odd number, Got: ({kernel_size})'
247
+
248
+ # 1st layer
249
+ padding = kernel_size // 2
250
+ layers = [nn.Conv2d(in_channels=in_channel, out_channels=n_channel_list[0], kernel_size=kernel_size, stride=1, padding=padding)]
251
+ # Hidden layers ~ Output layer
252
+ layers.extend([nn.Conv2d(in_channels=n_channel_list[i], out_channels=n_channel_list[i+1], kernel_size=kernel_size, stride=1, padding=padding) for i in range(len(n_channel_list)-1)])
253
+ self.layers = nn.ModuleList(layers)
254
+ self.activation_list = nn.ModuleList(activation_list)
255
+
256
+ # Skip layers
257
+ self.skip = skip
258
+ n_skip_channel_list = [in_channel]+[n_channel_list[i] for i in range(skip-1, len(n_channel_list), skip)]
259
+
260
+ skip_layers = nn.ModuleDict()
261
+ for i in range(1, len(n_skip_channel_list)):
262
+ for j in range(i):
263
+ skip_layers[str(j)+'_'+str(i)]=nn.Conv2d(in_channels=n_skip_channel_list[j], out_channels=n_skip_channel_list[i], kernel_size=kernel_size, stride=1, padding=padding, bias=False)
264
+ self.skip_layers = skip_layers
265
+
266
+ n = len(n_skip_channel_list)-1
267
+ self.n_skip = int(n*(n+1)/2)
268
+ assert self.n_skip == len(skip_layers), f'something wrong: n_skip({self.n_skip}), skip_layers({len(skip_layers)})'
269
+
270
+ def forward(self, x):
271
+ x_history = [x]
272
+ dest = 1 # Destination index of skip layers
273
+ for i, (layer, activation) in enumerate(zip(self.layers, self.activation_list)):
274
+ if (i+1) % self.skip == 0:
275
+ assert dest == len(x_history), f'Length of x_history{len(x_history)} and destination number{dest} must match'
276
+ skip_x = torch.stack([self.skip_layers[str(src)+'_'+str(dest)](x_) for src, x_ in enumerate(x_history)], dim=-1).sum(dim=-1)
277
+ x = activation(layer(x)+skip_x)
278
+ x_history.append(x)
279
+ dest += 1
280
+ else:
281
+ x = activation(layer(x))
282
+
283
+ return x
284
+
285
+ class Gaussian(nn.Module):
286
+ def __init__(self, amp=1, mu=0, sigma=1):
287
+ super().__init__()
288
+ self.register_parameter('mu', nn.Parameter(torch.tensor(mu, dtype=torch.float)))
289
+ self.register_parameter('sigma', nn.Parameter(torch.tensor(sigma, dtype=torch.float)))
290
+ self.register_parameter('amp', nn.Parameter(torch.tensor(amp, dtype=torch.float)))
291
+
292
+ def forward(self, x):
293
+ return self.amp/(self.sigma*np.sqrt(2*np.pi))*torch.exp(-0.5*((x-self.mu)/self.sigma)**2)
294
+
295
+ class SimpleGaussian(nn.Module):
296
+ def __init__(self, amp=1, mu=0, sigma=1):
297
+ super().__init__()
298
+ self.register_parameter('mu', nn.Parameter(torch.tensor(mu, dtype=torch.float)))
299
+ self.register_parameter('sigma', nn.Parameter(torch.tensor(sigma, dtype=torch.float)))
300
+ self.register_parameter('amp', nn.Parameter(torch.tensor(amp, dtype=torch.float)))
301
+
302
+ def forward(self, x):
303
+ return self.amp*torch.exp(-0.5*((x-self.mu)/self.sigma)**2)
304
+
305
+ class Residual(nn.Module):
306
+ """
307
+ Residual module which computes residual connections in forward pass.
308
+ Note that intermediate tensors need to have the same shape.
309
+
310
+ Parameters
311
+ ----------
312
+ blocks : list of nn.Module objects, or an iterable nn.Module object.
313
+
314
+ activation : nn.Module object (default: None)
315
+ activation function to be applied at each residual connection betwee blocks.
316
+
317
+ Examples
318
+ --------
319
+ >>> blocks = [nn.Linear(10,10) for i in range(5)]
320
+ >>> model = Residual(blocks)
321
+ >>> model
322
+
323
+ """
324
+ def __init__(self, blocks, activation=None):
325
+ super().__init__()
326
+ if issubclass(type(blocks), nn.Module):
327
+ self.blocks = blocks
328
+ elif issubclass(type(blocks), list):
329
+ self.blocks = nn.ModuleList(blocks)
330
+ else:
331
+ raise Exception('')
332
+ self.activation = activation
333
+
334
+ def forward(self, x):
335
+ if self.activation is not None:
336
+ for block in self.blocks:
337
+ x = self.activation(block(x)+x)
338
+
339
+ else: # No activation
340
+ for block in self.blocks:
341
+ x = block(x)+x
342
+ return x
343
+
344
+ class Parallel(nn.Module):
345
+ """
346
+ Similar to nn.Sequential, but parallel connection.
347
+ Note that the shape of each output from each module must be identical,
348
+ since Parallel() sums up all outputs in forward().
349
+ Also note that Parallel with nn.Identity() is identical to Residual()
350
+
351
+ Parameters
352
+ ----------
353
+ args : nn.Modules
354
+
355
+ Examples
356
+ --------
357
+ >>>
358
+ """
359
+ def __init__(self, *args):
360
+ super().__init__()
361
+ self._layers = args
362
+ for i, layer in enumerate(args):
363
+ self.add_module(str(i), layer)
364
+
365
+ def forward(self, x):
366
+ y_list = [layer(x) for layer in self._layers]
367
+ y = sum(y_list)
368
+ return y
369
+
370
+ def __iter__(self):
371
+ self._i = 0
372
+ return self
373
+
374
+ def __next__(self):
375
+ if self._i < len(self):
376
+ layer = self[self._i]
377
+ self._i +=1
378
+ return layer
379
+ else:
380
+ raise StopIteration
381
+
382
+ def __len__(self):
383
+ return len(self._layers)
384
+
385
+ def __getitem__(self, idx):
386
+ return self._layers[idx]
387
+
388
+ if __name__ == '__main__':
389
+ n_input = 5
390
+ n_hidden_list = [10,20,30,20,10]
391
+ activation_list = [nn.Sigmoid(), nn.ReLU(), nn.LeakyReLU(0.03), nn.Tanh(), nn.Identity()]
392
+ fnn = FNN(n_input, n_hidden_list, activation_list)
393
+ fnn_resnet = FNN_Resnet(n_input, n_hidden_list, activation_list)
394
+ fnn_densenet = FNN_Densenet(n_input, n_hidden_list, activation_list)
395
+ print(fnn)
396
+ print(fnn_resnet)
397
+ print(fnn_densenet)
@@ -0,0 +1,2 @@
1
+
2
+ from . import lr_scheduler
@@ -0,0 +1,195 @@
1
+ from torch.optim.lr_scheduler import _LRScheduler
2
+ class AdaptiveLR(_LRScheduler):
3
+ """Modify the learning rate of each parameter group,
4
+ depending on the current & previous loss values.
5
+
6
+ If current_loss < previous_loss:
7
+ lr += a*lr (Increment lr by a * lr)
8
+ If current loss > previous loss:
9
+ lr -= b*lr (Decrement lr by b * lr)
10
+
11
+ Args:
12
+ optimizer (Optimizer): Wrapped optimizer.
13
+ a: (float or list): A multiplicative factor to increment learning rate
14
+ when the current loss is lower than the previous loss.
15
+ b: (float or list): A multiplicative factor to decrement learning rate
16
+ when the current loss is higher than the previous loss.
17
+
18
+ The increment/decrement of learning rate is done on
19
+ each lr for each group in optimizer.param_groups
20
+ Example:
21
+ >>> # Assuming optimizer has two groups.
22
+ >>> a_list = [0.1, 0.2]
23
+ >>> b_list = [0.5, 0.9]
24
+ >>> scheduler = AdaptiveLR(optimizer, a=a_list, b=b_list)
25
+ >>> for epoch in range(100):
26
+ >>> train(...)
27
+ >>> validate(...)
28
+ >>> scheduler.step(loss)
29
+ """
30
+ requires_loss = True
31
+ def __init__(self, optimizer, a, b, last_epoch = -1, threshold = -float('inf'), fix = False, last_loss = float('inf')):
32
+ self.last_loss = last_loss
33
+ self.loss = self.last_loss
34
+ self.threshold = threshold
35
+ self.fix = fix
36
+ self.factor = 1
37
+ self.a = a
38
+ self.b = b
39
+ # if (not isinstance(a, list) and not isinstance(a, tuple)) and (not isinstance(b, list) and not isinstance(b, tuple)):
40
+ # self.a_s = [a] * len(optimizer.param_groups)
41
+ # self.b_s = [b] * len(optimizer.param_groups)
42
+ # elif (isinstance(a, list) or isinstance(a, tuple)) and (isinstance(b, list) or isinstance(b, tuple)):
43
+ # if len(a) != len(optimizer.param_groups) or len(b) != len(optimizer.param_groups):
44
+ # raise ValueError("Expected {} 'a's and 'b's, but got {}, {}".format(
45
+ # len(optimizer.param_groups), len(a), len(b)))
46
+ # self.a_s = list(a)
47
+ # self.b_s = list(b)
48
+ # else:
49
+ # raise ValueError("a and b has to be the same type, of either iterable or numeric values."
50
+ # "Got: a: {}, b: {}".format(type(a), type(b)))
51
+ super(AdaptiveLR, self).__init__(optimizer, last_epoch)
52
+
53
+ def step(self, loss = 0, epoch=None):
54
+ if self.last_epoch >= 0:
55
+ self.last_loss = self.loss
56
+ self.loss = loss
57
+ # self.last_epoch gets incremented afterwards
58
+ super(AdaptiveLR, self).step(epoch=epoch)
59
+
60
+ def get_lr(self):
61
+ if not self._get_lr_called_within_step:
62
+ warnings.warn("To get the last learning rate computed by the scheduler, "
63
+ "please use `get_last_lr()`.", DeprecationWarning)
64
+ if self.last_epoch > 0:
65
+ if self.factor < self.threshold:
66
+ # lr fixed after threshold
67
+ if self.fix:
68
+ return [base_lr * self.threshold for base_lr in self.base_lrs]
69
+ # lr not fixed after threshold
70
+ elif self.loss <= self.last_loss:
71
+ self.factor += self.factor * self.a
72
+ return [base_lr * self.factor for base_lr in self.base_lrs]
73
+ # return [group['lr'] + group['lr'] * self.a for group in self.optimizer.param_groups]
74
+ else:
75
+ return [base_lr * self.factor for base_lr in self.base_lrs]
76
+ # return [group['lr'] for group in self.optimizer.param_groups]
77
+ else:
78
+ if self.loss <= self.last_loss:
79
+ self.factor += self.factor * self.a
80
+ return [base_lr * self.factor for base_lr in self.base_lrs]
81
+ # return [group['lr'] + group['lr'] * self.a for group in self.optimizer.param_groups]
82
+ else:
83
+ self.factor -= self.factor * self.b
84
+ return [base_lr * self.factor for base_lr in self.base_lrs]
85
+ # return [group['lr'] - group['lr'] * self.b for group in self.optimizer.param_groups]
86
+ else:
87
+ return self.base_lrs
88
+
89
+ class LinearLR(_LRScheduler):
90
+ """Decay the learning rate of each parameter group by delta every epoch.
91
+ Every step,
92
+ lr = lr - initial_lr * delta
93
+ -----
94
+ Args:
95
+ optimizer (Optimizer): Wrapped optimizer.
96
+ delta: (float or list): A subtractive factor to decrement learning rate.
97
+ last_epoch (int): The index of last epoch. Default: -1.
98
+ Example:
99
+ >>> # Assuming optimizer has two groups.
100
+ >>> delta_list = [0.1, 0.2]
101
+ >>> scheduler = AdaptiveLR(optimizer, delta=delta_list)
102
+ >>> for epoch in range(100):
103
+ >>> train(...)
104
+ >>> validate(...)
105
+ >>> scheduler.step()
106
+ """
107
+ def __init__(self, optimizer, delta, last_epoch = -1):
108
+ self.deltas = delta
109
+ if not isinstance(delta, list) and not isinstance(delta, tuple):
110
+ self.deltas = [delta] * len(optimizer.param_groups)
111
+ else:
112
+ if len(delta) != len(optimizer.param_groups):
113
+ raise ValueError("Expected {} deltas, but got {}".format(
114
+ len(optimizer.param_groups), len(delta)))
115
+ self.deltas = list(delta)
116
+ super(LinearLR, self).__init__(optimizer, last_epoch)
117
+
118
+ def get_lr(self):
119
+ if not self._get_lr_called_within_step:
120
+ warnings.warn("To get the last learning rate computed by the scheduler, "
121
+ "please use `get_last_lr()`.", DeprecationWarning)
122
+ if self.last_epoch > 0:
123
+ return [group['lr'] - base_lr * delta for group, base_lr, delta in zip(self.optimizer.param_groups, self.base_lrs, self.deltas)]
124
+ else:
125
+ return self.base_lrs
126
+
127
+ def _get_closed_form_lr(self):
128
+ return [base_lr*(1 - delta * self.epoch) for base_lr, delta in zip(self.base_lrs, self.deltas)]
129
+
130
+
131
+ class NoneLR(_LRScheduler):
132
+ def __init__(self, optimizer, last_epoch = -1):
133
+ super(NoneLR, self).__init__(optimizer, last_epoch)
134
+ def get_lr(self):
135
+ return self.base_lrs
136
+ #
137
+ # import torch
138
+ # import torch.optim as optim
139
+ # w = torch.randn((1,5), requires_grad=True)
140
+ # y = torch.randn((2,3), requires_grad=True)
141
+ # optimizer = optim.Adam([w,y])
142
+ # optimizer
143
+ # lr_schduler = AdaptiveLR(optimizer, a=[0.1,0.2], b=0.5)
144
+ # help(AdaptiveLR1)
145
+ # lr_schduler.state_dict()
146
+ #
147
+ # for
148
+ # optimizer.step()
149
+ # lr_schduler.step()
150
+ # lr_schduler.state_dict()
151
+ #
152
+ # class AdaptiveLR():
153
+ # def __init__(self, optimizer, a, b, last_epoch = 0):
154
+ # self.optimizer = optimizer
155
+ # self.a = a
156
+ # self.b = b
157
+ # self.last_loss = float('inf')
158
+ # self.base_lrs = [param_group['lr'] for param_group in optimizer.param_groups]
159
+ # self.last_epoch = last_epoch
160
+ # self._last_lr = self.base_lrs
161
+ #
162
+ # def state_dict(self):
163
+ # content = dict(
164
+ # optimizer = self.optimizer,
165
+ # a = self.a,
166
+ # b = self.b,
167
+ # last_loss = self.last_loss,
168
+ # base_lrs = self.base_lrs,
169
+ # last_epoch = self.last_epoch,
170
+ # _last_lr = self._last_lr,
171
+ # )
172
+ # return content
173
+ #
174
+ # def step(self, loss):
175
+ # for i, param_group in enumerate(self.optimizer.param_groups):
176
+ # lr = param_group['lr']
177
+ # if loss <= self.last_loss:
178
+ # self._last_lr[i] += lr * self.a
179
+ # else:
180
+ # self._last_lr[i] -= lr * self.b
181
+ # self.optimizer.param_groups[i]['lr'] = self._last_lr[i]
182
+ # self.last_loss = loss
183
+ # self.last_epoch += 1
184
+ #
185
+ #
186
+ # def get_last_lr(self):
187
+ # return self._last_lr
188
+
189
+ def lr_schedule_VAE(epoch):
190
+ if epoch <= 100:
191
+ lr_target = 1e-4
192
+ lr_decay = (lr_target) ** (1/100 * epoch)
193
+ return lr_decay
194
+ else:
195
+ return 1e-3
tools/torch/plot.py ADDED
@@ -0,0 +1,13 @@
1
+
2
+ import matplotlib.pyplot as plt
3
+
4
+ # %%
5
+ def imshow(tensor, **kwargs):
6
+ '''
7
+ tensor of (Channel, width, height)
8
+ '''
9
+ tensor=tensor.detach().cpu().numpy()
10
+ fig, ax = plt.subplots()
11
+ ax.imshow(tensor.transpose(1,2,0))
12
+
13
+ return fig, ax