必须用tf.data.Dataset封装无标签推断流水线,显式选取特征列、设batch_size、匹配模型输入shape,并链式调用batch和prefetch;避免全量读入、维度错配及自定义预处理瓶颈。

用 tf.data.Dataset 构建无标签推断流水线
直接把未标注数据塞进 model.predict() 很容易内存爆掉或维度报错,核心是让数据加载和模型输入对齐。必须用 tf.data.Dataset 封装,且跳过 label 字段——哪怕原始文件里有 label 列,也只取特征列。
常见错误:用 pd.read_csv() 全量读入再转 tensor,结果 OOM;或忘了设 batch_size,导致 predict() 把整个数据当一个 batch 处理,显存炸裂。
- 用
tf.data.experimental.make_csv_dataset()时,传select_columns=['f1','f2','f3']显式指定特征列,不读 label 列 - 若数据是 numpy 或 tfrecord,用
tf.data.Dataset.from_tensor_slices(x_data),确保x_data是 shape=(N, D) 的 float32 张量 - 务必链式调用
.batch(32).prefetch(tf.data.AUTOTUNE),否则 GPU 等待数据 IO
model.predict() 的输入 shape 必须匹配训练时的 input layer
很多人在训练时用 Input(shape=(128,)),但推断时喂进 shape=(N, 128, 1) 的数据,结果报 ValueError: Input 0 is incompatible with layer。TensorFlow 不会自动 squeeze 或 expand 维度。
典型场景:文本 embedding 输出是 (batch, seq_len, dim),但分类头期望 (batch, dim)。这时候不能靠 predict() 自动适配。
立即学习“Python免费学习笔记(深入)”;
- 检查模型第一层:
model.input_shape返回的是训练时定义的 shape,比如(None, 128),那么你传的 batch 数据就必须是(B, 128) - 如果原始数据是图像,注意是否要归一化:
dataset.map(lambda x: x / 255.0),否则输出全为 0 或 nan - 遇到
Unknown input shape错误,大概率是 dataset 没 call.batch(),导致单样本 shape=(128,) 被当成 batch 维=1 处理
处理长序列或大尺寸图像时避免 CPU-GPU 数据搬运瓶颈
批量推断慢,八成不是模型本身慢,而是 tf.data pipeline 卡在 CPU 预处理或主机内存到 GPU 显存拷贝上。尤其当用 tf.io.decode_jpeg() 或 tf.py_function 做自定义预处理时,极易成为瓶颈。
- 禁用
tf.py_function做图像 resize —— 改用tf.image.resize(),它是图模式可加速的 - 对 JPEG 文件,加
num_parallel_reads=4和deterministic=False提速读取 - 如果显存充足,加
.cache()到内存(小数据集)或磁盘(大数据集),避免重复解码 - 用
model.predict(dataset, verbose=1)观察每 batch 耗时,若 “step xx/yy” 卡顿明显,问题在 data pipeline 而非 model
保存预测结果时注意 dtype 和格式一致性
默认 model.predict() 返回 float32 numpy 数组,但如果你后续要用 pandas 分析或写入 CSV,float32 可能被截断精度,或与已有字段类型不兼容。
更隐蔽的问题:多分类输出是 logits 还是 softmax?取决于你最后一层有没有 Softmax。没加的话,np.argmax() 直接用会出错。
- 确认输出语义:
model.layers[-1].activation是<function softmax at ...></function>还是<function linear at ...></function> - 保存前统一转 float64 或 int64:
preds = np.argmax(pred_logits, axis=1).astype(np.int64) - 写 CSV 时别用
np.savetxt()—— 它不支持混合类型;改用pandas.DataFrame({'pred': preds}).to_csv('out.csv', index=False) - 若需保留原始 ID,构建 dataset 时就得把 ID 和 feature 一起传入,例如
Dataset.from_tensor_slices((x_data, ids)),再在 map 中拆开
.reshape(-1, 128)。


















