欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

程序员文章站 2022-07-08 08:59:09
...

本教程参考Kevin的****:Youtube

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

Kevin知乎:点击打开链接

1.数据描述:

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

类别如下:

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

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

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

也就是说,将标签和图像存在一起,第一位是标签,剩余的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.整个项目内容:

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

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

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张

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

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

用了ont-hot的结果:

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)


3.错误解析:

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

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

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

建议大家用format.

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

另外图像是空白:

Kevin Xu-TensorFlow Tutorials-cifar10 input_data(1)

注意我们之前这里是警告。现在这是值错误,我并没有改上述代码的任何地方,只要换个环境运行就可以解决,我也不知道为什么,知道的可以告诉我哦。可能是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