Я решил начать изучать TensorFlow 2.0 и в качестве упражнения я хотел реализовать сценарий, который решает задачу оценки максимального логарифмического правдоподобия для нормального распределения. Моя общая проблема в том, что мой скрипт неправильно вычисляет градиенты. Я предполагаю, что моя функция отрицательного правдоподобия определена неправильно или я неправильно использую методы TensorFlow.
Я использовал следующую ссылку для реализации математики. Кто-нибудь знает, почему получаются следующие результаты:
Loss = 1363,5, mean = 1787,0, sigma = 1,0, grads0 = -9,4, grads1 = 110,8
и
Потери = 25160,5, среднее значение = 4116480,5, сигма = -33726359552,0, грады0 = 0,0, грады1 = -0,0
Нормальное распределение, из которого я отбираю данные, имеет среднее значение 1787 и дисперсию 1,0. Вот мой текущий код:
import math as m
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
SAMPLE_SIZE = 1000
SIGMA = 1.
MEAN = 1787.
INIT_SIGMA = -33726359552.0
INIT_MEAN = 4116480.5
normal_distribution_truth = tfd.Normal(loc=MEAN, scale=SIGMA)
data = normal_distribution_truth.sample(SAMPLE_SIZE)
optimizer = tf.optimizers.SGD(0.5)
mean = tf.Variable(INIT_MEAN, name='mean', dtype=tf.float32)
sigma = tf.Variable(INIT_SIGMA, name='sigma', dtype=tf.float32)
def negative_likelihood(mean, sigma):
pi_term = ((SAMPLE_SIZE / 2) * tf.math.log(2 * m.pi))
sigma_term = ((SAMPLE_SIZE / 2) * tf.math.log(tf.math.square(sigma)))
mean_term = ((1/(2*tf.math.square(sigma)))*tf.reduce_sum(tf.math.square((data-mean))))
return pi_term+sigma_term+mean_term
opt = tf.keras.optimizers.SGD(learning_rate=0.5)
for i in range(100):
with tf.GradientTape() as tape:
y = negative_likelihood(mean, sigma)
grads = tape.gradient(y, [mean, sigma])
processed_grads = [g for g in grads]
print('Loss = {:.1f}, mean = {:.1f}, sigma = {:.1f}, grads0 = {:.1f}, grads1 = {:.1f} '.format(y.numpy(),
mean.numpy(),
sigma.numpy(),
grads[0].numpy(),
grads[1].numpy()))
grads_and_vars = zip(processed_grads, [mean, sigma])
opt.apply_gradients(grads_and_vars)