Нахождение градиентов выходных данных относительно входных данных, где модель состоит из двух подмоделей: 1) кодер 2) LSTM - PullRequest
0 голосов
/ 07 октября 2019

Я новичок в pyTorch. У меня есть модель, состоящая из двух подмоделей, то есть 1) кодер 2) LSTM. Я передаю временные ряды через кодер кадр за кадром. После вывода из кодировщика, выход подается через LSTM, и он классифицирует (классификатор двух классов). Я хочу знать градиенты правильного вывода класса относительно ввода.

Я пытался получить градиенты относительно ввода. Это показывает, нет. Затем я попытался получить градиенты с входом LSTM, он также показывает None, то же самое для градиентов с выходом. Но когда я использовал register_hook, он показывает градиент вывода по отношению к самому выводу. Тем не менее, для ввода кодировщика WRT и ввода lstm он показывает KeyError.

grads = {}
def save_grad(name):
    def hook(grad):
        grads[name] = grad
    return hook

def compute_saliency_maps(self, X, y, encoder, classifier):
    encoder.eval()
    classifier.eval()

    # Wrap the input tensors in Variables
    X_var = Variable(X, requires_grad=True)
    y_var = Variable(y, requires_grad=False)


    encoder.zero_grad()
    classifier.zero_grad()
    mode = "test"
    inputs = [encoder(x, fmaps=False) for x in X_var]

    lstm_input = torch.stack(inputs)
    lstm_input_var = Variable(lstm_input, requires_grad=True)
    output = classifier(lstm_input_var, mode)
    output = torch.stack(output)

    grad_outputs = torch.zeros(200, 2)
    grad_outputs[:, y_var] = 1
    X_var.register_hook(save_grad('X_var'))
    output.register_hook(save_grad('output'))
    lstm_input_var.register_hook(save_grad('lstm_input_var'))
    output.backward(gradient=grad_outputs, retain_graph=True)

    saliency = grads['lstm_input_var']

    print(saliency)
    return saliency

Однако, если я использую простейшую модель, она работает, например:

x = Variable(torch.randn(1,1), requires_grad=True)
y = 3*x
z = y**2


y.register_hook(save_grad('y'))
z.register_hook(save_grad('z'))
x.register_hook(save_grad('x'))
z.backward()

print(grads['y'])
print(grads['z'])
print(grads['x'])

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

...