【问题标题】:Tensorflow custom activation functionTensorFlow 自定义激活函数
【发布时间】:2018-09-30 03:03:14
【问题描述】:

我使用 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 中使用自定义激活函数?非常感谢任何帮助。

【问题讨论】:

    标签: tensorflow activation-function


    【解决方案1】:

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

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

    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
    

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      【讨论】:

      • 我的方法对吗?我可以按照我的问题所示使用它吗?
      • 发生这种情况时你不喜欢吗?是的。您可以使用tf.gradients 做一个简单的测试用例来证明给自己看。使用tf.constant 作为输入设置一个非常简单的示例,然后运行tf.gradients(beta, cost),您将获得用于更新测试版的衍生产品。如果出现问题,您将得到 None 或错误。
      • 是的,我真的愿意!我将用一个工作示例来回答我自己的问题。
      猜你喜欢
      • 2018-08-30
      • 2020-12-07
      • 2018-04-15
      • 1970-01-01
      • 2021-10-29
      • 2020-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多