【问题标题】:TensorFlow - Unable to save checkpoint: Python exit code 139TensorFlow - 无法保存检查点:Python 退出代码 139
【发布时间】:2016-05-20 20:51:38
【问题描述】:

我正在尝试创建和训练用于识别图像中区域的网络。我的网络基于deep learning MNIST tutorial,但是,我忽略了其中一个完全连接的层(暂时)。

我的网络(尺寸反映我正在训练 128 x 128 像素的输入图像):

wConv1 = self.weightVariable([5, 5, 1, 32])
bConv1 = self.biasVariable([32])

x = tf.placeholder(tf.float32, [None, 16384])
yPrime = tf.placeholder(tf.float32, [None, 16384])
xImage = tf.reshape(self.x, [-1, 128, 128, 1])

#Convolutional Layer 1
hConv1 = tf.nn.relu(conv2d(xImage, wConv1) + bConv1)
hPool1 = maxPool(hConv1, 2)

# Convolutional Layer 2
wConv2 = weightVariable([5, 5, 32, 64])
bConv2 = biasVariable([64])

hConv2 = tf.nn.relu(conv2d(hPool1, wConv2) + bConv2)
hPool2 = maxPool(hConv2, 2)

# Fully Connected Layer
wFc1 = weightVariable([32 * 32 * 64, 16384])
bFc1 = biasVariable([16384])

hPool2Flat = tf.reshape(hPool2, [-1, 32 * 32 * 64])
hFc1 = tf.nn.relu(tf.matmul(hPool2Flat, wFc1) + bFc1)

# Dropout layer
keepProb = tf.placeholder(tf.float32)
hFc1Drop = tf.nn.dropout(hFc1, keepProb)

# Readout layer
y = tf.nn.softmax(tf.matmul(hPool2Flat, wFc1) + bFc1)

# Training
crossEntropy = tf.reduce_mean(-tf.reduce_sum(yPrime * tf.log(y + 1e-10), reduction_indices=[1]))
trainStep = tf.train.AdamOptimizer(learningRate).minimize(crossEntropy)

# Evaluation
p = tf.placeholder(tf.float32, [None, 16384])
q = tf.placeholder(tf.float32, [None, 16384])

correctPrediction = tf.equal(p, q)
accuracy = tf.reduce_mean(tf.cast(correctPrediction, tf.float32))

saver = tf.train.Saver(tf.trainable_variables())

# Additional functions used:
def weightVariable(self, shape, name):
    initial = tf.truncated_normal(shape, stddev=0.1, name=name)
    return tf.Variable(initial)

def biasVariable(self, shape, name):
    initial = tf.constant(0.1, shape=shape, name=name)
    return tf.Variable(initial)

def conv2d(self, x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def maxPool(self, x, poolSize):
    return tf.nn.max_pool(x, ksize=[1, poolSize, poolSize, 1], strides=[1, poolSize, poolSize, 1], padding='SAME')

# Saves the current state of the network to disk
def saveNetwork(self, step=None):
    folder = os.path.dirname(self.saverPath)
        if not os.path.isdir(folder):
            os.mkdir(folder)

        if step is None:
            self.saver.save(self.sess, self.saverPath, write_meta_graph=False)
        else:
            self.saver.save(self.sess, self.saverPath, global_step=step, write_meta_graph=False)

我能够很好地初始化和训练网络;我已经运行了 10000 次迭代,监控了进度,并验证了输出图像与我的预期一致。我的问题是我无法在训练结束时或在训练期间的检查点保存模型。当执行保存图形的调用时,python 脚本挂起并在几分钟后以代码 139 退出,据我了解,这与内存不足或尝试访问不可用的内存有关。

我还创建了一个训练良好的单层网络(基于MNIST tutorial)。我可以在检查点和训练完成后保存图表。

我进行了粗略的计算,图形变量应该使用大约 4 GB 的内存,尽管我知道 TensorFlow 确实消耗的内存比预期的要多。我正在运行 Ubuntu 16.04,PC 有 64 GB 的 RAM。在训练和保存期间,该过程在消耗 24 GB 内存时达到峰值(根据资源监视器),这仍然远低于可用量。我还使用 Ubuntu 14.04 复制了这一点。

我尝试了更小的批量大小,希望减少内存占用,甚至每步只有 4 个图像。它仍然无法保存检查点。

我对 TensorFlow 还很陌生,所以我不确定下一步该往哪里看,可以参考一些建议。如您所见,我已将保护程序设置为仅保存训练变量,希望这会减小它尝试保存的文件的大小(这样做将我的简单网络的图形文件的大小从 4 GB 减少到 2 GB )。是不是我试图将太大的文件保存到磁盘(硬盘空间应该不是问题,它保存到的驱动器是 2 TB 硬盘)?尝试写入磁盘时,Python 是否无法处理内存中的大文件?我什至认为这是一个内存问题,因为 Python 以代码 139 退出,我是否走在正确的轨道上?

【问题讨论】:

  • 你能分享一下你的self.weightVariable()/self.biasVariable()/weightVariable()/biasVariable()方法的实现吗?
  • @mrry 是的,我已经编辑了原始帖子以包含我在创建网络时使用的功能。它们也改编自深度学习教程。
  • 好的,这些没有什么可疑之处。图形序列化失败的最可能原因是图形中存储了一些大常量 - 通常来自隐式转换的 numpy 数组。这可能吗?您正在调用什么保存方法,完整的错误消息是什么?
  • @mrry 我在原始帖子中添加了一个类函数,用于在检查点和训练步骤结束时保存网络。当它被调用时,没有错误消息。脚本挂起几分钟,然后 python 控制台打印出“进程完成,退出代码 139”。培训包含在错误和异常处理程序中,但没有一个被触发。我将研究可能被隐式转换的 numpy 数组。关于我应该注意什么有什么建议吗?

标签: python python-3.x tensorflow


【解决方案1】:

您的进程似乎因分段错误而崩溃。 tf.train.Saver.save() 方法调用一些 C++ 代码,将所有变量序列化到一个文件中。这种序列化格式对最大张量有 2GB 的限制(因为它将每个变量序列化到一个 Protocol Buffer 中,它的最大记录大小为 2GB)。您的权重变量wFc1 的大小为 4GB。我怀疑故障发生在this line 附近;它以这种方式崩溃的事实是bug

一种可能的解决方案是对大变量进行分片。例如:

wFc1_0 = weight_variable([32 * 32 * 64, 4096])
wFc1_1 = weight_variable([32 * 32 * 64, 4096])
wFc1_2 = weight_variable([32 * 32 * 64, 4096])
wFc1_3 = weight_variable([32 * 32 * 64, 4096])

# ...

# Readout layer
y = tf.nn.softmax(
    tf.concat(1, [tf.matmul(hPool2Flat, wFc1_0),
                  tf.matmul(hPool2Flat, wFc1_1),
                  tf.matmul(hPool2Flat, wFc1_2),
                  tf.matmul(hPool2Flat, wFc1_3),
                 ]) + bFc1)

这可能不是最有效的分片,所以在这里进行实验是值得的。由于您有大量的类,您可能会发现 TensorFlow 的一些 sampled loss functions(支持分片权重)更有效。

【讨论】:

  • 感谢您的出色解释和建议。我已经离开了一天,但明天会试一试,看看它是否能解决问题。
  • 我尝试实施您的解决方案,但我在设置 y 的行中发现了 ValueError。错误显示“广播的形状不兼容:(?, 65536) 和 (16384,)。”
  • 原来的分片搞错了。更新了答案,现在它应该可以工作了!
  • 我明天会试一试。不过,我现在正试图解决这个问题,并且在执行每个 tf.matmul() 时是否还需要对 hPool2Flat 进行一些索引?否则(对我来说,我可能是错的)看起来每个 wFc1_n 都与 hPool2Flat 的同一子集相乘。
  • 在更正的版本中,整个hPool2Flat 应该与四个单独的变量相乘。您可以将每个wFc1_i 变量视为定义一个全连接层,其中包含wFc1 中1/4 的神经元。由于它是全连接的,每个神经元的输出都是hPool2Flat 中所有值的函数。
猜你喜欢
  • 2021-03-07
  • 1970-01-01
  • 2022-07-05
  • 2021-04-02
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
相关资源
最近更新 更多