Skip to content

Commit 2b7d602

Browse files
committed
Improvements in hyperparameter tuning
1 parent 6355dff commit 2b7d602

File tree

1 file changed

+46
-63
lines changed

1 file changed

+46
-63
lines changed

examples/Active_Learning/qbc_svc.py

+46-63
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,6 @@
2222
from matplotlib.lines import Line2D
2323

2424

25-
def spherical_to_cartesian(angles):
26-
"""
27-
Convert a list of 5 spherical angles to Cartesian coordinates.
28-
Parameters
29-
----------
30-
angles : (N,)-array
31-
List of 5 angles in radians.
32-
Returns
33-
-------
34-
coordinates : (N,6) array
35-
Cartesian coordinates computed from the input spherical angles.
36-
"""
37-
assert len(angles) == 5
38-
x1 = np.cos(angles[0])
39-
x2 = np.sin(angles[0]) * np.cos(angles[1])
40-
x3 = np.sin(angles[0]) * np.sin(angles[1]) * np.cos(angles[2])
41-
x4 = np.sin(angles[0]) * np.sin(angles[1]) * np.sin(angles[2]) * np.cos(angles[3])
42-
x5 = np.sin(angles[0]) * np.sin(angles[1]) * np.sin(angles[2]) * np.sin(angles[3]) * np.cos(angles[4])
43-
x6 = np.sin(angles[0]) * np.sin(angles[1]) * np.sin(angles[2]) * np.sin(angles[3]) * np.sin(angles[4])
44-
return np.array([x1, x2, x3, x4, x5, x6])
45-
46-
4725
def creator_rnd(npoints, precision=8):
4826
"""
4927
Generate random points in a 6D space, normalize them, and then round to the specified precision.
@@ -75,25 +53,6 @@ def creator_rnd(npoints, precision=8):
7553
points.append(point_rounded)
7654
return np.vstack(points)
7755

78-
'''
79-
def find_yloc(x, sig, mat):
80-
"""
81-
Function to expand unit stresses by factor and calculate yield function;
82-
used by search algorithm to find zeros of yield function.
83-
Parameters
84-
----------
85-
x : (N,)-array
86-
Multiplyer for stress
87-
sig : (N,6) array
88-
unit stress
89-
Returns
90-
-------
91-
f : 1d-array
92-
Yield function evaluated at sig=x.sp
93-
"""
94-
f = mat.calc_yf(sig * x[:, None])
95-
return f'''
96-
9756

9857
def eval_variance(angles, committee):
9958
"""
@@ -114,14 +73,35 @@ def eval_variance(angles, committee):
11473
Negative variance of the yield function outputs for maximization purpose.
11574
"""
11675
# Convert from spherical to Cartesian coordinates
117-
x = spherical_to_cartesian(angles)
76+
x = FE.sig_spherical_to_cartesian(angles)
11877
y = np.zeros(len(committee))
11978
for i, member in enumerate(committee):
120-
y[i] = member.calc_yf(x * member.sy)
79+
y[i] = member.calc_yf(x * member.sy * 0.5)
12180
variance = np.var(y)
12281
return -variance
12382

12483

84+
def comp_score(mat1, mat2, mat_ref, npoint=100, scale=10, offset=5):
85+
# analyze training result
86+
global nsamples_init, nsamples_to_generate
87+
loc = mat_ref.sy
88+
X1 = np.random.normal(loc=loc, scale=scale, size=int(npoint / 2))
89+
X2 = np.random.normal(loc=(loc - offset), scale=scale, size=int(npoint / 4))
90+
X3 = np.random.normal(loc=(loc + offset), scale=scale, size=int(npoint / 4))
91+
X = np.concatenate((X1, X2, X3))
92+
sunittest = FE.load_cases(number_3d=0, number_6d=len(X))
93+
sig_test = sunittest * X[:, None]
94+
yf_ml1 = mat1.calc_yf(sig_test)
95+
yf_ml2 = mat2.calc_yf(sig_test)
96+
yf_ref = mat_ref.calc_yf(sig_test)
97+
print(f'\n*** Training scores of active learning model with {nsamples_init} initial '
98+
f'and {nsamples_to_generate} training points:')
99+
FE.training_score(yf_ref, yf_ml1)
100+
print(f'\n*** Training scores of conventional learning model with {nsamples_init + nsamples_to_generate} '
101+
f'training points:')
102+
FE.training_score(yf_ref, yf_ml2)
103+
104+
125105
def plot_variances(var_list):
126106
plt.plot(var_list, marker='o')
127107
plt.xlabel('Iteration')
@@ -166,14 +146,15 @@ def read_vectors(file_name):
166146
vectors = np.loadtxt(file_name)
167147
return vectors
168148

149+
169150
# Query by committee parameters
170151
# max disagreement for yf-predictions,
171152
# for classifiers generally possible: vote_entropy, consensus_entropy or
172153
# maximum_disagreement, cf. https://modal-python.readthedocs.io/en/latest/content/query_strategies/Disagreement-sampling.html#disagreement-sampling
173154

174155
nmembers = 5 # Number of committee members
175-
nsamples_init = 80 # Number of initial samples
176-
nsamples_to_generate = 60 # Number of iterations
156+
nsamples_init = 42 # Number of initial samples
157+
nsamples_to_generate = 30 # Number of iterations
177158
subset_percentage = 0.8 # Percent of data used for each committee member
178159
init_rnd = False # Train with random initial data points
179160
file_init = None # 'DATA_sunit_iter_80.txt'
@@ -194,27 +175,27 @@ def read_vectors(file_name):
194175
sunit = creator_rnd(nsamples_init, 8)
195176
else:
196177
# alternative for training with equally spaced initial data points
197-
c = int(nsamples_init*2/3)
178+
c = int(nsamples_init / 3)
198179
d = nsamples_init - c
199180
sunit = FE.load_cases(number_3d=c, number_6d=d)
200181
np.savetxt('Test_Cases.txt', sunit)
201182

202183
# create set of unit stresses
203184
print('Created {0} unit stresses (6d Voigt tensor).'.format(nsamples_init))
204-
x1 = fsolve(mat_h.find_yloc, np.ones(nsamples_init) * mat_h.sy, args=(sunit, ), xtol=1.e-5)
185+
x1 = fsolve(mat_h.find_yloc, np.ones(nsamples_init) * mat_h.sy, args=(sunit,), xtol=1.e-5)
205186
sig = sunit * x1[:, None]
206187
print('Calculated {} yield stresses.'.format(nsamples_init))
207188

208189
# train SVC with yield stress data generated from Hill flow rule
209-
C = 4.0
210-
gamma = 2.0
190+
C = 3.0
191+
gamma = 0.5
211192
Ce = 0.99
212193
Fe = 0.1
213194
Nseq = 25
214195
vlevel = 0
215196
gsearch = True
216-
cvals = [3, 4, 6, 8]
217-
gvals = [1.5, 2.0, 2.5, 3.0]
197+
cvals = [1, 2, 3, 4, 5]
198+
gvals = [0.7, 1.0, 1.5, 2.0, 2.5]
218199

219200
mat_ml = FE.Material(name='ML-Hill') # define material
220201
mat_ml.train_SVC(C=C, gamma=gamma, Fe=Fe, Ce=Ce, Nseq=Nseq, sdata=sig, extend=False,
@@ -233,7 +214,7 @@ def read_vectors(file_name):
233214
committee = []
234215
tstart = time.time()
235216
for j in range(nmembers):
236-
idx = np.random.choice(np.arange(sig.shape[0]),
217+
idx = np.random.choice(np.arange(sig.shape[0]),
237218
int(sig.shape[0] * subset_percentage),
238219
replace=False)
239220
mat_ml = FE.Material(name='ML-Hill_{}'.format(j))
@@ -245,29 +226,29 @@ def read_vectors(file_name):
245226
hyp_g_list.append(mat_ml.gam_yf)
246227
committee.append(mat_ml)
247228
tend = time.time()
248-
print(f'***Iteration {i}:\n Time for training committee: {tend-tstart}')
229+
print(f'***Iteration {i}:\n Time for training committee: {tend - tstart}')
249230

250231
# Search for next unit vector to query
251232
tstart = time.time()
252-
res = differential_evolution(eval_variance, bounds, args=(committee, ),
233+
res = differential_evolution(eval_variance, bounds, args=(committee,),
253234
popsize=90, polish=True,
254235
updating='immediate')
255236
tend = time.time()
256-
print(f' Time for differential evolution: {tend-tstart}')
237+
print(f' Time for differential evolution: {tend - tstart}')
257238
sunit_neww = res.x
258-
sunit_new = spherical_to_cartesian(sunit_neww)
239+
sunit_new = FE.sig_spherical_to_cartesian(sunit_neww)
259240
variance = res.fun
260241
var.append(-variance)
261242

262243
# Calculate corresponding stress state and update data set
263-
x1 = fsolve(mat_h.find_yloc, mat_h.sy, args=(sunit_new, ), xtol=1.e-5)
244+
x1 = fsolve(mat_h.find_yloc, mat_h.sy, args=(sunit_new,), xtol=1.e-5)
264245
sig_new = sunit_new * x1[:, None]
265246
sig = np.vstack([sig, sig_new])
266247
sunit = np.vstack([sunit, sunit_new])
267248

268249
# Train final model with all data sets
269250
mat_ml = FE.Material(name='ML-Hill') # define material
270-
mat_ml.train_SVC(C=C, gamma=gamma, Fe=0.1, Ce=Ce, Nseq=Nseq,
251+
mat_ml.train_SVC(C=C, gamma=gamma, Fe=Fe, Ce=Ce, Nseq=Nseq,
271252
sdata=sig, extend=False,
272253
gridsearch=True, cvals=cvals, gvals=gvals,
273254
verbose=vlevel)
@@ -277,13 +258,16 @@ def read_vectors(file_name):
277258
c = int(Ntot / 3)
278259
d = Ntot - c
279260
sunit_r = FE.load_cases(number_3d=c, number_6d=d)
280-
x1 = fsolve(mat_h.find_yloc, np.ones(Ntot) * mat_h.sy, args=(sunit_r, ), xtol=1.e-5)
261+
x1 = fsolve(mat_h.find_yloc, np.ones(Ntot) * mat_h.sy, args=(sunit_r,), xtol=1.e-5)
281262
sig_r = sunit_r * x1[:, None]
282263
mat_ml_r = FE.Material(name='ML-Hill') # define material
283-
mat_ml_r.train_SVC(C=C, gamma=gamma, Fe=0.1, Ce=Ce, Nseq=Nseq,
264+
mat_ml_r.train_SVC(C=C, gamma=gamma, Fe=Fe, Ce=Ce, Nseq=Nseq,
284265
sdata=sig_r,
285266
gridsearch=True, cvals=cvals, gvals=gvals, verbose=vlevel)
286267

268+
# Evaluate results
269+
comp_score(mat_ml, mat_ml_r, mat_ref=mat_h, npoint=300)
270+
287271
# Plot results
288272
plot_yield_locus(mat_ml, mat_h, nsamples_to_generate, mat3=mat_ml_r)
289273
plot_variances(var)
@@ -299,7 +283,6 @@ def read_vectors(file_name):
299283
plt.show()
300284

301285
# Save data files
302-
np.savetxt('DATA_sig_iter_{}.txt'.format(i + 1), sig)
303-
np.savetxt('DATA_sunit_iter_{}.txt'.format(i + 1), sunit)
286+
np.savetxt('DATA_sig_iter_{}.txt'.format(nsamples_to_generate), sig)
287+
np.savetxt('DATA_sunit_iter_{}.txt'.format(nsamples_to_generate), sunit)
304288
np.savetxt('variance.txt', var)
305-

0 commit comments

Comments
 (0)