简体   繁体   English

tf.data.Dataset 对象作为 tf.Keras 模型的输入——ValueError

[英]tf.data.Dataset object as input to tf.Keras model -- ValueError

I am attempting to train a simple 3DCNN for action classification on a subset of the kinetics dataset.我正在尝试训练一个简单的 3DCNN 来对动力学数据集的一个子集进行动作分类。 I am passing a tf.data.Dataset.from_generator() object as the input in the call to model.fit().我传递一个 tf.data.Dataset.from_generator() 对象作为调用 model.fit() 的输入。

tensorflow version: r1.12张量流版本:r1.12

The generator that the tf.data.Dataset is initialized from yields a tuple of np.arrays.初始化 tf.data.Dataset 的生成器产生一个 np.arrays 元组。 The first is a pre-processed video with shape (50,45,80,3), the second is the one-hot encoding of the class with shape (22,)第一个是形状为 (50,45,80,3) 的预处理视频,第二个是形状为 (22,)

The code:代码:

import os
import numpy as np
import itertools

import tensorflow as tf
import tensorflow.data as data
from tensorflow.keras.models import Sequential 
from tensorflow.keras.layers import MaxPooling3D, Conv3D, BatchNormalization, Dense 
from tensorflow.keras.layers import Dropout, Activation, Flatten, Input


def train_generator():
    train_dir = '/home/kjd/Storage/kinetics-frames_proc_small'
    classes = os.listdir(train_dir)
    for index, label in enumerate(classes):
        clips = os.listdir(train_dir + '/' + label)
        for clip in clips:
            data = np.load(train_dir + '/' + label + '/' + clip)
            yield data, np.eye(22)[index].astype(int)


EPOCHS = 3
BATCH_SIZE = 32
dataset = data.Dataset.from_generator(train_generator, (tf.int64, tf.int64))



model = Sequential()
model.add(Conv3D(16, (3,3,3), strides=(1,1,1), padding='same', activation='relu',
                 input_shape=(50,45,80,3)))
model.add(Conv3D(32, (3,3,3), strides=(1,1,1), padding='same', activation='relu'))
model.add(MaxPooling3D(pool_size=(2,2,2), strides=(2,2,2)))
model.add(BatchNormalization())
model.add(Conv3D(64, (3,3,3), strides=(1,1,1), padding='same', activation='relu'))
model.add(Conv3D(128, (3,3,3), strides=(1,1,1), padding='same', activation='relu'))
model.add(MaxPooling3D(pool_size=(2,2,2), strides=(2,2,2)))
model.add(BatchNormalization())
model.add(Conv3D(256, (3,3,3), strides=(1,1,1), padding='same', activation='relu'))
model.add(Conv3D(512, (3,3,3), strides=(1,1,1), padding='same', activation='relu'))
model.add(MaxPooling3D(pool_size=(2,2,2), strides=(2,2,2)))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(22, activation='softmax'))


model.compile('adam', 'categorical_crossentropy', metrics=['accuracy'])
model.fit(dataset, batch_size=BATCH_SIZE, epochs=EPOCHS, shuffle=False,
          steps_per_epoch=1000) 

The error:错误:

Traceback (most recent call last):
  File "train.py", line 55, in <module>
    steps_per_epoch=1000)
  File "/home/kjd/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1683, in fit
    shuffle=shuffle)
  File "/home/kjd/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1200, in _standardize_user_data
    class_weight, batch_size)
  File "/home/kjd/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1328, in _standardize_weights
    exception_prefix='input')
  File "/home/kjd/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_utils.py", line 294, in standardize_input_data
    data = [standardize_single_array(x) for x in data]
  File "/home/kjd/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_utils.py", line 294, in <listcomp>
    data = [standardize_single_array(x) for x in data]
  File "/home/kjd/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_utils.py", line 228, in standardize_single_array
    if x.shape is not None and len(x.shape) == 1:
  File "/home/kjd/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/tensor_shape.py", line 745, in __len__
    raise ValueError("Cannot take the length of shape with unknown rank.")
ValueError: Cannot take the length of shape with unknown rank.

It seems tf.keras doesn't like something about the format of my input data.似乎 tf.keras 不喜欢我输入数据的格式。 I'm fairly new to tf/keras and not gleaning a whole lot from this error message though.我是 tf/keras 的新手,虽然没有从这个错误消息中收集到很多东西。 If anyone has any insight into what the problem is, your thoughts would be much appreciated.如果有人对问题有任何见解,您的想法将不胜感激。

I just got stuck with a similar problem trying to distribute my我只是遇到了类似的问题,试图分发我的

<DatasetV1Adapter shapes: <unknown>, types: tf.float32>" dataset using strategy.experimental_distribute_dataset() with tf.distribute.MirroredStrategy() as strategy. I got the same error as above (" raise ValueError("Cannot take the length of shape with unknown rank ValueError: Cannot take the length of shape with unknown rank. ") For anyone who gets stuck with a similar problem, my solution was to use my DatasetV1Adapter dataset and create a new dataset using data.Dataset.from_generator as follows: <DatasetV1Adapter shapes: <unknown>, types: tf.float32>" dataset using strategy.experimental_distribute_dataset() with tf.distribute.MirroredStrategy() as strategy. I got the same error as above (" raise ValueError("Cannot take the length of shape with unknown rank ValueError:无法获取具有未知等级的形状的长度。”)对于遇到类似问题的任何人,我的解决方案是使用我的 DatasetV1Adapter 数据集并使用 data.Dataset.from_generator 创建一个新数据集,如下所示:

        def generator(dataset):
            # dataset of type DatasetV1Adapter 
            for datapoint in dataset:
                yield datapoint

    dataset = tf.data.Dataset.from_generator(generator, (tf.float32), output_shapes=([None, None, None, None]))

dataset_dist = strategy.experimental_distribute_dataset(dataset)

Worked for me!为我工作!

I had this issue recently;我最近遇到了这个问题; you probably need to provide the output_shapes argument:您可能需要提供output_shapes参数:

dataset = data.Dataset.from_generator(train_generator, (tf.int64, tf.int64), output_shapes=(tf.TensorShape([None, None, None, None]), tf.TensorShape([None])))

assuming a 4-dimensional input image and a 1-dimensional output array.假设一个 4 维输入图像和一个 1 维输出数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM