Вычислить гессенскую матрицу и градиентный вектор среднего квадрата потерь с использованием тензорного потока - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь вычислить гессенскую матрицу и градиентный вектор среднего квадрата потерь.Генерация данных очень проста: два предиктора с термином перехвата.Коэффициент бета составляет [1,2,3].Теперь я хочу вычислить гессиан и градиент по значению истинной беты (а именно [1,2,3]).(Гессиан должен быть матрицей 3 * 3, а вектор градиента состоит из 3 элементов.)

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

Так как истинная бета-версия - почти оптимум обычного наименьшего квадрата (OLS), градиент должен быть близок к нулю.Поэтому я сомневаюсь, что мой код Tensorflow неверен.

import tensorflow as tf
import numpy as np
import random

random.seed(0)
np.random.seed(seed=0)

Простая генерация данных:

sample_size=1000
dim_x=2 # two predictors
x1=np.random.normal(loc=0.0, scale=1.0, size=(sample_size,1))
x2=np.random.normal(loc=0.0, scale=1.0, size=(sample_size,1))
x_train=np.concatenate((x1,x2), axis=1)

Beta=np.array([1,2,3])
mean_y=Beta[0]+x_train.dot(Beta[1:3])
y_train=mean_y+np.random.normal(loc=0.0, scale=1.0, size=(sample_size,))

Вычисление вектора градиента и гессиана с использованием Tensorflow:

sess = tf.Session()

x_input = tf.placeholder(tf.float64, [None, dim_x+1], name='x_input') 
y_input = tf.placeholder(tf.float64, name='y_input')

coeff = tf.Variable(tf.convert_to_tensor(Beta,tf.float64), name='coeff')
y_fit = tf.multiply(x_input, coeff)

loss_op = tf.reduce_sum(tf.pow(y_input - y_fit, 2))/sample_size
gradients_node = tf.gradients(loss_op, coeff)
hessians_node = tf.hessians(loss_op, coeff)

init = tf.global_variables_initializer()
sess.run(init)

input_x=np.concatenate((np.ones([sample_size,1]),x_train),axis=1)
gradients,loss = sess.run([gradients_node, loss_op],feed_dict={x_input: input_x,y_input: y_train.reshape(-1, 1)})
hessians = sess.run(hessians_node,feed_dict={x_input: input_x,y_input: y_train.reshape(-1, 1)})

print(gradients)
print(hessians)
sess.close()


[array([ 0.20178232,  0.34121165,  0.09825671])]
[array([[ 2.        ,  0.        ,  0.        ],
       [ 0.        ,  1.95256525,  0.        ],
       [ 0.        ,  0.        ,  1.87503835]])]

Вычисление вектора градиента и гессиана аналитически:

Resid=y_train.reshape(-1, 1)-input_x.dot(Beta).reshape(-1, 1)
gradientsMannual=-2*np.transpose(Resid).dot(input_x)/sample_size
print(gradientsMannual)
hessiansMannual=2*np.transpose(input_x).dot(input_x)/sample_size
print(hessiansMannual)


[[ 0.10245713  0.06634371  0.00258758]]
[[ 2.         -0.09051341  0.02723388]
 [-0.09051341  1.95256525 -0.06145151]
 [ 0.02723388 -0.06145151  1.87503835]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...