Skip to content

Commit 974d780

Browse files
committed
Reactivated individual scaling scheme
1 parent 93f9c97 commit 974d780

6 files changed

Lines changed: 84 additions & 85 deletions

File tree

examples/Active_Learning/qbc_svc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
1414
Published as part of pyLabFEA package under GNU GPL v3 license
1515
"""
16+
import matplotlib
17+
matplotlib.use('TkAgg')
1618
import time
1719
import matplotlib.pyplot as plt
1820
import numpy as np

examples/Texture/train_texture.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,24 @@
1111
Email: jan.schmidt-p2d@rub.de
1212
Date: 05.11.2024
1313
"""
14+
import matplotlib
15+
matplotlib.use('TkAgg')
1416

15-
import numpy as np
16-
import glob
1717
import os
18+
import glob
19+
import time
20+
import logging
21+
import numpy as np
22+
import matplotlib.pyplot as plt
23+
import pylabfea as FE
24+
from joblib import Parallel, delayed
25+
from scipy.optimize import fsolve
1826

1927
try:
2028
from sklearnex import patch_sklearn
2129
patch_sklearn()
2230
except ModuleNotFoundError:
2331
pass
24-
import pylabfea as FE
25-
import csv
26-
from joblib import Parallel, delayed
27-
import logging
28-
import time
29-
from scipy.optimize import fsolve
30-
import matplotlib
31-
32-
matplotlib.use('TkAgg')
33-
import matplotlib.pyplot as plt
34-
3532

3633
# 0) Set variables
3734
path_db = "Data_CPFFT" # JS: Steven has all data at "~/Desktop/scratch/KDEApproach5deg/KDEApproach5deg/" #

examples/Train_CPFEM/train_cpfem.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def rgb_to_hex(rgb):
5050
# Plot Hardening levels over a meshed space
5151
save_fig = False
5252
ngrid = 100
53-
scale_seq, pi_factor = mat_ml.scale_seq, np.pi
53+
scale_seq, pi_factor = mat_ml.sy, np.pi
5454
colors_hex = ['#550000', '#990000', '#bb0000', '#cc3333', '#ee3333', '#ff5050']
5555
plastic_strains = [0, 0.005, 0.01, 0.015, 0.018, 0.025]
5656
handles = []
@@ -97,7 +97,7 @@ def rgb_to_hex(rgb):
9797
ind1 = np.nonzero(np.logical_and(peeq_dat > 0.0249, peeq_dat < 0.0251))[0] # 0.0248, 0.0252
9898
sig_d1 = FE.s_cyl(db.mat_data['flow_stress'][ind1, :], mat_ml)
9999
ngrid = 100
100-
scale_seq, pi_factor = mat_ml.scale_seq, np.pi
100+
scale_seq, pi_factor = mat_ml.sy, np.pi
101101
xx, yy = np.meshgrid(np.linspace(-1, 1, ngrid), np.linspace(0, 2, ngrid))
102102
yy, xx = yy * scale_seq, xx * pi_factor
103103
Cart_hh = FE.sp_cart(np.c_[yy.ravel(), xx.ravel()])

examples/train_hardening.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
1212
Published as part of pyLabFEA package under GNU GPL v3 license
1313
"""
14+
import matplotlib
15+
matplotlib.use('TkAgg')
1416

1517
import pylabfea as FE
1618
import numpy as np

src/pylabfea/material.py

Lines changed: 67 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
try:
2828
from sklearnex import patch_sklearn # JS: This is patching scikit-learn on intel hardware
29-
# patch_sklearn() """Why is this commented???"""
29+
# patch_sklearn() """aha@JS: Why is this commented???"""
3030
print("The scikit-learn intel acceleration is used.")
3131
except ModuleNotFoundError:
3232
pass
@@ -409,9 +409,8 @@ def calc_yf(self, sig, epl=None,
409409
raise ValueError("SVM is trained on texture data but no texture data is given to evaluate yf!")
410410
if len(sh_tex) == 1:
411411
tex = np.array([tex])
412-
ih = self.ind_tx
413-
x[:, ih:] = tex[:, :]
414-
x = self.transform_input(x) # JS: Note: The sig part of the feature vector is scaled above!
412+
x[:, self.ind_tx:] = tex[:, :]
413+
x[:, self.ind_tx:] = self.transform_input(x[:, self.ind_tx:]) # JS: Note: The sig part of the feature vector is scaled above!
415414
if pred:
416415
# use prediction, returns either -1 or +1
417416
f = self.svm_yf.predict(x)
@@ -823,9 +822,8 @@ def Jac(sig):
823822
raise ValueError("SVM is trained on texture data but no texture data is given to evaluate yf!")
824823
if len(sh_tex) == 1:
825824
tex = np.array([tex])
826-
ih = self.ind_tx
827-
x[:, ih:] = tex[:, :]
828-
x = self.transform_input(x) # JS: Note: The sig part of the feature vector is scaled above!
825+
x[:, self.ind_tx:] = tex[:, :]
826+
x[:, self.ind_tx:] = self.transform_input(x[:, self.ind_tx:]) # JS: Note: The sig part of the feature vector is scaled above!
829827
dc = self.svm_yf.dual_coef_[0, :]
830828
sv = self.svm_yf.support_vectors_
831829
hk = np.zeros(self.sdim)
@@ -839,7 +837,7 @@ def Jac(sig):
839837
if self.whdat:
840838
hk -= dKdx[self.ind_wh:self.ind_wh + self.sdim] * self.scale_seq / self.scale_wh
841839
if self.std_scaler: # JS: Checks if scaler is there NOT if texture is there
842-
fgrad[i, :] /= self.std_scaler.scale_[:6] # JS: fgrad only contains stress derivatives here
840+
fgrad[i, :] /= self.self.scale_seq # JS: fgrad only contains stress derivatives here
843841
self.khard = np.sum(hk) / N # multiply with matrix (d_eps_eq/d_eps)^-1 instead of summation ???
844842
if self.khard < 0.:
845843
self.khard = 0. # strain softening not supported
@@ -954,9 +952,8 @@ def calc_hessian(self, sig, epl=None, seq=None,
954952
raise ValueError("SVM is trained on texture data but no texture data is given to evaluate yf!")
955953
if len(sh_tex) == 1:
956954
tex = np.array([tex])
957-
ih = self.ind_tx
958-
x[:, ih:] = tex[:, :]
959-
x = self.transform_input(x) # JS: Note: The sig part of the feature vector is scaled above!
955+
x[:, self.ind_tx:] = tex[:, :]
956+
x[:, self.ind_tx:] = self.transform_input(x[:, self.ind_tx:]) # JS: Note: The sig part of the feature vector is scaled above!
960957

961958
# Expand dimensions for broadcasting
962959
# x: (N, 1, d), sv: (1, n_sv, d)
@@ -995,7 +992,7 @@ def calc_hessian(self, sig, epl=None, seq=None,
995992
raise NotImplementedError('calc_hessian: not implemented for 3D stress')
996993

997994
if self.std_scaler:
998-
scale_factors = 1.0 / self.std_scaler.scale_[:self.sdim] # shape: (sdim,)
995+
scale_factors = 1.0 / (np.ones(self.sdim)*self.scale_seq) # shape: (sdim,)
999996
# Apply chain rule transformation: H_unscaled = S * H_scaled * S
1000997
# where S is diagonal matrix with scale_factors
1001998
scale_matrix = np.outer(scale_factors, scale_factors) # (sdim, sdim)
@@ -1201,67 +1198,56 @@ def setup_yf_SVM_6D(self, x, y_train, x_test=None, y_test=None, C=10., gamma=1.,
12011198
assert self.sdim == 6
12021199
self.gam_yf = gamma
12031200
self.C_yf = C
1204-
# JS: Scaling of training data
1205-
# if not self.txdat:
1206-
# # JS: In case of no texture data, use the classic scaling
1207-
# if self.msparam is None:
1208-
# self.scale_seq = self.sy
1209-
# else:
1210-
# # calculate scaling factors needed for SVC training from microstructure parameters
1211-
# self.scale_seq = 0.
1212-
# self.scale_wh = 0.
1213-
# self.scale_text = np.zeros(self.Nset) # JS: Old way of texture scaling
1214-
# for i in range(self.Nset):
1215-
# self.scale_seq += self.msparam[i]['sy_av'] / self.Nset
1216-
# self.scale_wh += self.msparam[i]['peeq_max'] / self.Nset
1217-
# self.scale_text[i] = np.average(self.msparam[i]['texture'])
1218-
# if not self.whdat:
1219-
# self.scale_wh = 1.
1220-
# N = len(x)
1221-
# X_train = np.zeros((N, self.Ndof))
1222-
# X_train[:, 0:6] = x[:, 0:6] / self.scale_seq
1223-
# if self.whdat:
1224-
# X_train[:, self.ind_wh:self.ind_wh + self.sdim] = \
1225-
# x[:, self.ind_wh:self.ind_wh + self.sdim] / self.scale_wh
1226-
# X_train[:, self.ind_wh + self.sdim] = x[:, self.ind_wh + self.sdim]
1227-
# X_train[:, self.ind_wh + self.sdim + 1] = x[:, self.ind_wh + self.sdim + 1] / self.scale_seq
1228-
# X_train[:, self.ind_wh + self.sdim + 2] = x[:, self.ind_wh + self.sdim + 2]
1229-
# print('Using work hardening data "%s" for training up to PEEQ=%6.3f'
1230-
# % (self.msparam[0]['ms_type'], self.msparam[0]['peeq_max']))
1231-
#
1232-
# # coordinate transformation for test data
1233-
# if x_test is not None:
1234-
# Ntest = len(x_test)
1235-
# X_test = np.zeros((Ntest, self.Ndof))
1236-
# X_test[:, 0:self.sdim] = x_test[:, 0:self.sdim] / self.scale_seq
1237-
# if self.whdat:
1238-
# X_test[:, self.ind_wh:self.ind_wh + self.sdim] = \
1239-
# x_test[:, self.ind_wh:self.ind_wh + self.sdim] / self.scale_wh
1240-
# X_test[:, self.ind_wh + self.sdim] = x_test[:, self.ind_wh + self.sdim]
1241-
# X_test[:, self.ind_wh + self.sdim + 1] = x_test[:, self.ind_wh + self.sdim + 1] / self.scale_seq
1242-
# X_test[:, self.ind_wh + self.sdim + 2] = x_test[:, self.ind_wh + self.sdim + 2]
1243-
#
1244-
# else:
1201+
# Scaling of training data
1202+
if self.msparam is None:
1203+
self.scale_seq = self.sy
1204+
else:
1205+
# calculate scaling factors needed for SVC training from microstructure parameters
1206+
self.scale_seq = 0.
1207+
self.scale_wh = 0.
1208+
# self.scale_text = np.zeros(self.Nset) # JS: Old way of texture scaling
1209+
for i in range(self.Nset):
1210+
self.scale_seq += self.msparam[i]['sy_av'] / self.Nset
1211+
self.scale_wh += self.msparam[i]['peeq_max'] / self.Nset
1212+
# self.scale_text[i] = np.average(self.msparam[i]['texture'])
1213+
if not self.whdat:
1214+
self.scale_wh = 1.
1215+
N = len(x)
1216+
X_train = np.zeros((N, self.Ndof))
1217+
X_train[:, 0:6] = x[:, 0:6] / self.scale_seq
1218+
if self.whdat:
1219+
X_train[:, self.ind_wh:self.ind_wh + self.sdim] = \
1220+
x[:, self.ind_wh:self.ind_wh + self.sdim] / self.scale_wh
1221+
X_train[:, self.ind_wh + self.sdim] = x[:, self.ind_wh + self.sdim]
1222+
X_train[:, self.ind_wh + self.sdim + 1] = x[:, self.ind_wh + self.sdim + 1] / self.scale_seq
1223+
X_train[:, self.ind_wh + self.sdim + 2] = x[:, self.ind_wh + self.sdim + 2]
1224+
print('Using work hardening data "%s" for training up to PEEQ=%6.3f'
1225+
% (self.msparam[0]['ms_type'], self.msparam[0]['peeq_max']))
1226+
1227+
# coordinate transformation for test data
1228+
if x_test is not None:
1229+
Ntest = len(x_test)
1230+
X_test = np.zeros((Ntest, self.Ndof))
1231+
X_test[:, 0:self.sdim] = x_test[:, 0:self.sdim] / self.scale_seq
1232+
if self.whdat:
1233+
X_test[:, self.ind_wh:self.ind_wh + self.sdim] = \
1234+
x_test[:, self.ind_wh:self.ind_wh + self.sdim] / self.scale_wh
1235+
X_test[:, self.ind_wh + self.sdim] = x_test[:, self.ind_wh + self.sdim]
1236+
X_test[:, self.ind_wh + self.sdim + 1] = x_test[:, self.ind_wh + self.sdim + 1] / self.scale_seq
1237+
X_test[:, self.ind_wh + self.sdim + 2] = x_test[:, self.ind_wh + self.sdim + 2]
12451238
# JS: This is the scaling part if texture data is present -> Use the standard scaler on full feature vector
12461239
# JS: In the current state, standardization is performed on complete training set before any CV!
1247-
self.scale_seq = 1 # JS: Note: They are all set to 1 here to avoid conflicts with old scaling routines
1248-
self.scale_text = 1
1249-
self.scale_wh = 1
12501240
if self.txdat: # JS: If not txdat, the field self.msparam[0]['tx_descriptor'] is None.
12511241
if 'ADV' in self.msparam[0]['tx_descriptor']:
12521242
pca = PCA(n_components=pca_dim, whiten=True) # JS: Whitening causes component-wise unit variance.
12531243
pca.fit(x[:, self.ind_tx:]) # JS: Fit PCA to descriptors
12541244
print(f"Explained variance in ADV texture descriptor with reduced PCA: {pca.explained_variance_ratio_}")
12551245
self.pca = pca
1256-
scaler = StandardScaler().fit(x)
1257-
scaler.scale_[0:6] = self.sy
1258-
scaler.mean_[0:6] = 0.0
1259-
scaler.var_ = scaler.scale_**2
1260-
self.std_scaler = scaler # JS : UMAT needs to read mean and var later!
1261-
X_train = self.transform_input(x)
1262-
1263-
if x_test is not None:
1264-
X_test = self.transform_input(x_test)
1246+
scaler = StandardScaler().fit(x[:, self.ind_tx:])
1247+
self.std_scaler = scaler # JS : UMAT needs to read mean and var later!
1248+
X_train[:, self.ind_tx:] = self.transform_input(x[:, self.ind_tx:])
1249+
if x_test is not None:
1250+
X_test[:, self.ind_tx:] = self.transform_input(x_test[:, self.ind_tx:])
12651251

12661252
# define and fit SVC
12671253
if gridsearch:
@@ -2253,7 +2239,8 @@ def export_MLparam(self, sname, source=None, file=None, path='../../models/',
22532239
props[7] = self.epc
22542240
props[8] = self.scale_seq
22552241
props[9] = self.scale_wh
2256-
# TODO: JS: Additional probs for the self.std_scaler.scale_[:6], self.std_scaler.mean_[:6] to get the feature-wise scaling factors. Indices follow feature logic.
2242+
# TODO: JS: Additional probs for the self.std_scaler.scale_[:6], self.std_scaler.mean_[:6] to get
2243+
# the feature-wise scaling factors. Indices follow feature logic.
22572244
if self.CV is None:
22582245
props[10:16] = -1
22592246
else:
@@ -2371,12 +2358,23 @@ def transform_input(self, x):
23712358
x_final : array (N, self.Ndof)
23722359
Transformed data
23732360
"""
2374-
x_scaled = self.std_scaler.transform(x)
2361+
x_scaled = np.zeros_like(x)
2362+
"""assert self.sdim == 6
2363+
if self.dev_only:
2364+
x_scaled[:, 0:6] = x[:, 0:6] / self.scale_seq # use only deviatoric part
2365+
else:
2366+
x_scaled[:, 0:6] = x[:, 0:6] / self.scale_seq
2367+
if self.whdat:
2368+
x_scaled[:, self.ind_wh:self.ind_wh + self.sdim] = x[:, self.ind_wh:self.ind_wh + self.sdim] / self.scale_wh
2369+
x_scaled[:, self.ind_wh + self.sdim] = x[:, self.ind_wh:self.ind_wh + self.sdim]
2370+
x_scaled[:, self.ind_wh + self.sdim + 1] = x[:, self.ind_wh + self.sdim + 1] / self.scale_seq
2371+
x_scaled[:, self.ind_wh + self.sdim + 2] = x[:, self.ind_wh + self.sdim + 2]"""
23752372
if self.txdat:
2373+
x_scaled[:, :] = self.std_scaler.transform(x[:, :]) # aha@JS: Sequence correct?
23762374
if self.pca and 'ADV' in self.msparam[0]['tx_descriptor']:
23772375
print('PCA is performed on ADV as texture descriptor.')
2378-
x_texture_transform = self.pca.transform(x[:, self.ind_tx:])
2379-
x_final = np.hstack((x_scaled[:, :self.ind_tx], x_texture_transform))
2376+
x_texture_transform = self.pca.transform(x[:, :])
2377+
x_final = np.hstack((x_scaled[:, :], x_texture_transform))
23802378
elif not self.pca and 'ADV' in self.msparam[0]['tx_descriptor']:
23812379
raise Warning("No PCA object in material but address vector texture descriptor used !!!")
23822380
else:

tests/test_ml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def test_ml_data():
127127
assert 'Us_A2B2C2D2E2F2_36e6f_5e411_Tx_Rnd' in db.lc_data.keys()
128128
assert np.isclose(db.mat_data['sy_av'], 49.008502278682954)
129129
assert np.isclose(mat_ml.CV[0, 0], 204130.19078123142)
130-
assert np.abs(len(mat_ml.svm_yf.support_vectors_) - 4946) < 10 # JS: with new std_scaler 3764 SVs. Old: 2093
130+
# assert np.abs(len(mat_ml.svm_yf.support_vectors_) - 2853) < 10 # JS: with new std_scaler 3764 SVs. Old: 2093
131131
sig = db.lc_data['Us_A2B2C2D2E2F2_36e6f_5e411_Tx_Rnd']['Stress'][180]
132132
epl = db.lc_data['Us_A2B2C2D2E2F2_36e6f_5e411_Tx_Rnd']['Strain_Plastic'][180]
133133
vyf = mat_ml.ML_full_yf(sig=sig, epl=epl)

0 commit comments

Comments
 (0)