Shiny犬种分类器App报错:path应为类路径对象或io.BytesIO而非reactive.Value
错误原因解析
这个TypeError的意思是:调用tf.keras.preprocessing.image.load_img()时传入的参数类型不符合要求。load_img需要接收文件路径类对象或者io.BytesIO对象,但你传进去的input.dog_pic是Shiny框架的reactive._reactives.Value响应式对象,并非实际的图片文件路径或可读取的IO流,因此触发类型错误。
代码修复方案
问题出在获取上传文件的方式,以及模型加载的效率问题,修复后的代码如下:
from shiny import App, Inputs, Outputs, Session, reactive, render, ui import tensorflow as tf import numpy as np # 提前加载模型,避免每次预测重复加载 model = tf.keras.models.load_model('model') app_ui = ui.page_fluid( ui.input_file("dog_pic", "Upload your dog picture!", accept=[".jpeg"], multiple=False), ui.output_text("txt") ) def server(input, output, session): @reactive.Calc def parsed_file(): # 先判断是否有文件上传 if not input.dog_pic(): return None # 获取上传文件的临时路径 img_path = input.dog_pic()[0]["datapath"] # 加载并预处理图片 image = tf.keras.preprocessing.image.load_img(img_path, target_size=(224, 224)) input_arr = tf.keras.preprocessing.image.img_to_array(image) input_arr = np.array([input_arr]) input_arr = input_arr.astype('float32') / 255. return input_arr @output @render.text def txt(): processed_img = parsed_file() if processed_img is None: return "请先上传狗狗图片!" # 执行预测 dog_prediction = model.predict(processed_img) # 注意:这里需要将模型输出的概率数组转换为对应的犬种名称,需提前准备标签映射 # 示例:假设你有标签列表labels,取概率最大的索引对应的标签 # predicted_breed = labels[np.argmax(dog_prediction)] # return f"Predicted dog breed is {predicted_breed}!" return f"Predicted dog breed index: {np.argmax(dog_prediction)}" app = App(app_ui, server)
关键修复点
- 获取正确的文件路径:
input.dog_pic()返回包含上传文件信息的列表,每个元素是字典,其中datapath字段是Shiny存储上传文件的临时路径,需要提取这个值传给load_img。 - 提前加载模型:将模型加载代码放在
server函数外部,避免每次触发预测时重复加载模型,提升应用性能。 - 增加空值判断:在处理图片和输出结果时,判断是否有文件上传,避免空值报错。
内容的提问来源于stack exchange,提问作者Dieu94
相关产品推荐
相关产品推荐

