Керас, вычисление градиента потерь по входу в LSTM - PullRequest
0 голосов
/ 17 мая 2019

Я довольно новичок в машинном обучении, и я возился с примерами из состязаний. Я пытаюсь обмануть двоичный текстовый классификатор LSTM на уровне символов. Таким образом, мне нужен градиент потерь w.r.t. вход.

Функция градиента, хотя возвращает None.

Я уже пытался получить градиенты, как в этом посте или этот пост , но функция градиентов по-прежнему возвращает None.

РЕДАКТИРОВАТЬ: Я хотел сделать что-то похожее, чем в это GIT РЕПО.

Я думал, что проблема может быть в том, что это был классификатор 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. входные данные, чтобы увидеть, какой из символов имеет наибольшее влияние на вывод. Таким образом, я мог обмануть классификатор, изменив соответствующие символы. Это возможно? Если да, что не так с моим подходом?

Спасибо, что уделили время.

Ответы [ 2 ]

0 голосов
/ 11 июня 2019

Я только что нашел эту тему .Функция градиентов возвращает None, потому что слой внедрения не дифференцируем.

Уровень внедрения реализован как K.gather, который не дифференцируем, поэтому градиента нет.

0 голосов
/ 17 мая 2019

Градиенты могут быть вычислены только для "обучаемых" тензоров, поэтому вы можете захотеть заключить свои данные в tf.Variable ().

Как только вы захотите поработать с градиентом, я бы предложил сделать это с помощью tenorflow, который прекрасно интегрируется с Keras. Ниже приведен мой пример, обратите внимание, что он работает в режиме активного исполнения (по умолчанию в tenorflow 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...