TensorFlow笔记_卷积神经网络搭建

1.预备知识

在实际应用中,图像大多是彩色图像,虽然全连接网络一般被认为是分类预测的最佳网络,但待优化的参数过多,容易导致模型过拟合。

TensorFlow笔记_卷积神经网络搭建_第1张图片

为了解决参数量过大而导致模型过拟合的问题,一般不会将原始图像直接输入,而是先对图像进行特征提取,再将提取到的特征输入全连接网络。

1.1卷积

卷积是一种有效提取图像特征的方法。用一个正方形的卷积核,按指定步长在输入特征图上滑动,遍历输入特征图中的每个像素点。每一个步长,卷积核会与输入特征图出现重合区域,重合区域对应元素相乘后求和再加上偏置项得到输出特征的一个像素点。下图利用3*3*1的卷积核对5*5*1的单通道图像做卷积后得到的结果。

TensorFlow笔记_卷积神经网络搭建_第2张图片

对于彩色图像(多通道),卷积核通道数与输入特征通道数一致,用多个卷积核可实现对同一层输入特征的多次特征提取,卷积核的个数决定输出层的通道数,即输出特征图的深度。下图利用三通道卷积核对三通道彩色特征图做卷积计算。

TensorFlow笔记_卷积神经网络搭建_第3张图片

1.2感受野

感受野是卷积神经网络各输出层每个像素点在原始图像上的映射区域大小。

TensorFlow笔记_卷积神经网络搭建_第4张图片

 采用不同尺寸的卷积核时,最大的区别就是感受野的大小不同,将常采用多层小卷积核来替换一层大的卷积核,在保持感受野相同的情况下减少参数量和计算量。下图采用2层3*3卷积核替换1层5*5卷积核,当x大于10时,两层3*3卷积核优于一层5*5卷积核。

TensorFlow笔记_卷积神经网络搭建_第5张图片

设输入特征图的宽、高均为x,卷积计算的步长为1,显然,两个3 * 3卷积核的参数量为9 + 9 = 18,小于5 * 5卷积核的25,前者的参数量更少。

在计算量上,输出特征尺寸计算公式:输出图片边长=(输入图片边长 -卷积核长+1)/ 步长,对于5 * 5卷积核来说,输出特征图共有(x – 5 + 1)^2个像素点,每个像素点需要进行5 * 5 = 25次乘加运算,则总计算量为25 * (x – 5 + 1)^2 = 25x^2 – 200x + 400;对于两个3 * 3卷积核来说,第一个3 * 3卷积核输出特征图共有(x – 3 + 1)^2个像素点,每个像素点需要进行3 * 3 = 9次乘加运算,第二个3 * 3卷积核输出特征图共有(x – 3 + 1 – 3 + 1)^2个像素点,每个像素点同样需要进行9次乘加运算,则总计算量为9 * (x – 3 + 1)^2 + 9 * (x – 3 + 1 – 3 + 1)^2 = 18 x^2 – 108x + 180。

1.3全零填充

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

 在Tensorflow框架中,用参数padding = ‘SAME’或padding = ‘VALID’表示是否进行全零填充,其对输出特征尺寸大小的影响如下:

TensorFlow笔记_卷积神经网络搭建_第6张图片

 2.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= (高, 宽, 通道数) #输入特征图维度,可省略
)

 2.1BN批标准化

标准化:是数据符合均值为0,标准差为1的分布

批标准化:对一小批数据(batch),做标准化处理

TensorFlow笔记_卷积神经网络搭建_第7张图片

Batch Normalization将神经网络每层的输入都调整到均值为0方差为1的标准正态分布,其目的是解决神经网络中梯度消失的问题。

TensorFlow笔记_卷积神经网络搭建_第8张图片

 Batch Normalization另一个重要作用是缩放和偏移,缩放因子和偏移因子都是可训练参数

TensorFlow笔记_卷积神经网络搭建_第9张图片

 BN层位于卷积层之后,激活层之前

tf.keras.layers.BatchNormalization()

2.2池化

 池化用于减少特征数据量。最大池化可提取图片纹理,均值池化可保留背景特征。

TensorFlow笔记_卷积神经网络搭建_第10张图片

tf.keras.layers.MaxPool2D(pool_size=池化核尺寸,#正方形写核长整数,或(核高h,核宽w)
                          strides=池化步长,#步长整数,或(纵向步长h,横向步长w),默认为1
                          pool_sizepadding=‘valid’or‘same’#使用全零填充是“same”,不使用是“valid”(默认)
)

tf.keras.layers.AveragePooling2D(pool_size=池化核尺寸,#正方形写核长整数,或(核高h,核宽w)
                                 strides=池化步长,#步长整数,或(纵向步长h,横向步长w),默认为1
                                 pool_sizepadding=‘valid’or‘same’#使用全零填充是“same”,不使用是“valid”(默认)
)

2.3舍弃

在神经网络训练时,将一部分神经元按照一定概率从神经网络中暂时舍弃,神经网络使用时,被舍弃的神经元恢复连接。

TensorFlow笔记_卷积神经网络搭建_第11张图片

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

3卷积神经网络搭建

卷积神经网络:借助卷积核提取特征后,送入全连接网络。

TensorFlow笔记_卷积神经网络搭建_第12张图片

 Cifar10数据集:提供5万张32*32 像素点的十分类彩色图片和标签,用于训练。提供1万张32*32 像素点的十分类彩色图片和标签,用于测试。

TensorFlow笔记_卷积神经网络搭建_第13张图片

TensorFlow笔记_卷积神经网络搭建_第14张图片

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

TensorFlow笔记_卷积神经网络搭建_第15张图片

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