在pytorch环境下,假设有一个叫data的csv文件,x有16列,3900行,y有1列,3900行,从数据中均匀地选择60%作为训练集,20%作为测试集,20%作为验证集,将它们输入到有注意力机制的GRU中训练并预测,并绘制预测值与验证集对比图,准确率,损失率。
该回答引用GPTᴼᴾᴱᴺᴬᴵ
import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
# 定义注意力机制的 GRU 模型
class AttentionGRU(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(AttentionGRU, self).__init__()
self.hidden_size = hidden_size
self.gru = nn.GRU(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
self.softmax = nn.Softmax(dim=1)
def forward(self, input):
output, _ = self.gru(input)
attn_weights = self.softmax(output)
weighted_output = torch.bmm(attn_weights.permute(0,2,1), output)
output = self.fc(weighted_output)
return output
# 读取数据
data = pd.read_csv('data.csv') # 替换为你的数据文件名
X = data.iloc[:, :16].values
y = data.iloc[:, 16].values
# 划分数据集为训练集、验证集和测试集
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)
X_valid, X_test, y_valid, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
# 转换为 PyTorch 的 Tensor
X_train = torch.Tensor(X_train)
X_valid = torch.Tensor(X_valid)
X_test = torch.Tensor(X_test)
y_train = torch.Tensor(y_train)
y_valid = torch.Tensor(y_valid)
y_test = torch.Tensor(y_test)
# 构建模型
input_size = 16
hidden_size = 64
output_size = 1
model = AttentionGRU(input_size, hidden_size, output_size)
# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练模型
epochs = 100
train_losses = []
valid_losses = []
for epoch in range(epochs):
model.train()
optimizer.zero_grad()
outputs = model(X_train)
loss = criterion(outputs.view(-1), y_train)
loss.backward()
optimizer.step()
train_losses.append(loss.item())
model.eval()
with torch.no_grad():
outputs_valid = model(X_valid)
loss_valid = criterion(outputs_valid.view(-1), y_valid)
valid_losses.append(loss_valid.item())
print('Epoch [{}/{}], Train Loss: {:.4f}, Valid Loss: {:.4f}'.format(epoch+1, epochs, loss.item(), loss_valid.item()))
# 绘制损失曲线
plt.plot(train_losses, label='Train Loss')
plt.plot(valid_losses, label='Valid Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
# 模型预测
model.eval()
with torch.no_grad():
outputs_test = model(X_test)
y_pred = outputs_test.view(-1).numpy()
y_true = y_test.numpy()
# 绘制预测值与验证集对比图
plt.plot(y_true, label='True')
plt.plot(y_pred, label='Predicted')
plt.xlabel('Sample Index')
plt.ylabel('Prediction')
plt.legend()
plt.show()
计算准确率
y_pred_binary = np.round(y_pred) # 将预测值四舍五入为二分类结果(0或1)
accuracy = np.mean(y_pred_binary == y_true) * 100
print('Accuracy: {:.2f}%'.format(accuracy))
以上代码首先读取名为 data.csv
的数据文件,并将其划分为训练集、验证集和测试集,其中训练集占 60%,验证集和测试集各占 20%。然后定义了一个带有注意力机制的 GRU 模型,并使用均方误差作为损失函数和 Adam 优化器进行训练。训练过程中,记录了训练集和验证集的损失,并绘制了损失曲线。最后,使用训练好的模型在测试集上进行预测,绘制了预测值与真实值的对比图,并计算了准确率。
引用chatGPT作答,以下是一个简单的示例代码,以实现您描述的任务。在这个例子中,我们假设数据文件名为"data.csv",并将其放在当前工作目录下。
首先,我们需要加载所需的Python库,读取数据文件并对数据进行预处理:
import pandas as pd
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
from sklearn.model_selection import train_test_split
# 读取数据
data = pd.read_csv("data.csv")
# 将数据划分为训练集、测试集和验证集
train_data, test_data, valid_data = train_test_split(data, test_size=0.2, random_state=42)
train_data, valid_data = train_test_split(train_data, test_size=0.25, random_state=42)
# 将数据转换为张量
train_x = torch.tensor(train_data.iloc[:, :-1].values, dtype=torch.float32)
train_y = torch.tensor(train_data.iloc[:, -1].values, dtype=torch.float32)
valid_x = torch.tensor(valid_data.iloc[:, :-1].values, dtype=torch.float32)
valid_y = torch.tensor(valid_data.iloc[:, -1].values, dtype=torch.float32)
test_x = torch.tensor(test_data.iloc[:, :-1].values, dtype=torch.float32)
test_y = torch.tensor(test_data.iloc[:, -1].values, dtype=torch.float32)
# 标准化数据
train_mean, train_std = train_x.mean(dim=0), train_x.std(dim=0)
train_x = (train_x - train_mean) / train_std
valid_x = (valid_x - train_mean) / train_std
test_x = (test_x - train_mean) / train_std
接下来,我们定义一个带有注意力机制的GRU模型:
class AttentionGRU(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(AttentionGRU, self).__init__()
self.hidden_size = hidden_size
self.gru = nn.GRU(input_size, hidden_size, batch_first=True)
self.fc1 = nn.Linear(hidden_size, output_size)
self.attention = nn.Linear(hidden_size, hidden_size)
def forward(self, x):
batch_size, seq_len, _ = x.size()
h0 = torch.zeros(1, batch_size, self.hidden_size)
output, hidden = self.gru(x, h0)
attention_weights = torch.softmax(self.attention(output), dim=1)
context_vector = torch.sum(attention_weights * output, dim=1)
output = self.fc1(context_vector)
return output
然后,我们定义一个数据集类,以将训练集、测试集和验证集加载到PyTorch的DataLoader中:
class MyDataset(Dataset):
def __init__(self, x, y):
self.x = x
self.y = y
def __getitem__(self, index):
return self.x[index], self.y[index]
def __len__(self):
return len(self.x)
接下来,我们定义超参数并创建数据加载器:
# 定义超参数
input_size = 16
hidden_size = 64
output_size = 1
lr = 0.001
epochs = 50
batch_size = 32
# 创建数据加载器
train_dataset = MyDataset(train
接下来,我们定义训练和验证函数,并在训练集上训练模型:
def train(model, optimizer, criterion, train_loader, valid_loader, epochs):
train_loss_history = []
valid_loss_history = []
valid_acc_history = []
for epoch in range(1, epochs+1):
model.train()
train_loss = 0
for x, y in train_loader:
optimizer.zero_grad()
y_pred = model(x)
loss = criterion(y_pred.squeeze(), y)
loss.backward()
optimizer.step()
train_loss += loss.item() * x.size(0)
train_loss /= len(train_loader.dataset)
train_loss_history.append(train_loss)
valid_loss, valid_acc = evaluate(model, criterion, valid_loader)
valid_loss_history.append(valid_loss)
valid_acc_history.append(valid_acc)
print(f"Epoch {epoch}/{epochs} - train loss: {train_loss:.4f}, valid loss: {valid_loss:.4f}, valid acc: {valid_acc:.4f}")
return train_loss_history, valid_loss_history, valid_acc_history
def evaluate(model, criterion, data_loader):
model.eval()
loss = 0
correct = 0
with torch.no_grad():
for x, y in data_loader:
y_pred = model(x)
loss += criterion(y_pred.squeeze(), y).item() * x.size(0)
pred = torch.round(y_pred.squeeze())
correct += (pred == y).sum().item()
loss /= len(data_loader.dataset)
acc = correct / len(data_loader.dataset)
return loss, acc
# 创建模型和优化器
model = AttentionGRU(input_size, hidden_size, output_size)
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
criterion = nn.BCEWithLogitsLoss()
# 创建数据加载器
train_dataset = MyDataset(train_x, train_y)
valid_dataset = MyDataset(valid_x, valid_y)
test_dataset = MyDataset(test_x, test_y)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
valid_loader = DataLoader(valid_dataset, batch_size=batch_size)
test_loader = DataLoader(test_dataset, batch_size=batch_size)
# 训练模型
train_loss_history, valid_loss_history, valid_acc_history = train(model, optimizer, criterion, train_loader, valid_loader, epochs)
最后,我们可以使用测试集对模型进行评估,并绘制预测值与验证集对比图:
# 在测试集上评估模型
test_loss, test_acc = evaluate(model, criterion, test_loader)
print(f"Test loss: {test_loss:.4f}, test acc: {test_acc:.4f}")
# 绘制预测值与验证集对比图
model.eval()
valid_pred = model(valid_x).squeeze().detach().numpy()
valid_y = valid_y.numpy()
plt.plot(valid_y, label="true")
plt.plot(valid_pred, label="pred")
plt.legend()
plt.show()
这样,您就可以训练一个带有注意力机制的GRU模型,以预测给定数据集中的目标变量,并评估该模型在测试集上的表现。同时,您还可以通过绘制预测值与验证集的对比图来检查模型的预测能力。