【问题标题】:Keras, calculating gradients of the loss wrt the input on an LSTMKeras,计算 LSTM 输入的损失梯度
【发布时间】:2019-05-17 13:53:44
【问题描述】:

我对机器学习很陌生,而且我一直在处理对抗性示例。 我试图欺骗二进制字符级 LSTM 文本分类器。 因此,我需要损失 w.r.t 的梯度。输入。

渐变函数虽然返回None

我已经尝试过获取渐变,例如 this postthis post,但梯度函数仍返回None

编辑:我想做与this git repo 类似的事情。

我在想问题可能在于它是一个 LSTM 分类器。 我现在不确定。但是我认为即使从 LSTM 分类器中也应该可以得到这些梯度,对吧?

这是我的代码:

import numpy as np
from keras.preprocessing import sequence
from keras.models import load_model
import data
import pickle
import keras.backend as K

def adversary():
    model, valid_chars = loadModel()    
    model.summary()

    #load data
    X, y, maxlen, _ , max_features, indata = prepare_data(valid_chars)

    target = y[0]

    # Get the loss and gradient of the loss wrt the inputs  
    target = np.asarray(target).astype('float32').reshape((-1,1))
    loss = K.binary_crossentropy(target, model.output)
    print(target)
    print(model.output)
    print(model.input)
    print(loss)
    grads = K.gradients(loss, model.input)

    #f = K.function([model.input], [loss, grads])

    #print(f(X[1:2]))
    print(model.predict(X[0:1]))

    print(grads)

输出如下:

Layer (type)                 Output Shape              Param #   
=================================================================
embedding_1 (Embedding)      (None, 74, 128)           5120      
_________________________________________________________________
lstm_1 (LSTM)                (None, 128)               131584    
_________________________________________________________________
dropout_1 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 129       
_________________________________________________________________
activation_1 (Activation)    (None, 1)                 0         
=================================================================
Total params: 136,833
Trainable params: 136,833
Non-trainable params: 0
_________________________________________________________________
Maxlen: 74
Data preparing finished
[[0.]]
Tensor("activation_1/Sigmoid:0", shape=(?, 1), dtype=float32)
Tensor("embedding_1_input:0", shape=(?, 74), dtype=float32)
Tensor("logistic_loss_1:0", shape=(?, 1), dtype=float32)
[[1.1397913e-13]]
[None]

我希望得到损失 w.r.t 的梯度。输入数据以查看哪个字符对输出的影响最大。 因此,我可以通过修改相应的字符来欺骗分类器。 这可能吗?如果是,我的方法有什么问题?

感谢您的宝贵时间。

【问题讨论】:

    标签: tensorflow keras gradient


    【解决方案1】:

    只能为“可训练”张量计算梯度,因此您可能希望将输入包装到 tf.Variable() 中。

    如果您想使用渐变,我建议您使用 tensorflow,它与 Keras 完美集成。下面是我的示例,注意它在急切执行模式下工作(默认在 tensorflow 2.0 中)。

    def train_actor(self, sars):
        obs1, actions, rewards, obs2 = sars
    
    
        with tf.GradientTape() as tape:
            would_do_actions = self.compute_actions(obs1)
            score = tf.reduce_mean(self.critic(observations=obs1, actions=would_do_actions))
            loss = - score
    
        grads = tape.gradient(loss, self.actor.trainable_weights)
        self.optimizer.apply_gradients(zip(grads, self.actor.trainable_weights))
    

    【讨论】:

    【解决方案2】:

    我刚刚找到this thread。 gradients 函数返回None,因为嵌入层不可微。

    嵌入层实现为不可微分的K.gather,所以没有梯度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-08
      • 2018-04-13
      • 2016-07-01
      • 1970-01-01
      • 2017-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多