0

我使用 TensorFlow 实现了一个网络,并在我的代码中创建了执行以下操作的模型:

def multilayer_perceptron(x, weights, biases):
    layer_1 = tf.add(tf.matmul(x, weights["h1"]), biases["b1"])
    layer_1 = tf.nn.relu(layer_1)
    out_layer = tf.add(tf.matmul(layer_1, weights["out"]), biases["out"])
    return out_layer

我初始化权重和偏差:

weights = {
    "h": tf.Variable(tf.random_normal([n_input, n_hidden_1])),
    "out": tf.Variable(tf.random_normal([n_hidden_1, n_classes]))
    }

biases = {
    "b": tf.Variable(tf.random_normal([n_hidden_1])),
    "out": tf.Variable(tf.random_normal([n_classes]))
    }

现在我想使用自定义激活函数。因此,我tf.nn.relu(layer_1)用定义为的自定义激活函数替换了custom_sigmoid(layer_1)

def custom_sigmoid(x):
    beta = tf.Variable(tf.random.normal(x.get_shape[1]))
    return tf.sigmoid(beta*x)

beta可训练参数在哪里。我意识到这是行不通的,因为我不知道如何实现派生以便 TensorFlow 可以使用它。

问题:如何在 TensorFlow 中使用自定义激活函数?我真的很感激任何帮助。

4

2 回答 2

4

我试着回答我自己的问题。这是我所做的并且似乎有效的方法:

首先我定义了一个自定义激活函数:

def custom_sigmoid(x, beta_weights):
    return tf.sigmoid(beta_weights*x)

然后我为激活函数创建权重:

beta_weights = {
    "beta1": tf.Variable(tf.random_normal([n_hidden_1]))
    }

最后我添加beta_weights到我的模型函数并替换激活函数multilayer_perceptron()

def multilayer_perceptron(x, weights, biases, beta_weights):
    layer_1 = tf.add(tf.matmul(x, weights["h1"]), biases["b1"])
    #layer_1 = tf.nn.relu(layer_1) # Old
    layer_1 = custom_sigmoid(x, beta_weights["beta1"]) # New
    out_layer = tf.add(tf.matmul(layer_1, weights["out"]), biases["out"])
    return out_layer
于 2018-04-20T11:38:04.887 回答
1

这就是自动微分的美妙之处!你不需要知道如何计算函数的导数,只要你使用所有本质上可微的 tensorflow 构造(在 tensorflow 中有一些函数只是不可微分的函数)。

对于其他所有内容,导数都是由 tensorflow 为您计算的,可以使用本质上可微分的任何操作组合,您无需考虑梯度。通过tf.graidents在测试用例中使用来验证它,以表明 tensorflow 正在计算相对于您的成本函数的梯度。

对于好奇的人,这里有一个很好的自动微分解释:

https://alexey.radul.name/ideas/2013/introduction-to-automatic-differentiation/

您可以通过检查它是否存在于集合中来确保 beta 是一个可训练的参数tf.GraphKeys.TRAINABLE_VARIABLES,这意味着优化器将计算它的导数并更新它(如果它不在该集合中,您应该调查)。

于 2018-04-19T15:08:39.303 回答