需求:需要根据前n步的相关特征去预测一个结果,这个结果是一个类别
模型:使用GRU加全连接层作为模型实现预测分类的任务
# 构建GRU
class GRU(torch.nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super().__init__()
self.input_size = input_size
self.hidden_size = hidden_size
self.num_layers = num_layers
self.output_size = output_size
self.gru = torch.nn.GRU(self.input_size, self.hidden_size, self.num_layers, batch_first=True)
self.linear = torch.nn.Linear(self.hidden_size, self.output_size)
def forward(self, input_seq):
output, _ = self.gru(input_seq, None)
pred = output[:, -1, :]
pred = self.linear(output)
return pred
损失函数:使用交叉熵作为损失函数,交叉熵多用于分类任务
loss_function = torch.nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.Adam(model.parameters(),lr=0.05)
读取原始数据文件:原始的数据文件是txt类型的,使用pandas的read_csv()方法读取原始文件,由于是多个文件所以需要读取一整个文件夹,然后将每个文件中的内容拼接到一起,这使用的方法是pandas的concat()
# 读取数据文件夹
def getData(path):
dataList = []
files = os.listdir(path.encode('utf-8').decode('utf-8'))
for file in files:
txt_path = path + file
f = pd.read_csv(txt_path,header = None,encoding='utf-8')
dataList.append(f)
data = pd.concat(dataList)
return data
# 单个文件
def get_one_data(file):
f = pd.read_csv(file,header = None,encoding='utf-8')
return f
数据集划分:需要将准备的数据划分为训练集、验证集、测试集,可以将测试集单独保存用于后续的评估。将划分的数据进行进一步封装,封装成dataset类型(因为想要使用dataloader为模型加载数据)
# 数据转dataset
class data_to_dataset(Dataset):
def __init__(self, data):
self.data = data
def __getitem__(self, item):
return self.data[item]
def __len__(self):
return len(self.data)
预测结果分析:训练过程使用训练损失和验证损失来查看拟合情况,然后可以输出一下预测的准确度(预测的类别/对应标签);使用测试集测试预测的准确度。
# 训练函数定义
def train(data, model, device, loss_fuc, optim):
loss_print = []
preds = []
labels = []
for batch_idx, (seq,label) in enumerate(data,0):
seq = seq.to(torch.float32)
seq = seq.to(device)
label = label[:, -1]
labels.append(label.numpy().tolist())
label = label.to(device)
pred = model(seq)
loss = loss_fuc(pred, label)
loss_print.append(loss.item())
optim.zero_grad()
loss.backward()
optim.step()
_, pred_index = torch.max(pred, 1)
preds.append(pred_index.numpy().tolist())
for i in range(len(labels)):
labels[0] = np.hstack((labels[0], labels[i]))
for h in range(len(preds)):
preds[0] = np.hstack((preds[0], preds[h]))
loss = np.mean(loss_print)
accuracy = sum(labels[0] == preds[0]) / len(labels[0])
return loss, accuracy