如何为层中的每个节点为 Keras relu 函数分配自定义 alpha?

Posted

技术标签:

【中文标题】如何为层中的每个节点为 Keras relu 函数分配自定义 alpha?【英文标题】:How can I assign a custom alpha for Keras relu function, for each node in a layer? 【发布时间】:2020-03-25 01:35:17 【问题描述】:

我想为每个 Keras 激活函数添加一个特定于节点的变量。我希望每个节点使用不同的值 (alpha) 计算激活值(输出)。

这可以全局完成,例如使用alpha relu 激活函数的参数 (link):

# Build Model
...
model.add(Dense(units=128))
model.add(Activation(lambda x: custom_activation(x, alpha=0.1)))
...

我也可以写自定义激活函数,不过alpha参数也是全局的。 (link)

# Custom activation function
def custom_activation(x, alpha=0.0):
    return (K.sigmoid(x + alpha))

# Build Model
...
model.add(Dense(units=128))
model.add(Activation(lambda x: custom_activation(x, alpha=0.1)))
...

在自定义函数中,我目前只能访问以下变量:

(Pdb) locals()
'x': <tf.Tensor 'dense/Identity:0' shape=(None, 128) dtype=float32>, 'alpha': 0.1

我想使用自定义激活函数,但 alpha 对于网络中的每个节点都是唯一的。例如,如果层中有 128 个单元,那么我希望也有 128 个 alpha 值,每个单元/节点一个。然后我想激活函数来

如何创建一个层中每个单元/节点唯一的alpha 值?

【问题讨论】:

【参考方案1】:

我不建议对那个使用 lambda 层,这太骇人听闻了。我建议你编写自己的层如下:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# Custom layer 
class CustomAct(tf.keras.layers.Layer):

    def __init__(self):
        super(CustomAct, self).__init__()

    def build(self, input_shape):
        self.alpha = self.add_weight(name='alpha', 
                                      shape=[input_shape[1], ],
                                      initializer='uniform',
                                      trainable=True)
        super(CustomAct, self).build(input_shape)

    def call(self, x):
        return tf.sigmoid(x+self.alpha)

    def get_alpha(self):
        return self.alpha        

inputs = np.random.random([16, 32]).astype(np.float32)

# Model 
model = tf.keras.models.Sequential()
model.add(tf.keras.Input(inputs.shape[-1]))
model.add(tf.keras.layers.Dense(128))
model.add(CustomAct())

# Test
model.compile(loss="MSE")


alpha_after_initialization = model.layers[-1].get_alpha()
plt.plot(alpha_after_initialization.numpy())

x = np.random.random([18, 32])
y = np.random.random([18, 128])
for _ in range(20):
    model.fit(x, y)

out_after_20_steps = alpha_after_initialization = model.layers[-1].get_alpha()
plt.plot(alpha_after_initialization.numpy())

plt.show()

当然,您应该将所有 tf​​ 引用更改为您的 keras 引用。

【讨论】:

我只是假设你想让 alpha 可训练。如果没有,只需将 argumentmnt trainable 设置为 False 并使用您想要的值进行初始化。 太棒了!这回答了我正在寻找的 99% 的内容。我想远程设置 alpha (trainable = False)。我将如何编写 set_alpha 函数? 您想在开始时设置一次 alpha 还是在每个 epoch 实时更新它? 对您的代码的小修正:inputs = np.random.random([16, 32]).astype(np.float32) 应该高于 model = tf.keras.models.Sequential() 是的,这会起作用。但是,如果你真的想抽取随机样本,我会建议直接在 tensorflow 中这样做?

以上是关于如何为层中的每个节点为 Keras relu 函数分配自定义 alpha?的主要内容,如果未能解决你的问题,请参考以下文章

如何有条件地缩放 Keras Lambda 层中的值?

如何为 keras 使用自定义损失函数

如何为开放图层中的开放街道地图使用不同的主题?

如何为 LSTM 实现 Keras 自定义损失函数

如何为 keras 模型使用 tensorflow 自定义损失?

Keras如何在Relu激活函数中使用max_value