赞
踩
基础的AutoEncoder可以参考:https://blog.csdn.net/weixin_35757704/article/details/118457110
而LSTM AutoEncoder
是将原始的全连接变成了LSTM,然后构造出来的AutoEncoder模型,输入与输出是一样的数据为最佳
博主发现网上对于LSTM AutoEncoder的版本都不一样,通常来讲有:
以下是两种网络架构:
这个结构比较简单,就是encoder的时候过一个lstm,decoder的时候再过一个lstm
class LstmAutoEncoder(nn.Module): def __init__(self, input_layer=300, hidden_layer=100, batch_size=20): super(LstmAutoEncoder, self).__init__() self.input_layer = input_layer self.hidden_layer = hidden_layer self.batch_size = batch_size self.encoder_lstm = nn.LSTM(self.input_layer, self.hidden_layer, batch_first=True) self.decoder_lstm = nn.LSTM(self.hidden_layer, self.input_layer, batch_first=True) def forward(self, input_x): input_x = input_x.view(len(input_x), 1, -1) # encoder encoder_lstm, (n, c) = self.encoder_lstm(input_x, (torch.zeros(1, self.batch_size, self.hidden_layer), torch.zeros(1, self.batch_size, self.hidden_layer))) # decoder decoder_lstm, (n, c) = self.decoder_lstm(encoder_lstm, (torch.zeros(1, self.batch_size, self.input_layer), torch.zeros(1, self.batch_size, self.input_layer))) return decoder_lstm.squeeze()
这个网络结构就是:
class LstmFcAutoEncoder(nn.Module): def __init__(self, input_layer=300, hidden_layer=100, batch_size=20): super(LstmFcAutoEncoder, self).__init__() self.input_layer = input_layer self.hidden_layer = hidden_layer self.batch_size = batch_size self.encoder_lstm = nn.LSTM(self.input_layer, self.hidden_layer, batch_first=True) self.encoder_fc = nn.Linear(self.hidden_layer, self.hidden_layer) self.decoder_lstm = nn.LSTM(self.hidden_layer, self.input_layer, batch_first=True) self.decoder_fc = nn.Linear(self.hidden_layer, self.hidden_layer) self.relu = nn.ReLU() def forward(self, input_x): input_x = input_x.view(len(input_x), 1, -1) # encoder encoder_lstm, (n, c) = self.encoder_lstm(input_x, # shape: (n_layers, batch, hidden_size) (torch.zeros(1, self.batch_size, self.hidden_layer), torch.zeros(1, self.batch_size, self.hidden_layer))) encoder_fc = self.encoder_fc(encoder_lstm) encoder_out = self.relu(encoder_fc) # decoder decoder_fc = self.relu(self.decoder_fc(encoder_out)) decoder_lstm, (n, c) = self.decoder_lstm(decoder_fc, (torch.zeros(1, 20, self.input_layer), torch.zeros(1, 20, self.input_layer))) return decoder_lstm.squeeze()
import torch import torch.nn as nn import torch.utils.data as Data def get_train_data(): """得到训练数据,这里使用随机数生成训练数据,由此导致最终结果并不好""" def get_tensor_from_pd(dataframe_series) -> torch.Tensor: return torch.tensor(data=dataframe_series.values) import numpy as np import pandas as pd from sklearn import preprocessing # 生成训练数据x并做归一化后,构造成dataframe格式,再转换为tensor格式 df = pd.DataFrame(data=preprocessing.MinMaxScaler().fit_transform(np.random.randint(0, 10, size=(2000, 300)))) y = pd.Series(np.random.randint(0, 2, 2000)) return get_tensor_from_pd(df).float(), get_tensor_from_pd(y).float() class LstmAutoEncoder(nn.Module): def __init__(self, input_layer=300, hidden_layer=100, batch_size=20): super(LstmAutoEncoder, self).__init__() self.input_layer = input_layer self.hidden_layer = hidden_layer self.batch_size = batch_size self.encoder_lstm = nn.LSTM(self.input_layer, self.hidden_layer, batch_first=True) self.decoder_lstm = nn.LSTM(self.hidden_layer, self.input_layer, batch_first=True) def forward(self, input_x): input_x = input_x.view(len(input_x), 1, -1) # encoder encoder_lstm, (n, c) = self.encoder_lstm(input_x, (torch.zeros(1, self.batch_size, self.hidden_layer), torch.zeros(1, self.batch_size, self.hidden_layer))) # decoder decoder_lstm, (n, c) = self.decoder_lstm(encoder_lstm, (torch.zeros(1, self.batch_size, self.input_layer), torch.zeros(1, self.batch_size, self.input_layer))) return decoder_lstm.squeeze() class LstmFcAutoEncoder(nn.Module): def __init__(self, input_layer=300, hidden_layer=100, batch_size=20): super(LstmFcAutoEncoder, self).__init__() self.input_layer = input_layer self.hidden_layer = hidden_layer self.batch_size = batch_size self.encoder_lstm = nn.LSTM(self.input_layer, self.hidden_layer, batch_first=True) self.encoder_fc = nn.Linear(self.hidden_layer, self.hidden_layer) self.decoder_lstm = nn.LSTM(self.hidden_layer, self.input_layer, batch_first=True) self.decoder_fc = nn.Linear(self.hidden_layer, self.hidden_layer) self.relu = nn.ReLU() def forward(self, input_x): input_x = input_x.view(len(input_x), 1, -1) # encoder encoder_lstm, (n, c) = self.encoder_lstm(input_x, # shape: (n_layers, batch, hidden_size) (torch.zeros(1, self.batch_size, self.hidden_layer), torch.zeros(1, self.batch_size, self.hidden_layer))) encoder_fc = self.encoder_fc(encoder_lstm) encoder_out = self.relu(encoder_fc) # decoder decoder_fc = self.relu(self.decoder_fc(encoder_out)) decoder_lstm, (n, c) = self.decoder_lstm(decoder_fc, (torch.zeros(1, 20, self.input_layer), torch.zeros(1, 20, self.input_layer))) return decoder_lstm.squeeze() if __name__ == '__main__': # 得到数据 x, y = get_train_data() train_loader = Data.DataLoader( dataset=Data.TensorDataset(x, y), # 封装进Data.TensorDataset()类的数据,可以为任意维度 batch_size=20, # 每块的大小 shuffle=True, # 要不要打乱数据 (打乱比较好) num_workers=2, # 多进程(multiprocess)来读数据 ) # 建模三件套:loss,优化,epochs model = LstmAutoEncoder() # lstm # model = LstmFcAutoEncoder() # lstm+fc模型 loss_function = nn.MSELoss() # loss optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 优化器 epochs = 150 # 开始训练 model.train() for i in range(epochs): for seq, labels in train_loader: optimizer.zero_grad() y_pred = model(seq).squeeze() # 压缩维度:得到输出,并将维度为1的去除 single_loss = loss_function(y_pred, seq) # 若想要获得类别,二分类问题使用四舍五入的方法即可:print(torch.round(y_pred)) single_loss.backward() optimizer.step() print("Train Step:", i, " loss: ", single_loss) # 每20次,输出一次前20个的结果,对比一下效果 if i % 20 == 0: test_data = x[:20] y_pred = model(test_data).squeeze() # 压缩维度:得到输出,并将维度为1的去除 print("TEST: ", test_data) print("PRED: ", y_pred) print("LOSS: ", loss_function(y_pred, test_data))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。