TransformerEncoder训练报错:IteratorGetNext张量批量元素不匹配
问题分析与解决方案
核心错误原因
你的报错根源是模型输入层形状定义与实际输入数据形状不匹配,同时拆分多数据集再合并的处理方式放大了形状对齐风险:
- 输入层
shape参数混淆了词汇表大小和序列长度:text_input定义为shape=(MAX_TOKENS_TEXT,),但TextVectorization输出的序列长度是max_text_length,两者完全不是一个概念loc_input和keyword_input同样错误使用MAX_TOKENS_KEYWORDS(词汇表容量)作为输入形状,而非对应的序列长度MAX_LOC_LENGTH和MAX_KEYWORD_LENGTH
- 拆分三个独立Dataset再zip的操作,容易因batch处理后的微小差异引发形状不匹配
分步修复方案
1. 修正模型输入层的形状定义
将输入层shape改为对应特征的实际序列长度,而非词汇表大小:
# 修正输入层形状:使用序列长度而非词汇表容量 loc_input = Input(shape=(MAX_LOC_LENGTH,), dtype='int64', name='location') keyword_input = Input(shape=(MAX_KEYWORD_LENGTH,), dtype='int64', name='keyword') text_input = Input(shape=(max_text_length,), dtype="int64", name='text')
2. 简化数据集处理流程(避免拆分多Dataset)
直接从DataFrame创建包含所有特征的单个Dataset,从根源避免对齐问题:
# 直接创建包含三个特征+标签的训练/验证数据集 train_dataset = data.Dataset.from_tensor_slices( ( { 'location': train_data['location'].values.astype(str), 'keyword': train_data['keyword'].values.astype(str), 'text': train_data['text'].values.astype(str) }, train_data['target'].values.astype(bool) ) ) val_dataset = data.Dataset.from_tensor_slices( ( { 'location': validation_data['location'].values.astype(str), 'keyword': validation_data['keyword'].values.astype(str), 'text': validation_data['text'].values.astype(str) }, validation_data['target'].values.astype(bool) ) ) # 统一处理向量化 def vectorize_batch(inputs, labels): return { 'location': loc_vectorization(inputs['location']), 'keyword': keyword_vectorization(inputs['keyword']), 'text': text_vectorization(inputs['text']) }, labels # 应用向量化并批量处理 train_full_vectorized = train_dataset.map(vectorize_batch, num_parallel_calls=-1).batch(BATCH_SIZE) val_full_vectorized = val_dataset.map(vectorize_batch, num_parallel_calls=-1).batch(BATCH_SIZE)
3. 确保Transformer输出可与Conv1D结果拼接
TransformerEncoder默认输出形状是(batch_size, seq_len, d_model),必须通过全局池化压缩序列维度,才能和Conv1D的池化输出拼接:
def generate_transformer(input_layer): # 词嵌入层(需提前定义EMBEDDING_DIM) x = Embedding(MAX_TOKENS_TEXT, EMBEDDING_DIM)(input_layer) # 位置编码 x = PositionalEncoding()(x) # TransformerEncoder层(需提前定义num_layers、d_model、num_heads等参数) x = TransformerEncoder(num_layers=2, d_model=EMBEDDING_DIM, num_heads=4)(x) # 全局池化,将序列维度压缩为特征维度 x = GlobalAveragePooling1D()(x) return x
额外验证步骤
- 用
next(iter(train_full_vectorized))查看批量后输入特征的形状,确认与模型输入层完全匹配 - 检查
MAX_LOC_LENGTH、MAX_KEYWORD_LENGTH、max_text_length是否是通过统计数据集得到的真实序列长度,而非随意设置的数值
内容的提问来源于stack exchange,提问作者Faptimus420
相关产品推荐
相关产品推荐

