关于 tensorflow 如何将自己的数据导入

通过学习书籍我使用过了 minst 数据集,现在我想用自己的数据跑一下神经网络,老师给的数据是在 csv 文件中的,请问各位大神如何导入和使用自己的数据呀,minst 数据包是 TFRecord 数据类型的吗?我可以把自己的数据封装成类似 minst 包类型的吗,因为我觉得使用 minst.train.nextbatch 等 API 特别的方便。神经网络基本搭好了,就差把数据放进去了,求大神帮帮忙(手机码字如果有错误请见谅)


提问人:Oreo.,发帖时间:2018-4-18 19:22:27

很多方式啊 我觉得目前来说你去学习下 pandas 是挺不错的。


Loner,发表于 2018-4-18 19:25:55

今天老师给了一篇全英论文
PANDA:Facilitating Usable AI Development
是这个东西吗


Oreo.(提问人),2018-4-18 19:33:42

tf 中的 minst 数据集用的是单独的导入脚本,所以不一定适用于你的数据。导入 CSV 的具体做法取决于你模型需要的输入格式,常见的一个想法是把数据导入成 numpy array,好处是你不需要安装学习 pandas,而 numpy 是 tf 必需的。当然 pandas 是很强大的,学会是有好处的。举例说明 CSV 导入成两个 numpy array:

import numpy as np
import pandas as pd

# 这段是做一个测试 CSV,没有实际意义。
df = pd.DataFrame (np.arange (15).reshape (5,3), columns=['x1', 'x2', 'y'])
df.to_csv ('test.csv', index=False)

# 读入所有数据,去掉表头(一行)
data = np.genfromtxt ('test.csv', delimiter=",", skip_header=1)
# 除去最后一列,其余都是 features
features = data [:, 0:-1]
# 最后一列是 targets
targets = data [:, -1]

# 输出确认
print (features, targets)

使用 tf.data 的想法也是很好的,冒昧借用这个思路更新一下代码:

import tensorflow as tf
# 读入所有文本数据,去掉表头(一行)
dataset = tf.data.TextLineDataset ('test.csv').skip (1)

def _parse_function (line):
    # 默认空缺数据
    default_val = 0
    # 总列数
    num_cols = 3
    data = tf.decode_csv (line, [[default_val] for i in range (num_cols)])
    # 除去最后一列,其余都是 features
    features = tf.stack (data [0:-1])
    # 最后一列是 targets
    targets = data [-1]
    return features, targets

dataset = dataset.map (_parse_function)
batched_dataset = dataset.batch (2)
# 以下迭代器可以用来输入模型数据
iterator = batched_dataset.make_one_shot_iterator ()

# 以下代码为检验迭代器结果
next_element = iterator.get_next ()
with tf.Session () as sess:
    print (sess.run (next_element))
    print (sess.run (next_element))
    print (sess.run (next_element))

yunhai_luo,发表于 2018-4-19 06:55:13

可以使用最新的 tf.data 来进行数据的导入


周军,发表于 2018-4-19

很好的想法!冒昧借用您的想法更新了一下我的答案代码。


yunhai_luo,2018-4-19 12:37

我是用 pandas 包成 dataset
再丟給 tf.estimator

可以參考官方教學
https://www.tensorflow.org/get_started/premade_estimators


yesseecity,发表于 2018-4-19 08:43:27

用第二个代码成功实现了!!!csv 文件内容为:
Screen Shot 2020-03-30 at 6.47.41 PM

最后测试输出为:

#bacth = 2
(array ([[1, 1],
       [2, 2]]), array ([1, 2]))
(array ([[3, 3],
       [4, 4]]), array ([3, 4]))
(array ([[5, 5],
       [6, 6]]), array ([5, 6]))
(array ([[7, 7],
       [8, 8]]), array ([7, 8]))

谢谢指点!!!:tongue:


2018年4月20日00:49:19

还有一个小点想问一下
我用的还是上面的那个 csv 文件内容

x, y = iterator.get_next ()
with tf.Session () as sess:
    print (sess.run (y))
    print (sess.run (x))

之后的输出是

[1 2]
[[3 3]
[4 4]]

如果我更换 x,y 的输出顺序的话输出结果是

[[1 1]
[2 2]]
[3 4]

这样就表明我的 x 和 y 不是同一组数据的 failure 和 target,请问要怎么解决这种情况呀 :sweat:


2018年4月20日01:07:47

暂时想了一个小想法就是把特征值和标签分开两个 csv 文件中
但这样算上 train validation 和 test 就要 6 个 csv 文件了。。


Oreo.(提问人), 2018-4-19 23:23:57

你得到的结果是正确的。你每执行一次 sess.run (x) 或 sess.run (y) 都是执行了一次 iterator.get_next ()。下面解释你的第一段代码,第二段同理。x, y = iterator.get_next ()

with tf.Session () as sess:
    print (sess.run (y)) # 执行了 iterator.get_next () 相关的一次计算,取出了 [[1, 1], [2, 2]] 和 [1, 2],[1, 2] 是 y 的结果并从 sess.run 返回,x 你没要
    print (sess.run (x)) # 第二次执行了 iterator.get_next () 相关的一次计算,取出了第二组 [[3, 3], [4, 4]] 和 [3, 4],[[3, 3], [4, 4]] 是 x 的结果并从 sess.run 返回,y 你没要

显然,如果是 print (sess.run ((x, y))) 和 print (sess.run ((y, x))),那么结果就是一致的,而且 x 和 y 会是对应的。


yunhai_luo,发表于 2018-4-20 01:32:20

可以啦可以啦,谢谢大牛指点!!!


Oreo.(提问人),发表于 2018-4-20 08:36:34

还有一个小问题! :grimacing:

如果在计算正确率的时候要使用到 dataset 的所有 feature 和 target

validata_feed = {x: dataset_feature, y: dataset_target}
validate_acc = sess.run (accuracy, feed_dict=validate_feed)

那么要怎么才能获得’dataset_feature’和’dataset_target’呢?

用 mnist 来示例,差不多就是这样的

validate_feed = {x: mnist.validation.images,y_: mnist.validation.labels}
test_feed = {x: mnist.test.images, y_: mnist.test.labels}

也不知道自己表达的清不清楚,还请大牛指点一下

把这个问题解决了,感觉自己也能拿数据来跑一下了


我看了一下您第一段代码,好像用第一段代码的话就可以获得所有的 feature 和 target,但是用第一段代码的话就不像第二段代码一样可以获得一个迭代器,同时也能有类似 mnist.next_batch 的功能(只是个人的见解)
那用第二段的方法,可以从 dataset 中获得所有的 feature 和 target 吗?


我看了一下书还有找了一些资料,发现正确率其实不用用到所有的 feature 和 target,只要最后把预测值和 label 放到加到两个不同数组中去比较就可以啦!!


Oreo.(提问者),发表于 2018-4-20 09:41:42

喂一组数据:

x = tf.placeholder (tf.float32, shape=(1, 2))
sess.run (y, feed_dict={x: [[0.5,0.6]]})

喂多组数据:

x = tf.placeholder (tf.float32, shape=(None, 2))
sess.run (y, feed_dict={x: [[0.1,0.2],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})

Tensorflower_攸岚,发表于 2018-4-20 12:49:11

很高兴能帮到你,可惜我不是什么大牛,所以你也别期望太高。

我不是很确定你想问什么,我猜想你是想问拆分训练集和验证集的问题。关于这一点我个人觉得常见做法之一是先用 sklearn.model_selection.train_test_split 拆分原始数据,然后再分别封装成 tf.data.Dataset。就我所知,好像没有很好的直接拆分 tf.data.Dataset 的办法。在这个过程中,既需要你会用 scikit-learn,同时也可能会用到 numpy 相关操作,比如我第一段代码中的一些操作。

这也就说到了关于两个方法的问题,我简单说说自己的感受,第一个方法更加低级一些,代码可能会稍稍复杂一些,但操作更灵活。第二个方法更高级,也就是代码更集成、更直观、更容易理解,但如果你有新的需求就比较麻烦了。除此之外,第二个方法可能还有一个好处(细节我不太懂,所以我不是很确定,如果有错请大家不吝赐教),那就是所有操作都放在了计算图中。第一个方法不论数据有多大,都要真正地读入到 features 和 targets 中,而第二个方法真正的数据操作发生在计算图中,由 tensorflow 核心的 C++ 代码实现,效率会更高。

至于正确率的计算,取决于你的模型和计算图。如果你想要在计算图中计算正确率,就要把相应的 labels/targets 送进去,比如用 Estimator.evaluate。


yunhai_luo,发表于 2018-4-20 13:45:58

这个问题我已经解决了,实验可知 train_label_batch 和 train_feature_batch 是同一组的
现在又在解决权重为 nan 的问题

又有一个问题要麻烦一下大佬了。。。

# 定义数据迭代器
train_iteratior = train_dataset.make_one_shot_iterator ()
train_feature_batch, train_label_batch = train_iteratior.get_next ()

# 计算 y
y = inference (train_feature_batch, weights1, biases1, weights2, biases2)

# 计算交叉熵及其平均值
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits (logits=y, labels=train_label_batch)
cross_entropy_mean = tf.reduce_mean (cross_entropy)

在我计算交叉熵的时候,调用上述tf.nn.sparse_softmax_cross_entropy_with_logits函数
同时会计算 y 和 train_label_batch
但是y = inference (train_feature_batch, weights1, biases1, weights2, biases2)
这样train_label_batchtrain_feature_batch又不是同时调用的,这样的话他们就不是一组batch的 feature 和 labele,这个问题要怎么解决呀。。。


Oreo.(提问者),发表于 2018-4-21 00:08:44

你哪个问题解决了?总之我解释一下吧:
从你现有的部分代码判断,你的计算图中只执行了一次 train_feature_batch, train_label_batch = train_iteratior.get_next (),这样图中其他地方用到的 train_feature_batch 和 train_label_batch 不论几次都是一样且对应的。你可能跟之前你说的 sess.run (y) 和 sess.run (x) 混淆了,那里是算了两次计算图,所以出现了两组 x, y,而这里你是同一次对计算图的计算,并且图中只有一次 train_iteratior.get_next (),图中 train_feature_batch 和 train_label_batch 的引用不是调用计算,我猜应该两者的值应该不变且一致。希望你的实验可以验证我的猜想。


yunhai_luo,发表于 2018-4-21 02:42:10

Panda 是一个 Python 的库。它提供了很多很方便的数据读取,处理,可视化等等的工具。具体可以参考


舟 3332,发表于 2018-5-2 17:52:04