Rui Wan commited on
Commit
f6af415
·
1 Parent(s): bdfdfb9

model update

Browse files
Files changed (3) hide show
  1. main_thermo.py +166 -0
  2. model_checkpoint.pth +3 -0
  3. model_inverse.py +11 -11
main_thermo.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ from Dataset import Dataset
5
+ from model import NeuralNetwork
6
+
7
+ DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
8
+ # Set global plotting parameters
9
+ plt.rcParams.update({'font.size': 14,
10
+ 'figure.figsize': (10, 8),
11
+ 'lines.linewidth': 2,
12
+ 'lines.markersize': 6,
13
+ 'axes.grid': True,
14
+ 'axes.labelsize': 16,
15
+ 'legend.fontsize': 14,
16
+ 'xtick.labelsize': 14,
17
+ 'ytick.labelsize': 14,
18
+ 'figure.autolayout': True
19
+ })
20
+
21
+ def set_seed(seed=42):
22
+ np.random.seed(seed)
23
+ torch.manual_seed(seed)
24
+ if torch.cuda.is_available():
25
+ torch.cuda.manual_seed_all(seed)
26
+
27
+ def train_neural_network(model, inputs, outputs, optimizer, epochs=1000, lr_scheduler=None):
28
+ model.train()
29
+ for epoch in range(epochs):
30
+ optimizer.zero_grad()
31
+ predictions = model(inputs)
32
+ loss = torch.mean(torch.square(predictions - outputs))
33
+ loss.backward()
34
+ optimizer.step()
35
+
36
+ if lr_scheduler:
37
+ lr_scheduler.step()
38
+
39
+ if epoch % 100 == 0:
40
+ print(f'Epoch {epoch}, Loss: {loss.item()}, Learning Rate: {optimizer.param_groups[0]["lr"]}')
41
+
42
+ def main():
43
+ set_seed(5324)
44
+ dataset = Dataset()
45
+ inputs = dataset.get_input(normalize=True)
46
+ outputs = dataset.get_output(normalize=True)
47
+
48
+ idx_train = np.random.choice(len(inputs), size=int(0.98 * len(inputs)), replace=False)
49
+ idx_test = np.setdiff1d(np.arange(len(inputs)), idx_train)
50
+
51
+ inputs_train = torch.tensor(inputs[idx_train], dtype=torch.float32).to(DEVICE)
52
+ outputs_train = torch.tensor(outputs[idx_train], dtype=torch.float32).to(DEVICE)
53
+
54
+ inputs_test = torch.tensor(inputs[idx_test], dtype=torch.float32).to(DEVICE)
55
+ outputs_test = torch.tensor(outputs[idx_test], dtype=torch.float32).to(DEVICE)
56
+
57
+ layer_sizes = [inputs.shape[1]] + [64] * 3 + [outputs.shape[1]]
58
+ model = NeuralNetwork(layer_sizes, dropout_rate=0.0, activation=torch.nn.ReLU).to(DEVICE)
59
+ optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
60
+ lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5000, gamma=0.9)
61
+
62
+ # Create a proper dataset that keeps input-output pairs together
63
+ train_dataset = torch.utils.data.TensorDataset(inputs_train, outputs_train)
64
+ train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=16, shuffle=True)
65
+
66
+ # Train the model
67
+ epochs = 20000
68
+ for epoch in range(epochs):
69
+ model.train()
70
+ for inputs_batch, outputs_batch in train_loader:
71
+ inputs_batch = inputs_batch.to(DEVICE)
72
+ outputs_batch = outputs_batch.to(DEVICE)
73
+ optimizer.zero_grad()
74
+ predictions = model(inputs_batch)
75
+ loss = torch.mean(torch.square(predictions - outputs_batch))
76
+ loss.backward()
77
+ optimizer.step()
78
+
79
+ if lr_scheduler:
80
+ lr_scheduler.step()
81
+
82
+ if epoch % 500 == 0:
83
+ train_pred = model(inputs_train)
84
+ train_loss = torch.mean(torch.square(train_pred - outputs_train))
85
+ test_pred = model(inputs_test)
86
+ test_loss = torch.mean(torch.square(test_pred - outputs_test))
87
+ print(f'Epoch {epoch}, Train Loss: {train_loss.item():.6f}, Test Loss: {test_loss.item():.6f}')
88
+ # print(f'Learning Rate: {optimizer.param_groups[0]["lr"]}')
89
+
90
+
91
+ predictions = model.predict(inputs_test)
92
+ test_loss = torch.mean(torch.square(predictions - outputs_test))
93
+ print(f'Test Loss: {test_loss.item()}. Samples: {idx_test}')
94
+
95
+ x = np.arange(0, len(idx_test))
96
+
97
+ outputs_test = dataset.denormalize_output(outputs_test.cpu().numpy())
98
+ predictions = dataset.denormalize_output(predictions.cpu().numpy())
99
+ # for sample in outputs_test:
100
+ # print(f'Test samples: {sample}')
101
+ plt.figure(figsize=(10, 6))
102
+ plt.plot(x, outputs_test[:, 0], color='b', linestyle='--', label='True A1')
103
+ plt.plot(x, predictions[:, 0], color='b', linestyle='-', label='Predicted A1')
104
+ plt.plot(x, outputs_test[:, 1], color='r', linestyle='--', label='True B1')
105
+ plt.plot(x, predictions[:, 1], color='r', linestyle='-', label='Predicted B1')
106
+ plt.plot(x, outputs_test[:, 2], color='g', linestyle='--', label='True C1')
107
+ plt.plot(x, predictions[:, 2], color='g', linestyle='-', label='Predicted C1')
108
+ plt.gca().xaxis.set_major_locator(plt.MaxNLocator(integer=True))
109
+ plt.xlabel('Sample Index')
110
+ plt.xticks(ticks=range(len(idx_test)),labels=idx_test + 1)
111
+ plt.ylabel('Springback Angle (Degrees)')
112
+ plt.title('Springback Angle Prediction')
113
+ plt.legend(loc='upper right')
114
+ plt.savefig('springback_angle_prediction.png')
115
+
116
+
117
+ plt.figure(figsize=(10, 6))
118
+ plt.plot(x, outputs_test[:, 3], color='m', linestyle='--', label='True Stress(Max)')
119
+ plt.plot(x, predictions[:, 3], color='m', linestyle='-', label='Predicted Stress(Max)')
120
+ plt.xlabel('Sample Index')
121
+ plt.xticks(ticks=range(len(idx_test)),labels=idx_test + 1)
122
+ plt.ylabel('Stress (MPa)')
123
+ plt.legend(loc='upper left')
124
+ plt.savefig('stress_max_prediction.png')
125
+
126
+
127
+
128
+ # MSE
129
+ mse = np.mean((predictions - outputs_test) ** 2, axis=0)
130
+ print(f'Mean Squared Error for A1: {mse[0]:.6f}, B1: {mse[1]:.6f}, C1: {mse[2]:.6f}, Stress(Max): {mse[3]:.6f}')
131
+
132
+ # R 2 score
133
+ ss_ress = np.sum((outputs_test - predictions) ** 2, axis=0)
134
+ ss_tots = np.sum((outputs_test - np.mean(outputs_test, axis=0)) ** 2, axis=0)
135
+ r2_scores = 1 - ss_ress / ss_tots
136
+ print(f'R² Score for A1: {r2_scores[0]:.6f}, B1: {r2_scores[1]:.6f}, C1: {r2_scores[2]:.6f}, Stress(Max): {r2_scores[3]:.6f}')
137
+
138
+ # Error
139
+
140
+ # Save the model
141
+ model_save_path = './model_checkpoint.pth'
142
+ model_config = {'layer_sizes': layer_sizes,
143
+ 'dropout_rate': 0.05
144
+ }
145
+ checkpoint = {
146
+ 'model_state_dict': model.state_dict(),
147
+ 'model_config': model_config
148
+ }
149
+ torch.save(checkpoint, model_save_path)
150
+ # Load the model
151
+ # model = NeuralNetwork(layer_sizes)
152
+ # model.load_state_dict(torch.load(model_save_path))
153
+
154
+ def load_model(model_path):
155
+ checkpoint = torch.load(model_path)
156
+ model_config = checkpoint['model_config']
157
+ model = NeuralNetwork(model_config['layer_sizes'], dropout_rate=model_config['dropout_rate'], activation=torch.nn.ReLU).to(DEVICE)
158
+ model.load_state_dict(checkpoint['model_state_dict'])
159
+ print(f"Model loaded from {model_path}")
160
+ return model
161
+
162
+
163
+ if __name__ == "__main__":
164
+ main()
165
+ # model = load_model('./model_checkpoint.pth')
166
+
model_checkpoint.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b9ae97d59647cd7449f86b66f0b44526047fa1316600b52defc9fd990cdfdf28
3
+ size 39563
model_inverse.py CHANGED
@@ -90,7 +90,7 @@ def load_model(model_path):
90
  return model
91
 
92
  def inverse_design(ply_number, y_target, n_restarts=20, epochs=1000, use_lbfgs=False):
93
- model = load_model('./model_inverse_ckpt.pth')
94
 
95
  data = Dataset()
96
  y_target_norm = data.normalize_output(y_target) # (A1, B1, C1, Stress)
@@ -101,7 +101,7 @@ def inverse_design(ply_number, y_target, n_restarts=20, epochs=1000, use_lbfgs=F
101
  output_std = torch.tensor(data.output_std)
102
 
103
  weights = torch.tensor([1.0, 1.0, 1.0, 0.0], dtype=torch.float32)
104
- bounds = torch.tensor([[350., 450.], [100., 500.], [450., 550.]], dtype=torch.float32) # Initial_Temp, Punch_Velocity, Cooling_Time
105
  best = {"loss": float('inf'), "input": None, "output": None}
106
 
107
  for restart in range(n_restarts):
@@ -235,15 +235,15 @@ def inverse_model():
235
  # Error
236
 
237
  # Save the model
238
- # model_save_path = './model_inverse_ckpt.pth'
239
- # model_config = {'layer_sizes': layer_sizes,
240
- # 'dropout_rate': 0.05
241
- # }
242
- # checkpoint = {
243
- # 'model_state_dict': model.state_dict(),
244
- # 'model_config': model_config
245
- # }
246
- # torch.save(checkpoint, model_save_path)
247
 
248
 
249
  if __name__ == "__main__":
 
90
  return model
91
 
92
  def inverse_design(ply_number, y_target, n_restarts=20, epochs=1000, use_lbfgs=False):
93
+ model = load_model('./model_checkpoint.pth')
94
 
95
  data = Dataset()
96
  y_target_norm = data.normalize_output(y_target) # (A1, B1, C1, Stress)
 
101
  output_std = torch.tensor(data.output_std)
102
 
103
  weights = torch.tensor([1.0, 1.0, 1.0, 0.0], dtype=torch.float32)
104
+ bounds = torch.tensor([[100., 600.], [100., 600.], [100., 600.]], dtype=torch.float32) # Initial_Temp, Punch_Velocity, Cooling_Time
105
  best = {"loss": float('inf'), "input": None, "output": None}
106
 
107
  for restart in range(n_restarts):
 
235
  # Error
236
 
237
  # Save the model
238
+ model_save_path = './model_inverse_ckpt.pth'
239
+ model_config = {'layer_sizes': layer_sizes,
240
+ 'dropout_rate': 0.05
241
+ }
242
+ checkpoint = {
243
+ 'model_state_dict': model.state_dict(),
244
+ 'model_config': model_config
245
+ }
246
+ torch.save(checkpoint, model_save_path)
247
 
248
 
249
  if __name__ == "__main__":