【问题标题】:Round an activation function in Keras在 Keras 中舍入一个激活函数
【发布时间】:2023-03-13 21:25:01
【问题描述】:

我正在尝试创建一个激活函数以在我的 keras 模型中使用。

基本上,我想要的是一个只有两位小数的 sigmoid 函数。所以我试图像这样创建自己的激活函数:

def mySigmoid(x):
    return np.around(K.sigmoid(x), decimals=2)

然后:

get_custom_objects().update({'mySigmoid': Activation(mySigmoid)})

但由于某种原因,我这样做会出错。

有人可以帮帮我吗?

非常感谢

堆栈跟踪:

AttributeError                            Traceback (most recent call last)
<ipython-input-52-891a9f63ca56> in <module>()
      3 model.add(Dense(30, activation='softmax'))
      4 
----> 5 model.add(Dense(10, activation='mySigmoid'))
      6 model.summary()
      7 sgd = optimizers.SGD(lr=0.1, decay=1e-5, momentum=0.3, nesterov=True)

/usr/local/lib/python2.7/dist-packages/keras/models.pyc in add(self, layer)
    473                           output_shapes=[self.outputs[0]._keras_shape])
    474         else:
--> 475             output_tensor = layer(self.outputs[0])
    476             if isinstance(output_tensor, list):
    477                 raise TypeError('All layers in a Sequential model '

/usr/local/lib/python2.7/dist-packages/keras/engine/topology.pyc in __call__(self, inputs, **kwargs)
    600 
    601             # Actually call the layer, collecting output(s), mask(s), and shape(s).
--> 602             output = self.call(inputs, **kwargs)
    603             output_mask = self.compute_mask(inputs, previous_mask)
    604 

/usr/local/lib/python2.7/dist-packages/keras/layers/core.pyc in call(self, inputs)
    843             output = K.bias_add(output, self.bias)
    844         if self.activation is not None:
--> 845             output = self.activation(output)
    846         return output
    847 

/usr/local/lib/python2.7/dist-packages/keras/engine/topology.pyc in __call__(self, inputs, **kwargs)
    600 
    601             # Actually call the layer, collecting output(s), mask(s), and shape(s).
--> 602             output = self.call(inputs, **kwargs)
    603             output_mask = self.compute_mask(inputs, previous_mask)
    604 

/usr/local/lib/python2.7/dist-packages/keras/layers/core.pyc in call(self, inputs)
    284 
    285     def call(self, inputs):
--> 286         return self.activation(inputs)
    287 
    288     def get_config(self):

<ipython-input-50-cc621aa5ea1b> in mySigmoid(x)
      1 def mySigmoid(x):
----> 2     return np.around(K.sigmoid(x), decimals=2)
      3     #return (K.sigmoid(x) * 5) - 1

/usr/local/lib/python2.7/dist-packages/numpy/core/fromnumeric.pyc in around(a, decimals, out)
   2787 
   2788     """
-> 2789     return _wrapfunc(a, 'round', decimals=decimals, out=out)
   2790 
   2791 

/usr/local/lib/python2.7/dist-packages/numpy/core/fromnumeric.pyc in _wrapfunc(obj, method, *args, **kwds)
     65     # a downstream library like 'pandas'.
     66     except (AttributeError, TypeError):
---> 67         return _wrapit(obj, method, *args, **kwds)
     68 
     69 

/usr/local/lib/python2.7/dist-packages/numpy/core/fromnumeric.pyc in _wrapit(obj, method, *args, **kwds)
     45     except AttributeError:
     46         wrap = None
---> 47     result = getattr(asarray(obj), method)(*args, **kwds)
     48     if wrap:
     49         if not isinstance(result, mu.ndarray):

AttributeError: 'Tensor' object has no attribute 'rint'

我的任务:我正在尝试创建一个神经网络来预测住宅门窗的打开状态。

这些状态是从 0 到 1 的浮点数,最多保留两位小数。

输入数据集组织为:

headerInput = ['hour', 'Temperature', 'Wind_Speed', 'Wind_Direction', 'Humidity', 'Air_Density', 'Rain_Status', 'Jardim_PMV','Jardim_Temp','livingRoom_PMV','livingRoom_Temp','mezzanine_PMV','mezzanine_Temp']

示例:

14.0,15.1,3.1,230.0,40.0,1.21136396241,0.0,-2.0925950832,15.2547144369,-1.59841620663,17.4451394848,-4.48642007828,17.7701378164,-1.87781304943,16.4544875583,-0.334880991824,20.9530677507,-3.98155421448,18.0000031279,-2.06816062239,16.9694428505,-1.27592184517,17.7946534879

输出数据集:

headerOutput = ['window_1','window_2','window_3','window_4','window_5','window_6','window_7','window_8','window_9','window_10']

示例:

0.0,0.94,0.82,0.0,0.4,0.67,0.0,1.0,1.0,0.95,0.0,0.64,0.0,0.75,0.78,0.77,0.23,0.78,0.21,0.29,0.7,0.48,0.0

目前我的网络拓扑如下,如有需要可以更改:

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'))
model.summary()
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)

【问题讨论】:

  • 欢迎堆栈溢出。您应该始终在堆栈跟踪中附加错误消息。
  • 只需将其添加到询问部分

标签: python neural-network keras activation-function


【解决方案1】:

这里有两个问题:

  1. np.round 想要一个兼容的非符号对象,而 K.sigmoid 返回一个符号张量。 (更新这是您的错误的来源)。
  2. Keras 本身需要一个损失函数来返回一个符号张量,而np.round 返回一个非符号值。 (更新这将是下一个错误)。

底线是您必须在所有函数中坚持使用keras.backend 中的函数。如果你不热衷于兼容性(即你只打算在特定的后端运行你的模型,无论是 Theano 还是 Tensorflow),你也可以直接使用你的后端定义的操作,因为keras.backend 相对有限。

在任何支持的后端也没有直接的方法来舍入浮点值。更重要的是,我认为对激活函数进行四舍五入没有多大意义,因为它可能会严重损害梯度。

更新

如果您这样做是为了得到一个四舍五入的输出,则无需摆弄激活函数本身。您可以简单地对输出进行四舍五入:np.round(yournetwork.predict(...), 2)

【讨论】:

  • 我想这样做的原因是因为我的输出总是一个介于 0 和 1 之间的数字(sigmoid 输出),但它也总是一个只有两位小数的值。在我当前的网络中,我不断得到小数点后 8 位的输出。
  • @fsofelipe 为什么要费心去摆弄激活函数呢?毕竟是非线性的。从网络获取输出后,您可以随意转换这些值。
  • 主要原因是我有我的神经网络并且我正在尝试预测值。但由于某种原因,我的 NN 独立于输入返回相同的值。我认为这可能会发生,因为我得到的 val_acc 较低,这与数据特征(两位小数)有关。
  • @fsofelipe 您的模型不太可能因此而表现不佳。您能否展示您的损失函数并描述您的数据集和目标(您应该使用此信息更新您的问题)
  • 我刚刚做到了。所以如果你能看看我将不胜感激
猜你喜欢
  • 2017-08-10
  • 2019-09-10
  • 2020-12-05
  • 2018-05-26
  • 2020-09-12
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
相关资源
最近更新 更多