Python 在Tensorflow 2.0中翻转和旋转张量(U形网络内)会耗尽内存。如何做好这件事?
我在Tensorflow 2.0(和tf.keras)中实现了一个简单的稠密U网来进行语义分割。 在每个密集块的末尾,我想随机旋转和/或翻转张量(只是为了实验)。图像的初始大小为256x256。在我想要执行翻转/旋转的时刻,张量始终具有C=5个通道(即,开始时的形状=[?,256256,5](NHWC),在执行池时减少H&W,但C始终为5,批大小为N=8)。因此,张量并不是很大 需要澄清的是:请注意,我的目标不是进行扩充,而是 分析中间特征映射受损时的网络行为 轻微的方向变化。类似的想法也曾被研究过 翻转/旋转内核或特征图(Gao等人,2017, 用于密集预测的高效不变CNN,arXiv:1711.09064) 我的第一次尝试是将其作为一个函数来实现: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)。因此,张量并不是很大 需要澄清的是:请注意,我的目标不是进行扩充,而是 分析中间特征映射受损时的网络行为 轻微的方向变化。类似的想法也曾被研
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
用作Pythonbool
。
使用渴望执行或用@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