tensorflow - 转换为张量后,参差不齐的张量没有 len()

标签 tensorflow keras tensorflow2.0 tf.keras ragged-tensors

我正在对具有可变维度的图像堆栈训练深度学习模型。 (Shape = [Batch, None, 256, 256, 1]),其中 None 可以是可变的。

我使用 tf.RaggedTensor.merge_dimsions(0,1) 将参差不齐的张量转换为 [None, 256, 256, 1] 的形状以运行预训练的 keras CNN 模型。

但是,使用 KerasLayer API 会导致以下错误:TypeError: the object of type 'RaggedTensor' has no len()

当我在 KerasLayer 外部应用 .merge_dimsions 并将张量传递给相同的预训练模型时,我没有收到此错误。

import tensorflow as tf

# Synthetic Data Pipeline
def synthetic_gen():
  varShape = tf.random.uniform((), minval=1, maxval=12, dtype=tf.int32)
  image = tf.random.normal((varShape, 256, 256, 1))
  image = tf.RaggedTensor.from_tensor(image, ragged_rank=1)
  yield image

ds = tf.data.Dataset.from_generator(synthetic_gen, output_signature=(tf.RaggedTensorSpec(shape=(None, 256, 256, 1), dtype=tf.float32, ragged_rank=1)))
ds = ds.repeat().batch(8)
print(next(iter(ds)).shape)

# Build Model
inputs = tf.keras.Input(
    type_spec=tf.RaggedTensorSpec(
        shape=(8, None, 256, 256, 1), 
        dtype=tf.float32, 
        ragged_rank=1))

ResNet50 = tf.keras.applications.ResNet50(
    include_top=True, 
    input_shape=(256, 256, 1),
    weights=None)

def merge(x):
  x = x.merge_dims(0, 1)
  return x
x = tf.keras.layers.Lambda(merge)(inputs)
merged_inputs = x
# x = ResNet50(x) # Uncommenting this will result in `model` producing an error when run for inference.

model = tf.keras.Model(inputs, x)

# Run inference
data = next(iter(ds))
model(data).shape # Will be an error if ResNet50 is used

这是一个演示问题的 colab notebook。 https://colab.research.google.com/drive/1kN78mf4_oNqxWOluV054NlqmakC5msli?usp=sharing

最佳答案

不确定以下答案或解决方法对于复杂的网络设计是否稳定。但这里有一些提示。你得到的原因

Ragged Tensors have no len()

是因为 ResNet 模型,因为它需要 tensor 而不是 ragged_tensor。不过,我不确定 ResNet(weights=None) 是否能够直接采用 ragged_tensor。因此,如果我们可以在 ResNet 被馈送之前转换参差不齐的数据,也许它就不会提示了。下面是完整的工作代码。但请注意,可能存在一些有效的方法。


数据

import tensorflow as tf

# Synthetic Data Pipeline
def synthetic_gen():
  varShape = tf.random.uniform((), minval=1, maxval=12, dtype=tf.int32)
  image = tf.random.normal((varShape, 256, 256, 1))
  image = tf.RaggedTensor.from_tensor(image, ragged_rank=1)
  yield image

ds = tf.data.Dataset.from_generator(synthetic_gen, 
                                    output_signature=(tf.RaggedTensorSpec(
                                        shape=(None, 256, 256, 1), 
                                        dtype=tf.float32, ragged_rank=1
                                        )
                                    )
                                )
ds = ds.repeat().batch(8)

基本模型

# Build Model
inputs = tf.keras.Input(
    type_spec=tf.RaggedTensorSpec(
        shape=(8, None, 256, 256, 1), 
        dtype=tf.float32, 
        ragged_rank=1))

ResNet50 = tf.keras.applications.ResNet50(
    include_top=True, 
    input_shape=(256, 256, 1),
    weights=None)

def merge(x):
  x = x.merge_dims(0, 1)
  return x

衣衫褴褛的模特

在这里,我们将 ragged_tensor 转换为 tensor,然后再将数据传递给 ResNet

class RagModel(tf.keras.Model):
    def __init__(self):
        super(RagModel, self).__init__()
        # base models 
        self.a = tf.keras.layers.Lambda(merge)
        # convert: tensor = ragged_tensor.to_tensor()
        self.b = tf.keras.layers.Lambda(lambda x: x.to_tensor())
        self.c = ResNet50
    
    def call(self, inputs, training=None, plot=False, **kwargs):
        x = self.a(inputs)
        x = self.b(x) if not plot else x
        x = self.c(x)
        return x
    
    # a helper function to plot 
    def build_graph(self):
        x = tf.keras.Input(type_spec=tf.RaggedTensorSpec(
            shape=(8, None, 256, 256, 1),
            dtype=tf.float32, ragged_rank=1)
        )
        return tf.keras.Model(inputs=[x],
                              outputs=self.call(x, plot=True))
   
x_model = RagModel()

运行

data = next(iter(ds)); print(data.shape)
x_model(data).shape 
(8, None, 256, 256, 1)
TensorShape([39, 1000])

情节

tf.keras.utils.plot_model(x_model.build_graph(), 
              show_shapes=True, show_layer_names=True)

enter image description here

x_model.build_graph().summary()

Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         [(8, None, 256, 256, 1)]  0         
_________________________________________________________________
lambda_2 (Lambda)            (None, 256, 256, 1)       0         
_________________________________________________________________
resnet50 (Functional)        (None, 1000)              25630440  
=================================================================
Total params: 25,630,440
Trainable params: 25,577,320
Non-trainable params: 53,120
_________________________________________________________________

关于tensorflow - 转换为张量后,参差不齐的张量没有 len(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68638911/

相关文章:

python - TensorFlow: TypeError: int() 参数必须是字符串、类字节对象或数字,而不是 'NoneType'

python - 使用 TF 2.0 将 saving_model 转换为 TFLite 模型

tensorflow - 在v1.0+ 中使用reuse_variables() 有什么危险吗?

python - 使用张量计算错误值的梯度下降

python - 为什么隐藏深层的输出对于某些维度具有零方差?

python - 用于 conv2d 和手动加载图像的 Keras input_shape

python - 尝试从图像中提取补丁并获取 "UnimplementedError: Only support ksizes across space"

Python Beam 无法 pickle/dill 大型 Tensorflow 模型

tensorflow - keras 以不同的学习率恢复训练

python - TensorFlow 数据不适用于多输入 keras 模型