TensorFlow搭建卷积神经网络:以Cifar10数据集分类为例

全连接神经网络

  • 全连接网络特点:每个神经元与前后相邻层的每一个神经元都有连接关系。(可以实现分类和预测)
  • 全连接网络的参数个数为: ∑ ( 前 层 × 后 层 + 后 层 ) \sum(前层\times后层+后层) (×+)

  虽然全连接网络一般被认为是分类预测的最佳网络,但待优化的参数过多,容易导致模型过拟合。为了解决参数量过大而导致模型过拟合的问题,一般不会将原始图像直接输入,而是先对图像进行特征提取,再将提取到的特征输入全连接网络。

卷积神经网络基础模块

1. 卷积Convolutional

  卷积计算可认为是一种有效提取图像特征的方法。一般会用一个正方形的卷积核,按指定步长,在输入特征图上滑动,遍历输入特征图中的每个像素点。每一个步长,卷积核会与输入特征图出现重合区域,重合区域对应元素相乘、求和再加上偏置项得到输出特征的一个像素点。

  • 输入特征图的深度(channel数),决定了当前层卷积核的深度;
  • 当前层卷积核的个数,决定了当前层输出特征图的深度。

感受野Receptive Field

  感受野是指卷积神经网络各输出特征图中的每个像素点,在原始输入图片上映射区域的大小。
在这里插入图片描述
  当我们采用尺寸不同的卷积核时,最大的区别就是感受野的大小不同,所以经常会采用多层小卷积核来替换一层大卷积核,在保持感受野相同的情况下减少参数量和计算量。例如十分常见的用2层 3 × 3 3\times 3 3×3卷积核来替换1层 5 × 5 5\times 5 5×5卷积核的方法,

  • 输出特征边长=(输入特征边长-卷积核长+1)/步长
  • 两层 3 × 3 3\times3 3×3卷积核计算量: 9 × ( x − 3 + 1 ) 2 + 9 × ( x − 3 + 1 − 3 + 1 ) 2 = 18 x 2 − 108 x + 180 9\times(x-3+1)^2+9\times(x-3+1-3+1)^2=18x^2-108x+180 9×(x3+1)2+9×(x3+13+1)2=18x2108x+180
  • 一层 5 × 5 5\times 5 5×5卷积核计算量: 25 × ( x − 5 + 1 ) 2 = 25 x 2 − 200 x + 400 25\times(x-5+1)^2=25x^2-200x+400 25×(x5+1)2=25x2200x+400

全零填充Padding

  为了保持输出图像尺寸与输入图像一致,经常会在输入图像周围进行全零填充。

在这里插入图片描述

TF描述卷积层

在这里插入图片描述

model = tf.keras.models.Sequential([
	Conv2D(6, 5, padding='valid', activation='sigmoid'),
	MaxPool2D(2, 2),
	Conv2D(6, (5, 5), padding='valid', activation='sigmoid'),
	MaxPool2D(2, (2, 2)),
	Conv2D(filters=6, kernel_size=(5, 5),padding='valid',activation='sigmoid'),
	MaxPool2D(pool_size=(2, 2), strides=2),
	Flatten(),
	Dense(10, activation='softmax')
	])

2. 批标准化Batch Normalization,BN

  • 标准化:使数据符合0均值,1为标准差的分布。
  • 批标准化:对一小批数据(batch),做标准化处理。

  当使用随机梯度下降来训练网络时,每次参数更新都会导致该神经层的输入分布发生改变。从机器学习角度来看,如果一个神经层的输入分布发生了改变,那么其参数需要重新学习,这种现象叫作内部协变量偏移(Internal Covariate Shift)。Batch Normalization将神经网络每层的输入都调整到均值为0,方差为1的标准正态分布,可以解决内部协方差偏移问题及神经网络中梯度消失的问题。将原本偏移的特征数据,拉回到0均值,使进入激活函数的数据分布在激活函数线性区域,使得输入数据的微小变换更明显地体现到激活函数的输出,提升了激活函数对输入数据的区分力。
在这里插入图片描述
  对净输入的标准归一化会使得其取值集中到0 附近,如果使用Sigmoid型激活函数时,这个取值区间刚好是接近线性变换的区间,减弱了神经网络的非线性性质。因此,为了使得归一化不对网络的表示能力造成负面影响,可以通过一个附加的缩放平移变换改变取值区间。
在这里插入图片描述
  BN操作通常位于卷积层之后,激活层之前,在Tensorflow框架中,通常使用Keras中的tf.keras.layers.BatchNormalization()函数来构建BN层。

  • 在调用此函数时,需要注意的一个参数是training,此参数只在调用时指定,在模型进行前向推理时产生作用,当training = True时,BN操作采用当前batch的均值和标准差;当training = False时,BN操作采用滑动平均(running)的均值和标准差。在Tensorflow中,通常会指定training = False,可以更好地反映模型在测试集上的真实效果。滑动平均(running) 即通过一个个batch历史的叠加,最终趋向数据集整体分布的过程,在测试集上进行推理时,滑动平均的参数也就是最终保存的参数。
  • Tensorflow中的BN函数其实还有很多参数,其中比较常用的是momentum,即动量参数,与sgd优化器中的动量参数含义类似但略有区别,具体作用为滑动平均running = momentum * running + (1 – momentum) * batch,一般设置一个比较大的值,在Tensorflow框架中默认为0.99。

12. 批标准化(Batch Normalization )
【深度学习】深入理解Batch Normalization批标准化

3. 池化Pooling

  • 池化的作用是减少特征数量(降维)。
  • 最大值池化可提取图片纹理,均值池化可保留背景特征。

  在Tensorflow框架下,可以利用Keras来构建池化层,使用的是tf.keras.layers.MaxPool2D函数和tf.keras.layers.AveragePooling2D函数,
在这里插入图片描述

model = tf.keras.models.Sequential([
	Conv2D(filters=6, kernel_size=(5, 5), padding='same'), # 卷积层
	BatchNormalization(), # BN层
	Activation('relu'), # 激活层
	MaxPool2D(pool_size=(2, 2), strides=2, padding='same'), # 池化层
	Dropout(0.2), # dropout层
	])

4. 舍弃Dropout

  在神经网络的训练过程中,将一部分神经元按照一定概率从神经网络中暂时舍弃,使用时被舍弃的神经元恢复链接。在Tensorflow框架下,利用tf.keras.layers.Dropout(p)函数构建Dropout层,参数为舍弃的概率(大于0小于1)。
在这里插入图片描述

tf.keras搭建卷积神经网络八股

  • 卷积神经网络:借助卷积核提取特征后,送入全连接网络。
  • 卷积就是特征提取器,就是CBAPD。
    在这里插入图片描述
  • 第一步:import引入tensorflow及keras、numpy等所需模块。
  • 第二步:读取数据集,有的数据集可以从sklearn等模块中引入,但是在实际应用中,大多需要从图片和标签文件中读取所需的数据集。
  • 第三步:搭建所需的网络结构,当网络结构比较简单时,可以利用keras模块中的tf.keras.Sequential来搭建顺序网络模型;但是当网络不再是简单的顺序结构,而是有其它特殊结构出现时(例如ResNet中的跳连结构),便需要利用class来定义自己的网络结构。前者使用起来更加方便,但实际应用中往往需要利用后者来搭建网络。
  • 第四步:对搭建好的网络进行编译(compile),通常在这一步指定所采用的优化器(如Adam、sgd、RMSdrop等)以及损失函数(如交叉熵函数、均方差函数等),选择哪种优化器和损失函数往往对训练的速度和效果有很大的影响。
  • 第五步:将数据输入编译好的网络来进行训练(model.fit),在这一步中指定训练轮数epochs以及batch_size等信息,由于神经网络的参数量和计算量一般都比较大,训练所需的时间也会比较长,尤其是在硬件条件受限的情况下,所以在这一步中通常会加入断点续训以及模型参数保存等功能,使训练更加方便,同时防止程序意外停止导致数据丢失的情况发生。
  • 第六步:将神经网络模型的具体信息打印出来(model.summary),包括网络结构、网络各层的参数等,便于对网络进行浏览和检查。

卷积神经网络搭建示例——Cifar10数据集

  cifar10数据集介绍:该数据集共有60000张彩色图像,每张尺寸为32 * 32,分为10类,每类6000张。训练集50000张,分为5个训练批,每批10000张;从每一类随机取1000张构成测试集,共10000张,剩下的随机排列组成训练集。

Github网站上cifar10数据集分类准确率的排行榜

#----------------------
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
from tensorflow.keras import Model

np.set_printoptions(threshold=np.inf)
#----------------------
cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

#----------------------
class Baseline(Model):
    def __init__(self):
        super(Baseline, self).__init__()
        self.c1 = Conv2D(filters=6, kernel_size=(5, 5), padding='same')  # 卷积层
        self.b1 = BatchNormalization()  # BN层
        self.a1 = Activation('relu')  # 激活层
        self.p1 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')  # 池化层
        self.d1 = Dropout(0.2)  # dropout层

        self.flatten = Flatten()
        self.f1 = Dense(128, activation='relu')
        self.d2 = Dropout(0.2)
        self.f2 = Dense(10, activation='softmax')

    def call(self, x):
        x = self.c1(x)
        x = self.b1(x)
        x = self.a1(x)
        x = self.p1(x)
        x = self.d1(x)

        x = self.flatten(x)
        x = self.f1(x)
        x = self.d2(x)
        y = self.f2(x)
        return y


model = Baseline()
#----------------------
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])
#----------------------
checkpoint_save_path = "./checkpoint/Baseline.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
                                                 save_weights_only=True,
                                                 save_best_only=True)

history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,
                    callbacks=[cp_callback])
#----------------------
model.summary()

# print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:
    file.write(str(v.name) + '\n')
    file.write(str(v.shape) + '\n')
    file.write(str(v.numpy()) + '\n')
file.close()

#----------------------
# 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']

plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()

北大人工智能实践:Tensorflow笔记

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值