tensorflow 导入数据(3)

1、概述

从文件读取数据时,往往是需要数据转换时,尤其对于多维数据,在使用文件形式进行存储时,除了tfrecord文件格式化,其他的文件的存储都显得无能为力。所以真正从文件读入的数据需要经过转换之后才能够使用。同样在tensorflow这种以小批次进行梯度下降的框架中,需要打乱数据以及对数据进行batch处理,本文主要讨论这些问题。

2、使用Dataset.map() 预处理数据

Dataset.map(f) 转换通过将指定函数 f 应用于输入数据集的每个元素来生成新数据集。此转换基于 map() 函数(通常应用于函数式编程语言中的列表和其他结构)。函数 f 会接受表示输入中单个元素的 tf.Tensor 对象,并返回表示新数据集中单个元素的 tf.Tensor 对象。此函数的实现使用标准的 TensorFlow 指令将一个元素转换为另一个元素。

下面以nlp的word-embeding为例来说明这个情况,在我们存储的原始预料中包含一些关键词,并且包含这些关键词对应的id,我们可以使用下面代码来看一下数据的基本形态:

# 从CSV文件中读取数据
import pandas as pd
data = pd.read_csv('cutword_ths.csv',header=None,delimiter=' ',names=['id','text'])
data.head()

输出结果如下图所示:

tensorflow 导入数据(3)_第1张图片

我们可以尝试使用dataSet读取文本文件的方式读取一下这个文件,具体代码请参考如下:

# 从文本文件中读取数据
dataset = tf.data.TextLineDataset('cutword_ths.csv')
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
with tf.Session() as sess:
    value = sess.run(next_element)
    print(value)

输出结果如下图所示:

很明显这个结果是非结构化数据,所有的数据都是以文本流的形式读入到文件当中的,此时我们可以使用map方法将其转化成结构化数据,请参考下面代码:

# 从文本文件中读取数据
def _parse_csv(line):
    FIELD_DEFAULTS = [[0], ['']]
    fields = tf.decode_csv(line,FIELD_DEFAULTS,name=None,field_delim=' ')
    features = dict(zip(COLUMNS,fields))
    return features
COLUMNS = ['id', 'text']
dataset = tf.data.TextLineDataset('cutword_ths.csv').skip(1)
dataset=dataset.map(_parse_csv)
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
with tf.Session() as sess:
    value = sess.run(next_element)
    print(value['id'],value['text'].decode('utf-8'))

输出结果如下图所示:

但此时依然不是一个可进入tensorflow进行训练的数据,那么需要对数据进行进一步的处理方式。此时可以对输入数据使用tf.py_func() 进行进一步处理。

3、tf.py_func()嵌入Python数据

为了确保性能,我们建议您尽可能使用 TensorFlow 指令预处理数据。不过,在解析输入数据时,调用外部 Python 库有时很有用。为此,请在 Dataset.map() 转换中调用 tf.py_func() 指令。

3.1 关于py_func()

py_func()的语法定义如下:

tf.py_func(
    func,
    inp,
    Tout,
    stateful=True,
    name=None
)

该函数将一组ndarray类型的数据作为输入,并返回一组ndarray的数据,主要用于在tensorflow的张量处理中使用python中的库函数,参数含义如下:

  • func: 处理数据的python函数名
  • inp: 函数的输入的张量列表
  • Tout:输出值的数据类型 列表
  • stateful: 布尔值,指名函数是否有状态
  • name: 在graph中的标识名称。

请参照下面示例代码:

# 从文本文件中读取数据
def _word_embed(features):
    maxlen =10 
    features=features.decode('utf-8')
    padding = ''
    train_sentences = []
    embeddingUnknown = [0 for i in range(100)]
    labels = []
    tag = features.split(',')
   
    if len(tag)>maxlen:
            tag = tag[0:maxlen]
    else:
            tag.extend([padding]*(maxlen-len(tag)))
    train_sentence = []
    for word in tag:
        if word in model.wv.vocab:
                train_sentence.append(model.wv[word])
        else:
                train_sentence.append(embeddingUnknown)
    return np.array(train_sentence,dtype=np.float32)
def _parse_csv(line):
    FIELD_DEFAULTS = [[0], ['']]
    fields = tf.decode_csv(line,FIELD_DEFAULTS,name=None,field_delim=' ')
    features = dict(zip(COLUMNS,fields))
    ids=features.pop('id')
    y = tf.py_func(_word_embed,[features['text']], [tf.float32])
    return y
COLUMNS = ['id', 'text']
dataset = tf.data.TextLineDataset('cutword_ths.csv').skip(1)
dataset=dataset.map(_parse_csv)
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
with tf.Session() as sess:
    value = sess.run(next_element)
    print(value[0].shape)

上面的代码比较复杂,主要是将句子转化为词向量。输出结果如下图所示,因为词向量是一个100维的矩阵,所以这里只输出了他的形状:

4、数据批量化

很多时候我们需要对一个批次的数据进行统一的训练,所以数据的批量化就变得十分的重要。如果我们已经构建了数据集(DataSet)那么批量化的工作也非常简单,请参照如下代码

dataset = tf.data.TextLineDataset('cutword_ths.csv').skip(1)
dataset=dataset.map(_parse_csv)
dataset = dataset.batch(4)
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
with tf.Session() as sess:
    value = sess.run(next_element)
    print(value[0].shape)

输出结果如下图所示:

 

 

 

你可能感兴趣的:(机器学习与人工智能,新版tensorflow)