Python 在Tensorflow 2.0中翻转和旋转张量(U形网络内)会耗尽内存。如何做好这件事?

Python 在Tensorflow 2.0中翻转和旋转张量(U形网络内)会耗尽内存。如何做好这件事?,python,tensorflow,keras,google-colaboratory,Python,Tensorflow,Keras,Google Colaboratory,我在Tensorflow 2.0(和tf.keras)中实现了一个简单的稠密U网来进行语义分割。 在每个密集块的末尾,我想随机旋转和/或翻转张量(只是为了实验)。图像的初始大小为256x256。在我想要执行翻转/旋转的时刻,张量始终具有C=5个通道(即,开始时的形状=[?,256256,5](NHWC),在执行池时减少H&W,但C始终为5,批大小为N=8)。因此,张量并不是很大 需要澄清的是:请注意,我的目标不是进行扩充,而是 分析中间特征映射受损时的网络行为 轻微的方向变化。类似的想法也曾被研

我在Tensorflow 2.0(和tf.keras)中实现了一个简单的稠密U网来进行语义分割。 在每个密集块的末尾,我想随机旋转和/或翻转张量(只是为了实验)。图像的初始大小为256x256。在我想要执行翻转/旋转的时刻,张量始终具有C=5个通道(即,开始时的形状=[?,256256,5](NHWC),在执行池时减少H&W,但C始终为5,批大小为N=8)。因此,张量并不是很大

需要澄清的是:请注意,我的目标不是进行扩充,而是 分析中间特征映射受损时的网络行为 轻微的方向变化。类似的想法也曾被研究过 翻转/旋转内核或特征图(Gao等人,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
。 使用渴望执行或用@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>]
现在它工作了!然而,我在训练时耗尽了记忆

注意:我使用的是带有GPU的Google Colab。GPU有12GB的内存。 然而,内存问题不是来自GPU,而是来自RAM内存,后者是 具有25 GB,并显示在屏幕的右上角 谷歌Colab笔记本

我注意到RAM正在缓慢但持续地增加,直到超过25GB并崩溃

我已经大大减少了卷积(C=2)的深度和特征映射,以使其工作,但即使在这种情况下,它最终也会破坏内存(可能在100-200次迭代中工作良好…)

这表明我做错了什么。是因为新的张量被创建,而旧的张量没有从内存中删除吗?如何处理此问题以避免内存耗尽

任何关于如何正确完成这项工作的意见都是非常受欢迎的


提前谢谢

我见过人们使用Keras提供的预处理功能进行数据扩充(翻转等)的案例。以下是参考资料:


希望这将为您节省一些精力,或者至少提供一个工作参考点。我希望这有帮助。

我遇到了同样的问题,看起来有些tf函数与符号张量冲突。 最后我自己编写了一个rot90函数来解决这个问题:

  • 创建网格网格
  • 翻转与转置
  • 收集 这很有效

谢谢你的回答!然而,我的目标不是增加,而是研究网络行为,当这种修改在网络中以随机的方式发生。考虑共享代码,它将提高你的问题的质量,并将有助于可能的未来读者。
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))
def rot90(x):
    """
    a helper to rotate a 4D tensor applying transpose and flip on it's meshgrid
    tf.image.rot90 throws errors on eager execution. This is a workaround.
    :param x, tf tensor of dim NHWC
    :returns x_r, x rotated by 90 deg along spatial hxw dimension
    """
    n, h, w, c = tf.shape(x)
    x_ind = tf.stack(tf.meshgrid(tf.range(n), h - tf.range(h) - 1, tf.range(w), indexing='ij'))
    x_ind = tf.transpose(x_ind, [1, 3, 2, 0])
    x_r = tf.gather_nd(x, x_ind, batch_dims=0)

    return x_r