如何在 Keras / Tensorflow 中将(无,)批量维度重新引入张量?

Posted

技术标签:

【中文标题】如何在 Keras / Tensorflow 中将(无,)批量维度重新引入张量?【英文标题】:How to reintroduce (None, ) batch dimension to tensor in Keras / Tensorflow? 【发布时间】:2019-08-17 22:18:19 【问题描述】:

我正在尝试使用与 Google 机器学习引擎兼容的 Keras 创建 tensorflow 模型。我有一个现有的训练有素的 Keras 模型,它采用向量浮点输入。我在现有模型的前面引入了一个字符串向量输入层。这将传递要预处理的字符串。我正在尝试使用 Lambda 层预处理图像数据。在预处理时,为了解码字符串 jpeg 数据,我需要从张量中删除批量维度。预处理后,我需要重新引入“无”批次维度。这就是我面临的问题。似乎没有办法重新引入“无”作为批次维度。 Google ML Engine 要求批次维度在整个模型中一直是未知的。

张量流版本:1.12 Keras 版本:2.2.4 操作系统:Debian Linux(VM 实例) Python 版本:2.7

我尝试过: 1. 使用 [None,299,299,3] 和 [-1,299,299,3] 进行 Reshape()。两者都不能按要求工作

    tf.reshape 如上。不起作用。
img_height=299
img_width=299
inputs = Input(shape=[1],dtype=tf.string)
inputs_inter1 = Lambda(preprocess_input, output_shape=(img_height,img_width,3))(inputs)
print(inputs_inter1.shape)

print("Combining with string vector input")
combine_out = trainedmodel(inputs_inter1)     
Combinedmodel = Model(inputs,combine_out)
input_tensor = Combinedmodel.inputs[0]
output_tensor = Combinedmodel.outputs[0]
print("Inputs: "+str(input_tensor))
print("Outputs: "+str(output_tensor))
def preprocess_input(x):

    import tensorflow as tf

    x=tf.reshape(x,())
    x = tf.image.decode_jpeg(x,channels=3)
    x = tf.image.resize_images(x,(299,299))
    x = tf.cast(x, tf.float32)
    x = tf.math.divide(x, 255.0)
    x = tf.math.subtract(x, 0.5)
    x = tf.math.multiply(x, 2.0)
    x = tf.expand_dims(x,0)    
return x

预期结果:

输入:张量("input_1_1:0", shape=(?, 1), dtype=string)

输出:Tensor("model_2/model_1/dense_2/Softmax:0", shape=(?, 8), dtype=float32)

实际结果:

输入:张量("input_1_1:0", shape=(?, 1), dtype=string)

输出:Tensor("model_2/model_1/dense_2/Softmax:0", shape=(1, 8), dtype=float32)

【问题讨论】:

【参考方案1】:

回答我自己的问题。

诀窍是创建一个具有所需尺寸 [None,299,299,3] 的新占位符,将预处理的张量复制到其中并从 Lambda 函数/层返回该占位符。

def preprocess_input(x):

    import tensorflow as tf

    x=tf.reshape(x,())
    x = tf.image.decode_jpeg(x,channels=3)
    x = tf.image.resize_images(x,(299,299))
    x = tf.cast(x, tf.float32)
    x = tf.math.divide(x, 255.0)
    x = tf.math.subtract(x, 0.5)
    x = tf.math.multiply(x, 2.0)

    x = tf.placeholder_with_default(x,[None,299,299,3])

    return x

tf.placeholder_with_default的用法可以在这里找到:https://www.tensorflow.org/api_docs/python/tf/placeholder_with_default

预计到达时间: 最新的 Tensorflow 2.0 具有向后兼容的占位符和默认功能。可以短期使用。

tf.compat.v1.placeholder_with_default

【讨论】:

唉,但 tf. placeholder_with_default() 现在已被 TF2.0 弃用。 @Hephaestus 感谢您的信息。编辑答案以包括 TF2.0 向后兼容功能。

以上是关于如何在 Keras / Tensorflow 中将(无,)批量维度重新引入张量?的主要内容,如果未能解决你的问题,请参考以下文章

在 keras 中将“learning_phase”用于 tensorflow 后端?

如何在 Keras 中将顺序模型添加到预训练模型?

Keras 2.3.0 发布:支持TensorFlow 2.0!!!!!

在 Keras 中将变压器输出连接到 CNN 输入的问题

如何在 Tensorflow 中从 tf.keras 导入 keras?

如何在训练 tensorflow.keras 期间替换损失函数