Использование TF Estimator с генератором TFRecord - PullRequest
0 голосов
/ 24 августа 2018

Я пытаюсь создать простой NN, который читает в папке tfrecords.Каждая запись имеет вектор 'mean_rgb' со значением 1024 и метку категории.Я пытаюсь создать простой NN прямой связи, который изучает категории на основе этого векторного признака.

def generate(dir, shuffle, batch_size):
    def parse(serialized):
        features = {
            'mean_rgb': tf.FixedLenFeature([1024], tf.float32),
            'category': tf.FixedLenFeature([], tf.int64)
        }
        parsed_example = tf.parse_single_example(serialized=serialized, features=features)
        vrv = parsed_example['mean_rgb']
        label = parsed_example['category']
        d = dict(zip(['mean_rgb'], [vrv])), label
        return d

    dataset = tf.data.TFRecordDataset(dir).repeat(1)
    dataset = dataset.map(parse)
    if shuffle:
        dataset = dataset.shuffle(8000)
    dataset = dataset.batch(batch_size)
    iterator = dataset.make_one_shot_iterator()
    next = iterator.get_next()
    print(next)
    return next

def batch_generator(dir, shuffle=False, batch_size=64):
    sess = K.get_session()
    while True:
        yield sess.run(generate(dir, shuffle, batch_size))

num_classes = 29
batch_size = 64

yt8m_train = [os.path.join(yt8m_dir_train, x) for x in read_all_file_names(yt8m_dir_train) if '.tfrecord' in x]

yt8m_test = [os.path.join(yt8m_dir_test, x) for x in read_all_file_names(yt8m_dir_test) if '.tfrecord' in x]

feature_columns = [tf.feature_column.numeric_column(k) for k in ['mean_rgb']]

#batch_generator(yt8m_test).__next__()

classifier = tf.estimator.DNNClassifier(
    feature_columns=feature_columns,
    hidden_units=[1024, 1024],
    n_classes=num_classes,
    model_dir=model_dir)

classifier.train(
    input_fn=lambda: generate(yt8m_train, True, batch_size))

Однако я получаю следующую ошибку:

InvalidArgumentError (см.выше для трассировки): вход для изменения формы - тензор с 65536 значениями, но запрошенная форма имеет 64

Я не уверен, почему он видит вход как вектор 64x1024 = 65536 вместо (64, 1024) вектор.Когда я печатаю следующий элемент в генераторе, я получаю

({'mean_rgb': <tf.Tensor: id=23, shape=(64, 1024), dtype=float32, numpy=
array([[ 0.9243997 ,  0.28990048, -0.4130672 , ..., -0.096692  ,
         0.27225342,  0.13346168],
       [ 0.5853526 ,  0.67050666, -0.24683481, ..., -0.6999033 ,
        -0.4100128 , -0.00349384],
       [ 0.49572858,  0.5231492 , -0.53445834, ...,  0.0449002 ,
         0.10582132, -0.37333965],
       ...,
       [ 0.5776026 , -0.07128889, -0.61762846, ...,  0.22194198,
         0.61441416, -0.27355513],
       [-0.01848815,  0.20132884,  1.1023484 , ...,  0.06496283,
         0.29560333,  0.09157721],
       [-0.25877073, -1.9552246 ,  0.10309827, ...,  0.22032814,
        -0.6812989 , -0.23649289]], dtype=float32)>}

, который имеет правильную (64, 1024) форму

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Я полагаю, что проблема заключалась в том, что feature_columns = [tf.feature_column.numeric_column(k) for k in ['mean_rgb']] предполагает, что столбец является скалярным - тогда как на самом деле это вектор 1024.Мне пришлось добавить shape=1024 к вызову numeric_column.Также пришлось удалить существующую контрольную точку сохраненной модели.

0 голосов
/ 25 августа 2018

проблема в том, как работает features_columns, например, у меня была похожая проблема, и я решил, что, изменив форму здесь, это часть моего кода, которая поможет вам понять:

определение features_column:

feature_columns = {
        'images': tf.feature_column.numeric_column('images', self.shape),
    }

затем для создания входных данных для модели:

        with tf.name_scope('input'):
            feature_columns = list(self._features_columns().values())
            input_layer = tf.feature_column.input_layer(
                features=features, feature_columns=feature_columns)

            input_layer = tf.reshape(
                input_layer,
                shape=(-1, self.parameters.size, self.parameters.size,
                       self.parameters.channels))

, если обратить внимание на последнюю часть, которую мне пришлось изменить форму тензора, то -1 означает, что Tensorflow вычисляетразмер партии

...