У меня есть простая Dense-U-net, реализованная в Tensorflow 2.0 (и tf.keras) для выполнения семантической сегментации. В конце каждого плотного блока я хочу случайным образом вращать и / или переворачивать тензоры (только для экспериментов). Начальный размер изображения 256х256. В настоящий момент я хочу выполнить переворачивание / вращение, тензоры всегда имеют C = 5 каналов (то есть, форма = [?, 256,256,5] (NHWC) в начале, сокращая H & W, поскольку выполняется объединение, но Cвсегда 5 и размер партии N = 8). Таким образом, тензоры не очень велики.
Для пояснения: обратите внимание, что я не ставлю целью расширение, а анализ поведения сети, когда карты промежуточных объектов испытывают небольшое изменение ориентации. Подобные идеи были изучены либо с помощью переворачивания / вращения ядер, либо с помощью карт характеристик (Gao et al. 2017, Эффективные и инвариантные CNN для плотного прогнозирования, arXiv: 1711.09064).
Моей первой попыткой было реализоватьэто как функция:
def random_rotation_flip(x):
x = tf.image.random_flip_left_right(x)
x = tf.image.rot90(x, k=tf.random.uniform(shape=[], minval=1,
maxval=4, dtype=tf.int32))
return x
Это приводит к ошибке:
OperatorNotAllowedInGraphError: использование tf.Tensor
в качестве Python bool
не допускается при выполнении Graph. Используйте Eager для выполнения или украсьте эту функцию с помощью @ tf.function.
Я не совсем уверен, что происходит, но если я добавлю @ tf.function в начале определения функции:
@tf.function
def random_rotation_flip(x):
x = tf.image.random_flip_left_right(x)
x = tf.image.rot90(x, k=tf.random.uniform(shape=[], minval=1,
maxval=4, dtype=tf.int32))
return x
Я получаю:
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: conv1_block1_2_conv/Identity:0
During handling of the above exception, another exception occurred:
_SymbolicException Traceback (most recent call last)
9 frames
/tensorflow-2.0.0/python3.6/tensorflow_core/python/eager/execute.py in quick_execute(op_name,
num_outputs, inputs, attrs, ctx, name)
73 raise core._SymbolicException(
74 "Inputs to eager execution function cannot be Keras symbolic "
---> 75 "tensors, but found {}".format(keras_symbolic_tensors))
76 raise e
77 # pylint: enable=protected-access
_SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found
[<tf.Tensor 'conv1_block1_2_conv/Identity:0' shape=(None, 256, 256, 5) dtype=float32>]
Мои первые вопросы:
- Может кто-нибудь объяснить, что происходит и как это решить?
- Можно ли выполнять эти две операции (переворачивание и вращение) внутри функции?
- Должен ли я сделать это по-другому?
Сейчасвторая часть вопроса!
В попытке преодолеть это я реализовал это в Layer:
class MyRandomRotationFlipLayer(layers.Layer):
def __init__(self):
super(MyRandomRotationFlipLayer, self).__init__()
def call(self, input):
x = tf.image.random_flip_left_right(input)
return tf.image.rot90(x, k=tf.random.uniform(shape=[], minval=1,
maxval=4, dtype=tf.int32))
Теперь это работает! Тем не менее, я исчерпал память во время тренировки.
Примечание. Я использую Google Colab с графическим процессором. Графический процессор имеет 12 ГБ памяти. Однако проблема памяти связана не с графическим процессором, а с оперативной памятью, которая имеет 25 ГБ и указана в правом верхнем углу ноутбука Google Colab.
Я заметил, что объем оперативной памяти увеличиваетсямедленно, но непрерывно, пока он не выходит за пределы 25 ГБ и не падает.
Я значительно уменьшил карты глубины и характеристик моих сверток (C = 2), чтобы заставить его работать, но даже в этом случае это в конечном итогевылетает память (может быть, она хорошо работает для 100-200 итераций ...).
Это говорит о том, что я делаю что-то не так. Это потому, что создаются новые тензоры, а старые не удаляются из памяти? Как это следует делать, чтобы избежать исчерпания памяти?
Любая информация о том, как это должно быть сделано правильно, приветствуется.
Заранее спасибо!