在创建卷积神经网络时,遇到了内存溢出的问题,困扰我比较久的有两个。
1 中间产生的tensor过大导致内存不够
核心错误信息如下:
(1) Resource exhausted: OOM when allocating tensor with shape[4000,256,127,127] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
[[node Conv2D_1 (defined at work55.py:116) ]]
很明显,这里是因为我的张量太大了,所以没有足够的内存可以分配。 这个张量是做前向传播的一个中间量,由输入图片矩阵做卷积得到,核查后发现是我的卷积核太大了(哭)。 卷积核改小以后就可以顺利运行了。
ps:这个格式的内存溢出错误还挺常见的,我在之前也遇到不少。总结一下就是:找到引起溢出的变量,倒推出它产生的原因再考虑修改。
2 TensorFlow变量初始化后占用内存过大
需要初始化的tf变量:
def initialize_parameters():
"""
初始化参数。
卷积核的维度:
[ filter_height, filter_width, in_channel, out_channels ],其中 filter_height 为卷积核高度,filter_width 为卷积核宽度,
in_channel 是图像通道数 ,和 input 的 in_channel 要保持一致,out_channel 是卷积核数量
残差图像作为第一层卷积的原始输入,第一层卷积有8个5×5的卷积核,中间三层的卷积中有256个3×3的卷积核,第五层卷积则有256个3×3的卷积核。
返回:
包含了tensor类型的W1-W5的字典
"""
tf.set_random_seed(4)
W1 = tf.get_variable("W1",[5,5,3,8],initializer=tf.contrib.layers.xavier_initializer(seed=0))
W2 = tf.get_variable("W2",[3,3,8,8],initializer=tf.contrib.layers.xavier_initializer(seed=1))
W3 = tf.get_variable("W3",[3,3,8,8],initializer=tf.contrib.layers.xavier_initializer(seed=2))
parameters={
"W1":W1,
"W2":W2,
"W3":W3,
}
return parameters
init = tf.global_variables_initializer()
sess.run(init)
(这里的W1、W2、W3就是上文提到的初始太大后来被改小的卷积核)
可以看到,程序开始运行后,占了22.5GB的GPU内存,真的贼不合理。初始占据这么大的内存就导致后面我有其他数据进内存的时候内存溢出了。 最初我以为是run后初始变量占空间太大,后来简单算了一下没有那么大,具体什么原因我到现在也不是很清楚,但是这个问题我解决了哈哈哈哈。
添加代码如下:
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
with tf.Session(config=config) as sess:
sess.run(init)
'''
other code
'''
代码的作用在于不会一次性分配GPU内存,而是按需分配,就可以避免一次分配大量内存而后续内存不够的情况。 参考博客: https://www.cnblogs.com/txg198955/p/6734358.html
|