ValueError: No gradients provided for any variable - Tensorflow 2.0, Keras

孤街醉人 提交于 2020-04-18 01:08:11

问题


I am trying to implement a simple sequence-to-sequence model using Keras.

However, I keep seeing the following ValueError:

ValueError: No gradients provided for any variable: ['simple_model/time_distributed/kernel:0', 'simple_model/time_distributed/bias:0', 'simple_model/embedding/embeddings:0', 'simple_model/conv2d/kernel:0', 'simple_model/conv2d/bias:0', 'simple_model/dense_1/kernel:0', 'simple_model/dense_1/bias:0'].

Other questions like "ValueError: No gradients provided for any variable" or looking at this issue on github suggests that this might have something to do with the cross-entropy loss function but I fail to see what I am doing wrong here.

This below is a standalone example and should reproduce the exception from above.

I do not think that this is the problem, but I want to mention that I am on a nightly build of Tensorflow. tf-nightly==2.2.0.dev20200410 to be precise.

import random
from functools import partial

import tensorflow as tf
from tensorflow import keras
from tensorflow_datasets.core.features.text import SubwordTextEncoder

EOS = '<eos>'
PAD = '<pad>'

RESERVED_TOKENS = [EOS, PAD]
EOS_ID = RESERVED_TOKENS.index(EOS)
PAD_ID = RESERVED_TOKENS.index(PAD)

dictionary = [
    'verstehen',
    'verstanden',
    'vergessen',
    'verlegen',
    'verlernen',
    'vertun',
    'vertan',
    'verloren',
    'verlieren',
    'verlassen',
    'verhandeln',
]

dictionary = [word.lower() for word in dictionary]


class SimpleModel(keras.models.Model):

    def __init__(self, params, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.params = params
        self.out_layer = keras.layers.Dense(1, activation='softmax')

        self.model_layers = [
            keras.layers.Embedding(params['vocab_size'], params['vocab_size']),
            keras.layers.Lambda(lambda l: tf.expand_dims(l, -1)),
            keras.layers.Conv2D(1, 4),
            keras.layers.MaxPooling2D(1),
            keras.layers.Dense(1, activation='relu'),
            keras.layers.TimeDistributed(self.out_layer)
        ]

    def call(self, example, training=None, mask=None):
        x = example['inputs']
        for layer in self.model_layers:
            x = layer(x)
        return x


def sample_generator(text_encoder: SubwordTextEncoder, max_sample: int = None):
    count = 0

    while True:
        random.shuffle(dictionary)

        for word in dictionary:

            for i in range(1, len(word)):

                inputs = word[:i]
                targets = word

                example = dict(
                    inputs=text_encoder.encode(inputs) + [EOS_ID],
                    targets=text_encoder.encode(targets) + [EOS_ID],
                )
                count += 1

                yield example

                if max_sample is not None and count >= max_sample:
                    print('Reached max_samples (%d)' % max_sample)
                    return


def make_dataset(generator_fn, params, training):

    dataset = tf.data.Dataset.from_generator(
        generator_fn,
        output_types={
            'inputs': tf.int64,
            'targets': tf.int64,
        }
    ).padded_batch(
        params['batch_size'],
        padded_shapes={
            'inputs': (None,),
            'targets': (None,)
        },
    )

    if training:
        dataset = dataset.map(partial(prepare_example, params=params)).repeat()

    return dataset


def prepare_example(example: dict, params: dict):
    # Make sure targets are one-hot encoded
    example['targets'] = tf.one_hot(example['targets'], depth=params['vocab_size'])
    return example


def main():

    text_encoder = SubwordTextEncoder.build_from_corpus(
        iter(dictionary),
        target_vocab_size=1000,
        max_subword_length=6,
        reserved_tokens=RESERVED_TOKENS
    )

    generator_fn = partial(sample_generator, text_encoder=text_encoder, max_sample=10)

    params = dict(
        batch_size=20,
        vocab_size=text_encoder.vocab_size,
        hidden_size=32,
        max_input_length=30,
        max_target_length=30
    )

    model = SimpleModel(params)

    model.compile(
        optimizer='adam',
        loss='categorical_crossentropy',
    )

    train_dataset = make_dataset(generator_fn, params, training=True)
    dev_dataset = make_dataset(generator_fn, params, training=False)

    # Peek data
    for train_batch, dev_batch in zip(train_dataset, dev_dataset):
        print(train_batch)
        print(dev_batch)
        break

    model.fit(
        train_dataset,
        epochs=1000,
        steps_per_epoch=100,
        validation_data=dev_dataset,
        validation_steps=100,
    )


if __name__ == '__main__':
    main()

Thank you for any help on this.

来源:https://stackoverflow.com/questions/61249708/valueerror-no-gradients-provided-for-any-variable-tensorflow-2-0-keras

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!