我最近遇到了以更大的尺寸保存模型的问题。 我正在使用 tensorflow 1.4
之前,我用过
tf.train.string_input_producer()
和tf.train.batch()
从文本文件加载图像。在培训中,
tf.train.start_queue_runners()
和tf.train.Coordinator()
用于向网络提供数据。在这种情况下,每次我使用
保存模型 saver.save(sess, checkpoint_path, global_step=iters)
只给了我一个小尺寸的文件,即一个名为 model.ckpt-1000.data-00000-of-00001 的文件,只有1.6MB。
现在,我使用
tf.data.Dataset.from_tensor_slices()
将图像提供给输入placeholder
,保存的模型变为290MB。但我不知道为什么。我怀疑张量流saver
也将数据集保存到模型中。如果是这样,如何删除它们以使其变小,并且仅保存网络的权重。
这不是网络依赖,因为我在两个网络中尝试过它们都是这样的。
我用谷歌搜索,但遗憾的是没有看到任何与此问题有关的灵感。 (或者这不是问题,只是我不知道怎么办?)
非常感谢您的任何想法和帮助!
我初始化数据集的方法是:
1.首先生成numpy.array
数据集:
self.train_hr, self.train_lr = cifar10.load_dataset(sess)
初始数据集是numpy.array,例如[8000,32,32,3]
。我将sess
传递给此函数是因为在函数中,我执行了tf.image.resize_images()
并使用sess.run()
生成numpy.array
。返回self.train_hr
和self.train_lr
的形状numpy.array
为[8000,64,64,3]
。
2.然后我创建了数据集:
self.img_hr = tf.placeholder(tf.float32)
self.img_lr = tf.placeholder(tf.float32)
dataset = tf.data.Dataset.from_tensor_slices((self.img_hr, self.img_lr))
dataset = dataset.repeat(conf.num_epoch).shuffle(buffer_size=conf.shuffle_size).batch(conf.batch_size)
self.iterator = dataset.make_initializable_iterator()
self.next_batch = self.iterator.get_next()
3.然后我初始化了网络和数据集,进行了培训并保存了模型:
self.labels = tf.placeholder(tf.float32,
shape=[conf.batch_size, conf.hr_size, conf.hr_size, conf.img_channel])
self.inputs = tf.placeholder(tf.float32,
shape=[conf.batch_size, conf.lr_size, conf.lr_size, conf.img_channel])
self.net = Net(self.labels, self.inputs, mask_type=conf.mask_type,
is_linear_only=conf.linear_mapping_only, scope='sr_spc')
sess.run(self.iterator.initializer,
feed_dict={self.img_hr: self.train_hr, self.img_lr: self.train_lr})
while True:
hr_img, lr_img = sess.run(self.next_batch)
_, loss, summary_str = sess.run([train_op, self.net.loss, summary_op],
feed_dict={self.labels: hr_img, self.inputs: lr_img})
...
...
checkpoint_path = os.path.join(conf.model_dir, 'model.ckpt')
saver.save(sess, checkpoint_path, global_step=iters)
所有sess
都是相同的实例。
答案 0 :(得分:2)
我怀疑您从数据集中创建了张量流常量tf.constant
,这可以解释数据集与图表一起存储的原因。有一个可初始化的数据集,可让您在运行时使用feed_dict
提供数据。它需要配置一些额外的代码,但它可能是您想要使用的。
https://www.tensorflow.org/programmers_guide/datasets
请注意,在Python包装器中自动为您创建常量。以下陈述是等效的:
tf.Variable(42)
tf.Variable(tf.constant(42))
答案 1 :(得分:0)
Tensorflow确实会保存您的数据集。要解决它,让我们理解为什么。
张量流如何工作以及它节省了什么?
简而言之,Tensorflow API允许您通过代码构建计算图,然后对其进行优化。您在图中定义的每个op / variable / constant都在处理张量并且是该图的一部分。这个框架很方便,因为Tensorflow只是构建一个图形,然后框架决定(或指定)计算图形的位置,以便从硬件中获得最大速度,例如,通过在GPU上进行计算。
GPU就是一个很好的例子,因为这是一个很好的例子。从HDD / RAM /处理器向GPU发送数据在时间上是昂贵的。因此,Tensorflow还允许您创建输入生成器,通过排队和管理threads,几乎可以自动管理在所有外围设备之间传输的数据。但是,我从这种方法中获得了很多好处。 请注意,数据集生成的输入也是张量,特别是用作网络输入的常量/变量。。因此,它们是图表的一部分。
保存图表时,我们会保存以下几项内容:
使用数据集时,会保存不可训练变量的值,因此检查点文件会更大。
要更好地理解数据集,请在包文件中查看其实现。
TL; DR - 如何解决问题?
如果没有降低性能,请使用提供字典来提供占位符。不要使用张量来存储数据。这样就不会保存这些变量。
仅保存您要加载的张量(权重,偏差等)。您可以使用.eval()
方法查找其值,将其另存为JSON等,然后通过重新构建图表来加载它。
答案 2 :(得分:0)
我解决了这个问题(不完美,因为我还不知道问题发生在哪里)。相反,我做了一个解决方法,以避免保存大量数据。
我在一个特定的变量列表中定义了一个saver
。该列表仅包含我的图表的节点。在这里,我展示了我的解决方法的一个小例子:
import tensorflow as tf
v1= tf.Variable(tf.random_normal([784, 200], stddev=0.35), name="v1")
v2= tf.Variable(tf.zeros([200]), name="v2")
saver = tf.train.Saver( [v2])
# saver = tf.train.Saver()
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
saver.save(sess,"checkpoint/model_test",global_step=1)
v2是变量列表。或者您可以使用variables_list = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='net')
收集所有节点。