You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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("请先上传图像")

关键说明

  1. @st.cache_resource装饰initialize_model():模型仅在首次选择或切换模型时加载一次,既提升性能,也避免了传参混淆。
  2. 按钮置于顶层逻辑:确保key="predict"的按钮仅被创建一次,彻底解决DuplicateWidgetID错误。
  3. 上传文件逻辑嵌套在按钮点击事件内:只有点击按钮时才会读取图像并执行预测,流程清晰无冲突。

内容的提问来源于stack exchange,提问作者Bluetail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 12:39:24