如何实现支持输入与前层输出乘法交互的神经网络架构?
特征交互模型的相关概念与框架实现
对应模型概念
你设计的这种显式特征乘法交互结构,本质属于**因式分解机(Factorization Machines, FM)**的核心逻辑范畴。FM的核心就是通过特征隐向量的乘积来捕捉不同特征维度间的交互关系,正好匹配你“用乘法交互替代求和交互”的需求。如果要延伸,后续的NFM(神经因式分解机)是在FM基础上加入神经网络进一步建模复杂交互,但你的结构更偏向基础的显式特征交叉实现。
PyTorch 实现示例
假设我们将车手(Driver)和天气(Weather)都做one-hot编码,车手有3个类别、天气有2个类别,代码实现如下:
import torch import torch.nn as nn import torch.optim as optim class RaceTimePredictor(nn.Module): def __init__(self, driver_num, weather_num, emb_dim=8): super().__init__() # Layer 1: 车手特征的隐向量编码 self.driver_embedding = nn.Embedding(driver_num, emb_dim) # Layer 2: 处理特征交互后的映射层 self.interaction_proj = nn.Linear(driver_num * emb_dim * weather_num, 16) # Layer 3: 输出预测时间 self.output_layer = nn.Linear(16, 1) def forward(self, driver_onehot, weather_onehot): # 从one-hot编码中提取车手索引,获取对应隐向量 driver_idx = torch.argmax(driver_onehot, dim=1) driver_emb = self.driver_embedding(driver_idx) # 扩展维度以实现车手隐向量与天气特征的逐元素乘法 driver_emb_exp = driver_emb.unsqueeze(2) # shape: [batch_size, emb_dim, 1] weather_exp = weather_onehot.unsqueeze(1) # shape: [batch_size, 1, weather_num] # 计算特征交互(对应你架构中的Layer2逻辑) interaction = driver_emb_exp * weather_exp # 展平后送入映射层 interaction_flat = interaction.flatten(start_dim=1) layer2_out = torch.relu(self.interaction_proj(interaction_flat)) # 输出预测时间 pred_time = self.output_layer(layer2_out) return pred_time # 测试模型 if __name__ == "__main__": # 模拟输入:2个样本,分别是D1+雨天、D2+晴天 driver_onehot = torch.tensor([[1,0,0], [0,1,0]], dtype=torch.float32) weather_onehot = torch.tensor([[1,0], [0,1]], dtype=torch.float32) # 模拟标签:时间转成秒 time_labels = torch.tensor([[120.0], [170.0]], dtype=torch.float32) model = RaceTimePredictor(3, 2) optimizer = optim.Adam(model.parameters(), lr=0.001) criterion = nn.MSELoss() # 单次训练步骤 pred = model(driver_onehot, weather_onehot) loss = criterion(pred, time_labels) loss.backward() optimizer.step() print(f"预测时间:{pred.detach().numpy()}")
TensorFlow/Keras 实现示例
同样基于one-hot编码的输入,代码实现如下:
import tensorflow as tf from tensorflow.keras import layers, Model def build_race_predictor(driver_num, weather_num, emb_dim=8): # 定义输入层 driver_input = layers.Input(shape=(driver_num,), name="driver_input") weather_input = layers.Input(shape=(weather_num,), name="weather_input") # Layer 1: 车手特征的隐向量编码 driver_idx = tf.argmax(driver_input, axis=1) driver_emb = layers.Embedding(input_dim=driver_num, output_dim=emb_dim)(driver_idx) # Layer 2: 计算特征乘法交互 driver_emb_exp = layers.Reshape((emb_dim, 1))(driver_emb) weather_exp = layers.Reshape((1, weather_num))(weather_input) # 逐元素乘法实现特征交互 interaction = layers.Multiply()([driver_emb_exp, weather_exp]) interaction_flat = layers.Flatten()(interaction) # 交互特征映射 layer2_out = layers.Dense(16, activation="relu")(interaction_flat) # Layer 3: 输出预测时间 pred_time = layers.Dense(1, name="predicted_time")(layer2_out) # 构建并返回模型 model = Model(inputs=[driver_input, weather_input], outputs=pred_time) return model # 测试模型 if __name__ == "__main__": model = build_race_predictor(3, 2) model.compile(optimizer="adam", loss="mse") # 模拟训练数据 driver_onehot = tf.convert_to_tensor([[1,0,0], [0,1,0], [0,0,1]], dtype=tf.float32) weather_onehot = tf.convert_to_tensor([[1,0], [0,1], [1,0]], dtype=tf.float32) time_labels = tf.convert_to_tensor([[120.0], [170.0], [290.0]], dtype=tf.float32) # 训练模型 model.fit([driver_onehot, weather_onehot], time_labels, epochs=10, batch_size=1)
内容的提问来源于stack exchange,提问作者Carlos Coelho
相关产品推荐
相关产品推荐

