第三章:Tensorflow 2.0 利用高级接口实现对cifar10 数据集的全连接(理论+实战实现)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/LQ_qing/article/details/99859735

 

理论部分

一、cifar 10 数据集简介

cifar 10相比于MNIST数据集而言更为复杂,其拥有10个种类(猫、飞机、汽车、鸟、鹿、狗、青蛙、马、船卡车),这十大类共同组成了50k的训练集,10k的测试集,每一张图片都是32*32的3通道图片(彩色图片),在神经网络中,通常表示成如下形式:

                                                                              [b , w, h, c] =  [b, 32 ,32, 3]

下面给出一些cifar 10 中的部分图片。我们可以看出,32*32尺寸的彩色图片是不够清晰的,所以相比于MNIST数据集,cifar 10 数据集更为复杂,少奶奶利用全连接层进行训练的话准确率最多达到0.46,但利用卷积神经网络进行计算的话,准确率大概是全连接层的两倍,这就是为什么卷积神经网络比全连接网络更受欢迎的原因。对于卷积神经网络,少奶奶将在后续博文中详细介绍,这里就不再展开赘述了。

                                         

二、损失函数------交叉熵

神经网络中给的熵

熵在不同的运用范围里,其表达的主体是不同的,在神经网络中,熵表达的意义是恒量信息的不确定度,即信息的稳定程度可以通过熵进行量化,熵越小,包含信息就越多也越不稳定,熵越大则包含的信息就越少也越稳定,具体计算公式如下:

                                                                   H(X) =-\sum_{x}^{\; }{p(x) \log_{2}}\: p(x)  

例如:a = [0.25, 0.25, 0.25, 0.25]  b =  [0, 0,0, 0.25]

根据公式计算可得:

H(a) = -(0.25*\log_{2} 0.25 +0.25*\log_{2} 0.25 +0.25*\log_{2} 0.25 +0.25*\log_{2} 0.25 )

H(a) = 2

H(b) = -(0*\log_{2}0 +0*\log_{2} 0 +0*\log_{2} 0 +0.25*\log_{2} 0.25 )

H(b) = 0.5

由于a的熵值比b的大,所以a包含的信息比b更加稳定,我们观察可得,a中的数值变化不大,所以稳定,而b中的数值变化是比较大的, 所以其不稳定

 神经网络中的交叉熵

神经网络中的交叉熵恒量的是两个分布之间的稳定程度,通俗的讲,就是恒量标签和预测值之间的距离大小,若预测值和标签相差很大,则说明预测值中的最大值和最小值相差不大,预测结果中的数值稳定(如a所示),若预测值和标签相差不大,则说明预测值中的最大值和最小值相差很大。预测结果中的数值非常不稳定(如b所示),在神经网络中,我们希望交叉熵越小越好,即预测结果中的数值越不稳定越好。因为交叉熵越不稳定,那么预测值中数值最大的一类最有可能是正确的结果,而交叉熵越稳定,那么预测值中的较大值会出现好几个,我们就无法判断最有可能是正确的结果,具体公式如下:

                                                                  H(p(x),q(x)) =-\sum_{x}^{\; }{p(x) \log_{2}}\: q(x)

而交叉熵的公式还可以表示成如下形式 :

                                                                   H(p(x),q(x)) =H(p)+D_{KL}(p|q)

其中:H(p)表示熵,D_{KL}(p|q)表示p和q之间的散度,当p=q时,D_{KL}(p|q)=0,那么上述公式就会变成熵的计算公式。

交叉熵在神经网络中的运用

在神经网络中,交叉熵主要用于损失函数,实现标签和预测值之间的损失计算,下面少奶奶将具体讲解其计算流程。

例如:

                   输入一张图片:image = [1, 32, 32, 3] ,其代表cat。在cifar 10中,cat的标签label=3,则转化成one_hot编码是

                    one_hot = [ 0,0,0,1,0,0,0,0,0,0]

                    模型的预测值:pre = [ 0.01,0.01,0.01,0.91,0.01,0.01,0.01,0.01,0.01,0.01 ]

                     loss=-\sum_{x}^{\; }{p(x) \log_{2}}\: q(x)

                     loss= -(0*\log_{2}0.01 +0*\log_{2}0.01 +0*\log_{2}0.01 +1*\log_{2}0.91 +0*\log_{2}0.01 +0*\log_{2}0.01 +0*\log_{2}0.01 +0*\log_{2}0.01 +0*\log_{2}0.01 +0*\log_{2}0.01 )

                  loss= -1*\log_{2}0.91

通过上述计算,我们可以明白,利用交叉熵对One_hot编码的数据进行损失计算是可行的,当然,通过对交叉熵进行求导然后根据学习率去更新权重也是可行的,只不过Tensorflow会自动为我们进行求导操作,若想知道其反向传播的本质是什么,大家可以查看少奶奶写的前置博文,希望对大家能有所帮助,

                                第一章:Tensorflow 2.0 实现简单的线性回归模型(理论+实践)

Tensorflow 2.0 提供的高级接口--------keras 

 

首先,keras并不是tf.keras,这里提到的keras是Tensorflow 2.0 重新封装的高级接口,其拥有的操作方法 例如:Sequential、

complie、layers、losses、metries等,对我们构建神经网络时拥有很好的封装,我们只需要写很少的代码就能实现一个比较复杂的神经网络,当然,我们也可以利用keras自定义神经网络,少奶奶将在下一章进行讲解。这一节,少奶奶主要讲解如何利用keras的一些核心接口,实现网络层的构建。

什么是keras .Sequential()?

Sequential主要是构建神经网络模型的函数,具体用法如下:

首先在前面引入相应模块

直接调用Sequential对象

其后面填入的是一个list集合,集合里都是继承了keras.layer.Layer的对象,其中Layer对象用于定义每一层的参数数量和激活函数。上述代码代表的是,利用Sequential构建五层的全连接网路。

什么是keras.metries?

 

 

在训练中,我们通常都会计算loss值和准确率,为了使得loss值和准确率更加具有代表性,我们通常在所有训练集在迭代完一次后统计以下loss值和准确率,而在计算时,其方法和步骤是固定的,所以,Tensorflow提供了metries这个接口,我们只需要在对应位置调用该接口 就能轻松实现对loss值和准确率的计算。

什么是keras.complie?

在写训练相关代码时,我们通常的步骤如下:

步骤一:把训练集划分成不同批次进行训练

步骤二:计算梯度和loss值

步骤三:反向梯度更新

步骤四:投入测试数据进行测试

由于这四步是固定化的,没有什么技术含量,所以Tensorflow使用了complie对这些固定的结构进行封装,因此,我们只需要简单的几行代码就可以轻松实现上述四步。

上面的代码分别设置了优化函数(Adam)和学习率(lr = 0.01),损失函数(CategoricalCrossentropy),以及正确率

上面的代码设置了投喂的训练数据,整个训练数据需要重复训练的次数,测试数据以及每隔多少训练次数就进行一次测试。

例如,使用train_db用作训练数据,该训练数据需要重复训练5次,每隔2次输出一次测试结果,test_db为测试数据.

实战部分


 
 
  1. import tensorflow as tf
  2. from tensorflow import keras
  3. from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics
  4. import matplotlib.pyplot as plt
  5. import io
  6. import datetime
  7. (x, y), (test_x, test_y) = datasets.cifar10.load_data()
  8. # 数据预处理
  9. def progress (x ,y):
  10. x = 2 * tf.cast(x, dtype=tf.float32) / 255. - 1.
  11. x = tf.reshape(x, [ -1, 32* 32* 3])
  12. y = tf.one_hot(y, depth= 10, dtype=tf.int32)
  13. return x, y
  14. # 构建dataset对象 方便对数据的管理
  15. db_train = tf.data.Dataset.from_tensor_slices((x,y)).shuffle( 1000)
  16. db_test = tf.data.Dataset.from_tensor_slices((test_x,test_y))
  17. # deal with data
  18. train_db = db_train.map(progress).batch( 128)
  19. test_db = db_test.map(progress).batch( 128)
  20. train_iter = iter(train_db)
  21. train_next = next(train_iter)
  22. print(train_next[ 0].shape)
  23. # 利用Tensorflow的Sequential容器去构建model
  24. model = Sequential([
  25. layers.Dense( 256, activation=tf.nn.relu),
  26. layers.Dense( 128, activation=tf.nn.relu),
  27. layers.Dense( 64, activation=tf.nn.relu),
  28. layers.Dense( 32, activation=tf.nn.relu),
  29. layers.Dense( 10)
  30. ])
  31. model.build(input_shape=[ None, 32* 32* 3])
  32. model.summary()
  33. # 利用Sequential的compile方法,简化损失函数,梯度优化,计算准确率等操作
  34. model.compile(optimizer=optimizers.Adam(lr = 0.01),
  35. loss = tf.losses.CategoricalCrossentropy(from_logits= True),
  36. metrics=[ 'accuracy']
  37. )
  38. # 设置模型对整体数据重复训练5次,每训练2次打印一次正确率
  39. model.fit(train_db, epochs= 5, validation_data = test_db,
  40. validation_freq= 2)
  41. # 另一种打印模型正确率的接口方法
  42. model.evaluate(test_db)

训练结果

我们可以看到,利用五层全连接实现对cifar10的训练,准确率只有0.46,并不算太高,这也从侧面反映了全连接网络对于处理复杂数据集的不足,下一篇,少奶奶将介绍利用keras的自定义网络功能实现对cifar10的全连接训练(理论+实战),欢迎大家浏览查看  

 

开篇:开启Tensorflow 2.0时代

第一章:Tensorflow 2.0 实现简单的线性回归模型(理论+实践)

第二章:Tensorflow 2.0 手写全连接MNIST数据集(理论+实战)

第三章:Tensorflow 2.0 利用高级接口实现对cifar10 数据集的全连接(理论+实战实现)

第四章:Tensorflow 2.0 实现自定义层和自定义模型的编写并实现cifar10 的全连接网络(理论+实战)

第五章:Tensorflow 2.0 利用十三层卷积神经网络实现cifar 100训练(理论+实战)

第六章:优化神经网络的技巧(理论)

第七章:Tensorflow2.0 RNN循环神经网络实现IMDB数据集训练(理论+实践)

第八章:Tensorflow2.0 传统RNN缺陷和LSTM网络原理(理论+实战)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值