DNNRegressor培训输入fn多个标签

时间:2018-02-05 18:40:08

标签: python tensorflow

我正在尝试实现一个TensorFlow DNNRegressor,它使用一个带有多个标签的张量,但它会因为我不理解的错误而失败。 我在Tensorflow 1.4.1上完成了95%的测试,我刚刚切换到1.5.0 / CUDA 9,但它仍然失败了(你知道,我只是希望:))

作为参考,我使用了boston示例和pandas输入func源代码 https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/input_fn/boston.py https://github.com/tensorflow/tensorflow/blob/r1.5/tensorflow/python/estimator/inputs/pandas_io.py

在下面的要点中,您可以找到完整的python代码,生成的输出,训练数据和(当前未使用的)测试数据。训练数据和测试数据非常小,只是构建代码。 https://gist.github.com/anonymous/c3e9fbe5f5faf373fa230909347318cd

错误信息如下(堆栈跟踪在gist中,我没有在此处发布以避免污染帖子)

  

tensorflow.python.framework.errors_impl.InvalidArgumentError:断言失败:[标签形状必须是[batch_size,20]] [条件x == y不按元素持有:] [x(dnn / head / labels / assert_equal / x:0)=] [20] [y(dnn / head / labels / strided_slice:0)=] [3]        [[Node:dnn / head / labels / assert_equal / Assert / Assert = Assert [T = [DT_STRING,DT_STRING,DT_STRING,DT_INT32,DT_STRING,DT_INT32],summarize = 3,_device =“/ job:localhost / replica:0 /任务:0 /设备:CPU:0“](dnn / head / labels / assert_equal / All / _151,dnn / head / labels / assert_equal / Assert / Assert / data_0,dnn / head / labels / assert_equal / Assert / Assert / data_1,dnn / head / labels / assert_equal / Assert / Assert / data_2,dnn / head / logits / assert_equal / x / _153,dnn / head / labels / assert_equal / Assert / Assert / data_4,dnn / head / labels / strided_slice / _155)]]

input_fn如下

def get_input_fn(dataset,
                 model_labels=None,
                 batch_size=128,
                 num_epochs=1,
                 shuffle=None,
                 queue_capacity=1000,
                 num_threads=1):

    dataset = dataset.copy()

    if queue_capacity is None:
        if shuffle:
            queue_capacity = 4 * len(dataset)
        else:
            queue_capacity = len(dataset)

    min_after_dequeue = max(queue_capacity / 4, 1)

    def input_fn():
        queue = feeding_functions._enqueue_data(
            dataset,
            queue_capacity,
            shuffle=shuffle,
            min_after_dequeue=min_after_dequeue,
            num_threads=num_threads,
            enqueue_size=batch_size,
            num_epochs=num_epochs)

        if num_epochs is None:
            features = queue.dequeue_many(batch_size)
        else:
            features = queue.dequeue_up_to(batch_size)

        assert len(features) == len(dataset.columns) + 1, ('Features should have one '
                                                     'extra element for the index.')

        features = features[1:]
        features = dict(zip(list(dataset.columns), features))

        if model_labels is not None:
            #labels = tf.stack([features.pop(model_label) for model_label in model_labels], 0);
            labels = [features.pop(model_label) for model_label in model_labels]

            return features, labels

        return features

    return input_fn

我能够使用以下输入fn进行训练和预测,但是看起来不适合处理我以后想要用于训练的数据量。 另外,当我将它与evaluate方法一起使用时,它会卡住。

def get_input_fn(dataset,
                 model_labels=None):

    def input_fn():
        features = {k: tf.constant(len(dataset), shape=[dataset[k].size, 1]) for k in model_features}

        if model_labels is not None:
            labels_data = []
            for i in range(0, len(dataset)):
                    temp = []
                    for label in model_labels:
                            temp.append(dataset[label].values[i])
                    labels_data.append(temp)
            labels = tf.constant(labels_data, shape=[len(dataset), len(model_labels)])

            return features, labels
        else:
            return features

    return input_fn

谢谢!

备注: 如果您检查要点中的完整代码,您会注意到要素和标签的数量取决于类别的数量,它是从种子数据动态构建的。 可能我可以切换到使用RNN并将每个纪元映射到一个类别而不是构建那个巨大的矩阵,但目前我专注于让这个测试工作。

1 个答案:

答案 0 :(得分:1)

最后我略微改变了我的方法生成,测试代码已经在prepare.py和train.py中分割,prepare.py将数据写入一些CSV(输入数据和类别)和列车中.py我将输入fn替换为加载那些csv,构建数据集,使用tf.read_csv解析数据集行(加上一些其他东西)。

csv_field_defaults = [[0]] * (1 + len(model_features) + len(model_labels))

def _parse_line(line):
    fields = tf.decode_csv(line, csv_field_defaults)

    # Remove the user id
    fields.pop(0)

    features = dict(zip(model_features + model_labels,fields))
    labels = tf.stack([features.pop(model_label) for model_label in model_labels])

    return features, labels

def csv_input_fn(csv_path, batch_size):
    dataset = tf.data.TextLineDataset(csv_path).skip(1)
    dataset = dataset.map(_parse_line)
    dataset = dataset.shuffle(1000).repeat().batch(batch_size)
    return dataset.make_one_shot_iterator().get_next()

# Initialize tensor flow
tf.logging.set_verbosity(tf.logging.INFO)

# Initialize the neural network
feature_cols = [tf.feature_column.numeric_column(k) for k in model_features]
regressor = tf.estimator.DNNRegressor(feature_columns=feature_cols,
                                      label_dimension=len(model_labels),
                                      hidden_units=[4096, 2048, 1024, 512],
                                      model_dir="tf_model")

我目前能够处理10000条记录,但我需要解析更多数据,希望此实现表现更好

csv_input_fn来自tensorflow示例,而我修改了_parse_line以根据需要处理功能和标签。