Keras中词嵌入位置处理:药物相互作用CNN模型的Padding困惑
处理药物-药物相互作用抽取中Padding的实用方案
我之前在做类似的关系抽取任务时也踩过这个坑,核心是要让padding的虚拟位置不会干扰模型对真实距离特征的学习,这里分享几个经过实践验证的处理思路:
1. 为Padding位置分配特殊距离标记
真实句子里,单词到两个药物的相对距离范围是有限的(比如假设最大句长是128,距离范围大概是[-127, 127])。对于padding的位置,我们可以给dist1和dist2设置一个超出正常范围的固定值,比如max_seq_len + 1,这样模型能轻松区分真实距离和padding的假距离。
举个Python预处理的例子:
max_seq_len = 128 # 原句子的dist1列表,比如对应"药物A 与 药物B 相互作用"的dist1是[0,1,2,3](假设药物A在位置0) padded_dist1 = dist1 + [max_seq_len + 1] * (max_seq_len - len(dist1)) padded_dist2 = dist2 + [max_seq_len + 1] * (max_seq_len - len(dist2))
同时,Word2Vec部分的padding要对应使用专门的<PAD>嵌入(如果预训练词表没有,可以随机初始化一个向量,效果比全零向量更好)。
2. 配合Masking层让模型自动忽略Padding位置
在CNN模型中,可以加入Masking层,让模型跳过padding位置的特征计算,避免无效信息干扰。比如在TensorFlow/Keras中的实现:
from tensorflow.keras.layers import Input, Masking, Conv1D # 输入维度:词嵌入维度 + 2个距离特征 input_dim = w2v_dim + 2 inputs = Input(shape=(max_seq_len, input_dim)) # 用我们设置的特殊距离值作为mask标记 masked_inputs = Masking(mask_value=max_seq_len + 1)(inputs) # 后续接CNN层 conv_layer = Conv1D(filters=64, kernel_size=3, activation='relu')(masked_inputs)
3. 对距离特征做归一化(可选优化)
如果担心特殊值的分布和真实距离差异太大,可以先把真实距离归一化到[0,1]区间,再给padding位置分配一个比如-1的标记,这样既保证区分度,也不会让数值范围波动太大:
def normalize_dist(dist, max_seq_len): # 把[-max_seq_len, max_seq_len]映射到[0,1] return (dist + max_seq_len) / (2 * max_seq_len) # 真实距离先归一化,padding位置设为-1 padded_dist1 = [normalize_dist(d, max_seq_len) for d in dist1] + [-1] * (max_seq_len - len(dist1))
这种方式适合对数值敏感的模型结构,注意Masking层的mask值要对应改成-1。
关键注意事项
- 三个嵌入部分(w2v、dist1、dist2)的padding要严格一一对应:每个padding位置的w2v用
向量,dist1和dist2用统一的特殊值,不能出现错位。 - 绝对不要用0作为padding的距离值——0对应单词和药物位置重合的真实情况,会混淆模型判断。
内容的提问来源于stack exchange,提问作者seanysull
相关产品推荐
相关产品推荐

