【问题标题】:Tensorflow 2: Getting "WARNING:tensorflow:9 out of the last 9 calls to <function> triggered tf.function retracing. Tracing is expensive"Tensorflow 2:在对 <function> 的最后 9 次调用中获取“WARNING:tensorflow:9 触发 tf.function 回溯。追踪成本很高”
【发布时间】:2020-05-06 23:47:47
【问题描述】:

我认为这个错误来自形状问题,但我不知道在哪里。完整的错误消息建议执行以下操作:

另外,tf.function 具有experimental_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)

【问题讨论】:

    标签: python tensorflow machine-learning keras deep-learning


    【解决方案1】:

    TF/DR:此错误的根本原因是train_data 的形状发生变化,该形状因批次而异。修复 train_data 的大小/形状可解决此跟踪警告。我更改了以下行,然后一切都按预期工作。完整的要点是here

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

    详情:

    如警告信息中所述

    WARNING:tensorflow:10 次调用中的最后 11 次 触发 tf.function 回溯。追踪是 昂贵且追踪数量过多可能是由于 (1) 在循环中重复创建@tf.function,(2)传递张量 不同的形状,(3) 传递 Python 对象而不是张量。为了 (1),请在循环之外定义您的@tf.function。对于 (2), @tf.function 有 Experimental_relax_shapes=True 选项,可以放松 可以避免不必要的回溯的参数形状。

    由于警告消息中提到的三个原因而发生此回溯警告。原因 (1) 不是根本原因,因为 @tf.function 没有在循环中调用,原因 (3) 也不是根本原因,因为 train_step 和 test_step 的参数都是张量对象。所以根本原因是警告中提到的原因(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 
    

    【讨论】:

    • 1.如果训练数据集的数据大小应该随着模型训练而改变(例如gans(pggan)的渐进式增长),以至于我无法提前塑造大小,这是不可避免的吗? 2. 这个警告是否意味着我根本没有利用 @tf.function 的任何优势?
    猜你喜欢
    • 2021-05-22
    • 1970-01-01
    • 2021-11-07
    • 2017-07-15
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多