Tensorflow 自定义激活函数
Tensorflow custom activation function
我使用 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 构造(在 tensorflow 中有些函数只是不可微分函数)。
对于其他一切,导数都是由 tensorflow 为您计算的,可以使用本质上可微分的任何操作组合,您永远不需要考虑梯度。通过在测试用例中使用 tf.graidents
来验证它,以表明 tensorflow 正在计算相对于您的成本函数的梯度。
对于好奇的人,这里有一个关于自动微分的很好的解释:
https://alexey.radul.name/ideas/2013/introduction-to-automatic-differentiation/
您可以通过检查它是否存在于集合 tf.GraphKeys.TRAINABLE_VARIABLES
中来确保 beta 是可训练参数,这意味着优化器将计算其导数 w.r.t。成本并更新它(如果它不在您应该调查的那个集合中)。
我试着回答我自己的问题。这是我所做的以及似乎有效的事情:
首先我定义了一个自定义激活函数:
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
我使用 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 构造(在 tensorflow 中有些函数只是不可微分函数)。
对于其他一切,导数都是由 tensorflow 为您计算的,可以使用本质上可微分的任何操作组合,您永远不需要考虑梯度。通过在测试用例中使用 tf.graidents
来验证它,以表明 tensorflow 正在计算相对于您的成本函数的梯度。
对于好奇的人,这里有一个关于自动微分的很好的解释:
https://alexey.radul.name/ideas/2013/introduction-to-automatic-differentiation/
您可以通过检查它是否存在于集合 tf.GraphKeys.TRAINABLE_VARIABLES
中来确保 beta 是可训练参数,这意味着优化器将计算其导数 w.r.t。成本并更新它(如果它不在您应该调查的那个集合中)。
我试着回答我自己的问题。这是我所做的以及似乎有效的事情:
首先我定义了一个自定义激活函数:
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