cifar10数据集的读取Python/Tensorflow

cifar10数据集的读取Python/Tensorflow在使用tensorflow等框架进行神经网络的构建时,数据集的读取操作至关重要,本文参考别人代码,记录了对cifar10数据集读取的理解

大家好,又见面了,我是你们的朋友全栈君。

 以github上yscbm的代码为例进行讲解,代码链接:https://github.com/yscbm/tensorflow/blob/master/common/extract_cifar10.py

首先导入必要的模块

<pre><code>

import gzip

import numpy as np

import os

import tensorflow as tf

</pre></code>

我们定义一些变量,因为针对的是cifar10数据集,所以变量的值都是固定的,为什么定义这些变量呢,因为变量的名字可以很直观的告诉我们这个数字的代表什么,试想如果代码里面全是些数字,我们会不会看糊涂了呢,我们知道cifar10数据集下载下来你会发现有data_batch_1.bin,data_batch_2.bin….data_batch_5.bin五个作为训练,test_batch.bin作为测试,每一个文件都是10000张图片,因此50000张用于训练,10000张用于测试

<pre><code>

LABEL_SIZE = 1

IMAGE_SIZE = 32

NUM_CHANNELS = 3

PIXEL_DEPTH = 255

NUM_CLASSES = 10

TRAIN_NUM = 10000

TRAIN_NUMS = 50000

TEST_NUM = 10000

</pre></code>

接着我们定义提取数据的函数

<pre><code>

def extract_data(filenames):


    #验证文件是否存在


    for f in filenames:


        if not tf.gfile.Exists(f):


            raise ValueError(‘Failed to find file: ‘ + f)


    #读取数据


    labels = None


    images = None

    for f in filenames:


        bytestream=open(f,’rb’) 


        #读取数据,首先将数据集中的数据读取进来作为buf


        buf = bytestream.read(TRAIN_NUM * (IMAGE_SIZE * IMAGE_SIZE * NUM_CHANNELS+LABEL_SIZE))


        #把数据流转化为np的数组,为什么要转化为np数组呢,因为array数组只支持一维操作,为了满足我们的操作需求,我们利用np.frombuffer()将buf转化为numpy数组现在data的shape为(30730000,),3073是3*1024+1得到的,3个channel(r,g,b),每个channel有1024=32*32个信息,再加上 1 个label

        data = np.frombuffer(buf, dtype=np.uint8)

        #改变数据格式,将shape从原来的(30730000,)——>为(10000,3073)


        data = data.reshape(TRAIN_NUM,LABEL_SIZE+IMAGE_SIZE* IMAGE_SIZE* NUM_CHANNELS)

        #分割数组,分割数组,np.hsplit是在水平方向上,将数组分解为label_size的一部分和剩余部分两个数组,在这里label_size=1,也就是把标签label给作为一个数组单独切分出来如果你对np.split还不太了解,可以自行查阅一下,此时label_images的shape应该是这样的[array([…….]) , array([…………………..])]   


        labels_images = np.hsplit(data, [LABEL_SIZE])

        label = labels_images[0].reshape(TRAIN_NUM)#此时labels_images[0]就是我们上面切分数组得到的第一个数组,在这里就是label数组,这时的shape为array([[3] , [6] , [4] , ……. ,[7]]),我们把它reshape()一下变为了array([3 , 6 , …….. ,7])  

        image = labels_images[1].reshape(TRAIN_NUM,IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)#此时labels_image[1]就是我们上面切分数组的剩余部分,也就是图片部分我们把它reshape()为(10000,32,32,3) 

        if labels == None:


            labels = label


            images = image


        else:


            #合并数组,不能用加法


            labels = np.concatenate((labels,label))


            images = np.concatenate((images,image))

    images = (images – (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH

    return labels,images

</pre></code>

定义提取训练数据函数

<pre><code>

def extract_train_data(files_dir):


    #获得训练数据


    filenames = [os.path.join(files_dir, ‘data_batch_%d.bin’ % i) for i in xrange(1, 6)]


    return extract_data(filenames)

</pre></code>

定义提取测试数据函数    

<pre><code>

def extract_test_data(files_dir):


    #获得测试数据


    filenames = [os.path.join(files_dir, ‘test_batch.bin’),]


    return extract_data(filenames)

</pre></code>    

把稠密数据label[1,5…]变为[[0,1,0,0…],[…]…]

<pre><code>

def dense_to_one_hot(labels_dense, num_classes):


    #数据数量,np.shape[0]返回行数,对于一维数据返回的是元素个数,如果读取了5个文件的所有训练数据,那么现在的num_labels的值应该是50000


    num_labels = labels_dense.shape[0]

    #生成[0,1,2…]*10,[0,10,20…],之所以这样子是每隔10个数定义一次值,比如第0个,第11个,第22个……的值都赋值为1


    index_offset = np.arange(num_labels) * num_classes

    #初始化np的二维数组,一个全0,shape为(50000,10)的数组


    labels_one_hot = np.zeros((num_labels, num_classes))

    #相对应位置赋值变为[[0,1,0,0…],[…]…],np.flat将labels_one_hot砸平为1维


    labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1

    return labels_one_hot

</pre></code>

定义cifar10数据集类

<pre><code>

class Cifar10DataSet(object):


    “””docstring for Cifar10DataSet”””


    def __init__(self,data_dir):


        super(Cifar10DataSet, self).__init__()


        self.train_labels,self.train_images = extract_train_data(os.path.join(data_dir,’cifar10/cifar-10-batches-bin’))


        self.test_labels,self.test_images = extract_test_data(os.path.join(data_dir,’cifar10/cifar-10-batches-bin’))


        


        print self.train_labels.size

        self.train_labels = dense_to_one_hot(self.train_labels,NUM_CLASSES)


        self.test_labels = dense_to_one_hot(self.test_labels,NUM_CLASSES)

        #epoch完成次数


        self.epochs_completed = 0


        #当前批次在epoch中进行的进度


        self.index_in_epoch = 0


    def next_train_batch(self,batch_size):


        #起始位置


        start = self.index_in_epoch


        self.index_in_epoch += batch_size


        #print “self.index_in_epoch: “,self.index_in_epoch


        #完成了一次epoch


        if self.index_in_epoch > TRAIN_NUMS:


            #epoch完成次数加1,50000张全部训练完一次,那么没有数据用了怎么办,采取的办法就是将原来的数据集打乱顺序再用


            self.epochs_completed += 1


            #print “self.epochs_completed: “,self.epochs_completed


            #打乱数据顺序,随机性


            perm = np.arange(TRAIN_NUMS)


            np.random.shuffle(perm)


            self.train_images = self.train_images[perm]


            self.train_labels = self.train_labels[perm]


            start = 0


            self.index_in_epoch = batch_size


            #条件不成立会报错


            assert batch_size <= TRAIN_NUMS

        end = self.index_in_epoch


        #print “start,end: “,start,end

        return self.train_images[start:end], self.train_labels[start:end]

    def test_data(self):


        return self.test_images,self.test_labels

</pre></code>

<pre><code>

def main():


    cc = Cifar10DataSet(‘../data/’)


    cc.next_train_batch(100)

if __name__ == ‘__main__’:


    main()

</pre></code>

LABEL_SIZE = 1
IMAGE_SIZE = 32
NUM_CHANNELS = 3
PIXEL_DEPTH = 255
NUM_CLASSES = 10

TRAIN_NUM = 10000
TRAIN_NUMS = 50000
TEST_NUM = 10000
</pre></code>
接着我们定义提取数据的函数
<pre><code>
def extract_data(filenames):
    #验证文件是否存在
    for f in filenames:
        if not tf.gfile.Exists(f):
            raise ValueError('Failed to find file: ' + f)
    #读取数据
    labels = None
    images = None

    for f in filenames:
        bytestream=open(f,'rb') 
        #读取数据,首先将数据集中的数据读取进来作为buf
        buf = bytestream.read(TRAIN_NUM * (IMAGE_SIZE * IMAGE_SIZE * NUM_CHANNELS+LABEL_SIZE))
        #把数据流转化为np的数组,为什么要转化为np数组呢,因为array数组只支持一维操作,为了满足我们的操作需求,我们利用np.frombuffer()将buf转化为numpy数组现在data的shape为(30730000,),3073是3*1024+1得到的,3个channel(r,g,b),每个channel有1024=32*32个信息,再加上 1 个label

        data = np.frombuffer(buf, dtype=np.uint8)

        #改变数据格式,将shape从原来的(30730000,)——>为(10000,3073)
        data = data.reshape(TRAIN_NUM,LABEL_SIZE+IMAGE_SIZE* IMAGE_SIZE* NUM_CHANNELS)

        #分割数组,分割数组,np.hsplit是在水平方向上,将数组分解为label_size的一部分和剩余部分两个数组,在这里label_size=1,也就是把标签label给作为一个数组单独切分出来如果你对np.split还不太了解,可以自行查阅一下,此时label_images的shape应该是这样的[array([.......]) , array([.......................])]   
        labels_images = np.hsplit(data, [LABEL_SIZE])

        label = labels_images[0].reshape(TRAIN_NUM)#此时labels_images[0]就是我们上面切分数组得到的第一个数组,在这里就是label数组,这时的shape为array([[3] , [6] , [4] , ....... ,[7]]),我们把它reshape()一下变为了array([3 , 6 , ........ ,7])  

        image = labels_images[1].reshape(TRAIN_NUM,IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)#此时labels_image[1]就是我们上面切分数组的剩余部分,也就是图片部分我们把它reshape()为(10000,32,32,3) 

        if labels == None:
            labels = label
            images = image
        else:
            #合并数组,不能用加法
            labels = np.concatenate((labels,label))
            images = np.concatenate((images,image))

    images = (images - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH

    return labels,images
</pre></code>
定义提取训练数据函数
<pre><code>
def extract_train_data(files_dir):
    #获得训练数据
    filenames = [os.path.join(files_dir, 'data_batch_%d.bin' % i) for i in xrange(1, 6)]
    return extract_data(filenames)
</pre></code>
定义提取测试数据函数    
<pre><code>
def extract_test_data(files_dir):
    #获得测试数据
    filenames = [os.path.join(files_dir, 'test_batch.bin'),]
    return extract_data(filenames)
</pre></code>    
把稠密数据label[1,5...]变为[[0,1,0,0...],[...]...]
<pre><code>
def dense_to_one_hot(labels_dense, num_classes):
    #数据数量,np.shape[0]返回行数,对于一维数据返回的是元素个数,如果读取了5个文件的所有训练数据,那么现在的num_labels的值应该是50000
    num_labels = labels_dense.shape[0]

    #生成[0,1,2...]*10,[0,10,20...],之所以这样子是每隔10个数定义一次值,比如第0个,第11个,第22个......的值都赋值为1
    index_offset = np.arange(num_labels) * num_classes

    #初始化np的二维数组,一个全0,shape为(50000,10)的数组
    labels_one_hot = np.zeros((num_labels, num_classes))

    #相对应位置赋值变为[[0,1,0,0...],[...]...],np.flat将labels_one_hot砸平为1维
    labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1

    return labels_one_hot
</pre></code>
定义cifar10数据集类
<pre><code>
class Cifar10DataSet(object):
    """docstring for Cifar10DataSet"""
    def __init__(self,data_dir):
        super(Cifar10DataSet, self).__init__()
        self.train_labels,self.train_images = extract_train_data(os.path.join(data_dir,'cifar10/cifar-10-batches-bin'))
        self.test_labels,self.test_images = extract_test_data(os.path.join(data_dir,'cifar10/cifar-10-batches-bin'))
        
        print self.train_labels.size

        self.train_labels = dense_to_one_hot(self.train_labels,NUM_CLASSES)
        self.test_labels = dense_to_one_hot(self.test_labels,NUM_CLASSES)

        #epoch完成次数
        self.epochs_completed = 0
        #当前批次在epoch中进行的进度
        self.index_in_epoch = 0


    def next_train_batch(self,batch_size):
        #起始位置
        start = self.index_in_epoch
        self.index_in_epoch += batch_size
        #print "self.index_in_epoch: ",self.index_in_epoch
        #完成了一次epoch
        if self.index_in_epoch > TRAIN_NUMS:
            #epoch完成次数加1,50000张全部训练完一次,那么没有数据用了怎么办,采取的办法就是将原来的数据集打乱顺序再用
            self.epochs_completed += 1
            #print "self.epochs_completed: ",self.epochs_completed
            #打乱数据顺序,随机性
            perm = np.arange(TRAIN_NUMS)
            np.random.shuffle(perm)
            self.train_images = self.train_images[perm]
            self.train_labels = self.train_labels[perm]
            start = 0
            self.index_in_epoch = batch_size
            #条件不成立会报错
            assert batch_size <= TRAIN_NUMS

        end = self.index_in_epoch
        #print "start,end: ",start,end

        return self.train_images[start:end], self.train_labels[start:end]

    def test_data(self):
        return self.test_images,self.test_labels

</pre></code>

<pre><code>
def main():
    cc = Cifar10DataSet('../data/')
    cc.next_train_batch(100)

if __name__ == '__main__':
    main()
</pre></code>

以上就是我对cifar10数据集读取的理解,cifar10数据集的介绍参考   http://blog.csdn.net/garfielder007/article/details/51480844

本文作为自己的笔记


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/152075.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 微商分销系统哪家好,要怎么做?

    微商分销系统哪家好,要怎么做?分销模式的本质是分享经济,wemall微商分销系统将传统商品高昂的推广费用让利给消费者,并抽取一定金额作为分销商的佣金。分销模式使消费者直接与商家沟通,增加用户粘性,促成品牌的口碑转化为流量,相比与零售,分销有着无可比拟的优势,这也使越来越多的微商分销系统涌现出来。微信封杀分…

  • 载入java VM时windows出现错误:2 的解决方法

    载入javaVM时Windows出现错误:2的解决方法问题:执行安装包时出现下图错误。原因:该安装包运行时需用到JAVA运行环境(JRE),JDK默认的安装路径是C:\ProgramFiles\Java,有些安装包默认从此处找JRE环境变量,如果你的JDK是自定义安装目录的话,就会出现上述错误。解决方法:首先确定JAVA_HOME环境变量配置是否正确,要和注册表中版本保持一致,WIN+R—>cmd中输入指令java-version可以查看环境变量的JAVA版本。找到安装包文件

  • 知乎转载_知乎上的文章可以转载吗

    知乎转载_知乎上的文章可以转载吗链接:https://www.zhihu.com/question/22590902/answer/55182189来源:知乎著作权归作者所有,转载请联系作者获得授权。题主的问题是如何白手起家靠一个人赚到100万,我觉得这个是可以做到的,但是要分阶段,不太可能从一个从无经商经验的人突然转变成一个人折腾点东西就能赚百万(多个人一起有可能)。我先把我个人的阶段拆解开来,给你一个直观的感受。…

  • 什么是敏捷开发_一个完整的敏捷开发的流程

    什么是敏捷开发_一个完整的敏捷开发的流程0、先来一张导图1、概念简单的说,敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。换言之,

  • VggNet10模型的cifar10深度学习训练

    VggNet10模型的cifar10深度学习训练目录一:数据准备:二:VGG模型三:代码部分1.input_data.py2.VGG.py3.tools.py4.train_and_val.py一:数据准备:先放些链接,cifar10的数据集的下载地址:http://www.cs.toronto.edu/~kriz/cifar.html用二进制tfcords的数据集训练,下载第三个,下载的数据文件集是…

  • 2019年最佳黑客书籍 – 初级到高级[通俗易懂]

    2019年最佳黑客书籍 – 初级到高级[通俗易懂]2019年最佳黑客书籍-初级到高级2019年4月17日斯特凡本文译自https://www.ceos3c.com/hacking/the-best-hacking-books/出于流行的要求,现在是时候将2019年最佳黑客书籍列表整理在一起。现在,这个列表不仅包含2019年发布的黑客书籍,而且还包含了今年值得一提的所有书籍。仍然会有一些经常被提及的经典,即使它们多年没有更新,它们仍然…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号