Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

本教程参考Kevin的视频教程:Youtube

数据集下载地址为:点击打开链接

Kevin知乎:点击打开链接

1.数据描述:

CIFAR10共有10个类,60000张图片,其中50000张彩色图像用于训练,大小为32*32;10000张用于测试。在官网下载二进制数据,这个类型的数据是分批次的,不会一起加入内存。版本为Binary version

类别如下:


数据的存储格式很特别,需要注意一下:


也就是说,将标签和图像存在一起,第一位是标签,剩余的32*32*3=3072位是图像。

2.数据步骤:

#对数据的处理主要步骤如下:
#1.读取的数据
#2.加入队列用tf.train.string_input_producer()
#3.用tf.FixedLengthRecordReader读取队列的内容,这个读取数据需要数据是等尺寸的,刚好适用这个CIFAR的读取
#4.解码,因为原始image是二进制形式的,解码成unit8

#5.重构图像的size,为img_depth, img_height, img_width

3.整个实验主要包括数据的处理、训练以及评估,这一部分主要讲数据的处理。

4.整个项目内容:


--------------------------------进入代码分解部分--------------------------------------------------------

1.导入各种需要的包

import tensorflow as tf
import numpy as np
import os

2.创建一个函数read_cifar10(),读取数据并进行分批次:

# Reading data
def read_cifar10(data_dir, is_train, batch_size, shuffle):
    """Read CIFAR10

    Args:
        data_dir: CIFAR10数据地址
        is_train: boolen 是训练数据还是测试数据,true为训练数据
        batch_size:
        shuffle:    是否打乱顺序    
    Returns:
        label: 1D tensor, tf.int32  标签
        image: 4D tensor, [batch_size, height, width, 3], tf.float32  图像size

    """
    img_width = 32
    img_height = 32
    img_depth = 3
    # 设定标签占一位,图像占32*32*3位
    label_bytes = 1
    image_bytes = img_width * img_height * img_depth

    with tf.name_scope('input'):
        # 如果是训练就读训练文件(这里要分批次),是测试就读测试文件
        if is_train:
            filenames = [os.path.join(data_dir, 'data_batch_%d.bin' %ii)
                         for ii in np.arange(1, 6)]
        else:
            filenames = [os.path.join(data_dir, 'test_batch.bin')]

        filename_queue = tf.train.string_input_producer(filenames)
        # 加入队列,注意:猫狗数据大战加入队列用的是slice_input_producer([]),这个函数是传入列表,因为它的label和image不在一个文件里面
        # 而这个数据是在一个里面

        # 读取队列内容
        reader = tf.FixedLengthRecordReader(label_bytes + image_bytes)

        key, value = reader.read(filename_queue)

        # 解码
        record_bytes = tf.decode_raw(value, tf.uint8)

        # 获得标签:从record_bytes切出来再转换成tf.int32
        label = tf.slice(record_bytes, [0], [label_bytes])
        label = tf.cast(label, tf.int32)

        # 获得图像:从record_bytes切出来再重构size,并且转换成tf能识别的类型
        image_raw = tf.slice(record_bytes, [label_bytes], [image_bytes])
        image_raw = tf.reshape(image_raw, [img_depth, img_height, img_width])
        image = tf.transpose(image_raw, (1, 2, 0))  # convert from D/H/W to H/W/D
        image = tf.cast(image, tf.float32)

        #        # data argumentation(这里没做增强)

        #        image = tf.random_crop(image, [24, 24, 3])# randomly crop the image size to 24 x 24
        #        image = tf.image.random_flip_left_right(image)
        #        image = tf.image.random_brightness(image, max_delta=63)
        #        image = tf.image.random_contrast(image,lower=0.2,upper=1.8)


        # 标准化数据,用了之后图像会很奇怪,用为值是0-1,要看原始图像需要注释掉这句
        image = tf.image.per_image_standardization(image)  # substract off the mean and divide by the variance

        # 根据打乱顺序与否进行不同的batch
        if shuffle:
            images, label_batch = tf.train.shuffle_batch(
                [image, label],
                batch_size=batch_size,
                num_threads=16,
                capacity=2000,
                min_after_dequeue=1500)
        else:
            images, label_batch = tf.train.batch(
                [image, label],
                batch_size=batch_size,
                num_threads=16,
                capacity=2000)

        # 如果不用one-hot,就把这个return打开
        label_batch = tf.reshape(label_batch, [batch_size])
        return images, label_batch
        # 注意:这后面的代码全被我注释掉了,是因为用one-hot编码的数据会在评估阶段发生错误,其他地方运行是没有问题的
        # ## ONE-HOT,用下面的return。
        # # 由于原始的标签是0-9的10个类别,将他换成one-hot编码
        # n_classes = 10
        # label_batch = tf.one_hot(label_batch, depth=n_classes)
        # label_batch = tf.reshape(label_batch, [batch_size, n_classes])
        # return images, label_batch

2.到这一部分,数据的处理就完了,我们可以测试一下函数有没有问题。但是需要注意的是这一步会出现很多问题,稍后将我遇到的问题分享给大家,先上代码。

###测试,训练的时候需要注释掉下面的:快捷注释的方法,1.把要注释的折叠起来,选中然后Ctrl + '/'就ok
##  2.鼠标选中要注释的块,然后Ctrl + '/'。注意:网上很多说这种方法是Ctrl + shift+ '/',我试过不行
## 块注释有了,怎么块取消注释呢,很简单同注释的方法一样,再操作一下就好了

import matplotlib.pyplot as plt

data_dir = 'D:/Python/neural network/CIFAR10-Guoqingxu/data/'
BATCH_SIZE = 2
image_batch, label_batch = read_cifar10(data_dir,
                                        is_train=True,
                                        batch_size=BATCH_SIZE,
                                        shuffle=True)

with tf.Session() as sess:
    i = 0
    #用coord和threads监控队列
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord)

    try:
        while not coord.should_stop() and i<1:

            img, label = sess.run([image_batch, label_batch])


            # just test one batch
            for j in np.arange(BATCH_SIZE):
                print('label: {}'.format(label[j]))
                # 视频用的%d,会出错
                plt.imshow(img[j,:,:,:])
                plt.show()
            i+=1

    except tf.errors.OutOfRangeError:
        print('done!')
    finally:
        coord.request_stop()
    coord.join(threads)

好了,这一部分数据的处理就完了。

不用one-hot结果:只测试了2张



大家看这里有警告,没法解决,解决了的也可以告诉我啊,互相学习!!

用了ont-hot的结果:



3.错误解析:

3.1 TypeError: %d format: a number is required, not numpy.ndarray

这里在代码里已经提到过,出错点在


建议大家用format.

3.2 ValueError: Floating point image RGB values must be in the 0..1 range.

另外图像是空白:


注意我们之前这里是警告。现在这是值错误,我并没有改上述代码的任何地方,只要换个环境运行就可以解决,我也不知道为什么,知道的可以告诉我哦。可能是tensorflow不同的版本造成的,我环境的版本不一样。

最后为了照顾比较懒的朋友,粘贴我的全部代码。

#########################################################
#输入数据
#CIFAR10共有60000张图片,其中50000张彩色图像用于训练,大小为32*32;10000张用于测试。在官网下载二进制数据,
# 这个类型的数据是分批次的,不会一起加入内存。地址http://www.cs.toronto.edu/~kriz/cifar.html,版本为Binary version
#数据的存放格式如https://zhuanlan.zhihu.com/p/26141396描述
# 一张图像占了3073位,第一位是标签,其余的32*32*3=3072位是图像像素,注意代码会根据这个来提取标签和图像size
#对数据的处理主要步骤如下:
#1.读取的数据
#2.加入队列用tf.train.string_input_producer()
#3.用tf.FixedLengthRecordReader读取队列的内容,这个读取数据需要数据是等尺寸的,刚好适用这个CIFAR的读取
#4.解码,因为原始image是二进制形式的,解码成unit8
#5.重构图像的size,为img_depth, img_height, img_width
##########################################################################

import tensorflow as tf
import numpy as np
import os


# Reading data
def read_cifar10(data_dir, is_train, batch_size, shuffle):
    """Read CIFAR10

    Args:
        data_dir: CIFAR10数据地址
        is_train: boolen 是训练数据还是测试数据,true为训练数据
        batch_size:
        shuffle:    是否打乱顺序    
    Returns:
        label: 1D tensor, tf.int32  标签
        image: 4D tensor, [batch_size, height, width, 3], tf.float32  图像size

    """
    img_width = 32
    img_height = 32
    img_depth = 3
    # 设定标签占一位,图像占32*32*3位
    label_bytes = 1
    image_bytes = img_width * img_height * img_depth

    with tf.name_scope('input'):
        # 如果是训练就读训练文件(这里要分批次),是测试就读测试文件
        if is_train:
            filenames = [os.path.join(data_dir, 'data_batch_%d.bin' %ii)
                         for ii in np.arange(1, 6)]
        else:
            filenames = [os.path.join(data_dir, 'test_batch.bin')]

        filename_queue = tf.train.string_input_producer(filenames)
        # 加入队列,注意:猫狗数据大战加入队列用的是slice_input_producer([]),这个函数是传入列表,因为它的label和image不在一个文件里面
        # 而这个数据是在一个里面

        # 读取队列内容
        reader = tf.FixedLengthRecordReader(label_bytes + image_bytes)

        key, value = reader.read(filename_queue)

        # 解码
        record_bytes = tf.decode_raw(value, tf.uint8)

        # 获得标签:从record_bytes切出来再转换成tf.int32
        label = tf.slice(record_bytes, [0], [label_bytes])
        label = tf.cast(label, tf.int32)

        # 获得图像:从record_bytes切出来再重构size,并且转换成tf能识别的类型
        image_raw = tf.slice(record_bytes, [label_bytes], [image_bytes])
        image_raw = tf.reshape(image_raw, [img_depth, img_height, img_width])
        image = tf.transpose(image_raw, (1, 2, 0))  # convert from D/H/W to H/W/D
        image = tf.cast(image, tf.float32)

        #        # data argumentation(这里没做增强)

        #        image = tf.random_crop(image, [24, 24, 3])# randomly crop the image size to 24 x 24
        #        image = tf.image.random_flip_left_right(image)
        #        image = tf.image.random_brightness(image, max_delta=63)
        #        image = tf.image.random_contrast(image,lower=0.2,upper=1.8)


        # 标准化数据,用了之后图像会很奇怪,用为值是0-1,要看原始图像需要注释掉这句
        image = tf.image.per_image_standardization(image)  # substract off the mean and divide by the variance

        # 根据打乱顺序与否进行不同的batch
        if shuffle:
            images, label_batch = tf.train.shuffle_batch(
                [image, label],
                batch_size=batch_size,
                num_threads=16,
                capacity=2000,
                min_after_dequeue=1500)
        else:
            images, label_batch = tf.train.batch(
                [image, label],
                batch_size=batch_size,
                num_threads=16,
                capacity=2000)

        # 如果不用one-hot,就把这个return打开
        # label_batch = tf.reshape(label_batch, [batch_size])
        # return images, label_batch

        # ONE-HOT,用下面的return。
        #由于原始的标签是0-9的10个类别,将他换成one-hot编码
        n_classes = 10
        label_batch = tf.one_hot(label_batch, depth=n_classes)
        label_batch = tf.reshape(label_batch, [batch_size, n_classes])
        return images, label_batch


###测试,训练的时候需要注释掉下面的:快捷注释的方法,1.把要注释的折叠起来,选中然后Ctrl + '/'就ok
##  2.鼠标选中要注释的块,然后Ctrl + '/'。注意:网上很多说这种方法是Ctrl + shift+ '/',我试过不行
## 块注释有了,怎么块取消注释呢,很简单同注释的方法一样,再操作一下就好了

import matplotlib.pyplot as plt

data_dir = 'D:/Python/neural network/CIFAR10-Guoqingxu/data/'
BATCH_SIZE = 2
image_batch, label_batch = read_cifar10(data_dir,
                                        is_train=True,
                                        batch_size=BATCH_SIZE,
                                        shuffle=True)

with tf.Session() as sess:
    i = 0
    #用coord和threads监控队列
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord)

    try:
        while not coord.should_stop() and i<1:

            img, label = sess.run([image_batch, label_batch])


            # just test one batch
            for j in np.arange(BATCH_SIZE):
                #print('label: %d' %label[j])
                print('label: {}'.format(label[j]))
                # 视频用的%d,会出错
                plt.imshow(img[j,:,:,:])
                plt.show()
            i+=1

    except tf.errors.OutOfRangeError:
        print('done!')
    finally:
        coord.request_stop()
    coord.join(threads)










阅读更多
文章标签: CIFAR10 tensorflow
个人分类: cifar10
上一篇TensoeFlow 模型保存为pb文件的解释,怎么使用pb文件/模型的Save and Restore
下一篇Kevin Xu-TensorFlow Tutorials-cifar10 (2)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭