问题
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