【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——[附完整训练代码]

一、CIFAR-10数据集介绍

1.1 CIFAR-10数据集的内容

CIFAR10数据集共有60000个样本,每个样本都是一张32*32像素的RGB图像(彩色图像),每个RGB图像又必定分为3个通道(R通道、G通道、B通道)。这60000个样本被分成了50000个训练样本和10000个测试样本。
CIFAR10数据集是用来监督学习训练的,那么每个样本就一定都配备了一个标签值(用来区分这个样本是什么),不同类别的物体用不同的标签值,CIFAR10中有10类物体,标签值分别按照0~9来区分,他们分别是飞机( airplane )、汽车( automobile )、鸟( bird )、猫( cat )、鹿( deer )、狗( dog )、青蛙( frog )、马( horse )、船( ship )和卡车( truck )。
CIFAR10数据集的内容,如图所示。
在这里插入图片描述
(该图源于官网)
CIFAR-10数据集有多种下载方式,本文仅介绍两种。

1.2 CIFAR-10数据集的结构组成

CIFAR10数据集结构组成可分为这四个部分:
·train_x:(50000, 32, 32, 3)——训练样本
·train_y:(50000, 1)——训练样本标签
·test_x:(10000, 32, 32, 3)——测试样本
·test_y:(10000, 1)——测试样本标签

1.3 CIFAR-10数据集的下载方式

方法一:
官网下载链接:http://www.cs.toronto.edu/~kriz/cifar.html
可以下载这三个版本,分别是python版本、Matlab版本和C编译好的二进制版本。
在这里插入图片描述
方法二:
在Keras中已经内置了多种公共数据集,其中就包含CIFAR-10数据集,如图所示。
在这里插入图片描述
所以可以直接调用 tf.keras.datasets.cifar10,直接下载数据集。

1.4 CIFAR-10数据集与CIFAR-100数据集(拓展)

这个数据集与CIFAR-10类似,只不过它有100个类,每个类包含600个图像。每个类有500个训练图像和100个测试图像。CIFAR-100中的100个子类被分为20个大类。每个图像都有一个“fine”标签(它所属的子类)和一个“coarse”标签(它所属的大类)。

CIFAR-100的结构组成:

大类子类
水栖哺乳动物海狸,海豚,水獭,海豹,鲸鱼
鱼类水族鱼,比目鱼,鳐,鲨鱼,鳟鱼
兰花,罂粟,玫瑰,向日葵,郁金香
食物容器瓶子,碗,罐头,杯子,盘子
水果和蔬菜苹果,蘑菇,橘子,梨,甜椒
家用电器时钟,电脑键盘,灯,电话,电视
家居家具床,椅子,沙发,桌子,衣柜
昆虫蜜蜂、甲虫、蝴蝶、毛虫、蟑螂
大型食肉动物熊,豹,狮子,老虎,狼
大型人造户外用品桥梁、城堡、房屋、道路、摩天大楼
大型户外自然景观云、森林、高山、平原、大海
大型杂食动物和食草动物骆驼,牛,黑猩猩,大象,袋鼠
中型哺乳动物狐狸,豪猪,负鼠,浣熊,臭鼬
非昆虫无脊椎动物螃蟹,龙虾,蜗牛,蜘蛛,蠕虫
人类宝贝,男孩,女孩,男人,女人
爬行动物鳄鱼,恐龙,蜥蜴,蛇,乌龟
小型哺乳动物仓鼠,老鼠,兔子,鼩鼱,松鼠
树木枫树、橡树、棕榈树、松树、柳树
交通工具自行车、公共汽车、摩托车、小货车、火车
其他车类割草机,火箭,有轨电车,坦克,拖拉机

CIFAR-10数据集与CIFAR-100数据集的区别也就显而易见啦。

1.5 CIFAR-10数据集与MNIST数据集对比(拓展)

关于MNIST数据集的介绍,我写过一篇文章,并也附带了MNIST数据集的模型训练完整代码,感兴趣的朋友可以看它。
使用MNIST数据集训练手写数字识别模型——附完整代码训练好的模型文件——直接用
链接:https://blog.csdn.net/weixin_45954454/article/details/114455209?spm=1001.2014.3001.5501

CIFAR-10数据集与MNIST数据集二者的区别主要是在以下几点:
·维度不同:CIFAR-10数据集有4个维度,MNIST数据集有3个维度
·图像类型不同:CIFAR-10数据集是RGB图像(有三个通道),MNIST数据集是灰度图像,这也是为什么CIFAR-10数据集比MNIST数据集多出一个维度的原因。
·图像内容不同:CIFAR-10数据集展示的是各种不同的物体(猫、狗、飞机、汽车…),MNIST数据集展示的是不同人的手写0~9数字。

二、卷积神经网络

2.1卷积神经网络函数介绍

主要使用函数:tf.keras.layers.Conv2D()

tf.keras.layers.Conv2D(
    filters, kernel_size, strides=(1, 1), padding='valid', data_format=None,
    dilation_rate=(1, 1), activation=None, use_bias=True,
    kernel_initializer='glorot_uniform', bias_initializer='zeros',
    kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None,
    kernel_constraint=None, bias_constraint=None, **kwargs
)

这一层创建了一个卷积核,它与层输入进行卷积以产生输出张量。如果use_bias为真,则创建一个偏差向量并添加到输出中。最后,如果激活不是None,它也会应用到输出。
当使用这一层作为模型的第一层时,提供关键字参数input_shape(整数元组,不包括样本轴),例如,对于data_format="channels_last"中的128x128 RGB图片,输入input_shape=(128, 128, 3)。

参数说明
filters整数,即输出空间的维数(即卷积中输出滤波器的数量)
kernel_size一个整数或2个整数的元组/列表,指定2D卷积窗口的高度和宽度。可以是单个整数,为所有空间维度指定相同的值。
strides一个整数或2个整数的元组/列表,指定沿高度和宽度卷积的步长。可以是单个整数,为所有空间维度指定相同的值。指定任何stride值!= 1与指定任何dilation_rate值!= 1是不兼容的。
padding“valid”或“same”(不区分大小写)。补0策略。“valid”代表只进行有效的卷积,即对边界数据不处理。“same”代表保留边界处的卷积结果,通常会导致输出shape与输入shape相同。
data_format字符串,channels_last(默认)或channels_first之一。输入中维度的顺序。channels_last对应于形状的输入(batch_size,高度,宽度,通道),而channels_first对应于形状的输入(batch_size,通道,高度,宽度)。默认值为在Keras配置文件~/. Keras / Keras .json中找到的image_data_format值。如果您从未设置它,那么它将是“channels_last”。
dilation_rate一个整数或2个整数的元组/列表,指定用于膨胀卷积的膨胀率。可以是单个整数,为所有空间维度指定相同的值。目前,指定任何dilation_rate值!= 1与指定任何stride值!= 1是不兼容的。
activation使用的激活功能。如果不指定任何内容,则不会应用任何激活(参见keras.activation)。
use_biasboolean,这个层是否使用偏差向量。
kernel_initializer内核权重矩阵的初始化器(参见keras.initializer)。
bias_initializer偏置向量的初始化器(参见keras.initializer)。
kernel_regularizer应用于内核权重矩阵的正则化函数(参见keras.regularizers)。
bias_regularizer应用于偏置向量的正则化函数(参见keras.regularizers)。
activity_regularizer应用于层输出的正则化函数(它的“激活”)(参见keras.regularizers)。
kernel_constraint约束函数应用于内核矩阵(参见keras.constraints)。
bias_constraint应用于偏差向量的约束函数(参见keras.constraints)。

input_shape:
如果data_format=‘channels_first’,则4D张量的形状:(batch_size, channels, rows, cols);或者如果data_format=‘channels_last’,则4D张量的形状:(batch_size, rows, cols, channels)。
output_shape:
4D张量的形状:(batch_size, filters, new_rows, new_cols)如果data_format=‘channels_first’,或者4D张量的形状:(batch_size, new_rows, new_cols, filters)如果data_format=‘channels_last’。rows和cols值可能由于填充而改变。

(仅翻译的官方说明文档)
Tensorflow官方API网址如下,可以用来查询Tensorflow其他API的使用。(很全很详细)
Tensorflow官方API链接:https://tensorflow.google.cn/versions

三、模型训练思路

CIFAR-10数据集的模型训练思路与下面这篇文章相似,想了解设计过程和每一步代码作用的朋友可以看我写的这篇文章,这里就不赘述了。
使用MNIST数据集训练手写数字识别模型——附完整代码训练好的模型文件——直接用
链接:https://blog.csdn.net/weixin_45954454/article/details/114455209?spm=1001.2014.3001.5501

四、代码实现——直接用

本人使用的是Tensorflow2.2.0—gpu版本,就目前已更新的版本来看,2.0.0以上版本都可以直接使用。
如果你的GPU没有配置好,代码会在指定GPU那里报错的,如果是这种报错还不知道如何解决的话,就选择用CPU跑程序,即注释掉这两行代码:

gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(gpus[0],True)

注释掉后,基本就能跑通啦。

强调:其中model.save( )里的路径根据自己需要自行修改,若省去路径,默认保存到当前的工作路径。

########cifar10数据集##########
###########保存模型############
########卷积神经网络##########
#train_x:(50000, 32, 32, 3), train_y:(50000, 1), test_x:(10000, 32, 32, 3), test_y:(10000, 1)
#60000条训练数据和10000条测试数据,32x32像素的RGB图像
#第一层两个卷积层16个3*3卷积核,一个池化层:最大池化法2*2卷积核,激活函数:ReLU
#第二层两个卷积层32个3*3卷积核,一个池化层:最大池化法2*2卷积核,激活函数:ReLU
#隐含层激活函数:ReLU函数
#输出层激活函数:softmax函数(实现多分类)
#损失函数:稀疏交叉熵损失函数
#隐含层有128个神经元,输出层有10个节点
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

import time
print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print(nowtime)

#指定GPU
#import os
#os.environ["CUDA_VISIBLE_DEVICES"] = "0"
gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(gpus[0],True)
#初始化
plt.rcParams['font.sans-serif'] = ['SimHei']

#加载数据
cifar10 = tf.keras.datasets.cifar10
(train_x,train_y),(test_x,test_y) = cifar10.load_data()
print('\n train_x:%s, train_y:%s, test_x:%s, test_y:%s'%(train_x.shape,train_y.shape,test_x.shape,test_y.shape)) 

#数据预处理
X_train,X_test = tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)     #归一化
y_train,y_test = tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16)


#建立模型
model = tf.keras.Sequential()
##特征提取阶段
#第一层
model.add(tf.keras.layers.Conv2D(16,kernel_size=(3,3),padding='same',activation=tf.nn.relu,data_format='channels_last',input_shape=X_train.shape[1:]))  #卷积层,16个卷积核,大小(3,3),保持原图像大小,relu激活函数,输入形状(28,28,1)
model.add(tf.keras.layers.Conv2D(16,kernel_size=(3,3),padding='same',activation=tf.nn.relu))
model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))   #池化层,最大值池化,卷积核(2,2)
#第二层
model.add(tf.keras.layers.Conv2D(32,kernel_size=(3,3),padding='same',activation=tf.nn.relu))
model.add(tf.keras.layers.Conv2D(32,kernel_size=(3,3),padding='same',activation=tf.nn.relu))
model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))
##分类识别阶段
#第三层
model.add(tf.keras.layers.Flatten())    #改变输入形状
#第四层
model.add(tf.keras.layers.Dense(128,activation='relu'))     #全连接网络层,128个神经元,relu激活函数
model.add(tf.keras.layers.Dense(10,activation='softmax'))   #输出层,10个节点
print(model.summary())      #查看网络结构和参数信息

#配置模型训练方法
#adam算法参数采用keras默认的公开参数,损失函数采用稀疏交叉熵损失函数,准确率采用稀疏分类准确率函数
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['sparse_categorical_accuracy'])   

#训练模型
#批量训练大小为64,迭代5次,测试集比例0.2(48000条训练集数据,12000条测试集数据)
print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print('训练前时刻:'+str(nowtime))

history = model.fit(X_train,y_train,batch_size=64,epochs=5,validation_split=0.2)

print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print('训练后时刻:'+str(nowtime))

#评估模型
model.evaluate(X_test,y_test,verbose=2)     #每次迭代输出一条记录,来评价该模型是否有比较好的泛化能力

#保存整个模型
model.save('CIFAR10_CNN_weights.h5')

#结果可视化
print(history.history)
loss = history.history['loss']          #训练集损失
val_loss = history.history['val_loss']  #测试集损失
acc = history.history['sparse_categorical_accuracy']            #训练集准确率
val_acc = history.history['val_sparse_categorical_accuracy']    #测试集准确率

plt.figure(figsize=(10,3))

plt.subplot(121)
plt.plot(loss,color='b',label='train')
plt.plot(val_loss,color='r',label='test')
plt.ylabel('loss')
plt.legend()

plt.subplot(122)
plt.plot(acc,color='b',label='train')
plt.plot(val_acc,color='r',label='test')
plt.ylabel('Accuracy')
plt.legend()

#暂停5秒关闭画布,否则画布一直打开的同时,会持续占用GPU内存
#根据需要自行选择
#plt.ion()       #打开交互式操作模式
#plt.show()
#plt.pause(5)
#plt.close()

#使用模型
plt.figure()
for i in range(10):
    num = np.random.randint(1,10000)

    plt.subplot(2,5,i+1)
    plt.axis('off')
    plt.imshow(test_x[num],cmap='gray')
    demo = tf.reshape(X_test[num],(1,32,32,3))
    y_pred = np.argmax(model.predict(demo))
    plt.title('标签值:'+str(test_y[num])+'\n预测值:'+str(y_pred))
#y_pred = np.argmax(model.predict(X_test[0:5]),axis=1)
#print('X_test[0:5]: %s'%(X_test[0:5].shape))
#print('y_pred: %s'%(y_pred))

#plt.ion()       #打开交互式操作模式
plt.show()
#plt.pause(5)
#plt.close()

运行结果

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

从红色框选的内容分别是训练样本的损失函数值和准确率、测试样本的损失函数值和准确率,可以看到它每次训练迭代时损失函数和准确率的变化,从最后一次迭代结果上看,测试样本的损失函数值达到0.9423,准确率仅达到0.6761。这个结果并不是很好,我尝试过增加迭代次数,发现训练样本的损失函数值可以达到0.04,准确率达到0.98;但实际上训练模型却产生了越来越大的泛化误差,这就是训练过度的现象,从图中可以看出泛化能力最好时是在迭代第5次的状态,故只能选择迭代5次。
在这里插入图片描述

但为了可以达到更高的准确率,和泛化能力,可以通过修改小批量梯度下降的数量、训练模型的方法、修改网络层的参数等等办法……。

五、训练好的模型文件——直接用

csdn资源下载链接:【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——附完整代码训练好的模型文件——直接用。:https://download.csdn.net/download/weixin_45954454/15648644?spm=1001.2014.3001.5501

<本文内容主要参考于《神经网络与深度学习-Tensorflow实践》>

出现问题可私信我解决,不定期查看。
————————————————

<后续还会继续整理【神经网络与深度学习】相关内容,如果需要,可持续关注我哦~>

<整理不易,留个赞或评论支持一下我吧^^>

如有疑问,欢迎批评指正^^

  • 100
    点赞
  • 472
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
深度学习(DL,Deep Learning)是机器学习(ML,Machine Learning)领域中一个新的研究方向,它被引入机器学习使其更接近于最初的目标——人工智能(AI,Artificial Intelligence)。 [1] 深度学习是学习样本数据的内在规律和表示层次,这些学习过程中获得的信息对诸如文字、图像和声音等数据的解释有很大的帮助。它的最终目标是让机器能够像人一样具有分析学习能力,能够识别文字、图像和声音等数据。 深度学习是一个复杂的机器学习算法,在语音和图像识别方面取得的效果,远远超过先前相关技术。 [1] 深度学习在搜索技术、数据挖掘、机器学习、机器翻译、自然语言处理、多媒体学习、语音、推荐和个性化技术,以及其他相关领域都取得了很多成果。深度学习使机器模仿视听和思考等人类的活动,解决了很多复杂的模式识别难题,使得人工智能相关技术取得了很大进步。 [1] 深度学习是一类模式分析方法的统称,就具体研究内容而言,主要涉及三类方法: [2] (1)基于卷积运算的神经网络系统,即卷积神经网络(CNN)。 [2] (2)基于多层神经元的自编码神经网络,包括自编码(Auto encoder)以及近年来受到广泛关注的稀疏编码两类(Sparse Coding)。 [2] (3)以多层自编码神经网络的方式进行预训练,进而结合鉴别信息进一步优化神经网络权值的深度置信网络(DBN)。 [2] 通过多层处理,逐渐将初始的“低层”特征表示转化为“高层”特征表示后,用“简单模型”即可完成复杂的分类等学习任务。由此可将深度学习理解为进行“特征学习”(feature learning)或“表示学习”(representation learning)。 [3] 以往在机器学习用于现实任务时,描述样本的特征通常需由人类专家来设计,这成为“特征工程”(feature engineering)。众所周知,特征的好坏对泛化性能有至关重要的影响,人类专家设计出好特征也并非易事;特征学习(表征学习)则通过机器学习技术自身来产生好特征,这使机器学习向“全自动数据分析”又前进了一步。 [3] 近年来,研究人员也逐渐将这几类方法结合起来,如对原本是以有监督学习为基础的卷积神经网络结合自编码神经网络进行无监督的预训练,进而利用鉴别信息微调网络参数形成的卷积深度置信网络。与传统的学习方法相比,深度学习方法预设了更多的模型参数,因此模型训练难度更大,根据统计学习的一般规律知道,模型参数越多,需要参与训练的数据量也越大。 [2] 20世纪八九十年代由于计算机计算能力有限和相关技术的限制,可用于分析的数据量太小,深度学习在模式分析中并没有表现出优异的识别性能。自从2006年,Hinton等提出快速计算受限玻耳兹曼机(RBM)网络权值及偏差的CD-K算法以后,RBM就成了增加神经网络深度的有力工具,导致后面使用广泛的DBN(由Hin

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路遥_.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值