У меня есть некоторый код, который отлично работает в нетерпеливом режиме, но я изо всех сил пытаюсь преобразовать в режим графика, используя tenenflow 2.1 .
Быстрое объяснение того, что я намереваюсь do: Я хочу модель последовательности первого уровня, которая преобразует последовательность во встраивание (в этом примере - вложение символов в вложения слов), затем модель последовательности второго уровня, которая делает то же самое с предыдущим выводом (в этом пример вложения слов в вложения предложений).
Вот код, который делает именно это в нетерпеливом режиме:
import tensorflow as tf
vocab_size = 20
text = [
"this is a positive example".split(' '),
"this one is definitely negative and has more words".split(' ')
]
words_lengths_t = tf.ragged.constant([[len(w) for w in sent] for sent in text])
sentence_lengths_t = tf.constant([len(s) for s in text])
text_t = tf.ragged.constant([[c for w in sent for c in w] for sent in text])
int_chars = tf.dtypes.cast(tf.strings.to_hash_bucket_fast(text_t, vocab_size), tf.float32)
embedded = tf.keras.layers.Embedding(vocab_size, 2)(int_chars)
# unecessary conversion ragged -> tensor in eager mode, but necessary in graph mode:
w_lens_flat = words_lengths_t.flat_values
embedd_flat = embedded.flat_values
seq_lvl1_in = tf.keras.layers.Lambda(
lambda x: tf.RaggedTensor.from_row_lengths(x, w_lens_flat)
)(embedd_flat)
seq_lvl1_out = tf.keras.layers.LSTM(4)(seq_lvl1_in)
lstm_lvl2_in = tf.keras.layers.Lambda(
lambda x: tf.RaggedTensor.from_row_lengths(x, sentence_lengths_t)
)(seq_lvl1_out)
lstm_lvl2_out = tf.keras.layers.LSTM(4)(lstm_lvl2_in)
classifier = tf.keras.layers.Dense(1, activation='softmax', name='classifier')(lstm_lvl2_out)
print(classifier)
Теперь вот моя попытка запустить его в графическом режиме, используя keras.Model.compile()
. Обратите внимание, что я открыт для решений, использующих API тензорного потока более низкого уровня, чем Keras, если это необходимо.
Мне нужно было убедиться, что размер пакета был одинаковым для всех входов, поэтому я использую рваные тензоры в качестве входных данных, они извлекают свои flat_values, чтобы при необходимости изменять их.
import tensorflow as tf
vocab_size = 20
text = [
"this is a positive example".split(' '),
"this one is definitely negative and has more words".split(' ')
]
words_lengths = [[len(w) for w in sent] for sent in text]
sentence_lengths = [len(s) for s in text]
words_lengths_t = tf.ragged.constant(words_lengths)
sentence_lengths_t = tf.constant(sentence_lengths)
flat_characters = [[c for w in sent for c in w] for sent in text]
text_t = tf.ragged.constant(flat_characters)
int_chars = tf.dtypes.cast(tf.strings.to_hash_bucket_fast(text_t, vocab_size), tf.float32)
y = tf.constant([0.0, 1.0])
char_tokens = tf.keras.layers.Input(shape=(None,), ragged=True, name="int_chars")
w_lens = tf.keras.layers.Input(shape=(None,), ragged=True, name="w_len", dtype=tf.int32)
s_len = tf.keras.layers.Input(shape=(None, ), name="s_len", dtype=tf.int32)
embedd_size = 8
embedded = tf.keras.layers.Embedding(vocab_size, embedd_size)(char_tokens)
w_lens_flat = w_lens.flat_values
embedd_flat = embedded.flat_values
seq_lvl1_in = tf.keras.layers.Lambda(
lambda x: tf.RaggedTensor.from_row_lengths(x, w_lens_flat)
)(embedd_flat)
seq_lvl1_out = tf.keras.layers.LSTM(4)(seq_lvl1_in)
classifier = tf.keras.layers.Dense(1, activation='softmax', name='classifier')(seq_lvl1_out)
model = tf.keras.Model(inputs=[s_len, char_tokens, w_lens], outputs=classifier)
model.compile(
tf.keras.optimizers.Adam(),
loss=tf.keras.losses.CategoricalCrossentropy(),
metrics=['acc'],
)
model.fit({
'int_chars': int_chars,
'w_len': words_lengths_t,
's_len': sentence_lengths_t},
y, epochs=2)
Ошибка, которую я получаю на этом этапе, является
tenorflow. python .framework.errors_impl.InvalidArgumentError: Вы должны передать значение для тензора-заполнителя 'Placeholder' с помощью dtype float и shape [?]