import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 从CSV文件加载数据
data = pd.read_csv('dataset99.csv')
# 将前两列数据转换为PyTorch张量
tensor_data = torch.tensor(data.values[:, :2], dtype=torch.float32)
# 获取前两列特征的最小值和最大值
min_val1 = torch.min(tensor_data)
max_val1 = torch.max(tensor_data)
# 使用最小值和最大值进行0到1的归一化
normalized_data_1 = (tensor_data - min_val1) / (max_val1 - min_val1)
# 将第三列数据转换为PyTorch张量
third_column = torch.tensor(data.values[:, 2], dtype=torch.float32)
# 获取第三列特征的最小值和最大值
min_val_3 = torch.min(third_column)
max_val_3 = torch.max(third_column)
# 使用另一组最小值和最大值进行0到1的归一化
normalized_data_3 = (third_column - min_val_3) / (max_val_3 - min_val_3)
# 将前两列归一化后的数据和第三列归一化后的数据合并
normalized_data1 = torch.cat((normalized_data_1, normalized_data_3.unsqueeze(1)), dim=1)
# 获取归一化后的数据
inputs = normalized_data1[:, :2]
targets = normalized_data1[:, [2]]
# 定义神经网络模型
class IntegralNet(nn.Module):
def __init__(self):
super(IntegralNet, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size) # 输入是上限和下限
self.fc2 = nn.Linear(hidden_size, output_size) # 输出是积分结果
def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
# 创建模型和优化器
input_size = 2
hidden_size = 128
output_size = 1
model = IntegralNet()
optimizer = optim.Adam(model.parameters(), lr=0.008)
criterion = nn.MSELoss() # 使用均方误差损失函数
# 训练模型
num_epochs = 2000
for epoch in range(num_epochs):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}')
# 从CSV文件中加载a和b的值
test_data = pd.read_csv('test_data99.csv')
test_input = torch.tensor(test_data[['t', 'tc']].values, dtype=torch.float32)
'''
# 获取前两列特征的最小值和最大值
min_val2 = torch.min(test_input)
max_val2 = torch.max(test_input)
'''
# 使用最小值和最大值进行0到1的归一化
normalized_data_2 = (test_input - min_val1) / (max_val1 - min_val1)
# 获取归一化后的数据
test_input = normalized_data_2
# 使用训练后的模型来估计被积函数
tensor_delta_E = model(test_input)
estimated_integral_result = tensor_delta_E.detach().numpy()
E0 = targets.numpy()
# 测试训练的模型精度
# 读取用于度量精度的输入数据
ceshi = pd.read_csv('ceshi99.csv')
ceshi_input = torch.tensor(ceshi[['Lower', 'Upper']].values, dtype=torch.float32)
# 归一化操作
normalized_data_3 = (ceshi_input - min_val1) / (max_val1 - min_val1)
ceshi_input = normalized_data_3
validation = model(ceshi_input)
# 反归一化
# 室温至冷端温度的电势值
# 冷端至热端的输出电势值
original_data_3 = (tensor_delta_E * (max_val_3 - min_val_3)) + min_val_3
original_E0 = torch.tensor(data.values[:, [2]], dtype=torch.float32)
validationR = (validation * (max_val_3 - min_val_3)) + min_val_3
# 计算相对误差
m = np.array(ceshi.values[:, [2]]) - np.array(validationR.detach().numpy())
m_absolute = np.absolute(m) # 取标准热电势和预测热电势只差的绝对值
max_error = max(m_absolute) # 取最大的绝对误差
error = m_absolute/ceshi.values[:, [2]] # 计算相对误差
mm = max(error) # 取最大的相对误差
# variance = np.var(y3)
print('模型最大绝对误差为', max_error, 'mV')
print('模型最大相对误差为', mm * 100, '%')
# print('热电输出方差为', variance)
# 输出补偿数值及优化后的热电势
E = original_data_3 + original_E0
EEEEE = E.detach().numpy()
'''
print("补偿的热电势数值:", original_data_3.detach().numpy())
print('热电势:', E.detach().numpy())
'''
# 相关物理量由数组转化为列表绘图
T = np.array(data.values[:, [1]]).flatten().tolist()
V0 = np.array(data.values[:, [2]]).flatten().tolist()
V = np.array(E.detach().numpy()).flatten().tolist()
# 画图
plt.figure(1)
plt.plot(T, V0, 'b-', label='Before compensation')
plt.plot(T, V, 'r-', label='After compensation')
plt.draw()
plt.title('V-T of TFTCs', fontsize=14)
plt.xlabel('T(℃)')
plt.ylabel('Voltage(mV)')
plt.legend()
plt.grid()
plt.show()
全连接神经网络积分补偿
于 2023-09-25 23:57:36 首次发布