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

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

  • 一、CIFAR-10数据集介绍
    • 1.1 CIFAR-10数据集的内容
    • 1.2 CIFAR-10数据集的结构组成
    • 1.3 CIFAR-10数据集的下载方式
    • 1.4 CIFAR-10数据集与CIFAR-100数据集(拓展)
    • 1.5 CIFAR-10数据集与MNIST数据集对比(拓展)
  • 二、卷积神经网络
    • 2.1卷积神经网络函数介绍
  • 三、模型训练思路
  • 四、代码实现——直接用
  • 五、训练好的模型文件——直接用

一、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数据集的内容,如图所示。
【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——[附完整训练代码]_第1张图片
(该图源于官网)
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编译好的二进制版本。
【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——[附完整训练代码]_第2张图片
方法二:
在Keras中已经内置了多种公共数据集,其中就包含CIFAR-10数据集,如图所示。
【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——[附完整训练代码]_第3张图片
所以可以直接调用 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_bias boolean,这个层是否使用偏差向量。
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()

运行结果

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

从红色框选的内容分别是训练样本的损失函数值和准确率、测试样本的损失函数值和准确率,可以看到它每次训练迭代时损失函数和准确率的变化,从最后一次迭代结果上看,测试样本的损失函数值达到0.9423,准确率仅达到0.6761。这个结果并不是很好,我尝试过增加迭代次数,发现训练样本的损失函数值可以达到0.04,准确率达到0.98;但实际上训练模型却产生了越来越大的泛化误差,这就是训练过度的现象,从图中可以看出泛化能力最好时是在迭代第5次的状态,故只能选择迭代5次。
【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——[附完整训练代码]_第7张图片

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

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

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

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

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

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

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

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

你可能感兴趣的:(神经网络与深度学习,tensorflow,深度学习,机器学习,神经网络,python)