Tensorflow读取数据的4种方式(8)---《深度学习》

转载:Tensorflow从文件读取数据

TensorFlow程序读取数据一共有3种方法:

  • 供给数据(Feeding): 在TensorFlow程序运行的每一步, 让Python代码来供给数据。
  • 从文件读取数据: 在TensorFlow图的起始, 让一个输入管线从文件中读取数据。
  • 预加载数据: 在TensorFlow图中定义常量或变量来保存所有数据(仅适用于数据量比较小的情况)。

使用Tensorflow训练神经网络模型,首先要读取数据,宝宝参照网上几篇博客,琢磨出几种Tensorflow从文件读取数据的办法,实际上办法挺多的,怎么开心怎么来。比如可以在一个文本里面写入图片数据的地址和label,用tensorflow的read_file()可以读入图片;也可以将图片(比如图片的大小是3*32*32,其中3是通道)和label值直接存在CSV文件或者TXT文件,下面详细说明。
重点内容
(1)从字典结构的数据文件读取
(2)从bin file读入
(3)从CSV (TXT)中读取
(4)从原图读取

1.从字典结构的数据文件读取
(1)字典结构的数据文件
a).上一篇博客有提到如何得到字典结构的数据文件,即如何将自己图片以字典结构存储为数据文本
博客链接:
http://blog.csdn.net/zengxyuyu/article/details/53240463
b).cifar10数据有三种版本,分别是MATLAB,Python和bin版本
数据下载链接:
http://www.cs.toronto.edu/~kriz/cifar.html
其中Python版本的数据即是以字典结构存储的数据
(2)读入
用pickle来load字典结构的数据
代码如下:

import pickle as p#记得导入pickle,用它来加载数据
import os
import tensorflow as tf


filename = os.path.join("data","contact")#我把数据文本放在项目下的data文件夹下
X = None
Y = None
with open(filename, 'rb')as f:
    #从字典结构的数据文本加载数据,加载出来的数据保留了字典结构
    datadict = p.load(f)
    #获得所有的图像数据,是个6000*3*32*32的一维数组
    X = datadict['data']
    #获得所有图像的label,是个6000大小的一维数组
    Y = datadict['labels']
    print ("data数据X数组的大小:", X.shape)
    #将6000*3*32*32一维数组转换为(6000,3*32*32)的二维数组
    X = X.reshape(6000, -1)
#将X加入tf队列
valuequeue = tf.train.input_producer(X,shuffle=False)
valuelabel = tf.train.input_producer(Y,shuffle=False)
#每次出队一个
value = valuequeue.dequeue()
label = valuelabel.dequeue()    
#label是字符串类型的,需要转成tf.int32类型
result.label = tf.string_to_number(label,tf.int32)
#Convert from [depth, height, width] to [height, width, depth].
#value存入的时候就是数组,所以取出来就是数组,没必要像label从字符串转,现在reshape3*32*32的三维矩阵
image = tf.reshape(value,[result.depth, result.height, result.width])
result.uint8image = tf.transpose(image, [1, 2, 0])

 
 

2.从bin file读入
在官网的cifar的例子中就是从bin文件中读取的。bin文件需要以一定的size格式存储,比如每个样本的值占多少字节,label占多少字节,且这对于每个样本都是固定的,然后一个挨着一个存储。这样就可以使用tf.FixedLengthRecordReader 类来每次读取固定长度的字节,正好对应一个样本存储的字节(包括label)。并且用tf.decode_raw进行解析。

(1)制作bin file
如何将自己的图片存为bin file,可以看看下面这篇博客,这篇博客使用C++和opencv将图片存为二进制文件:
http://blog.csdn.net/code_better/article/details/53289759
(2)从bin file读入
下面代码摘自cifar10_input.py。在用tf.decode_raw(注意decode时使用的数据格式最好与存储是的相同)得到record_bytes后,用tf.slice抽取里面的内容,第二个输入参数表示从第几个字节开始抽取,第三个参数表示抽取的字节数。代码中的reshape是根据图片存储是的shape格式有关,具体问题具体分析。

import tensorflow as tf
image_bytes = result.height * result.width * result.depth
record_bytes = label_bytes + image_bytes
#record_bytes为3073
reader = tf.FixedLengthRecordReader(record_bytes=record_bytes)
#每次读取的大小为3073
result.key, value = reader.read(filename)

  # Convert from a string to a vector of uint8 that is record_bytes long.
  record_bytes = tf.decode_raw(value, tf.uint8)

  # The first bytes represent the label, which we convert from uint8->int32.
  label = tf.cast(
      tf.slice(record_bytes, [0], [label_bytes]), tf.int32)

  # The remaining bytes after the label represent the image, which we reshape
  # from [depth * height * width] to [depth, height, width].
  depth_major = tf.reshape(tf.slice(record_bytes, [label_bytes], [image_bytes]),
                           [result.depth, result.height, result.width])
  # Convert from [depth, height, width] to [height, width, depth].
  uint8image = tf.transpose(depth_major, [1, 2, 0])
 
 

最后自然还需要用shuffle_batch 生成batch。

3.从CSV (TXT)中读取
有的时候在数据量不是很大的时候,可以从CSV或者TXT文件进行读取。
(1)制作CSV(TXT)数据文本
CSV (TXT)一般是一行存一个样本(包括样本值和label),用逗号隔开。用python的普通文本写入即可。
(2)读取的时候tf.TextLineReader 类来每次读取一行,并使用tf.decode_csv来对每一行进行解析。
这里主要介绍一下 tf.decode_csv(records, record_defaults, field_delim=None, name=None)
首先records与第二种方法中相同,为reader读到的内容,这里为CSV (TXT)的一行。一般一行里面的值会用逗号或者空格隔开,这里第三个输入参数就是指定用什么来进行分割,默认为逗号。第二个输入参数是指定分割后每个属性的类型,比如分割后会有三列,那么第二个参数就应该是[[‘int32’], [], [‘string’]], 可见不指定类型(设为空[])也可以。如果分割后的属性比较多,比如有100个,可以用[ []*100 ]来表示
col= tf.decode_csv(records, record_defaults=[ [ ]*100 ], field_delim=‘ ’, name=None)
返回的col是长度为100的list。
需要注意的是,当数据量比较大的时候,存成CSV或TXT文件要比BIN文件大的多,因此在TF中读取的速度也会慢很多。因此尽量不要读取大的CSV的方式来输入。

filename_queue = tf.train.string_input_producer(["file0.csv", "file1.csv"])
#每次一行
reader = tf.TextLineReader()
key, value = reader.read(filename_queue)
#解析每次的一行,默认以逗号分开
image_v, label = tf.decode_csv(
    value, record_defaults=record_defaults)
result.label = tf.string_to_number(label,tf.int32)
image= tf.string_to_number(image_v,tf.int32)
image = tf.reshape(image,[result.depth, result.height, result.width])
# Convert from [depth, height, width] to [height, width, depth].
  result.uint8image = tf.transpose(image, [1, 2, 0])

 
 

TF 官方还推荐了他自己的一种文件格式https://www.tensorflow.org/versions/r0.10/how_tos/reading_data/index.html#standard-tensorflow-format, 我还 没用过,大家可以自己看看。

4.从原图读取
(1)制作数据路径文件
一行一例,每例包括该样本的地址和label,用逗号分割开,用python普通文件写入即可
(2) 读取
很多情况下我们的图片训练集就是原始图片本身,并没有像cifar dataset那样存成bin等格式。因此我们需要根据一个train_list列表,去挨个读取图片。这里我用到的方法是首先将train_list.txt中的image list(也就是每一行有图片的路劲和label组成)读入队列中,那么对每次dequeue的内容中可以提取当前图片的路劲和label

filename = os.path.join(data_dir, trainfilename)  
    with open(filename) as fid:  
        content = fid.read()  
    content = content.split('\n')  
    content = content[:-1]  
    valuequeue = tf.train.string_input_producer(content,shuffle=True)  
    value = valuequeue.dequeue()  
    dir, labels = tf.decode_csv(records=value, record_defaults=[["string"], [""]], field_delim=" ")  
    labels = tf.string_to_number(labels, tf.int32)  
    imagecontent = tf.read_file(dir)  
    image = tf.image.decode_png(imagecontent, channels=3, dtype=tf.uint8)  
    image = tf.cast(image, tf.float32)  
    #将图片统一为32*32大小的
    image = tf.image.resize_images(image,[32,32])
    image = tf.reshape(image,[result.depth, result.height, result.width])
    # Convert from [depth, height, width] to [height, width, depth].
    result.uint8image = tf.transpose(image, [1, 2, 0])
 
 

不过这个方法对电脑输入输出要求比较高,如果机械硬盘有坏道,就会报Input/Output error,出现这种情况,要修复机械硬盘坏道。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值