junshan-kit 2.3.9__py2.py3-none-any.whl → 2.4.1__py2.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.
junshan_kit/SPBM.py ADDED
@@ -0,0 +1,350 @@
1
+ from junshan_kit import SPBM, SPBM_func
2
+ import torch, time, os
3
+ from torch.optim.optimizer import Optimizer
4
+ from torch.nn.utils import parameters_to_vector, vector_to_parameters
5
+
6
+
7
+ class PF(Optimizer):
8
+ def __init__(self, params, model, hyperparams, Paras):
9
+ defaults = dict()
10
+ super().__init__(params, defaults)
11
+ self.model = model
12
+ self.cutting_num = hyperparams['cutting_number']
13
+ self.M = hyperparams['M']
14
+ self.delta = hyperparams['delta']
15
+ self.Paras = Paras
16
+
17
+ self.x_his, self.g_his, self.f_his = [], [], []
18
+
19
+ def step(self, closure=None):
20
+ if closure is None:
21
+ raise RuntimeError("Closure required for CuttingPlaneOptimizer")
22
+
23
+ # 清零梯度并前向计算
24
+ loss = closure()
25
+
26
+ with torch.no_grad():
27
+ xk = parameters_to_vector(self.model.parameters())
28
+ # print(torch.norm(xk))
29
+ g_k = parameters_to_vector([p.grad if p.grad is not None else torch.zeros_like(p) for p in self.model.parameters()])
30
+
31
+ # Add cutting plane
32
+ x_his, f_his, g_his = SPBM_func.add_cutting(self.x_his, self.f_his, self.g_his,xk.detach().clone(), g_k.detach().clone(), loss.detach().clone(), self.cutting_num)
33
+
34
+ ## Cut selection
35
+ selected_x, selected_f, selected_g = SPBM_func.cut_selection(x_his, f_his, g_his, self.M)
36
+
37
+ # the coefficient of dual problem
38
+ Gk, rk, ek = SPBM_func.get_var(selected_x, selected_f, selected_g, self.delta)
39
+
40
+ # SOVER (dual)
41
+ xk = SPBM_func.subproblem_pf(Gk, ek, xk, self.delta, self.Paras)
42
+
43
+ # print(len(self.f_his))
44
+ vector_to_parameters(xk, self.model.parameters())
45
+
46
+
47
+ # 暂时返回 loss(tensor 类型)
48
+ return loss
49
+
50
+ # <SPBM-TR>
51
+ class TR(Optimizer):
52
+ def __init__(self, params, model, hyperparams, Paras):
53
+ defaults = dict()
54
+ super().__init__(params, defaults)
55
+ self.model = model
56
+ self.cutting_num = hyperparams['cutting_number']
57
+ self.M = hyperparams['M']
58
+ self.delta = hyperparams['delta']
59
+ self.Paras = Paras
60
+
61
+ self.x_his, self.g_his, self.f_his = [], [], []
62
+
63
+ def step(self, closure=None):
64
+ if closure is None:
65
+ raise RuntimeError("Closure required for CuttingPlaneOptimizer")
66
+
67
+ # Reset the gradient and perform forward computation
68
+ loss = closure()
69
+
70
+ with torch.no_grad():
71
+ xk = parameters_to_vector(self.model.parameters())
72
+ # print(torch.norm(xk))
73
+ g_k = parameters_to_vector([p.grad if p.grad is not None else torch.zeros_like(p) for p in self.model.parameters()])
74
+
75
+ # Add cutting plane
76
+ x_his, f_his, g_his = SPBM_func.add_cutting(self.x_his, self.f_his, self.g_his,xk.detach().clone(), g_k.detach().clone(), loss.detach().clone(), self.cutting_num)
77
+
78
+ ## Cut selection
79
+ selected_x, selected_f, selected_g = SPBM_func.cut_selection(x_his, f_his, g_his, self.M)
80
+
81
+ # the coefficient of dual problem
82
+ Gk, rk, ek = SPBM_func.get_var(selected_x, selected_f, selected_g, self.delta)
83
+
84
+ # SOVER (dual)
85
+ xk = SPBM_func.subproblem_tr_2(Gk, ek, xk, rk, self.Paras)
86
+
87
+ # print(len(self.f_his))
88
+ vector_to_parameters(xk, self.model.parameters())
89
+
90
+ # tensor type
91
+ return loss
92
+ # <SPBM-TR>
93
+
94
+ # <SPBM-TR_NoneSpecial>
95
+ class TR_NoneSpecial(Optimizer):
96
+ def __init__(self, params, model, hyperparams, Paras):
97
+ defaults = dict()
98
+ super().__init__(params, defaults)
99
+ self.model = model
100
+ self.cutting_num = hyperparams['cutting_number']
101
+ self.M = hyperparams['M']
102
+ self.delta = hyperparams['delta']
103
+ self.Paras = Paras
104
+
105
+ self.x_his, self.g_his, self.f_his = [], [], []
106
+
107
+ def step(self, closure=None):
108
+ if closure is None:
109
+ raise RuntimeError("Closure required for CuttingPlaneOptimizer")
110
+
111
+ # Reset the gradient and perform forward computation
112
+ loss = closure()
113
+
114
+ with torch.no_grad():
115
+ xk = parameters_to_vector(self.model.parameters())
116
+ # print(torch.norm(xk))
117
+ g_k = parameters_to_vector([p.grad if p.grad is not None else torch.zeros_like(p) for p in self.model.parameters()])
118
+
119
+ # Add cutting plane
120
+ x_his, f_his, g_his = SPBM_func.add_cutting(self.x_his, self.f_his, self.g_his,xk.detach().clone(), g_k.detach().clone(), loss.detach().clone(), self.cutting_num)
121
+
122
+ ## Cut selection
123
+ selected_x, selected_f, selected_g = SPBM_func.cut_selection(x_his, f_his, g_his, self.M)
124
+
125
+ # the coefficient of dual problem
126
+ Gk, rk, ek = SPBM_func.get_var(selected_x, selected_f, selected_g, self.delta)
127
+
128
+ # SOVER (dual)
129
+ xk = SPBM_func.subproblem_tr_NoneSpecial(Gk, ek, xk, rk, self.Paras)
130
+
131
+ # print(len(self.f_his))
132
+ vector_to_parameters(xk, self.model.parameters())
133
+
134
+ # tensor type
135
+ return loss
136
+ # <SPBM-TR_NoneSpecial>
137
+
138
+ class TR_primal(Optimizer):
139
+ def __init__(self, params, model, hyperparams, Paras):
140
+ defaults = dict()
141
+ super().__init__(params, defaults)
142
+ self.model = model
143
+ self.cutting_num = hyperparams['cutting_number']
144
+ self.M = hyperparams['M']
145
+ self.delta = hyperparams['delta']
146
+ self.Paras = Paras
147
+
148
+ self.x_his, self.g_his, self.f_his = [], [], []
149
+
150
+ def step(self, closure=None):
151
+ if closure is None:
152
+ raise RuntimeError("Closure required for CuttingPlaneOptimizer")
153
+
154
+ # Reset the gradient and perform forward computation
155
+ loss = closure()
156
+
157
+ with torch.no_grad():
158
+ xk = parameters_to_vector(self.model.parameters())
159
+ # print(torch.norm(xk))
160
+ g_k = parameters_to_vector([p.grad if p.grad is not None else torch.zeros_like(p) for p in self.model.parameters()])
161
+
162
+ # Add cutting plane
163
+ x_his, f_his, g_his = SPBM_func.add_cutting(self.x_his, self.f_his, self.g_his,xk.detach().clone(), g_k.detach().clone(), loss.detach().clone(), self.cutting_num)
164
+
165
+ ## Cut selection
166
+ selected_x, selected_f, selected_g = SPBM_func.cut_selection(x_his, f_his, g_his, self.M)
167
+
168
+ # the coefficient of dual problem
169
+ Gk, rk, ek = SPBM_func.get_var(selected_x, selected_f, selected_g, self.delta)
170
+
171
+ # SOVER (dual)
172
+ xk = SPBM_func.subproblem_tr_primal(Gk, ek, xk, rk, self.Paras)
173
+
174
+ # print(len(self.f_his))
175
+ vector_to_parameters(xk, self.model.parameters())
176
+
177
+ # tensor type
178
+ return loss
179
+
180
+
181
+ class TR_NoneLower(Optimizer):
182
+ def __init__(self, params, model, hyperparams, Paras):
183
+ defaults = dict()
184
+ super().__init__(params, defaults)
185
+ self.model = model
186
+ self.cutting_num = hyperparams['cutting_number']
187
+ self.M = hyperparams['M']
188
+ self.delta = hyperparams['delta']
189
+ self.Paras = Paras
190
+
191
+ self.x_his, self.g_his, self.f_his = [], [], []
192
+
193
+ def step(self, closure=None):
194
+ if closure is None:
195
+ raise RuntimeError("Closure required for CuttingPlaneOptimizer")
196
+
197
+ # Reset the gradient and perform forward computation
198
+ loss = closure()
199
+
200
+ with torch.no_grad():
201
+ xk = parameters_to_vector(self.model.parameters())
202
+ # print(torch.norm(xk))
203
+ g_k = parameters_to_vector([p.grad if p.grad is not None else torch.zeros_like(p) for p in self.model.parameters()])
204
+
205
+ # Add cutting plane
206
+ x_his, f_his, g_his = SPBM_func.add_cutting(self.x_his, self.f_his, self.g_his,xk.detach().clone(), g_k.detach().clone(), loss.detach().clone(), self.cutting_num)
207
+
208
+ ## Cut selection
209
+ selected_x, selected_f, selected_g = SPBM_func.cut_selection(x_his, f_his, g_his, self.M)
210
+
211
+ # the coefficient of dual problem
212
+ Gk, rk, ek = SPBM_func.get_var(selected_x, selected_f, selected_g, self.delta)
213
+
214
+ # SOVER (dual)
215
+ xk = SPBM_func.subproblem_tr_NoneLower(Gk, ek, xk, rk, self.Paras)
216
+
217
+ # print(len(self.f_his))
218
+ vector_to_parameters(xk, self.model.parameters())
219
+
220
+ # tensor type
221
+ return loss
222
+
223
+ class TR_NoneCut(Optimizer):
224
+ def __init__(self, params, model, hyperparams, Paras):
225
+ defaults = dict()
226
+ super().__init__(params, defaults)
227
+ self.model = model
228
+ self.cutting_num = hyperparams['cutting_number']
229
+ self.M = hyperparams['M']
230
+ self.delta = hyperparams['delta']
231
+ self.Paras = Paras
232
+
233
+ self.x_his, self.g_his, self.f_his = [], [], []
234
+
235
+ def step(self, closure=None):
236
+ if closure is None:
237
+ raise RuntimeError("Closure required for CuttingPlaneOptimizer")
238
+
239
+ # Reset the gradient and perform forward computation
240
+ loss = closure()
241
+
242
+ with torch.no_grad():
243
+ xk = parameters_to_vector(self.model.parameters())
244
+ # print(torch.norm(xk))
245
+ g_k = parameters_to_vector([p.grad if p.grad is not None else torch.zeros_like(p) for p in self.model.parameters()])
246
+
247
+ # Add cutting plane
248
+ x_his, f_his, g_his = SPBM_func.add_cutting(self.x_his, self.f_his, self.g_his,xk.detach().clone(), g_k.detach().clone(), loss.detach().clone(), self.cutting_num)
249
+
250
+ # ## Cut selection
251
+ # selected_x, selected_f, selected_g = SPBM_func.cut_selection(x_his, f_his, g_his, self.M)
252
+
253
+ # the coefficient of dual problem
254
+ Gk, rk, ek = SPBM_func.get_var(x_his, f_his, g_his, self.delta)
255
+
256
+ # SOVER (dual)
257
+ xk = SPBM_func.subproblem_tr_NoneLower(Gk, ek, xk, rk, self.Paras)
258
+
259
+ # print(len(self.f_his))
260
+ vector_to_parameters(xk, self.model.parameters())
261
+
262
+ # tensor type
263
+ return loss
264
+
265
+ # ************************** SPBM-PF **************************
266
+ class PF_NoneLower(Optimizer):
267
+ def __init__(self, params, model, hyperparams, Paras):
268
+ defaults = dict()
269
+ super().__init__(params, defaults)
270
+ self.model = model
271
+ self.cutting_num = hyperparams['cutting_number']
272
+ self.M = hyperparams['M']
273
+ self.delta = hyperparams['delta']
274
+ self.Paras = Paras
275
+
276
+ self.x_his, self.g_his, self.f_his = [], [], []
277
+
278
+ def step(self, closure=None):
279
+ if closure is None:
280
+ raise RuntimeError("Closure required for CuttingPlaneOptimizer")
281
+
282
+ # Reset the gradient and perform forward computation
283
+ loss = closure()
284
+
285
+ with torch.no_grad():
286
+ xk = parameters_to_vector(self.model.parameters())
287
+ # print(torch.norm(xk))
288
+ g_k = parameters_to_vector([p.grad if p.grad is not None else torch.zeros_like(p) for p in self.model.parameters()])
289
+
290
+ # Add cutting plane
291
+ x_his, f_his, g_his = SPBM_func.add_cutting(self.x_his, self.f_his, self.g_his,xk.detach().clone(), g_k.detach().clone(), loss.detach().clone(), self.cutting_num)
292
+
293
+ ## Cut selection
294
+ selected_x, selected_f, selected_g = SPBM_func.cut_selection(x_his, f_his, g_his, self.M)
295
+
296
+ # the coefficient of dual problem
297
+ Gk, rk, ek = SPBM_func.get_var(selected_x, selected_f, selected_g, self.delta)
298
+
299
+ # SOVER (dual)
300
+ xk = SPBM_func.subproblem_pf_NoneLower(Gk, ek, xk, self.delta, self.Paras)
301
+
302
+ # print(len(self.f_his))
303
+ vector_to_parameters(xk, self.model.parameters())
304
+
305
+ # tensor type
306
+ return loss
307
+
308
+
309
+ class PF_NoneCut(Optimizer):
310
+ def __init__(self, params, model, hyperparams, Paras):
311
+ defaults = dict()
312
+ super().__init__(params, defaults)
313
+ self.model = model
314
+ self.cutting_num = hyperparams['cutting_number']
315
+ self.M = hyperparams['M']
316
+ self.delta = hyperparams['delta']
317
+ self.Paras = Paras
318
+
319
+ self.x_his, self.g_his, self.f_his = [], [], []
320
+
321
+ def step(self, closure=None):
322
+ if closure is None:
323
+ raise RuntimeError("Closure required for CuttingPlaneOptimizer")
324
+
325
+ # Reset the gradient and perform forward computation
326
+ loss = closure()
327
+
328
+ with torch.no_grad():
329
+ xk = parameters_to_vector(self.model.parameters())
330
+ # print(torch.norm(xk))
331
+ g_k = parameters_to_vector([p.grad if p.grad is not None else torch.zeros_like(p) for p in self.model.parameters()])
332
+
333
+ # Add cutting plane
334
+ x_his, f_his, g_his = SPBM_func.add_cutting(self.x_his, self.f_his, self.g_his,xk.detach().clone(), g_k.detach().clone(), loss.detach().clone(), self.cutting_num)
335
+
336
+ # ## Cut selection
337
+ # selected_x, selected_f, selected_g = SPBM_func.cut_selection(x_his, f_his, g_his, self.M)
338
+
339
+ # the coefficient of dual problem
340
+ Gk, rk, ek = SPBM_func.get_var(x_his, f_his, g_his, self.delta)
341
+
342
+ # SOVER (dual)
343
+ xk = SPBM_func.subproblem_pf_NoneLower(Gk, ek, xk, self.delta, self.Paras)
344
+
345
+ # print(len(self.f_his))
346
+ vector_to_parameters(xk, self.model.parameters())
347
+
348
+ # tensor type
349
+ return loss
350
+