You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Keras张量添加可训练权重张量?附时序编码场景需求

我来一步步帮你解决这两个问题~

问题1:如何为Keras张量添加可训练权重张量?

在Keras里,最规范的方式是通过自定义Layer,利用self.add_weight()方法创建可训练权重,再在call()方法里将它和输入张量做运算(比如相加、相乘等)。给你一个简单易懂的示例:

from tensorflow.keras.layers import Layer
import tensorflow as tf

class AddTrainableWeight(Layer):
    def __init__(self, weight_shape, **kwargs):
        self.weight_shape = weight_shape
        super().__init__(**kwargs)
    
    def build(self, input_shape):
        # 创建可训练权重,初始值可根据需求调整(随机正态、全零、Glorot初始化等)
        self.trainable_weight = self.add_weight(
            name='trainable_weight',
            shape=self.weight_shape,
            initializer='random_normal',
            trainable=True
        )
        super().build(input_shape)  # 必须调用父类的build方法完成初始化
    
    def call(self, inputs):
        # 这里以相加为例,你可以根据业务需求换成相乘、拼接等其他运算
        return inputs + self.trainable_weight
    
    def compute_output_shape(self, input_shape):
        # 相加操作下输出形状和输入一致,其他运算需对应调整
        return input_shape

使用示例:

如果你的输入张量形状是(batch_size, 32, 64),想要添加一个同维度的可训练权重:

input_tensor = tf.keras.Input(shape=(32,64))
output_tensor = AddTrainableWeight(weight_shape=(32,64))(input_tensor)

训练过程中,这个权重会跟着梯度自动更新。


问题2:实现论文中的时序编码自定义层

根据你提到的论文第5页的时序编码逻辑,核心是给每个位置的嵌入向量添加位置相关的可训练权重。你的输入形状是(batch_size, N, M),也就是每个样本包含N个长度为M的嵌入向量,我们只需要创建一个形状为(N, M)的可训练权重矩阵,借助Keras的广播机制,就能让每个样本的对应位置都加上这个权重(无需为每个batch样本单独创建权重,这也符合论文的设计逻辑)。

这里帮你完善并修正自定义层的代码:

from tensorflow.keras.layers import Layer
import tensorflow as tf

class TemporalEncodingLayer(Layer):
    def __init__(self, seq_len, embed_dim, **kwargs):
        self.seq_len = seq_len  # 对应你的N(序列长度)
        self.embed_dim = embed_dim  # 对应你的M(嵌入维度)
        super().__init__(**kwargs)
    
    def build(self, input_shape):
        # 校验输入形状是否和预期匹配
        assert input_shape[1] == self.seq_len, f"输入序列长度必须为{self.seq_len}"
        assert input_shape[2] == self.embed_dim, f"嵌入维度必须为{self.embed_dim}"
        
        # 创建时序编码的可训练权重,形状为(N, M)
        self.temporal_weights = self.add_weight(
            name='temporal_weights',
            shape=(self.seq_len, self.embed_dim),
            initializer='random_normal',  # 论文未指定初始化方式,可按需替换为glorot_uniform等
            trainable=True
        )
        super().build(input_shape)
    
    def call(self, inputs):
        # 利用广播机制,将输入张量和时序权重相加(自动适配batch维度)
        return inputs + self.temporal_weights
    
    def compute_output_shape(self, input_shape):
        # 输出形状和输入完全一致
        return input_shape

使用示例:

假设你的输入是(batch_size, 100, 256)(N=100,M=256):

# 定义输入层
input_embeds = tf.keras.Input(shape=(100, 256))
# 添加时序编码层
encoded_embeds = TemporalEncodingLayer(seq_len=100, embed_dim=256)(input_embeds)
# 后续可连接其他网络层...

关键说明:

  • 论文中的时序编码是位置依赖的,即所有样本的第i个嵌入向量,都加上同一个位置i的权重,这样既符合论文逻辑,又能避免不必要的参数冗余。
  • 即使你的batch_size是动态变化的(不是固定值),代码也能正常运行,Keras的广播机制会自动处理batch维度的适配。

内容的提问来源于stack exchange,提问作者Sean Paulsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:23:32