如何使用Tensorflow从文件队列中读取无符号的16位整数二进制数据?

时间:2018-07-31 04:42:42

标签: python tensorflow visual-studio-2017

我正在尝试修改Tensorflow的高级卷积神经网络教程,该教程最初使用CIFAR-10数据集(https://www.tensorflow.org/tutorials/images/deep_cnn)来处理无符号16位整数数据。我将以类似于CIFAR-10数据集的二进制格式读取数据。

原始代码从二进制格式读取无符号的8位整数数据。我设法从我自己的数据集中创建了8维样本,这些样本具有各种维度(下面的 result.depth 变量),并且训练顺利进行了。

但是我自己的数据是一个无符号的16位整数数据集。如果我将其重新采样为8位,则会丢失重要信息。因此,我想将无符号的16位数据输入到图中进行训练。

前2个字节包含数据的标签,其余(高度x宽度x深度x 2 字节)包含记录的数据。我使用这种方法将二进制文件写入光盘:

out = np.array(outp, dtype = np.uint16) #this variable contains the data
out.tofile("d:\\TF\\my_databatch_0.bin") 

这部分通常可以。如果我这样读它回内存:

in = np.fromfile("d:\\TF\\my_databatch_0.bin", dtype=np.uint16)

它为我提供了与写入光盘完全相同的阵列。 当我尝试通过修改后的输入函数将其馈入图形时,在后续步骤中将失败:

import tensorflow as tf
import numpy as np

##########################Reader for unsigned 16 bit numpy array###############
def read_cifar10(filename_queue):
  class CIFAR10Record(object):
    pass
  result = CIFAR10Record()

    label_bytes = 2  
    result.height = 32
    result.width = 32
    result.depth = 1
    result.bitdepth = 2 #2 if 16bit, 1 if 8bit
    image_bytes = result.height * result.width * result.depth * result.bitdepth
    record_bytes_ = label_bytes + image_bytes

    reader = tf.FixedLengthRecordReader(record_bytes=record_bytes_)
    result.key, value = reader.read(filename_queue)
    record_bytes__ = tf.decode_raw(value, tf.uint16, little_endian=True)

    result.label = tf.strided_slice(record_bytes__, [0], [label_bytes])
    data_img = tf.strided_slice(record_bytes__, [label_bytes], [label_bytes + image_bytes])
    depth_major = tf.reshape(data_img, [result.depth, result.height, result.width])
    result.uint16image = tf.transpose(depth_major, [1, 2, 0])

  return result

我对网络体系结构进行了修改,以接受各种维度数据(在下面的示例代码中将其设置为1)。用我的8位样本,它奏效了。我在16位数据中遇到的错误:

tensorflow.python.framework.errors_impl.InvalidArgumentError: Input to reshape is a tensor with 1023 values, but the requested shape has 1024
     [[Node: data_augmentation/Reshape = Reshape[T=DT_UINT16, Tshape=DT_INT32, _device="/job:localhost/replica:0/task:0/device:CPU:0"](data_augmentation/StridedSlice_1, data_augmentation/Reshape/shape)]] 

在图形的读取或数据自变量部分,数据丢失了1或2个字节。我的张量缺少最后一个元素。

这是原始输入文件,我正在尝试对其进行修改:https://github.com/tensorflow/models/blob/master/tutorials/image/cifar10/cifar10_input.py

我在Windows 10上使用Visual Studio 2017和Python 3.5.2。Tensorflow的版本为1.9.0。

1 个答案:

答案 0 :(得分:0)

我想出了一个使用TFRecords格式(https://www.tensorflow.org/api_guides/python/python_io#tfrecords_format_details)的解决方案。

该解决方案的灵感来自以下线程:How do I convert a directory of jpeg images to TFRecords file in tensorflow?

从4D图像数组([IMG_ID] [y] [x] [BAND_ID])和1D标签数组创建TFRecords数据集是使用引用的 convert_to(图像,标签,名称)< / em>接受答案。

阅读功能已根据Tensorflow的最新API进行了修改:

def read_TFrecords(filename_queue):

  class CIFAR10Record(object):
    pass
  result = CIFAR10Record()
  item_type = tf.uint16
  label_bytes = item_type.size  
  result.height = 32
  result.width = 32
  result.depth = 1

  reader = tf.TFRecordReader()
  _, serialized_example = reader.read(filename_queue)
  features = tf.parse_single_example(
    serialized_example,
    features={
            'image_raw': tf.FixedLenFeature([], tf.string),
            'label': tf.FixedLenFeature([], tf.int64),
             })

  image = tf.decode_raw(features['image_raw'], item_type)

  image = tf.reshape(image, [result.depth, result.height, result.width])
  image.set_shape([result.depth, result.height, result.width])
  result.uint16image = tf.transpose(image, [1, 2, 0])# tf.cast(image, tf.float32)
  result.label = tf.cast(features['label'], tf.int32)

  return result

在Tensorflow(https://github.com/tensorflow/models/blob/master/tutorials/image/cifar10/cifar10_input.py)的Advanced Convolutional Neural Networks教程的输入中,需要通过从 distorted_inputs(data_dir,batch_size)函数中删除以下行来进行进一步修改:< / p>

read_input.label.set_shape([1])

因为它已经从阅读器作为一维张量传递了。

通过这种方式,我可以将自己的无符号16位整数数据从文件队列中馈入图形。