第五讲卷积神经网络

本讲目标

用CNN实现离散数据的分类(以图像分类为例)

  1. 卷积计算过程
  2. 感受野
  3. 全零填充(Padding)
  4. TF描述卷积计算层
  5. 批标准化(Batch Normalization, BN)
  6. 池化(Pooling)
  7. 舍弃(Dropout)
  8. 卷积神经网络
  9. cifar10数据集
  10. 卷积神经网络搭建示例
  11. 实现LeNet、AlexNet、VGGNet、InceptionNet、ResNet五个经典神经网络

1、卷积计算过程

全连接神经网络:每个神经元与前后相邻层的每一个神经元都有连接关系,输入是特征,输出为预测的结果。

卷积:

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

输入特征图的深度(channel数),决定了当前层卷积核的深度;每个卷积核在卷积计算后,会得到一张输出特征图,当前层用了几个卷积核,就会有几张输出特征图,所以,当前卷积核的个数,决定了当前输出特征图的深度。在这里插入图片描述
单通道输入特征图的卷积计算
在这里插入图片描述
三通道输入特征图的卷积计算过程
在这里插入图片描述

2、感受野

卷积神经网络各输出特征图中的每个像素点,在原始输入图片上映射区域的大小。

3、全零填充

有时会希望输出特征图的尺寸保持不变,这个时候可以使用全零填充。

卷积输出特征图维度的计算公式:

  • 使用全零填充时,输出特征图边长: 输 入 特 征 图 边 长 步 长 \frac{输入特征图边长}{步长} (向上取整)
    在TF中用padding = ‘SAME’ 表示使用全零填充
  • 不使用全零填充时,输出特征图边长: 输 入 特 征 图 边 长 − 核 长 + 1 步 长 \frac{输入特征图边长-核长+1}{步长} +1(向上取整)
    在TF中用padding = 'VALID’表示不使用全零填充

4、TF描述卷积计算层

tf.keras.layers.Conv2D(
	filters = 卷积核个数,
	kernel_size = 卷积核尺寸,  # 正方形写核长整数,或(核高h, 核宽w)
	strides = 滑动步长,  # 横纵向写相同步长整数,或(纵向步长h,横向步长w),默认1
	padding = "same" or "valid",  # 默认valid
	activation = "relu" or "sigmoid" or "tanh" or "sofmax",  # 如有BN此处不写
	input_shape = (,, 通道数)  # 输入特征图维度,可省略
)

5、批标准化

标准化:使数据符合0均值,1为标准差的分布
批标准化:对一小批数据(batch),做标准化处理。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过上面的简单处理,会使数据完全符合标准正态分布,使激活函数丧失了非线性特性,因此为每个卷积核引入了两个可训练参数,缩放因子γ和偏移因子β。
在这里插入图片描述
在这里插入图片描述
BN层位于卷积层之后,激活层之前
TF描述标准化:

tf.keras.BatchNormalization()

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

6、池化

池化主要用于减少特征数据量
池化的主要方法有最大值池化和均值池化,最大值池化可提取图片文理,均值池化可保留背景特征。
在这里插入图片描述
TF描述池化

tf.keras.layers.MaxPool2D(
	pool_size = 池化核尺寸,  # 正方形写核长整数,或(核高h, 核宽w)
	strides = 池化步长,  # 步长整数,或(纵向步长h,横向步长w),默认为pool_size
	padding = "same" or "valid",  # 默认valid
)
tf.keras.layers.AveragePooling2D(
	pool_size = 池化核尺寸,  # 正方形写核长整数,或(核高h, 核宽w)
	strides = 池化步长,  # 步长整数,或(纵向步长h,横向步长w),默认为pool_size
	padding = "same" or "valid",  # 默认valid
)
model = tf.keras.models.Sequential([
	Conv2D(filters=6, kernel_size=(5, 5), padding="same"),   # 卷积层
	BatchNoemalization(),  # BN层
	Activation('relu'),  # 激活层
	MaxPool2D(pool_size=(2, 2), strides=2, padding='same'),  # 池化层
	Dropout(0.2),  # dropout层
])

7、舍弃

为了防止神经网络过拟合,在神经网络训练时,将一部分神经元按照一定概率从神经网络中暂时舍弃。神经网络使用时,被舍弃的神经元恢复链接。

TF描述舍弃

tf.keras.layers.Dropout(舍弃的概率)

model = tf.keras.models.Sequential([
	Conv2D(filters=6, kernel_size=(5, 5), padding="same"),   # 卷积层
	BatchNoemalization(),  # BN层
	Activation('relu'),  # 激活层
	MaxPool2D(pool_size=(2, 2), strides=2, padding='same'),  # 池化层
	Dropout(0.2),  # dropout层,0.2表示舍弃掉20%的神经元
])

8、卷积神经网络

卷积神经网络就是借助卷积核提取特征后,送入全连接神经网络
在这里插入图片描述
卷积就是特征提取器,就是CBAPD。

9、Cifar10数据集

提供了5万张32*32像素点的十分类彩色图片和标签,用于训练
提供了1万张32-32像素点的十分类彩色图片和标签,用于测试
在这里插入图片描述
导入Cifar10数据集

cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

# 可视化训练集输入特征的第一个元素
plt.imshow(x_train[0])  # 绘制图片
plt.show()

# 打印出训练集输入特征的第一个元素
print("x_train[0]:\n", x_train[0])

# 打印出训练集标签的第一个元素
print("y_train[0]:\n", y_train[0])

# 打印出整个训练集输入特征形状
print("x_train.shape:\n", x_train.shape)

# 打印出整个训练集标签的形状
print("y_train.shape:\n", y_train.shape)

# 打印出整个测试集输入特征的形状
print("x_test.shape:\n", x_test.shape)

# 打印出整个测试集标签的形状
print("y_test.shape:\n", y_test.shape)

10、卷积神经网络

卷积神经网络搭建示例
在这里插入图片描述
在这里插入图片描述

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()

###############################################    show   ###############################################

# 显示训练集和验证集的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()

11、LeNet

通过共享卷积核减少了网络的参数。
在统计卷积神经网络层数时,一般只统计卷积计算层和全连接计算层。
在这里插入图片描述

12、AlexNet

在这里插入图片描述

13、VGGNet

在这里插入图片描述

14、InceptionNet

在这里插入图片描述
用CBAPD描述Inception结构块
在这里插入图片描述
都采用了CBA操作,定义一个类减少代码长度
在这里插入图片描述

15、ResNet

提出了层间残差跳连,引入了前方信息。
在这里插入图片描述
在这里插入图片描述
将上述两个图封装到一个类中,当维度不同,会调用红色框里的代码,当维度相同,就不会调用红色框里的代码。
在这里插入图片描述

16、小结

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值