Streamlit人体二分类检测应用DuplicateWidgetID错误及代码优化求助
Streamlit应用问题修复方案
一、解决DuplicateWidgetID错误
出现DuplicateWidgetID错误(key='predict'重复),核心原因是同一个key的组件被重复渲染。常见场景是按钮被嵌套在会多次执行的条件分支、循环里,或者页面刷新时重复创建了相同key的组件。
修复方法:
- 确保
st.button("Get prediction", key="predict")在代码中仅定义一次,不要放在重复触发的if判断等逻辑块内。 - 若需动态生成组件,可通过拼接唯一标识生成key(比如
key=f"predict_{user_session_id}"),你的场景直接将按钮放在顶层代码逻辑即可避免重复。
二、解决上传文件传参问题
上传文件不需要传入initialize_model()函数——该函数的作用是初始化深度学习模型,应提前加载(用缓存避免重复加载),上传的图像是给预测函数使用的,而非模型初始化环节。
修正后的完整代码示例
import streamlit as st from PIL import Image import tensorflow as tf from tensorflow.keras.applications.resnet50 import ResNet50 from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Flatten # 缓存模型,避免每次刷新重新加载 @st.cache_resource def initialize_model(model_name): if model_name == "ResNet50": base_model = ResNet50(weights="imagenet", include_top=False, input_shape=(224,224,3)) model = Sequential([ base_model, Flatten(), Dense(2, activation="softmax") ]) # 加载你训练好的权重 # model.load_weights("resnet50_weights.h5") elif model_name == "CNN": # 定义自定义CNN模型 model = Sequential([ tf.keras.layers.Conv2D(32, (3,3), activation="relu", input_shape=(224,224,3)), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Flatten(), Dense(2, activation="softmax") ]) # model.load_weights("cnn_weights.h5") return model # 页面布局 st.title("人体检测二分类") uploaded_file = st.file_uploader("上传图像", type=["jpg", "png", "jpeg"]) model_choice = st.selectbox("选择模型", ["CNN", "ResNet50"]) # 初始化模型(缓存后仅在切换模型时重新加载) model = initialize_model(model_choice) # 预测按钮(仅定义一次,避免重复key) if st.button("Get prediction", key="predict"): if uploaded_file is not None: # 处理上传图像 img = Image.open(uploaded_file).resize((224,224)) img_array = tf.keras.preprocessing.image.img_to_array(img) img_array = tf.expand_dims(img_array, 0) # 增加batch维度 # 执行预测 predictions = model.predict(img_array) class_idx = tf.argmax(predictions, axis=1).numpy()[0] result = "检测到人体" if class_idx == 0 else "未检测到人体" st.success(result) else: st.warning("请先上传图像")
关键说明
@st.cache_resource装饰initialize_model():模型仅在首次选择或切换模型时加载一次,既提升性能,也避免了传参混淆。- 按钮置于顶层逻辑:确保
key="predict"的按钮仅被创建一次,彻底解决DuplicateWidgetID错误。 - 上传文件逻辑嵌套在按钮点击事件内:只有点击按钮时才会读取图像并执行预测,流程清晰无冲突。
内容的提问来源于stack exchange,提问作者Bluetail
相关产品推荐
相关产品推荐

