如何使用Tensorflow的make_csv_dataset为Keras模型配置数据集管道

我有一个大约200 GB的结构化数据集(CSV特征文件)。我使用make_csv_dataset来创建输入管道。这是我的代码

def pack_features_vector(features, labels):    """将特征打包成单一数组。"""    features = tf.stack(list(features.values()), axis=1)    return features, labelsdef main():        defaults=[float()]*len(selected_columns)    data_set=tf.data.experimental.make_csv_dataset(        file_pattern = "./../path-to-dataset/Train_DS/*/*.csv",        column_names=all_columns,    # all_columns=["col1,col2,..."]        select_columns=selected_columns,   # selected_columns= all_columns的一个子集        column_defaults=defaults,        label_name="Target",        batch_size=1000,         num_epochs=20,        num_parallel_reads=50,    #    shuffle_buffer_size=10000,        ignore_errors=True)    data_set = data_set.map(pack_features_vector)    N_VALIDATION = int(1e3)    N_TRAIN= int(1e4)    BUFFER_SIZE = int(1e4)    BATCH_SIZE = 1000    STEPS_PER_EPOCH = N_TRAIN//BATCH_SIZE    validate_ds = data_set.take(N_VALIDATION).cache().repeat()    train_ds = data_set.skip(N_VALIDATION).take(N_TRAIN).cache().repeat()    # validate_ds = validate_ds.batch(BATCH_SIZE)    # train_ds = train_ds.batch(BATCH_SIZE)    model = tf.keras.Sequential([    layers.Flatten(),    layers.Dense(256, activation='elu'),    layers.Dense(256, activation='elu'),    layers.Dense(128, activation='elu'),      layers.Dense(64, activation='elu'),     layers.Dense(32, activation='elu'),     layers.Dense(1,activation='sigmoid')     ])    model.compile(optimizer='adam',                loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),                metrics=['accuracy'])        model.fit(train_ds,            validation_data=validate_ds,            validation_steps=1,            steps_per_epoch= 1,            epochs=20,            verbose=1            )if __name__ == "__main__":    main()print('训练完成!')

现在,当我执行这段代码时,它在几分钟内就完成了(我认为没有经过整个训练数据),并出现了以下警告:

W tensorflow/core/kernels/data/cache_dataset_ops.cc:798] 调用迭代器没有完全读取被缓存的数据集。为了避免数据集意外截断,部分缓存的内容将被丢弃。这可能发生在你的输入管道类似于 dataset.cache().take(k).repeat() 的情况下。你应该使用 dataset.take(k).cache().repeat() 来代替。

根据这个警告以及训练在几分钟内完成意味着…输入管道配置不正确…请问有人可以指导我,如何纠正这个问题吗?

我的系统GPU是NVIDIA Quadro RTX 6000(计算能力7.5)。

基于其他函数如 experimental.CsvDataset 的解决方案也可以工作。

编辑

通过更改代码避免任何缓存,这个警告消失了,如下所示

    validate_ds = data_set.take(N_VALIDATION).repeat()    train_ds = data_set.skip(N_VALIDATION).take(N_TRAIN).repeat()

但现在的问题是,我得到了零准确率,即使是在训练数据上。我认为这是输入管道的问题。以下是输出。

enter image description here

编辑2

经过一些努力,我通过使用一个略低级但相似的API,CsvDataset,解决了已知问题。但现在,我得到了准确率=1.00,我认为这不太对。第一轮时是0.95,然后在接下来的19轮中是1.00。这是我的最终代码。

def preprocess(*fields):    features=tf.stack(fields[:-1])    # 将Target列的值转换为int以便用于二分类    labels=tf.stack([int(x) for x in fields[-1:]])    return features,labels  # x, ydef main():    # selected_columns=["col1,col2,..."]    selected_indices=[]    for selected_column in selected_columns:        index=all_columns.index(selected_column)        selected_indices.append(index)            print("All_columns长度"+str(len(all_columns)))    print("selected_columns长度"+str(len(selected_columns)))    print("selected_indices长度"+str(len(selected_indices)))    print(selected_indices)    defaults=[float()]*(len(selected_columns))    #defaults.append(int())    print("defaults"+str(defaults))    print("defaults长度"+str(len(defaults)))    FEATURES = len(selected_columns) - 1    training_csvs =  sorted(str(p) for p in pathlib.Path('.').glob("path-to-data/Train_DS/*/*.csv"))    testing_csvs =  sorted(str(p) for p in pathlib.Path('.').glob("path-to-data/Test_DS/*/*.csv"))    training_csvs    testing_csvs    training_dataset=tf.data.experimental.CsvDataset(                training_csvs,        record_defaults=defaults,         compression_type=None,         buffer_size=None,        header=True,         field_delim=',',        # use_quote_delim=True,        # na_value="",        select_cols=selected_indices        )        print(type(training_dataset))    for features in training_dataset.take(1):        print("训练样本在映射前")        print(features)        validate_ds = training_dataset.map(preprocess).take(10).batch(100).repeat()    train_ds = training_dataset.map(preprocess).skip(10).take(90).batch(100).repeat()    validate_ds    train_ds    for features,labels in train_ds.take(1):        print("训练样本")        print(features)        print(labels)        testing_dataset=tf.data.experimental.CsvDataset(                testing_csvs,        record_defaults=defaults,         compression_type=None,         buffer_size=None,        header=True,         field_delim=',',        use_quote_delim=True,        na_value="",        select_cols=selected_indices        )        print(type(testing_dataset))    test_ds = testing_dataset.map(preprocess).batch(100).repeat()    test_ds    for features,labels in test_ds.take(1):        print("测试样本")        print(features)        print(labels)        model = tf.keras.Sequential([                layers.Dense(256,activation='elu'),          layers.Dense(128,activation='elu'),          layers.Dense(64,activation='elu'),          layers.Dense(1,activation='sigmoid')         ])    history = model.compile(optimizer='adam', loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),                            metrics=['accuracy'])        model.fit(train_ds,        validation_data=validate_ds,        validation_steps=20,        steps_per_epoch= 20,        epochs=20,        verbose=1        )        loss, accuracy = model.evaluate(test_ds)    print("测试准确率", accuracy)if __name__ == "__main__":    main()print('训练完成!')

我尝试仅向模型提供一些无用的特征,但仍然得到准确率=1.00或100%。现在哪里出错了?是过拟合等问题吗?


回答:

在代码片段中,你写了

model.fit(train_ds,          validation_data=validate_ds,          validation_steps=1,          steps_per_epoch= 1,          epochs=20,          verbose=1)

steps_per_epoch= 1 是打字错误吗?如果不是,这意味着你只使用一个批次进行训练,这解释了快速训练和低准确率。validation_steps=1 也是一个问题

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注