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

Keras中自定义保留两位小数的Sigmoid激活函数报错求助

解决Keras自定义激活函数的AttributeError问题

错误原因分析

你遇到的AttributeError: 'Tensor' object has no attribute 'rint'是因为混用了NumPy和Keras后端的张量操作:

  • K.sigmoid(x)返回的是Keras后端(比如TensorFlow)的Tensor对象,而非NumPy数组
  • np.around()是NumPy专属函数,只能处理NumPy数组,无法识别Tensor对象的操作逻辑,因此触发了这个错误

正确的自定义激活函数实现

要处理Keras的张量,必须使用Keras后端(keras.backend)提供的函数来实现四舍五入逻辑。我们可以通过「乘以100 → 四舍五入 → 除以100」的方式实现保留两位小数的效果:

from keras import backend as K
from keras.layers import Activation
from keras.utils.generic_utils import get_custom_objects

def mySigmoid(x):
    # 先计算标准sigmoid输出
    sigmoid_output = K.sigmoid(x)
    # 用后端函数实现保留两位小数的四舍五入
    return K.round(sigmoid_output * 100) / 100

# 注册自定义激活函数
get_custom_objects().update({'mySigmoid': Activation(mySigmoid)})

重要注意事项:梯度与训练稳定性

虽然上面的代码能解决报错问题,但必须提醒你:四舍五入是不可导操作,将其放在激活函数中会破坏反向传播的梯度连续性,可能导致模型训练时梯度消失,难以收敛。

针对你的门窗开启状态预测任务,更合理的做法是:

  1. 训练阶段保持最后一层使用普通sigmoid激活,保证梯度正常传递
  2. 在模型预测完成后,再对输出结果做四舍五入处理

示例代码如下:

# 训练时的模型(最后一层用普通sigmoid)
model = Sequential()
model.add(Dense(40, input_shape=(13, ), kernel_initializer='random_normal', activation='tanh'))
model.add(Dense(40, activation='tanh'))
model.add(Dense(40, activation='tanh'))
model.add(Dense(40, activation='tanh'))
model.add(Dense(40, activation='relu'))
model.add(Dense(10, activation='sigmoid'))  # 用普通sigmoid保证训练稳定性

# 编译、训练模型(沿用你的原有配置)
sgd = optimizers.SGD(lr=0.1, decay=1e-5, momentum=0.3, nesterov=True)
model.compile(optimizer=sgd, loss='mean_squared_error', metrics=['mae', 'acc'])
model.fit(Input_np, Output_Norm, validation_split=0.3, epochs=35, batch_size=100)

# 预测后处理成两位小数
predictions = model.predict(Input_np)
rounded_predictions = np.around(predictions, decimals=2)

这种方式既满足了输出保留两位小数的需求,又能保证模型训练的稳定性,是更推荐的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:57:21