Tensorflow tf.hessian возвращает только нули - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть обученная модель керас, для которой мне нужно вычислить как градиенты, так и гессианы выходных данных относительно входных данных.Входные данные X являются массивом 5000x3, а выходные значения y равны 5000x1.

Градиентное вычисление отлично работает как с использованием градиентов кераса, так и функций градиента тензорного потока, и я получаю массив 5000x3 с правильными значениямив нем, но гессиан с использованием tf.hessian () возвращает только нули.Этого не должно быть, поскольку моя модель приближается к сильно нелинейной функции, поэтому вполне ожидаемо, что вторые производные будут отличны от нуля.

Код следующий (я упростил некоторые параметры для возможности восстановления):

def get_derivatives_NN(X, y):

    # Define Keras model
    model = keras.Sequential()
    model.add(keras.layers.Dense(500, activation=tf.nn.relu, input_shape=(X.shape[1],)))
    model.add(keras.layers.Dense(300, activation=tf.nn.relu))
    model.add(keras.layers.Dense(100, activation=tf.nn.relu))
    model.add(keras.layers.Dense(y.shape[1]))

    # Compile and fit model
    optimz = keras.optimizers.Adam(optimizer_parameters)
    model.compile(optimizer=optimz, loss='mse', metrics=['mae'])
    model.fit(X, y, epochs = 200, validation_split=0)

    # Evaluate gradients in Keras
    grads = keras.backend.gradients(model.output, model.input)[0] # tensor
    get_gradients = keras.backend.function([model.input], [grads])
    evaluated_gradients = get_gradients([X]) # this is the evaluated gradient in Keras

    # Evaluate gradienst in tf
    session = keras.backend.get_session()
    session.run(tf.global_variables_initializer())
    evaluated_gradients_TF = session.run(tf.gradients(model.output, model.input), feed_dict={model.input: X})

    # Evaluate hessian in tf
    evaluated_hessian = session.run(tf.hessians(model.output, model.input), feed_dict={model.input: X})

    return evaluated_gradients, evaluated_gradients_TF, evaluated_hessian

Вывод (усечение моей копии-вставки):

GRADIENT KERAS:
[array([[-0.00286908,  0.06114262,  0.0178928 ],
       [-0.00717778,  0.05055936,  0.0415092 ],
       [-0.00725342,  0.0075229 ,  0.06268862],
       ..., dtype=float32)]


GRADIENT TF:
[array([[-0.00286908,  0.06114262,  0.0178928 ],
       [-0.00717778,  0.05055936,  0.0415092 ],
       [-0.00725342,  0.0075229 ,  0.06268862],
       ..., dtype=float32)]

HESSIAN TF:
[array([[[[0., 0., 0.],
         [0., 0., 0.],
         [0., 0., 0.],
         ...,
         [0., 0., 0.],
         [0., 0., 0.],
         [0., 0., 0.]], ....... etcetera

С этим связаны две проблемы:

1) Размер гессиана на самом деле неимеет смысл для меня.Я ожидал (5000, 3, 3) массива или (5000,9) максимум, в то время как я получаю (5000, 3, 5000, 3);

2) Все значения являются нулями,Я проверил с помощью np.count_nonzero(evaluated_hessian), который возвращает 0.

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

РЕДАКТИРОВАТЬ: Если я использую вычисленный градиент в качестве входных данных для другого вызова get_derivative_NN, я получаю правильное значение для второй производной, так что это доказывает, что есть что-то странноепроисходит с функцией tf.hessians().

1 Ответ

0 голосов
/ 07 марта 2019

Что вы подразумеваете под "использованием вычисленного градиента в качестве входных данных для другого get_derivative вызова"?Вы имеете в виду get_derivatives_NN?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...