在TensorFlow中导入大型非图像数据集

我有一个大型数据集(300,000个样本 x 33,000个特征),当然无法一次性加载进内存。数据以HDF5格式保存。数据值大多为零(稀疏数据)。它们看起来像这样:

           Attr1    52  52  52  52  52  52  52  52 ...           Attr2    umb umb umb umb umb umb umb umb ...           CellID   TGC-1 TGG-1 CAG-1 TTC-1 GTG-1 GTA-1 CAA-1 CAC-1 ...Acc     Gene                                      ...243485  RP11-.3     0   0   0   0   0   0   0   0 ...237613  FAM138A     0   0   0   0   0   0   0   0 ...186092  OR4F5       0   0   0   0   0   0   0   0 ...238009  RP11-.7     0   0   0   0   0   0   0   0 ...239945  RP11-.8     0   0   0   0   0   0   0   0 ...279457  FO538.2     0   0   0   0   0   0   0   0 ...228463  AP006.2     0   0   0   0   0   0   0   0 ......     ...         ... ... ... ... ... ... ... ...

我已经尝试了以下方法,可以在TensorFlow中加载整个数据集(loompy只是一个在后台使用hdf5的包):

import tensorflow as tfimport numpy as npimport loompy as lpbatch_size = 1000with loompy.connect(filename, 'r') as ds:    ds_shape = (batch_size, ds.shape[0])    ds_dtype = ds[0:1, 0:1].dtype    labels = np.asarray([ds.ca.CellID, ds.ca.Attr1]).T    labels_shape = (batch_size, 1)data_placeholder = tf.placeholder(ds_dtype, ds_shape)labels_placeholder = tf.placeholder(labels[:,1].dtype, labels_shape)dataset = tf.data.Dataset.from_tensor_slices((data_placeholder, labels_placeholder))dataset = dataset.prefetch(batch_size)iterator = dataset.make_initializable_iterator()next_element = iterator.get_next()with tf.Session() as sess:    with loompy.connect(filename, 'r') as ds:        for i in range(0, ds.shape[1], batch_size):            batch = ds[0 : ds_shape[1], i : i + batch_size].T            batch_labels = np.asarray([ds.ca.CellID[i : i + batch_size],                                       ds.ca.Attr1[i : i + batch_size]]).T[:,1]            sess.run(iterator.initializer, feed_dict = {data_placeholder: batch,                       labels_placeholder: batch_labels.reshape(batch_size, 1)})            for _ in range(batch_size):                print(sess.run(next_element))

输出:

(array([0, 0, 0, …, 0, 0, 0], dtype=int32), array([b’52’], dtype=object))

(array([0, 0, 0, …, 0, 0, 0], dtype=int32), array([b’52’], dtype=object))

然而,通过这种方法,我无法将数据分割成训练、测试和评估集。此外,我只能在每个批次内进行洗牌,这通常效果不佳,因为一个批次中的数据通常属于同一类别。

如何处理这种数据,以便能够将它们加载为训练、测试和评估集,并进行洗牌等操作(最好尽可能利用我的TitanX GPU)?


回答:

如果还有人对这个话题感兴趣,以下是我对这个问题所找到的解决方案。最终我选择继续使用Loompy文件格式,因为它与我的工作非常方便(可以查看Loompy的相关信息)。为了将如此大量的信息导入我的模型,我使用了TensorFlow API中tf.data.Datasetfrom_generator()函数。此外,我创建了一个生成器来按需生成数据。

以下是我的输入函数的示例:

import loompy as lpimport tensorflow as tffrom sklearn.model_selection import train_test_splitmodel_input_name = ""input_size = 10000batch_size = 32epochs = 10# 训练、测试和评估集的输入函数def train_input_fn():    return _input_fn('TRAIN')def test_input_fn():    return _input_fn('TEST')def eval_input_fn():    return _input_fn('EVAL')# 通用输入函数def _input_fn(mode = 'TRAIN'):    """        参数            mode : 'TRAIN', 'TEST', 'EVAL'    """    # 一个生成器,用于根据分配给"indices"变量的索引,从给定的文件中生成数据和标签。    # 如果更改标签,请记得更新下面的from_generator()参数,以反映它们的类型。    def gen():        with lp.connect(FILE, 'r') as ds:            if ae:                for i in indices:                    yield {model_input_name: ds[:, i]}, ds[:, i]            else:                for i in indices:                    yield {model_input_name: ds[:, i]}, ds.ca.x_CellType[i]    # 获取训练、测试和评估集的索引    train_idx, test_idx, eval_idx = train_test_set_idx_split(TRAIN_RT, TEST_RT, EVAL_RT)    # 检查条件并将相应的集合分配给"indices"变量    if mode == 'TRAIN':        indices = train_idx    elif mode == 'TEST':        indices = test_idx    elif mode == 'EVAL':        indices = eval_idx    else:        print("错误的模式选择: ", mode)        exit(1)    dataset = tf.data.Dataset.from_generator(gen, ({model_input_name: tf.int64}, tf.int64),                                             output_shapes=({model_input_name: [input_size,]}, []))    # 对数据集进行洗牌、分批、映射、预取和重复。    # 如果需要对数据进行一些预处理,请在上面的单元格中创建你的函数,并在map()函数中调用它。    dataset = dataset.shuffle(buffer_size=batch_size*50)    dataset = dataset.batch(batch_size)    dataset = dataset.map(_reshape_labels)    dataset = dataset.map(_int2float)    # 映射到你需要的其他函数    dataset = dataset.map( ... )    dataset = dataset.prefetch(2)    dataset = dataset.repeat(epochs)    iterator = dataset.make_one_shot_iterator()    return iterator.get_next()# 获取给定数据集的训练、测试、评估索引def train_test_set_idx_split(train_rt, test_rt, eval_rt):    """ 该函数返回给定数据集的训练、测试和评估集的索引。        参数:            train_rt: 训练数据集的比例            test_rt:  测试数据集的比例            eval_rt:  评估数据集的比例        返回:            train_idx: 训练数据集的索引(来自给定数据集)            test_idx:  测试数据集的索引(来自给定数据集)            evel_idx:  评估数据集的索引(来自给定数据集)        注意:            只要(test_rt == evel_rt)为真,该函数就能正确工作。            如果需要(test_rt != evel_rt),则需要更复杂的方法。    """    with lp.connect(FILE, 'r') as ds:        idx = np.array(range(0, ds.shape[1]))    train_idx, test_idx = train_test_split(idx, train_size=train_rt, test_size=test_rt+eval_rt)    test_idx, eval_idx = train_test_split(test_idx, train_size=0.5, test_size=0.5)    return train_idx, test_idx, eval_idx# 根据需要重塑标签def _reshape_labels(data, labels):    return data, tf.reshape(labels, (-1,1))

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

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