将 TF Estimator 与 TFRecord 生成器结合使用

Using TF Estimator with TFRecord generator

我正在尝试创建一个在 tfrecords 文件夹中读取的简单神经网络。每条记录都有一个 1024 值 'mean_rgb' 向量和一个类别标签。我正在尝试创建一个简单的前馈神经网络来学习基于这个特征向量的类别。

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 (see above for traceback): Input to reshape is a tensor with 65536 values, but the requested shape has 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) 形状

问题出在 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 计算出批量大小

我认为问题在于 feature_columns = [tf.feature_column.numeric_column(k) for k in ['mean_rgb']] 假定该列是标量 - 而实际上它是 1024 向量。我必须将 shape=1024 添加到 numeric_column 调用中。还必须删除现有的检查点保存模型。