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

如何解决Keras训练时‘Unsupported object type float’报错?

解决Keras模型训练时的"Failed to convert a NumPy array to a Tensor"错误

问题描述

尝试构建用均值填充缺失值的二分类模型,训练时出现错误:Failed to convert a NumPy array to a Tensor (Unsupported object type float),原始代码如下:

from keras.models import Sequential, load_model
from keras.layers import Dense,Dropout
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import random

targetURL='../content/drive/MyDrive/1-2/caffeine.csv'
df = pd.read_csv(targetURL)

df=pd.get_dummies(df, columns=['sex'])

df.isnull().sum().sort_values(ascending=False).head(4)
df=df.fillna(df.mean(numeric_only=True))

standardization_df = (df - df.mean(numeric_only=True,axis=0)) / df.std(numeric_only=True,axis=0)

x=standardization_df.iloc[:,1:14]
y=df.iloc[:,14]
y=pd.get_dummies(y)

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1, shuffle=True,random_state=3)

model = Sequential()
model.add(Dense(24,  input_dim=13, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

score=model.evaluate(x_test, y_test)

history=model.fit(x_train, y_train, epochs=10, batch_size=10, verbose=0, validation_split=0.2)
hist_df=pd.df(history.history)

y_vloss=hist_df['val_loss']
y_loss=hist_df['loss']
x_len=np.arange(len(y_loss))

plt.plot(x_len, y_vloss, "o", c="red", makersize=2, label='Testset_loss')
plt.plot(x_len, y_loss, "o", c="blue", makersize=2, label='Trainset_loss')

plt.legend(loc='upper right')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

数据集包含sex(female/male)和target(yes/no)两个文本列,均为二分类取值。

错误原因及修改方案

1. 目标变量与模型输出层、损失函数不匹配

  • 问题:target是二分类,用pd.get_dummies()得到的是2列one-hot编码,但模型最后一层是Dense(1, activation='sigmoid'),对应二分类的二元交叉熵,而非多分类的categorical_crossentropy。
  • 修改:
    • 将target转换为0/1的标签编码,而非one-hot;
    • 损失函数改为binary_crossentropy。

2. 错误标准化分类变量

  • 问题:standardization_df包含了sex的one-hot列(0/1),分类变量不需要标准化,否则会破坏其语义。
  • 修改:仅对数值列做标准化,再合并one-hot的sex列到特征集。

3. 数据类型与格式问题

  • 问题:Pandas DataFrame转换为Tensor时可能因类型不兼容报错,需确保数据为float32类型;同时pd.df()是错误的API,应为pd.DataFrame()。

4. 评估时机错误

  • 问题:model.evaluate()在模型训练前执行,此时模型未训练,评估无意义且可能引发异常,应放在训练之后。

5. 绘图参数拼写错误

  • 问题:makersize应为markersize,拼写错误会导致绘图失败。

修正后的完整代码

from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

targetURL='../content/drive/MyDrive/1-2/caffeine.csv'
df = pd.read_csv(targetURL)

# 处理sex列的one-hot编码
df = pd.get_dummies(df, columns=['sex'])

# 均值填充缺失值
df = df.fillna(df.mean(numeric_only=True))

# 分离数值列和分类列(sex的one-hot)
numeric_cols = df.select_dtypes(include=[np.number]).columns.drop('target')  # 假设目标列名为target,可根据实际调整
categorical_cols = [col for col in df.columns if 'sex_' in col]

# 仅对数值列做标准化
standardized_numeric = (df[numeric_cols] - df[numeric_cols].mean()) / df[numeric_cols].std()

# 合并标准化后的数值列和分类列作为特征x
x = pd.concat([standardized_numeric, df[categorical_cols]], axis=1)
# 处理目标变量:将yes/no转换为1/0
y = df['target'].map({'yes': 1, 'no': 0}).astype('float32')

# 划分数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1, shuffle=True, random_state=3)

# 转换为numpy数组并指定类型,避免Tensor转换错误
x_train = x_train.values.astype('float32')
x_test = x_test.values.astype('float32')
y_train = y_train.values.astype('float32')
y_test = y_test.values.astype('float32')

# 构建模型:二分类用sigmoid输出+binary_crossentropy
model = Sequential()
model.add(Dense(24, input_dim=x_train.shape[1], activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# 先训练模型
history = model.fit(x_train, y_train, epochs=10, batch_size=10, verbose=1, validation_split=0.2)

# 训练后再评估测试集
score = model.evaluate(x_test, y_test)
print(f'Test loss: {score[0]}, Test accuracy: {score[1]}')

# 提取训练历史
hist_df = pd.DataFrame(history.history)

# 绘制损失曲线
y_vloss = hist_df['val_loss']
y_loss = hist_df['loss']
x_len = np.arange(len(y_loss))

plt.plot(x_len, y_vloss, "o", c="red", markersize=2, label='Validation Loss')
plt.plot(x_len, y_loss, "o", c="blue", markersize=2, label='Training Loss')

plt.legend(loc='upper right')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

关键说明

  • 若目标列名不是target,需根据实际数据集列名修改df['target']处的代码;
  • 用map()转换目标变量比one-hot更适合单输出的二分类模型;
  • 明确区分数值列和分类列的预处理逻辑,避免标准化破坏分类变量的意义;
  • 强制转换数据类型为float32,确保与Keras Tensor的兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:31:12