TF2/Keras TextVectorization维度及标签形状不兼容问题排查
多分类文本分类TensorFlow调试问题解决
问题梳理
- 输入维度不匹配错误:
TextVectorization输出形状(batch_size, 250)与模型输入要求不兼容,报错提示输入秩为2不符合要求,根源是输入文本为二维张量(来自df[['text']]生成的二维DataFrame)。 - 标签形状不兼容错误:独热编码后仍报错
Shapes (4, 1) and (None, 4) are incompatible,原因是模型中重复使用vectorize_layer导致输入二次处理,同时文本维度扩展操作冗余引发维度混乱。
关键修复步骤
- 修正文本输入格式:从DataFrame提取文本时使用
df['text'](一维Series)而非df[['text']](二维DataFrame),避免生成二维文本张量。 - 移除冗余维度扩展:删除
custom_standardization和vectorize_text中的tf.expand_dims操作,确保文本输入为一维张量。 - 调整模型结构:模型不再包含
vectorize_layer,因为train_ds等数据集已经经过vectorize_text完成文本向量化处理,重复加入会导致维度错误。
修正后的完整代码
from sklearn.model_selection import train_test_split import tensorflow as tf import re import numpy as np import pandas as pd import string # 加载并拆分数据:用df['text']获取一维文本数据 df = pd.read_csv('train.csv', index_col=[0]) X_train, X_test, y_train, y_test = train_test_split(df['text'], pd.get_dummies(df['target']).values, test_size=0.2, random_state=1) X_val, X_test, y_val, y_test = train_test_split(X_test, y_test, test_size=0.5, random_state=1) # 转换为tf数据集 raw_train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train)) raw_val_ds = tf.data.Dataset.from_tensor_slices((X_val, y_val)) raw_test_ds = tf.data.Dataset.from_tensor_slices((X_test, y_test)) # 文本清理:移除冗余的tf.expand_dims def custom_standardization(input_data): new_line_replace = tf.strings.regex_replace(input_data, '\n', ' ') non_alphanum_replace = tf.strings.regex_replace(new_line_replace, '[^a-zA-Z0-9_ ]', '') stripped = tf.strings.strip(non_alphanum_replace) lowercase = tf.strings.lower(stripped) return tf.strings.regex_replace(lowercase, '[%s]' % re.escape(string.punctuation), '') # 创建文本向量化层 max_features = 10000 sequence_length = 250 vectorize_layer = tf.keras.layers.TextVectorization( standardize=custom_standardization, max_tokens=max_features, output_mode='int', output_sequence_length=sequence_length) # 适配训练文本 train_text = raw_train_ds.map(lambda x, y: x) vectorize_layer.adapt(train_text) # 向量化文本:移除tf.expand_dims def vectorize_text(text, label): return vectorize_layer(text), label train_ds = raw_train_ds.map(vectorize_text) val_ds = raw_val_ds.map(vectorize_text) test_ds = raw_test_ds.map(vectorize_text) # 数据集优化 train_ds = train_ds.cache().prefetch(buffer_size=tf.data.AUTOTUNE) val_ds = val_ds.cache().prefetch(buffer_size=tf.data.AUTOTUNE) test_ds = test_ds.cache().prefetch(buffer_size=tf.data.AUTOTUNE) # 模型结构:移除vectorize_layer,因为数据集已完成向量化 model = tf.keras.Sequential([ tf.keras.layers.Embedding(max_features + 1, 16), tf.keras.layers.Dropout(0.2), tf.keras.layers.GlobalAveragePooling1D(), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(4, activation='softmax') # 多分类建议加softmax,配合categorical_crossentropy更规范 ]) model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy']) epochs = 10 history = model.fit( train_ds, validation_data=val_ds, epochs=epochs)
额外说明
- 模型最后一层增加
activation='softmax':多分类场景下,softmax输出对应各类别的概率分布,与categorical_crossentropy损失函数搭配更规范。 - 数据集优化的
cache()和prefetch()保留,提升训练效率。
内容的提问来源于stack exchange,提问作者apantovic
相关产品推荐
相关产品推荐

