Streamlit部署Keras模型报Cast string to float is not supported错误
问题原因
报错是因为st.text_input返回值默认是字符串类型,你将字符串直接拼接为numpy数组传入TensorFlow模型,但模型训练时接收的输入是数值型张量,不支持自动将字符串强制转换为浮点数,因此触发类型错误。
修复方案
按以下步骤调整即可解决问题:
- 统一输入数据类型:所有传入模型的特征值必须显式转换为和训练时一致的数值类型(整数/浮点数),不能直接传入字符串。
- 替换输入组件(推荐):不要用文本输入框采集结构化医疗特征,换成Streamlit原生的数值输入、选择框组件,从输入源头避免非法字符串输入,同时降低用户输入成本。
- 明确数组数据类型:组装numpy输入数组时,显式指定dtype为
np.float32,和TensorFlow模型默认的浮点输入类型对齐。 - 补充预处理对齐:如果模型训练前对特征做了归一化、标准化等缩放操作,推理时传入的输入必须执行完全相同的预处理,否则会出现预测结果偏差。
修正后的核心代码示例
# 表单部分替换为对应类型的输入组件,直接返回数值类型结果 with col1: age = st.number_input('Age', min_value=1, max_value=120, step=1, value=25) with col2: # 性别固定选项,直接返回模型需要的0/1数值 sex = st.selectbox('Sex', options=[('Male', 1), ('Female', 0)], format_func=lambda x:x[0])[1] with col3: cp = st.selectbox('Chest Pain types', options=[0,1,2,3]) with col1: trestbps = st.number_input('Resting Blood Pressure', min_value=80, max_value=200, step=1) with col2: chol = st.number_input('Serum Cholestoral in mg/dl', min_value=100, max_value=600, step=1) with col3: fbs = st.selectbox('Fasting Blood Sugar > 120 mg/dl', options=[('No',0), ('Yes',1)], format_func=lambda x:x[0])[1] with col1: restecg = st.selectbox('Resting Electrocardiographic results', options=[0,1,2]) with col2: thalach = st.number_input('Maximum Heart Rate achieved', min_value=60, max_value=220, step=1) with col3: exang = st.selectbox('Exercise Induced Angina', options=[('No',0), ('Yes',1)], format_func=lambda x:x[0])[1] with col1: oldpeak = st.number_input('ST depression induced by exercise', min_value=0.0, max_value=10.0, step=0.1) with col2: slope = st.selectbox('Slope of the peak exercise ST segment', options=[0,1,2]) with col3: ca = st.selectbox('Major vessels colored by flourosopy', options=[0,1,2,3,4]) with col1: thal = st.selectbox('thal: 0 = normal; 1 = fixed defect; 2 = reversable defect', options=[0,1,2]) # 预测逻辑部分 heart_diagnosis = '' if st.button('Heart Disease Test Result'): inputs = (age, sex, cp, trestbps, chol, fbs, restecg,thalach,exang,oldpeak,slope,ca,thal) # 显式指定数组类型为float32,避免类型不匹配 npArray = np.asarray(inputs, dtype=np.float32) inReshaped = npArray.reshape(1,-1) # 如果你训练时做了特征归一化/标准化,在这里对inReshaped做相同处理再传入predict heart_prediction = tb_model.predict(inReshaped) # 注意如果是sigmoid输出的概率值,要加阈值判断,不要直接和1比 if (heart_prediction[0][0] >= 0.5): heart_diagnosis = 'The person is having heart disease' else: heart_diagnosis = 'The person does not have any heart disease' st.success(heart_diagnosis)
补充说明:如果你暂时不想替换输入组件,可以在组装
inputs元组时,对每个st.text_input的返回值用float()强转,比如float(age),但这种方式遇到用户输入非数字内容时会直接报错,鲁棒性较差。
内容的提问来源于stack exchange,提问作者Zahir Ahmad
相关产品推荐
相关产品推荐

