TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)

北大MOOC——TF2.0笔记

以下是我的听课笔记,供以后回忆(大多内容来自ppt)

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

1.卷积过程

实际项目中的图片多是高分辨率彩色图,参数比灰度图的还要多,待优化的参数过多容易导致模型过拟合。因此实际应用时会先对原始图像进行特征提取,再把提取到的特征送给全连接网络。

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

2.感受野

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

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第1张图片

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第2张图片

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第3张图片

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第4张图片

在效果相同的情况下,采用两次3x3的卷积计算,还是一次5x5的卷积计算呢?这就需要计算参数情况。

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第5张图片

3.全零填充

使卷积计算之后,为了使图像的尺寸保持不变,可以使用全零填充。

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第6张图片

4.TF描述卷积计算层

tf.keras.layers.Conv2D (

filters= 卷积核个数,

kernel_size = 卷积核尺寸, #正方形写核长整数,或(核高h,核宽w)

strides= 滑动步长, #横纵向相同写步长整数,或(纵向步长h,横向步长w),默认1

padding= “same” or “valid”, #使用全零填充是“same”,不使用是“valid”(默认)

activation= “ relu ” or “ sigmoid ” or “ tanh ” or “ softmax”等 , #如有BN此处不写

input_shape= (高, 宽 , 通道数)      #输入特征图维度,可省略 )

 5.批标准化(Batch Normalization, BN)

神经网络对0附近的数据更敏感,但是随着网络层数的增加,特征数据会出现偏离0均值的情况。

标准化:使数据符合0均值,1为标准差的分布。 把偏移的特征数据重新拉回到0附近。

批标准化:对一小批数据(batch),做标准化处理 。使数据回归标准正态分布,常用在卷积操作和激活操作之间。

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第7张图片

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第8张图片

参考其他博主文章: 

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第9张图片

BN操作一般放于卷积层与激活层之间。 

 6.池化层

池化用于减少卷积神经网络的特征数据量。 池化有最大池化和平均池化。

最大值池化可提取图片纹理,均值池化可保留背景特征。

tf.keras.layers.MaxPool2D(#最大池化

      pool_size=池化核尺寸,#正方形写核长整数,或(核高h,核宽w)

      strides=池化步长,#步长整数, 或(纵向步长h,横向步长w),默认为pool_size

      padding=‘valid’or‘same’#使用全零填充是“same”,不使用是“valid”(默认) )

tf.keras.layers.AveragePooling2D( #平均池化

      #参数与最大池化相同 ) 

7.舍弃(Dropout)

在神经网络训练时,将一部分神经元按照一定概率从神经网络 中暂时舍弃。神经网络使用时,被舍弃的神经元恢复链接。
tf.keras.layers.Dropout(舍弃的概率)

8.卷积神经网络

卷积神经网络:借助卷积核提取特征后,送入全连接网络。
特征提取:包括卷积、批标准化、激活、池化四个步骤。

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第10张图片

卷积是什么?

卷积就是特征提取器,就是CBAPD(卷积、BN批标准化、激活、池化、Dropout)

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第11张图片

卷积神经网络搭建示例:
一层卷积,两层全连接

使用6个 5x5的卷积核

过2x2的池化层,步长为2

128个神经元的全连接层

10个神经元的全连接层(cifar10是10分类 )

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第12张图片

经典卷积网络:

8.1 LeNet

LeNet是由Yann LeCun于1998年提出,卷积网络开篇之作

通过共享卷积核减少了网络的参数,参数一般只计算卷积计算层和全连接计算层,其余操作可认为是卷积计算层的附属。

LeNet一共有5层网络,两次卷积+三层连续的全连接

LeNet提出时还没有BN操作,也没有Dropout层。

最后一层全连接层使用softmax激活函数,使输出满足概率分布。其余两层使用sigmoid激活函数。

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第13张图片

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第14张图片

代码:

import tensorflow as tf
import os
import numpy as np

np.set_printoptions(threshold=np.inf)

fashion = tf.keras.datasets.fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

checkpoint_save_path = "./checkpoint/fashion.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()

结果:

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第15张图片

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第16张图片

 8.2 AlexNet

AlexNet网络诞生于2012年,当年ImageNet竞赛的冠军,Top5错误率为16.4%,使用relu激活函数,提升了速度,使用了dropout缓解了过拟合。

AlexNet共有8层,第一层

C:使用了96个3x3的卷积核

B:使用LRN标准化

A:relu

P:max,3x3,步长为2

D:无

共5层卷积层+3层全连接层

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第17张图片

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第18张图片

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第19张图片

8.3 VGGNet

VGGNet诞生于2014年,当年ImageNet竞赛的亚军,Top5错误率减小到7.3%

VGGNet使用小尺寸卷积核,在减少参数的同时,提高了识别准确率。

经过两次【CBA——>CBAPD】——>三次【CBA ——>CBA ——>CBAPD】——>三层全连接层

卷积核的个数从64—>128—>256—>512逐渐增加,越靠后,特征图尺寸越小,通过增加卷积核的个数,增加了特征图深度,保持了信息的承载能力。
 TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第20张图片

8.4 InceptionNet

InceptionNet诞生于2014年,当年ImageNet竞赛冠军,Top5错误率为6.67%
InceptionNet引入了Inception结构,在同一层网络内使用不同尺寸的卷积核,可以提取不同尺寸的特征,提升了模型感知力。使用了批标准化,缓解了梯度消失。

InceptionNet的核心是其基本单元Inception结构块,无论是GoogLeNet(也就是Inception v1),还是inceptionNet的后续版本(比如v2,v3,v4)都是基于inception结构块搭建的网络。

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第21张图片

通过1x1卷积核, 作用到输入特征图的每个像素点,通过设定少于输入特征图深度的1x1卷积核个数,减少了输出特征图深度,起到了降为的作用,减少了参数量和计算量。

Inception结构块包括四个分支,分别经过1x1卷积核输出到卷积连接器。

经过1x1卷积核配合3x3卷积核输出到卷积连接器

经过1x1卷积核配合5x5卷积核输出到卷积连接器

经过3x3最大池化核配合1x1卷积核输出到卷积连接器

送到卷积连接器的特征数据尺寸相同,卷积连接器会把收到的这四路特征数据按深度方向拼接。形成Inception结构块的输出。

网络共有10层,第一层使用16个3x3的卷积核,两个Inception结构块组成一个block,每一个block中的第一个Inception结构块卷积步长为2,使输出特征图尺寸减半,因此将输出图的深度加深,保持特征提取中信息的承载量相同。第二个Inception结构块卷积步长为1。

block_0:设置的通道数是16,经过了4个分支,输出的深度是4x16=64

block_1的通道数是block_0的两倍32,输出深度是4x32=128。

这128个通道的数据会被送入平均池化,再送入10分类的全连接。

8.5 ResNet 

ResNet诞生于2015年,当年ImageNet竞赛冠军,Top5错误率为3.57%。

ResNet提出了层间残差跳连,引入了前方信息,缓解梯度消失,使神经网络层数增加成为可能。

ResNet的作者何凯在cifar10数据集上做了个实验,发现56层卷积网络错误率高于与20层卷积网络。

单纯堆叠神经网络层数,会使神经网络模型退化,以至于后面的特征丢失了前边特征的原本模样。于是他用了一根跳连线,将前边的特征直接接到了后边,使输出的H(x)包含堆叠卷积的非线性输出F(x)和跳过这两层卷积直接连接过来的恒等映射的x,让它们对应元素相加。这一操作有效缓解了神经网络模型堆叠导致的退化,使得神经网络可以向着更深层级发展。

注意:

Inception块中的“+”是沿深度方向叠加(千层蛋糕层数叠加)

ResNet块中的“+”是特征图对应元素值相加(矩阵值相加)
TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第22张图片

ResNet块中有两种情况:一种情况用图中的实线表示,两层堆叠卷积,没有改变特征图的维度,也就它们特征图的个数、高、宽、深度都相同,可以直接将F(x)与x相加。

另一种情况:图中用虚线表示,两层堆叠卷积改变了特征图的维度,需要借助1x1卷积操作,调整x的维度,使W(x)与 F(x)的维度一致。

代码中,若堆叠卷积层前后维度不同,residual_path=1,使用1x1卷积层操作。

ResNet模型:先是一个卷积层,再是8个ResNet块,最后是一层全连接,每个ResNet块有两层卷积,一共是18层网络。

8.6  总结

TensorFlow2.0笔记(五)——用CNN实现离散数据的分类(以图像分类为例)_第23张图片

 

 

 

 

你可能感兴趣的:(深度学习)