如何拼接不同形状张量用于LSTM银行交易序列生成训练?
解决LSTM融合交易主体信息与交易序列的方案
一、优化主体信息与交易序列的融合方式
直接将主体信息重复拼接在每个交易特征前的做法,会导致模型冗余学习重复信息,推荐两种更高效的融合思路:
1. 用主体信息初始化LSTM隐藏状态
LSTM的初始隐藏状态(h0、c0)可以通过主体信息映射得到,让主体信息全程影响序列生成逻辑,无需重复输入:
import torch import torch.nn as nn # 主体信息维度4,LSTM隐藏层维度设为64 subj_info = torch.tensor([26., 0., 1., 0.]) lstm_hidden_dim = 64 # 线性层将主体信息映射为LSTM初始隐藏状态所需维度 subj_encoder = nn.Linear(4, lstm_hidden_dim * 2) h0_c0 = subj_encoder(subj_info).chunk(2, dim=-1) h0 = h0_c0[0].unsqueeze(0).unsqueeze(0) # 形状适配LSTM输入:(num_layers, batch_size, hidden_dim) c0 = h0_c0[1].unsqueeze(0).unsqueeze(0) # 定义LSTM并传入交易序列与初始隐藏状态 lstm = nn.LSTM(input_size=4, hidden_size=lstm_hidden_dim, batch_first=True) operation_series = torch.randn(1, 14, 4) # 模拟交易序列,形状(batch, seq_len, feature_dim) output, (hn, cn) = lstm(operation_series, (h0, c0))
这种方式下,主体信息作为LSTM的初始记忆,全程指导交易序列的学习,避免冗余。
2. 主体信息嵌入后与交易特征拼接
若仍需将主体信息与交易序列结合,可先通过嵌入层将主体信息映射为与交易特征同维度的向量,再拼接至每个交易特征前,让模型自动学习主体信息的有效表示:
subj_embedding = nn.Linear(4, 4) # 将主体信息映射到交易特征维度 subj_emb = subj_embedding(subj_info).unsqueeze(0).repeat(14, 1) # 复制到序列长度 input_combined = torch.cat([subj_emb, operation_series], dim=-1) # 最终形状(14, 8)
二、tensor[[subj_info], [交易序列]]格式的处理与聚焦训练
如果一定要采用这种结构输入,需先扩展主体信息的序列维度,再通过以下方式让LSTM聚焦交易序列:
1. 分段输入+掩码机制
将主体信息作为序列的第一个时间步,后续为交易序列,用掩码标记主体信息与交易序列的边界,训练时仅计算交易序列部分的损失:
# 构造输入:主体信息作为首个时间步 subj_step = subj_info.unsqueeze(0) # 形状(1,4) input_seq = torch.cat([subj_step, operation_series], dim=0) # 形状(15,4) # 构造掩码:首个位置标记为0(主体信息),后续交易序列标记为1 mask = torch.tensor([0] + [1]*14).unsqueeze(-1) # LSTM处理序列后,仅取交易序列部分的输出计算损失 lstm = nn.LSTM(input_size=4, hidden_size=64, batch_first=True) output, _ = lstm(input_seq.unsqueeze(0)) trade_output = output[:, 1:, :] # 跳过主体信息对应的输出 # 后续用trade_output与交易序列目标计算损失
2. 双分支模型
主体信息走单独分支提取特征,交易序列走LSTM分支,最后融合两个分支的特征完成生成任务,结构更清晰:
class TradeGenerator(nn.Module): def __init__(self, subj_dim=4, trade_dim=4, hidden_dim=64): super().__init__() self.subj_encoder = nn.Linear(subj_dim, hidden_dim) self.lstm = nn.LSTM(trade_dim, hidden_dim, batch_first=True) self.decoder = nn.Linear(hidden_dim, trade_dim) def forward(self, subj_info, trade_series): # 提取主体特征并适配LSTM隐藏状态形状 subj_feat = self.subj_encoder(subj_info).unsqueeze(0).unsqueeze(0) # 初始化LSTM隐藏状态 h0 = subj_feat c0 = torch.zeros_like(h0) # 处理交易序列并生成预测 lstm_out, _ = self.lstm(trade_series.unsqueeze(0), (h0, c0)) pred_trade = self.decoder(lstm_out) return pred_trade.squeeze(0) # 使用示例 model = TradeGenerator() subj_info = torch.tensor([26., 0., 1., 0.]) operation_series = torch.randn(14,4) pred = model(subj_info, operation_series)
三、生成阶段的处理
训练完成后生成交易序列时:
- 若采用初始隐藏状态方案:先将输入的主体信息映射为LSTM的
h0和c0,从可选首笔交易开始,逐步将每一步的输出作为下一个时间步的输入,生成后续交易。 - 若采用嵌入拼接方案:将主体信息的嵌入向量重复至当前生成序列的长度,与生成的交易特征拼接后输入LSTM。
内容的提问来源于stack exchange,提问作者Stefano
相关产品推荐
相关产品推荐

