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

Keras含小数次幂的自定义激活函数NaN问题求助

Keras自定义激活函数小数次幂导致NaN问题解决

问题核心

在Keras中实现对sigmoid取小数次幂的自定义激活函数时,整数幂次运行正常,但小数幂次会导致模型预测出现NaN。单独测试公式能得到有效结果,但在神经网络中失效。

用户代码示例

import numpy as np
import pandas as pd
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Activation
import matplotlib.pyplot as plt
from scikeras.wrappers import KerasRegressor
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import MinMaxScaler

from keras import backend as K

def custom_activation(x):
    # return (K.sigmoid((x**0.9)))
    return (1 / (1 + K.exp((0.9/0.9)*(K.pow(-x,K.constant(1))))))

dataframe = pd.read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values

X = dataset[:, :13]  
Y = dataset[:, 13]  

scaler = MinMaxScaler()
X_normalized = scaler.fit_transform(X)
y_normalized = scaler.fit_transform(Y.reshape(-1, 1))

model = Sequential()
model.add(Dense(100, activation=custom_activation))
model.add(Dense(1, activation='linear'))  
model.compile(loss='mean_squared_error', optimizer='adam')  

a = model.fit(X_normalized, y_normalized,epochs=100, batch_size=32, verbose=1)
y_hat = model.predict(X_normalized) 

问题原因

单独测试时用的是归一化后的X_normalized(范围[0,1]),不存在负数,所以小数次幂计算正常。但在神经网络中:

  • Dense层的输出是Wx + b,权重W和偏置b是随机初始化的,必然会产生负数输出。
  • 负数的小数次幂在实数域无意义(比如(-2)^0.9等价于(-2)^(9/10),即对-2开10次方根再取9次方,而负数无法开偶次方根),计算时会直接生成NaN,进而在反向传播中扩散,导致整个模型输出NaN。

解决方案

方案1:调整计算顺序,先过sigmoid再取幂

如果需求是sigmoid(x)^α(α为小数),先通过sigmoid将输入映射到(0,1)区间,再取小数次幂,避免负数问题:

def custom_activation(x):
    sigmoid_out = K.sigmoid(x)
    return K.pow(sigmoid_out, 0.9)

方案2:确保幂运算输入非负

如果需求是sigmoid(x^α),先将输入转为非负数后再取幂:

def custom_activation(x):
    # 用ReLU将负数转为0,保证幂运算输入非负
    x_non_neg = K.relu(x)
    return K.sigmoid(K.pow(x_non_neg, 0.9))

方案3:数值稳定的幂运算实现

也可以用K.exp(0.9 * K.log(K.sigmoid(x)))替代直接取幂,进一步提升数值稳定性:

def custom_activation(x):
    sigmoid_out = K.sigmoid(x)
    # 避免log(0)的情况,添加极小值偏移
    safe_log = K.log(K.maximum(sigmoid_out, 1e-10))
    return K.exp(0.9 * safe_log)

验证说明

修改后的激活函数在网络运行时,不会再因负数输入产生NaN,同时保留小数次幂的特性。可以在训练过程中监控loss值,确认无NaN出现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:34:58