文章目录LSTMAutoEncoder简介LSTMAutoEncoder实现基本LSTMAutoEncoder网络结构LSTMFcAutoEncoder网络结构案例代码LSTMAu
文章目录
- LSTM AutoEncoder简介
- LSTM AutoEncoder 实现
- 基本LSTM AutoEncoder网络结构
- LSTM+Fc AutoEncoder网络结构
- 案例代码
LSTM AutoEncoder简介
基础的AutoEncoder可以参考:https://blog.csdn.net/weixin_35757704/article/details/118457110
而LSTM AutoEncoder
是将原始的全连接变成了LSTM,然后构造出来的AutoEncoder模型,输入与输出是一样的数据为最佳
LSTM AutoEncoder 实现
博主发现网上对于LSTM AutoEncoder的版本都不一样,通常来讲有:
- encoder与decoder都是:lstm
- encoder是 lstm + fc ; decoder是 fc + lstm
以下是两种网络架构:
基本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_layerself.hidden_layer = hidden_layerself.batch_size = batch_sizeself.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_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_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()
LSTM+Fc AutoEncoder网络结构
这个网络结构就是:
- 在encoder的时候过一个lstm,然后接一个全连接,最后用relu激活函数;
- 在decoder的时候先过全连接,然后用relu的激活函数,最后接lstm
class LstmFcAutoEncoder(nn.Module):def __init__(self, input_layer=300, hidden_layer=100, batch_size=20):super(LstmFcAutoEncoder, self).__init__()self.input_layer = input_layerself.hidden_layer = hidden_layerself.batch_size = batch_sizeself.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_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)))encoder_fc = self.encoder_fc(encoder_lstm)encoder_out = self.relu(encoder_fc)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 Datadef get_train_data():"""得到训练数据,这里使用随机数生成训练数据,由此导致最终结果并不好"""def get_tensor_from_pd(dataframe_series) -> torch.Tensor:return torch.tensor(data=dataframe_series.values)import numpy as npimport pandas as pdfrom sklearn import preprocessingdf = 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_layerself.hidden_layer = hidden_layerself.batch_size = batch_sizeself.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_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_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_layerself.hidden_layer = hidden_layerself.batch_size = batch_sizeself.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_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)))encoder_fc = self.encoder_fc(encoder_lstm)encoder_out = self.relu(encoder_fc)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), batch_size=20, shuffle=True, num_workers=2, )model = LstmAutoEncoder() loss_function = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) epochs = 150model.train()for i in range(epochs):for seq, labels in train_loader:optimizer.zero_grad()y_pred = model(seq).squeeze() single_loss = loss_function(y_pred, seq)single_loss.backward()optimizer.step()print("Train Step:", i, " loss: ", single_loss)if i % 20 == 0:test_data = x[:20]y_pred = model(test_data).squeeze() print("TEST: ", test_data)print("PRED: ", y_pred)print("LOSS: ", loss_function(y_pred, test_data))