在TensorFlow中运行不同批处理大小的保存模型的最佳方法是什么?



我训练了batch_size为128的TensorFlow存储库中的Cifar10示例模型,它工作得很好。然后我冻结了graph,并设法用c++运行它,就像他们在c++标签图像示例中所做的那样。

唯一的问题是,我必须人为地生成形状[128,image_height, image_width, channels]的张量来用c++对单个图像进行分类,因为保存的模型期望在一批中输入128个样本,因为这是来自队列的样本数量。

我尝试用batch_size = 1训练Cifar10示例,然后当我用c++运行模型时,我设法逐个分类示例,但这似乎不是一个很好的解决方案。我也尝试手动改变张量形状在保存的图形文件,但它没有工作。

我的问题是,用固定的批大小(如32、64、128等)训练模型,然后保存模型,以便它可以与任意长度的批大小一起使用,最好的方法是什么?如果这是不可能的,那么如何保存模型,以便能够逐个对样本进行分类。

听起来问题是TensorFlow将批大小"烘焙"到图中的其他张量(例如,如果图中包含一些张量ttf.shape(t),其形状取决于批大小,则批大小可能作为常量存储在图中)。解决方案是稍微改变你的程序,以便tf.train.batch()返回具有可变批大小的张量。

tf.train.batch()方法接受tf.Tensor作为batch_size参数。也许为可变大小的批修改程序的最简单的方法是为批大小定义一个占位符:

# Define a scalar tensor for the batch size, so that you can alter it at
# Session.run()-time.
batch_size_tensor = tf.placeholder(tf.int32, shape=[])
input_tensors = tf.train.batch(..., batch_size=batch_size_tensor, ...)

这将防止批大小被烘烤到你的GraphDef中,所以你应该能够在c++中提供任何批大小的值。但是,这种修改需要您在每一步都提供一个批处理大小的值,这有点繁琐。

假设您总是希望以批大小128进行训练,但保留以后更改批大小的灵活性,当提供替代值时,您可以使用tf.placeholder_with_default()指定批大小应该为128:

# Define a scalar tensor for the batch size, so that you can alter it at
# Session.run()-time.
batch_size_tensor = tf.placeholder_with_default(128, shape=[])
input_tensors = tf.train.batch(..., batch_size=batch_size_tensor, ...)

在图中需要固定批处理大小的原因是什么?

我认为一个好方法是建立一个具有可变批大小的图-通过将None作为第一个维度。在训练期间,您可以将批大小标志传递给数据提供程序,以便它在每次迭代中提供所需的数据量。

在模型被训练之后,您可以使用tf.train.Saver()导出图,它导出元图。为了进行推理,您可以加载导出的文件并使用任意数量的示例进行评估-也只是一个。
注意,这与冻结的图形不同。

最新更新