R语言Keras文本分类模型训练完成后新文本测试及报错处理
问题原因
触发报错的核心问题有3个:
- 新建的
text_vectorization_test层仅用单条测试文本做adapt,词表、分词规则和训练模型时使用的向量化层完全不一致,即使代码跑通,预测结果也完全无效 - 错误将输入文本转为
ncol=1的矩阵传入向量化层,且重复调用向量化层:首次调用已经将文本转为长度为50的整数序列,又将该序列作为字符串输入重复传入向量化层,最终输入形状为(None, 50),不符合layer_text_vectorization的输入要求(仅接受秩为1的字符向量,或最后一维为1的高维输入) - 原报错信息中文翻译:调用层"text_vectorization_4"(类型为TextVectorization)时遇到异常,使用
TextVectorization对字符串做分词时,输入秩必须为1或最后一个形状维度为1,实际接收到的输入为inputs.shape=(None, 50)、秩为2;该层接收到的调用参数为shape=(None, 50)的string类型tf.Tensor,可通过reticulate::py_last_error()查看详细错误信息。
正确实现方案
核心原则:推理阶段必须复用训练阶段在全量训练语料上adapt完成的向量化层,禁止用测试文本重新adapt新建的向量化层,否则词索引和训练阶段不匹配,特征完全失效。
- 单条/批量文本直接以一维字符向量形式传入,不需要转为矩阵
- 若训练时已将向量化层嵌入模型结构作为第一层,可直接将字符向量传入
predict(),无需手动做向量化 - 预测输出的概率值按二分类阈值(通常取0.5)转换为"yes"/"no"标签即可
修正后可运行代码
library(keras) # 替换为你训练阶段使用的、已经在全量训练语料上adapt完成的向量化层 # 禁止用单条测试文本adapt新建层 num_words <- 10000 max_length <- 50 text_vectorization <- layer_text_vectorization( max_tokens = num_words, output_sequence_length = max_length ) # 若训练时未保存向量化层,需重新传入全量训练文本做adapt # text_vectorization %>% adapt(训练集全部文本构成的字符向量) # 测试输入,直接使用一维字符向量,无需转矩阵 test_text <- c("you suck kid grow up", "Testing string with many words") # 向量化 input_tensor <- text_vectorization(test_text) # 传入训练好的模型做预测,将trained_model替换为你训练完成的模型对象 pred_prob <- predict(trained_model, input_tensor) # 二分类结果转标签,sigmoid输出大于0.5判定为霸凌内容"yes",否则为"no" pred_label <- ifelse(pred_prob > 0.5, "yes", "no") # 输出结果 result <- data.frame( tweet_text = test_text, is_bullying = pred_label ) print(result)
避坑提示
- 用单条测试文本adapt向量化层时,层的词表仅包含测试文本里的几个词,其余所有词都会被标记为未登录词(编码为1),模型无法识别正常语义,准确率会完全失效
- 不要重复调用向量化层:向量化层的输出是整数序列,不能再作为字符串输入传入向量化层
- 若训练时将向量化层直接写在模型结构最前端,可省略手动向量化步骤,直接运行
predict(trained_model, test_text)得到预测结果
内容的提问来源于stack exchange,提问作者Isaoud
相关产品推荐
相关产品推荐

