Тренировка Tensorflow + Keras: InvalidArgumentError: Несовместимые фигуры: [7,128,2,2] против [7,128,3,3] - PullRequest
0 голосов
/ 04 июня 2019

Внедрение и обучение сети Tiny-DSOD на тензор-флоу + керас.При запуске 1-й эпохи обучение завершается с ошибкой: tenorflow.python.framework.errors_impl.InvalidArgumentError: Несовместимые формы: [7,128,2,2] против [7,128,3,3]

Размер пакета равен 8размер изображения (300 300), а набор данных для обучения - PASCAL VOC 2007 + 2012.Ошибка возникает между одним из выходов на уровень прогнозирования (очень похоже на SSD) и потерей: [[{{node add_fpn_0_ / add}}]] [[{{node loss / add_50}}]]

В настоящее время версия tenorflow - 1.13, а keras - 2.2.4.Версия Python 3.6.Я проверил все, начиная с самой модели (формы соответствуют ожиданиям), изображения, генерируемые для пакетов (каждое изображение соответствует ожиданиям), изменение расчета потерь (в настоящее время используется Adam, но также пробовал с SGD, оно точно такое жепроблема.) и проверил тензорную доску, если может предоставить какую-либо информацию (все идет хорошо до этой точки прекращения).

history = model.fit_generator(generator=train_generator,
                   steps_per_epoch=math.ceil(n_train_samples/batch_size),
                          epochs=epochs,
                          callbacks=[tf.keras.callbacks.ModelCheckpoint('tinydsod300_weights_epoch--{epoch:02d}_loss--{loss:.4f}_val_loss--{val_loss:.4f}.h5',
                                                                        monitor='val_loss',
                                                                        verbose=1,
                                                                        save_best_only=True,
                                                                        save_weights_only=True,
                                                                        mode='auto', period=1),
                                     tf.keras.callbacks.LearningRateScheduler(lr_schedule),
                                     tf.keras.callbacks.EarlyStopping(monitor='val_loss',
                                                                      min_delta=0.001,
                                                                      patience=2),
                                     tf.keras.callbacks.TerminateOnNaN(),
                                     tf.keras.callbacks.TensorBoard(log_dir='./logs'),
                                     tf.keras.callbacks.BaseLogger()],
                          validation_data=val_generator,
                          validation_steps=math.ceil(n_val_samples/batch_size)

Полная ошибка:

WARNING:tensorflow:From /home/alexandre.pires/.conda/envs/neural_network/lib/python3.6/site-packages/tensorflow/python/ops/math_grad.py:102: div (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Deprecated in favor of operator or tf.math.divide.
2019-06-04 15:45:59.614299: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1512] Adding visible gpu devices: 0
2019-06-04 15:45:59.614330: I tensorflow/core/common_runtime/gpu/gpu_device.cc:984] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-06-04 15:45:59.614337: I tensorflow/core/common_runtime/gpu/gpu_device.cc:990]      0 
2019-06-04 15:45:59.614341: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1003] 0:   N 
2019-06-04 15:45:59.614513: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 2998 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1050 Ti, pci bus id: 0000:01:00.0, compute capability: 6.1)
Epoch 1/10
2019-06-04 15:46:28.296307: W tensorflow/core/common_runtime/bfc_allocator.cc:211] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.77GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.
Traceback (most recent call last):
  File "/home/alexandre.pires/PycharmProjects/neural_networks/tiny-dsod.py", line 830, in <module>
    validation_steps=math.ceil(n_val_samples/batch_size)
  File "/home/alexandre.pires/.conda/envs/neural_network/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1426, in fit_generator
    initial_epoch=initial_epoch)
  File "/home/alexandre.pires/.conda/envs/neural_network/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_generator.py", line 191, in model_iteration
    batch_outs = batch_function(*batch_data)
  File "/home/alexandre.pires/.conda/envs/neural_network/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1191, in train_on_batch
    outputs = self._fit_function(ins)  # pylint: disable=not-callable
  File "/home/alexandre.pires/.conda/envs/neural_network/lib/python3.6/site-packages/tensorflow/python/keras/backend.py", line 3076, in __call__
    run_metadata=self.run_metadata)
  File "/home/alexandre.pires/.conda/envs/neural_network/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1439, in __call__
    run_metadata_ptr)
  File "/home/alexandre.pires/.conda/envs/neural_network/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 528, in __exit__
    c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [7,128,2,2] vs. [7,128,3,3]
     [[{{node add_fpn_0_/add}}]]
     [[{{node loss/add_50}}]]

Последнее, что нужно добавить, это то, что предыдущий вывод для слоя прогнозирования действительно имеет форму [7,128,2,2], но это никогдавозникла любая ошибка.Любые советы о том, где я должен отладить дальше?Или откуда именно возникла эта ошибка?

РЕДАКТИРОВАТЬ1 - ИСПРАВЛЕНИЕ

В модель были внесены некоторые исправления и появилась новая ошибка, но все еще с такими же несовместимыми формами:

tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [8,128,2,2] vs. [8,128,3,3]
     [[{{node add_fpn_0_/add}}]]
     [[{{node loss/predictions_loss/broadcast_weights/assert_broadcastable/is_valid_shape/has_valid_nonscalar_shape/has_invalid_dims/concat}}]]

Глубокая свертка была исправлена, чтобы действовать, как предполагалось в исходной модели (сделано в кафе).

Свертка

        layer_name = "conv_" + name
        output = tf.keras.layers.Conv2D(filters=filter, kernel_size=kernel, padding=pad,
                                        strides=stride, kernel_initializer=self.kernel_initializer,
                                        kernel_regularizer=self.regularize, name=layer_name)(input)
        output = tf.keras.layers.BatchNormalization(name=layer_name + "batch_")(output)
        output = tf.keras.layers.Activation('relu', name=layer_name + "relu_")(output)

        return output

DepthWise

        if stride == 2:
            output = tf.keras.layers.ZeroPadding2D(padding=self.correct_pad(input, kernel[0]),
                                                   name='zeropad_' + layer_name)(input)
            output = tf.keras.layers.DepthwiseConv2D(kernel_size=kernel, padding='SAME' if stride == 1 else 'VALID',
                                                     strides=stride, kernel_initializer=self.kernel_initializer,
                                                     kernel_regularizer=self.regularize, name=layer_name)(output)
        else:
            output = tf.keras.layers.DepthwiseConv2D(kernel_size=kernel, padding='SAME' if stride == 1 else 'VALID',
                                                     strides=stride, kernel_initializer=self.kernel_initializer,
                                                     kernel_regularizer=self.regularize, name=layer_name)(input)
        if use_batch_norm:
            output = tf.keras.layers.BatchNormalization(center=True, scale=True, trainable=True,
                                                        name=layer_name + "batch_")(output)
            output = tf.keras.layers.Activation('relu', name=layer_name + "relu_")(output)

Upsample (простой билинейный)

        layer_name = "upsample_" + name
        output = tf.keras.layers.UpSampling2D(size=(input_shape[0], input_shape[1]), interpolation='bilinear',
                                               name=layer_name)(input)
        output = self._depthwise_conv_2d(output, filter=128, kernel=(3, 3), pad='SAME', stride=1, name=layer_name)

        return output

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

Мне удалось решить проблему. Проблема была расположена в слое Upsampling. Модель, на которой я основывался, использовала билинейную повышающую дискретизацию х2 на кофе. Реализация caffe отличается от реализации в tenorflow / keras. Я сделал специальный тестовый слой, чтобы проверить эту гипотезу, и сумел устранить проблему. Слой апсэмплинга, который я использую, теперь выглядит так:

    def UpSampling2DBilinear(self, stride, **kwargs):
        def layer(x):
            input_shape = tf.keras.backend.int_shape(x)
            output_shape = (stride * (input_shape[1] - 1) + 1, stride * (input_shape[2] - 1) + 1)
            if output_shape[0] == 9:
                output_shape = (10,10)
            if output_shape[0] == 37:
                output_shape = (38,38)

            return tf.image.resize_bilinear(x, output_shape, align_corners=True)

        return tf.keras.layers.Lambda(layer, **kwargs)

Очевидно, что это не окончательное решение для пользовательского слоя, но на данный момент оно работает для входного размера изображения (300 300).

Итак, для тех, кто сталкивается с подобной проблемой в будущем, вот контрольный список шагов, которые могут быть очень полезны для отладки:

  • Ошибка несовместимых фигур в прогнозах, в большинстве случаев связанная с вашей моделью. Это означает, что на каком-то этапе вы делаете что-то не так. Двойная / тройная / четырехкратная проверка каждого выхода модели на каждом слое (в этом случае keras имеет функцию model.summary (), помогающую в этом случае).

  • Если модель, которую вы реализуете, ее построение основано на Caffe (или любой другой среде, отличной от той, которую вы используете), проверьте детали реализации этого уровня. В моем случае я должен был изменить глубинные свертки, максимальное объединение и повышающую дискретизацию, чтобы соответствовать желаемому поведению.

  • Убедитесь, что функции потерь, генераторы партий и т. Д. Также полностью корректны, чтобы избежать дальнейших проблем.

Надеюсь, в будущем это будет полезно многим людям, борющимся с ошибками такого типа. Спасибо всем, кто пытался помочь мне с этим!

0 голосов
/ 04 июня 2019

Я думаю, что проблема заключается в размерах изображений внутри сети.

попробуйте изменить эту часть:

 output = self._depthwise_conv_2d(output, filter=128, kernel=(3, 3), pad='SAME', stride=1, name=layer_name)

для этого.

 output = self._depthwise_conv_2d(output, filter=128, kernel=(2, 2), pad='SAME', stride=1, name=layer_name)

если высм. вывод, который говорит вам, что у вас есть выход с 7 элементами, который имеет 128 фильтров с измерением 2 x 2, и ваша сеть имеет выход с 7 элементами с 128 фильтрами, который имеет измерение 3 x 3.

дайте мне знать, если я помогу.

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