Tensorflow 2: Получение «ПРЕДУПРЕЖДЕНИЕ: тензорный поток: 9 из последних 9 вызовов <function>запустили повторную трассировку tf.function. Трассировка стоит дорого» - PullRequest
2 голосов
/ 07 мая 2020

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

Кроме того, tf.function имеет параметр экспериментальной_relax_shapes = True, который смягчает формы аргументов, что позволяет избежать ненужного повторения.

Когда я ввожу этот аргумент в декоратор функции, он работает.

@tf.function(experimental_relax_shapes=True)

В чем может быть причина? Вот полный код:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
print(f'Tensorflow version {tf.__version__}')
from tensorflow import keras
from tensorflow.keras.layers import Dense, Conv1D, GlobalAveragePooling1D, Embedding
import tensorflow_datasets as tfds
from tensorflow.keras.models import Model

(train_data, test_data), info = tfds.load('imdb_reviews/subwords8k',
                                          split=[tfds.Split.TRAIN, tfds.Split.TEST],
                                          as_supervised=True, with_info=True)

padded_shapes = ([None], ())

train_dataset = train_data.shuffle(25000).\
    padded_batch(padded_shapes=padded_shapes, batch_size=16)
test_dataset = test_data.shuffle(25000).\
    padded_batch(padded_shapes=padded_shapes, batch_size=16)

n_words = info.features['text'].encoder.vocab_size


class ConvModel(Model):
    def __init__(self):
        super(ConvModel, self).__init__()
        self.embe = Embedding(n_words, output_dim=16)
        self.conv = Conv1D(32, kernel_size=6, activation='elu')
        self.glob = GlobalAveragePooling1D()
        self.dens = Dense(2)

    def call(self, x, training=None, mask=None):
        x = self.embe(x)
        x = self.conv(x)
        x = self.glob(x)
        x = self.dens(x)
        return x


conv = ConvModel()

conv(next(iter(train_dataset))[0])

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

train_loss = tf.keras.metrics.Mean()
test_loss = tf.keras.metrics.Mean()

train_acc = tf.keras.metrics.CategoricalAccuracy()
test_acc = tf.keras.metrics.CategoricalAccuracy()

optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)


@tf.function
def train_step(inputs, labels):
    with tf.GradientTape() as tape:
        logits = conv(inputs, training=True)
        loss = loss_object(labels, logits)
        train_loss(loss)
        train_acc(logits, labels)

    gradients = tape.gradient(loss, conv.trainable_variables)
    optimizer.apply_gradients(zip(gradients, conv.trainable_variables))


@tf.function
def test_step(inputs, labels):
    logits = conv(inputs, training=False)
    loss = loss_object(labels, logits)
    test_loss(loss)
    test_acc(logits, labels)


def learn():
    train_loss.reset_states()
    test_loss.reset_states()
    train_acc.reset_states()
    test_acc.reset_states()

    for text, target in train_dataset:
        train_step(inputs=text, labels=target)

    for text, target in test_dataset:
        test_step(inputs=text, labels=target)


def main(epochs=2):
    for epoch in tf.range(1, epochs + 1):
        learn()
        template = 'TRAIN LOSS {:>5.3f} TRAIN ACC {:.2f} TEST LOSS {:>5.3f} TEST ACC {:.2f}'

        print(template.format(
            train_loss.result(),
            train_acc.result(),
            test_loss.result(),
            test_acc.result()
        ))

if __name__ == '__main__':
    main(epochs=1)

1 Ответ

1 голос
/ 07 мая 2020

TF / DR: Root - причина этой ошибки связана с изменением формы train_data, которая меняется от партии к партии. Исправление размера / формы train_data устраняет это предупреждение трассировки. Я изменил следующую строку, тогда все работает как положено. Полная суть здесь

padded_shapes = ([9000], ())#None.

Подробности:

Как указано в предупреждающем сообщении

ПРЕДУПРЕЖДЕНИЕ: tenorflow: 10 из последние 11 вызовов сработавшей функции восстановления. Трассировка стоит дорого, и чрезмерное количество трассировок может быть связано с (1) многократным созданием функции @ tf. в al oop, (2) передачей тензоров с разными формами, (3) передачей Python объектов вместо тензоров. Для (1) определите функцию @ tf. вне l oop. Для (2) в @ tf.function есть опция экспериментальной_relax_shapes = True, которая смягчает формы аргументов, чтобы избежать ненужного повторного отслеживания.

это предупреждение об обратном отслеживании происходит по трем причинам, указанным в предупреждающем сообщении. Причина (1) не является причиной root, потому что функция @ tf. не вызывается в al oop, также причина (3) не является причиной root, потому что оба аргумента train_step и test_step - тензорные объекты. Итак, root -причина является причиной (2), упомянутой в предупреждении.

Когда я напечатал размер train_data, он напечатал разные размеры. Поэтому я попытался набить train_data так, чтобы форма была одинаковой для всех партий.

 padded_shapes = ([9000], ())#None.  # this line throws tracing error as the shape of text is varying for each step in an epoch.
    # as the data size is varying, tf.function will start retracing it
    # For the demonstration, I used 9000 as max length, but please change it accordingly 

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...