【问题标题】:Expected tensorflow model size from learned variables来自学习变量的预期张量流模型大小
【发布时间】:2018-04-29 01:37:44
【问题描述】:

在为图像分类任务训练卷积神经网络时,我们通常希望我们的算法能够学习将给定图像转换为正确标签的过滤器(和偏差)。我有几个模型我试图在模型大小、操作数量、准确性等方面进行比较。但是,从 tensorflow 输出的模型的大小,具体来说是 model.ckpt.data存储图中所有变量的值的文件不是我所期望的。事实上,它似乎大了三倍。

为了直接解决问题,我将基于this Jupyter 笔记本提出问题。下面是定义变量(权重和偏差)的部分:

# Store layers weight & bias
weights = {
# 5x5 conv, 1 input, 32 outputs
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32]),dtype=tf.float32),
# 5x5 conv, 32 inputs, 64 outputs
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64]),dtype=tf.float32),
# fully connected, 7*7*64 inputs, 1024 outputs
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024]),dtype=tf.float32),
# 1024 inputs, 10 outputs (class prediction)
'out': tf.Variable(tf.random_normal([1024, num_classes]),dtype=tf.float32)
}

biases = {
'bc1': tf.Variable(tf.random_normal([32]),dtype=tf.float32),
'bc2': tf.Variable(tf.random_normal([64]),dtype=tf.float32),
'bd1': tf.Variable(tf.random_normal([1024]),dtype=tf.float32),
'out': tf.Variable(tf.random_normal([num_classes]),dtype=tf.float32)
}

为了在训练过程结束时保存模型,我添加了几行代码:

# Save the model
save_path = saver.save(sess, logdir+"model.ckpt")
print("Model saved in file: %s" % save_path)

将所有这些变量加起来我们希望得到一个大小为 12.45Mb 的 model.ckpt.data 文件(我通过计算我们的模型学习的浮点元素的数量和然后将该值转换为兆字节)。但! .data 文件保存为 39.3Mb。这是为什么呢?

我对更复杂的网络(ResNet 的一种变体)采用了相同的方法,并且我预期的 model.data 大小也比实际 .data 文件的大小小约 3 倍。

所有这些变量的数据类型都是float32。

【问题讨论】:

    标签: python tensorflow jupyter-notebook conv-neural-network


    【解决方案1】:

    将所有这些变量加起来,我们希望得到一个大小为 12.45Mb 的 model.ckpt.data 文件

    传统上,大部分模型参数都在第一个全连接层,在本例中为wd1。仅计算其大小会产生:

    7*7*128 * 1024 * 4 = 25690112
    

    ...或25.6Mb。注意4 系数,因为变量dtype=tf.float32,即4 每个参数的字节数。其他层也对模型大小有影响,但影响不大。

    如您所见,您对12.45Mb 的估计有点偏离(您是否使用了每个参数 16 位?)。检查点还存储一些一般信息,因此开销约为 25%,这仍然很大,但不是 300%。

    [更新]

    正如已澄清的那样,有问题的模型实际上具有形状为[7*7*64, 1024] 的 FC1 层。所以上面计算的大小确实应该是12.5Mb。这让我更仔细地查看了保存的检查点。

    检查后,我注意到我最初错过的其他大变量:

    ...
    Variable_2 (DT_FLOAT) [3136,1024]
    Variable_2/Adam (DT_FLOAT) [3136,1024]
    Variable_2/Adam_1 (DT_FLOAT) [3136,1024]
    ...
    

    Variable_2 正好是 wd1,但 Adam 优化器还有 2 个副本。这些变量由the Adam optimizer 创建,它们被称为,并为所有可训练变量保存mv 累加器。现在总大小是有意义的。

    您可以运行以下代码来计算图形变量的总大小 - 37.47Mb

    var_sizes = [np.product(list(map(int, v.shape))) * v.dtype.size
                 for v in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES)]
    print(sum(var_sizes) / (1024 ** 2), 'MB')
    

    所以开销实际上很小。额外的大小是由于优化器造成的。

    【讨论】:

    • 哦!谢谢。不,我使用的是 32 位,但我使用的是“7*7*64*1024*4”。我的错。
    • 我已经更新了我的号码(见编辑 1)。我的问题中描述的问题仍然存在。
    • @karl71 你确定你保存的是同一个模型吗?正如你最初描述的那样,我刚刚获得了 39Mb
    • 抱歉给您带来了困惑。我的问题和我一开始描述的完全一样。我的错是我最初添加的权重和偏差代码与 Jupyter 笔记本的代码不匹配(它来自另一个)。所以,确实 .data 文件大小是 39Mb,但我说预期的 .data 文件应该是 12.5Mb 时也是正确的。 (基本上你上面的答案是使用我在问题正文中错误添加的数据)。很抱歉造成混乱。
    • @karl71。知道了谢谢。我已经找到原因了,看我的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 2017-11-22
    • 2021-09-07
    • 2022-01-14
    • 2021-01-18
    • 2018-04-11
    • 1970-01-01
    相关资源
    最近更新 更多