这将是一个非常简单的问题,但确实引起了我的注意。

我的目的是加载训练有素的TF模型,然后创建一个会话以运行预测/推断,并为我的设备环境评估适当的batch_size。

我准备了两种类型的模型:冻结模型和保存的模型。

对于冻结的模型,我通过.ParseFromString()成功加载并获得了GraphDef,并通过TensorRT优化了GraphDef,但是输入节点的batch_size固定为1(1 * 299 * 299 * 3)。似乎在导出然后冻结模型时无法配置batch_size,并且之后也无法更改,因为它是仅追加的。

对于保存的模型,输入节点的尺寸为?。 (?* 299 * 299 * 3)。似乎它应该能够接受任何大小的批次。但是在加载保存的模型之后,然后输入299 * 299 * 3图像,并出现以下错误:

ValueError: Cannot feed value of shape (299, 299, 3) for Tensor u'input:0', which has shape '(?, 299, 299, 3)'


我试图将轴= 0扩展到输入图像,但仍然出现错误:

InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'import/input' with dtype float and shape [?,299,299,3]

 [[Node: import/input = Placeholder[dtype=DT_FLOAT, shape=[?,299,299,3], _device="/job:localhost/replica:0/task:0/device:GPU:0"]()]]


总的来说,这应该是一个非常简单的问题,但是我不确定如何解决。

任何想法都将受到欢迎。

谢谢,



具有冻结模型的脚本,占位符固定为(1 * 299 * 299 * 3),因此仅接受“ args.batch_size”为1。

    g = ops.Graph()
with g.as_default():
    inp, out = importer.import_graph_def(graph_def=f32_graph, return_elements=['Placeholder','InceptionV3/Logits/SpatialSqueeze'])
    inp = inp.outputs[0]
    out = out.outputs[0]
    print tf.shape(inp)
    if args.image:
        import numpy as np
        func = TestKit.preprocess_func['tensorflow'][args.network]
        img = func(args.image)
        img = np.expand_dims(img, axis = 0)
    batch_input = img
    for i in range(int(args.batch_size)-1):
        batch_input = np.concatenate((batch_input, img), axis=0)
    print len(batch_input)
    gpu_options = cpb2.GPUOptions(per_process_gpu_memory_fraction=0.625)
    with csess.Session(config=cpb2.ConfigProto(gpu_options=gpu_options), graph=g) as sess:
        t0 = time.time()
        for _ in range(2000):
            val = sess.run(out, {inp: batch_input})
            predict = np.squeeze(val)
            top_indices = predict.argsort()[-5:][::-1]
            result = [(i, predict[i]) for i in top_indices]
        t1 = time.time()
        print result
        print 'Duration:', str(t1-t0)




保存的模型的脚本“ input:0”节点为(?* 299 * 299 * 3),但如上所述不能接受任何形状的输入图像。

    with tf.Graph().as_default():
    with tf.Session(graph=tf.Graph()) as sess:
        tf.saved_model.loader.load(sess, ['serve'], './')
        for op in sess.graph.get_operations():
            print str(op.name)

        if args.image:
            import numpy as np
            func = TestKit.preprocess_func['tensorflow'][args.network]
            img = func(args.image)
            img = np.expand_dims(img, axis = 0)
        inp, out = importer.import_graph_def(graph_def=sess.graph.as_graph_def(), return_elements=['input','InceptionV3/Logits/SpatialSqueeze'])
        t0 = time.time()
        for _ in range(1000):
            val = sess.run(out, {'input:0':img})
            predict = np.squeeze(val)
            top_indices = predict.argsort()[-5:][::-1]
            result = [(i, predict[i]) for i in top_indices]
        t1 = time.time()
        print result
        print 'Duration:', str(t1-t0)

最佳答案

我终于解决了问题。
关键是冻结模型将不会更改批处理大小,因为该图是仅追加的,因此一旦使用输入占位符(1 * 299 * 299 * 3)生成原始图,该图就永远不会更改。

最后,我尝试使用输入占位符(无* 299 * 299 * 3)重新生成原始二进制图(二进制.pbtxt)。然后将该二进制图转换为冻结模型,然后冻结模型可以具有尺寸为(?* 299 * 299 * 3)的输入占位符。现在支持批量输入。

谢谢,

关于python - 如何加载经过训练的TensorFlow模型以进行不同批次大小的预测?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49872844/

10-13 04:56