首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Keras中复制RegisterGradient和gradient_override_map

在Keras中复制RegisterGradient和gradient_override_map
EN

Stack Overflow用户
提问于 2018-04-17 18:44:04
回答 3查看 962关注 0票数 3

下面是在tensorflow中注册渐变和覆盖操作的渐变的代码。

代码语言:javascript
运行
复制
# Registering a gradient
some_multiplier = 0.5 

@tf.RegisterGradient("AdaGrad")
def _ada_grad(op, grad):
    return grad * some_multiplier 

# Overriding 
g = tf.get_default_graph()
with g.gradient_override_map({"Ada": "AdaGrad"}):
    model.loss = tf.identity(model.loss, name="Ada")

我想在keras中复制同样的东西。在搜索了很多东西之后,我找不到任何方法。

我尝试了下面的代码,但它不起作用。未修改渐变。我得到了相同的结果,无论有没有梯度覆盖。我通过将some_multiplier设置为零进行了检查。

代码语言:javascript
运行
复制
model = Model(...) # Keras model
model.compile(loss='sparse_categorical_crossentropy', optimizer=adadelta, metrics=['accuracy']) # Compiling Keras Model

@tf.RegisterGradient("AdaGrad")
def _ada_grad(op, grad):
    return grad * some_multiplier 

g = tf.get_default_graph()
with g.gradient_override_map({"Ada": "AdaGrad"}):
    model.total_loss = tf.identity(model.total_loss, name="Ada")
EN

回答 3

Stack Overflow用户

发布于 2018-04-17 18:48:32

同样的方法应该是可行的,但您需要确保使用Keras模型的图形。如果使用的是keras.model.Modeltf.keras.Model,则检索图表的方式会稍有不同

代码语言:javascript
运行
复制
model = Model(...) # Keras model
model.compile(loss='sparse_categorical_crossentropy', optimizer=adadelta, metrics=['accuracy']) # Compiling Keras Model

@tf.RegisterGradient("AdaGrad")
def _ada_grad(op, grad):
    return grad * some_multiplier 

# with keras.model.Model
from keras import backend as K
g = K.get_session().graph
# with tf.keras.Model
g = model.graph

with g.gradient_override_map({"Ada": "AdaGrad"}):
    model.total_loss = tf.identity(model.total_loss, name="Ada")
票数 0
EN

Stack Overflow用户

发布于 2018-11-29 19:12:25

TensorFlow的gradient_override_map不能与大多数Keras操作一起工作。我找到的最简单的方法是用它的TensorFlow实现替换Keras中的操作。

例如,假设考虑了relu激活,那么它将是简单的:

代码语言:javascript
运行
复制
tf.keras.activations.relu = tf.nn.relu
# <function tensorflow.python.keras.activations.relu(x, alpha=0.0, max_value=None, threshold=0)>
# <function tensorflow.python.ops.gen_nn_ops.relu(features, name=None)>

适用于大多数网络,因为在Keras模型中通常只有第一个参数用于ReLU。在其他操作不匹配的情况下,您可以围绕tf模拟创建一个包装器函数,以便将参数与Keras匹配。

使用VGG16网络的ReLU示例。

寄存器梯度。

代码语言:javascript
运行
复制
@tf.RegisterGradient("GuidedRelu")
def _GuidedReluGrad(op, grad):
    return tf.where(0. < grad, gen_nn_ops.relu_grad(grad, op.outputs[0]), 
tf.zeros_like(grad))

使用自定义梯度初始化网络。

代码语言:javascript
运行
复制
sess = tf.Session()
graph = tf.get_default_graph()
tf.keras.backend.set_session(sess)
with graph.gradient_override_map({'Relu': 'GuidedRelu'}):
    model = tf.keras.applications.VGG16()
票数 0
EN

Stack Overflow用户

发布于 2018-12-24 14:25:34

我也有同样的问题。在我的例子中,我使用"gradient_override_map“试图实现”引导式backprop“。

代码语言:javascript
运行
复制
@tf.RegisterGradient("GuidedRelu")
def GuidedReluGrad(op, grad):
    grad_filter = tf.cast(grad > 0, "float32")
    output_filter = tf.cast(op.outputs[0] > 0, "float32")
    return output_filter * grad_filter * grad

我使用VGG16作为预测模型。

代码语言:javascript
运行
复制
model = VGG16(include_top=True, weights='imagenet')
predicted = np.argmax(model.predict(np.expand_dims(img, axis=0)))

我尝试了下面的代码,但徒劳无功。

代码语言:javascript
运行
复制
with K.get_session().graph.gradient_override_map({'Relu': 'GuidedRelu'}):
    # here is implementation to get gradients
    # but "GuidedRelu" is not used

因此,我在调用"gradient_override_map“之前创建了一个新的图形和会话,并成功地将梯度函数从"Relu”更改为"GuidedRelu“。

代码语言:javascript
运行
复制
new_graph = tf.Graph()
with new_graph.as_default():
    new_sess = tf.Session(graph = new_graph)
    with new_sess.as_default():
        with new_graph.gradient_override_map({'Relu': 'GuidedRelu'}):
            new_model = VGG16(include_top=True, weights='imagenet')
            # here is implementation to get gradients with new graph/session
            # "GuidedRelu" is used

我不知道为什么前者行不通。但我希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49876024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档