Я пытаюсь вычислить гессенскую матрицу и градиентный вектор среднего квадрата потерь.Генерация данных очень проста: два предиктора с термином перехвата.Коэффициент бета составляет [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]]