首页 > 解决方案 > 使用 tf.eager 训练复杂的 nn 模型(更好地使用 TF2 符号支持)

问题描述

是否有(或多或少)简单的方法来编写复杂的 NN 模型,以便它可以在急切模式下进行训练?有这样的代码的例子吗?

例如,我想使用InceptionResnetV2. 我有使用创建的代码tf.contrib.slim。根据此链接https://github.com/tensorflow/tensorflow/issues/16182,不推荐使用 slim ,我需要使用Keras. 而且我真的不能使用苗条的代码进行训练,因为我不能获取变量列表并应用梯度(好的,我可以尝试将模型包装到GradientTape但不确定如何处理正则化损失)。

好的,让我们试试Keras

In [30]: tf.__version__                                                                                                                                                                          
Out[30]: '1.13.1'

In [31]: tf.enable_eager_execution()

In [32]: from keras.applications.inception_resnet_v2 import InceptionResNetV2

In [33]: model = InceptionResNetV2(weights=None)
...
/usr/local/lib/python3.6/dist-packages/keras_applications/inception_resnet_v2.py in InceptionResNetV2(include_top, weights, input_tensor, input_shape, pooling, classes, **kwargs)
    246 
    247     if input_tensor is None:
--> 248         img_input = layers.Input(shape=input_shape)
    249     else:
    250         if not backend.is_keras_tensor(input_tensor):
...
RuntimeError: tf.placeholder() is not compatible with eager execution.

默认情况下不起作用。

在本教程中,他们说我需要创建自己的模型类并自己维护变量https://www.tensorflow.org/tutorials/eager/custom_training#define_the_model。我不确定我想为《盗梦空间》做这件事。要创建和维护的变量太多。这就像回到旧版本的TF,在连苗条都不存在的日子里。

在本教程中,网络是使用Keras https://www.tensorflow.org/tutorials/eager/custom_training_walkthrough#create_a_model_using_keras创建的,但我怀疑我是否可以通过仅定义模型而不使用Input. 例如,在本文中,如果我理解正确,作者初始化 kerasInput并通过模型传播它(这RuntimeError在与 Eager 一起使用时会导致,如您之前所见)。我可以通过继承模型类来制作自己的模型,如下所示:https ://www.tensorflow.org/api_docs/python/tf/keras/Model 。哎呀,这样我需要维护层,而不是变量。在我看来,这几乎是同样的问题。

AutoGrad这里有一个有趣的提及https://www.tensorflow.org/beta/guide/autograph#keras_and_autograph。他们只覆盖__call__,所以在这种情况下我似乎不需要维护变量,但我还没有测试它。


那么,有没有简单的解决方案呢?

将苗条模型包裹起来GradientTape?然后我如何将 reg loss 应用于权重?

自己跟踪每个变量?听起来有点痛苦。

使用Keras?当模型中有分支和复杂结构时如何使用它?

标签: pythontensorflowtensorflow2.0eager

解决方案


您的第一种方法可能是最常见的。这个错误:

RuntimeError: tf.placeholder() 与急切执行不兼容。

是因为不能tf.placeholder在急切模式下使用 a 。热切执行时没有这种东西的概念。

您可以使用tf.dataAPI为您的训练数据构建数据集并将其提供给模型。将数据集替换为您的真实数据的情况如下:

import tensorflow as tf
tf.enable_eager_execution()

model = tf.keras.applications.inception_resnet_v2.InceptionResNetV2(weights=None)

model.compile(tf.keras.optimizers.Adam(), loss=tf.keras.losses.categorical_crossentropy)

### Replace with tf.data.Datasets for your actual training data!
train_x = tf.data.Dataset.from_tensor_slices(tf.random.normal((10,299,299,3)))
train_y = tf.data.Dataset.from_tensor_slices(tf.random.uniform((10,), maxval=10, dtype=tf.int32))
training_data = tf.data.Dataset.zip((train_x, train_y)).batch(BATCH_SIZE)

model.fit(training_data)

如您的标题中所述,这种方法也可以在 TensorFlow 2.0 中使用。


推荐阅读