无法在损失函数中使用VGG功能的MSE

问题描述 投票:4回答:1

我正在tf.keras中使用keras(tensorflow 2.0.0)我有一个网络,其输入是图像,输出也是图像。我想结合使用MSE,VGG功能空间中的MSE和其他一些损耗,这取决于中间层的输出。我正在定义自定义损失函数。我能够构建模型,并用自定义损失进行编译。但是当我使用fit_generator进行训练时,我得到的是SymbolicExceptionInputs to eager execution function cannot be Keras symbolic tensors

完整代码:训练文件:

def __init__(self, gray_images: bool, verbose: bool = True):
    super().__init__(gray_images, verbose)
    self.model = None
    self.vgg_feature_extractor = VggFeaturesExtractor(model_name='vgg16', layers=[3, 6, 10])

def build_model():
    image_input = Input(shape=(None, None, num_input_channels))
    out1 = self.build_out1_model(image_input, num_filters, depth_t)
    out2 = self.build_out2_model(image_input, num_filters, depth_n, use_bnorm)
    enhanced_image = ... # Some function of image_input, out1 and out2

    self.model = Model(inputs=image_input, outputs=enhanced_image)
    self.model.add_loss(loss_weights[1] * self.loss2(out2))
    self.model.compile(optimizer='adam', loss=self.vgg_loss)

def vgg_loss(self, gt_image, est_image):
    gt_features = self.vgg_feature_extractor.extract_features(gt_image)
    est_features = self.vgg_feature_extractor.extract_features(est_image)
    loss = tf.reduce_mean(tf.square(gt_features[0] - est_features[0])) + \
           tf.reduce_mean(tf.square(gt_features[1] - est_features[1])) + \
           tf.reduce_mean(tf.square(gt_features[2] - est_features[2]))
    return loss

VggFeatures.py:

class VggFeaturesExtractor:
    def __init__(self, model_name: str, layers: List[int]):
        self.model_name = model_name
        self.layers = layers
        if model_name == 'vgg16':
            from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
            vgg_model = VGG16(include_top=False)
            self.preprocess_input = preprocess_input
        elif model_name == 'vgg19':
            from tensorflow.keras.applications.vgg19 import VGG19, preprocess_input
            vgg_model = VGG19(include_top=False)
            self.preprocess_input = preprocess_input
        else:
            raise RuntimeError(f'Unknown Model: {model_name}')
        outputs = []
        for layer_num in layers:
            outputs.append(vgg_model.layers[layer_num].output)
        self.feature_extractor = keras.Model(inputs=vgg_model.input, outputs=outputs)

    def extract_features(self, images: numpy.ndarray):
        preprocessed_images = self.preprocess_input(images)
        features = self.feature_extractor(preprocessed_images)
        return features

堆栈跟踪:

Epoch 1/1000
Traceback (most recent call last):
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/eager/execute.py", line 61, in quick_execute
    num_outputs)
TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
  @tf.function
  def has_init_scope():
    my_constant = tf.constant(1.)
    with tf.init_scope():
      added = my_constant * 2
The graph tensor has name: StridedSliceGrad:0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/media/nagabhushan/Data02/SNB/IISc/Research/.../Workspace/Ideas/01_Supervised/src/N09.py", line 363, in <module>
    main()
  File "/media/nagabhushan/Data02/SNB/IISc/Research/.../Workspace/Ideas/01_Supervised/src/N09.py", line 343, in main
    args.save_interval)
  File "/media/nagabhushan/Data02/SNB/IISc/Research/.../Workspace/Ideas/01_Supervised/src/N09.py", line 92, in train_model
    verbose=self.verbose)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py", line 1297, in fit_generator
    steps_name='steps_per_epoch')
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_generator.py", line 265, in model_iteration
    batch_outs = batch_function(*batch_data)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py", line 973, in train_on_batch
    class_weight=class_weight, reset_metrics=reset_metrics)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2_utils.py", line 264, in train_on_batch
    output_loss_metrics=model._output_loss_metrics)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_eager.py", line 311, in train_on_batch
    output_loss_metrics=output_loss_metrics))
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_eager.py", line 268, in _process_single_batch
    grads = tape.gradient(scaled_total_loss, trainable_weights)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/eager/backprop.py", line 1014, in gradient
    unconnected_gradients=unconnected_gradients)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/eager/imperative_grad.py", line 76, in imperative_grad
    compat.as_str(unconnected_gradients.value))
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 911, in _backward_function_wrapper
    processed_args, remapped_captures)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 1224, in _call_flat
    ctx, args, cancellation_manager=cancellation_manager)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 511, in call
    ctx=ctx)
  File "/media/nagabhushan/Data02/SoftwareFiles/Anaconda/anaconda3/envs/.../lib/python3.7/site-packages/tensorflow_core/python/eager/execute.py", line 75, in quick_execute
    "tensors, but found {}".format(keras_symbolic_tensors))
tensorflow.python.eager.core._SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'StridedSliceGrad:0' shape=(16, 64, 64, 3) dtype=float32>]

Process finished with exit code 1

注意:1.如果将self.model.compile(optimizer='adam', loss=self.vgg_loss)替换为self.model.compile(optimizer='adam', loss='mse'),代码可以正常工作,这意味着代码的另一部分正常工作。2.我在SO上发现的有关VGG丢失的几乎每个问题都建议将VGG网络附加到主网络,为VGG网络设置trainable=False,然后进行MSE丢失训练。但是我无法做到这一点,因为损失函数中有很多组件。

python keras customization tensorflow2.0 loss-function
1个回答
0
投票

我能够通过禁用急切的执行来解决此问题。在tensorflow 2.0中,默认情况下启用急切执行。

tf.compat.v1.disable_eager_execution()

尽管我不明白这是如何解决此问题的。如果有人偶然发现类似问题,可以尝试禁用急切的执行。

© www.soinside.com 2019 - 2024. All rights reserved.