Вероятность Tensorflow - плотное отклонение - градиенты, не предусмотренные для любой переменной - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь построить модель байесовской регрессии Softmax, используя плотный слой Flip-Out с вероятностями Tensorflow.Эта модель обучается на наборе данных MNIST.

Tensorflow возвращает ошибку:

"Градиенты не указаны ни для одной переменной, проверьте график на наличие операций, которые не поддерживают градиенты,между переменными [] и потерями в 0x7f07fc127840>. "

Я полагаю, это связано с тем, что случайные переменные не являются дифференциальными, поэтому градиента не существует.Тем не менее, Tensorflow предоставляет четкую демонстрацию этого кода на своем веб-сайте - здесь .

У кого-нибудь есть исчерпывающий ответ о том, почему это происходит?

Мой кодкак показано ниже:

import tensorflow as tf
import tensorflow_probability as tfp
import matplotlib.pyplot as plt
import numpy as np

mnist = tf.keras.datasets.mnist
tfe = tf.contrib.eager
ed = tfp.edward2

tf.reset_default_graph()
tf.enable_eager_execution()

(x_train, y_train), (x_test, y_test) = mnist.load_data()

pix_w = 28
pix_h = 28

def vis_pix(image):
    plt.imshow(image, cmap='Greys')
    plt.show()

def scale(x, min_val=0.0, max_val=255.0):
    x = tf.cast(x, tf.float32)
    return tf.div(tf.subtract(x, min_val), tf.subtract(max_val, min_val))

def create_dataset(x, y):
    dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
    dataset = dataset.map(lambda x, y: (scale(x), tf.one_hot(y, 10)))
    dataset = dataset.map(lambda x, y: (tf.reshape(x, [pix_w * pix_h]), y))
    dataset = dataset.shuffle(10000).batch(30)
    return dataset

train_ds = create_dataset(x_train, y_train)

model = tf.keras.Sequential([
    tfp.layers.DenseFlipout(10)
])

optimizer = tf.train.AdamOptimizer()

def loss_fn(model, x, y):
    logits = model(x)
    neg_log_likelihood = tf.nn.softmax_cross_entropy_with_logits(labels=y, 
logits=logits)
    kl = sum(model.losses)
    elbow_loss = neg_log_likelihood + kl
    return elbow_loss

def get_accuracy(model, x, y):
    logits = model(x)
    yhat = tf.argmax(logits, 1)
    is_correct = tf.equal(yhat, tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))
    return accuracy

epochs = 1000
for (batch, (x, y)) in enumerate(train_ds):
    optimizer.minimize(lambda: loss_fn(model, x, y), 
global_step=tf.train.get_or_create_global_step())
    if batch % 10 == 0:
      acc = get_accuracy(model, x, y).numpy() * 100
      loss = loss_fn(model, x, y).numpy().mean()
      print("Iteration {}, loss: {:.3f}, train accuracy: 
{:.2f}%".format(batch, loss, acc))
    if batch > epochs:
        break
...