import matplotlib.pyplot as plt
x_train = torch.arange(0.1, 10, 0.1).reshape(-1, features_dim) # 训练数据
x_test = torch.arange(0.2, 10, 0.12).reshape(-1, features_dim) # 测试数据
y_train = torch.sin(x_train) + torch.normal(0, 0.1, x_train.shape) + 100 # 训练标签
y_test = torch.sin(x_test) + torch.normal(0, 0.15, x_test.shape) + 100 # 测试标签
plt.scatter(x_train, y_train, marker='x', s=20)
input_scaler = MinMaxScaler(feature_range=(-1, 1))
output_scaler = MinMaxScaler(feature_range=(-1, 1))
x_train_scaled = input_scaler.fit_transform(x_train)
x_test_scaled = input_scaler.transform(x_test)
y_train_scaled = output_scaler.fit_transform(y_train)
y_test_scaled = output_scaler.transform(y_test)
plt.scatter(x_train_scaled, y_train_scaled, marker='x', s=20)
model = Model(features_dim=1, output_dim=1, hidden_dim=8, hidden_layers_num=2, nonlinearity='Sigmoid', layer_norm=True)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
losses = np.zeros(epochs)
test_losses = np.zeros(epochs)
for epoch in range(epochs):
y_pred = model(x_train_scaled)
loss = loss_fn(y_pred, y_train_scaled)
y_test_pred = model(x_test_scaled)
test_loss = loss_fn(y_test_pred, y_test_scaled)
test_loss_value = test_loss.item()
losses[epoch] = loss_value
test_losses[epoch] = test_loss_value
ar2 = adjusted_r2_score(y_train_scaled, y_pred, features_dim)
print(f'Epoch {epoch}|{epochs}, Loss: {loss_value:>.6f}, Test Loss: {test_loss_value:>.6f}, Adjusted R²: {ar2:>.6f}')
plt.plot(losses, label='Train Loss')
plt.plot(test_losses, label='Test Loss')
y_pred_scaled = model(x_test_scaled)
y_pred = output_scaler.inverse_transform(y_pred_scaled)
plt.scatter(x_test, y_test, marker='x', s=20, label='Actual')
plt.plot(x_test, y_pred, label='Pred')
class ModelWrapper(nn.Module):
def __init__(self, base_model: nn.Module, input_scaler: MinMaxScaler, output_scaler: MinMaxScaler):
super(ModelWrapper, self).__init__()
self.base_model = base_model
self.input_scaler = input_scaler
self.output_scaler = output_scaler
def forward(self, x: torch.Tensor):
x_scaled = self.input_scaler.transform(x)
y_pred_scaled = self.base_model(x_scaled)
y_pred = self.output_scaler.inverse_transform(y_pred_scaled)
model_wrapper = ModelWrapper(model, input_scaler, output_scaler)
model_wrapper.eval() # 转换为 ONNX 格式前,需要将模型设置为评估模式
(torch.randn(1, features_dim, requires_grad=True), ), # 输入数据
opset_version=11, # ONNX 版本
export_params=True, # 是否导出参数
input_names=["input"], # 输入节点名称
output_names=["output"], # 输出节点名称