TF10——卷积神经网络搭建示例


TF10——卷积神经网络搭建示例

用卷积神经网络训练cifar10数据集,搭建一个一层卷积,两层全连接的网络

  • 使用6个5*5卷积核,过2*2池化核,池化步长是2
  • 过128个神经元的全连接层
  • 由于cifar10是10分类,所以最后还要过一层十个神经元的全连接层

根据搭建卷积网络的八股口诀CBAPD ,搭建如下神经网络:

image-20220320131026802

C:6个5*5的卷积核,步长是1,使用全零填充

B:使用批标准化

A:使用relu激活函数

P:使用最大池化,池化核是2*2,池化步长是2,使用全零填充

D:把20%的神经元休眠

Flatten把卷积送过来的数据拉直

送入128个神经元的全连接,过relu激活,过0.2的Dropout

过10个神经元的全连接,过softmax函数使输出符合概率分布

代码实现

image-20220320131659745

由于网络相对复杂了,所以我用class类搭建网络结构

image-20220320131805957

__init__函数中,准备出搭建神经网络要用到的每一层结构,卷积网络就是CBAPD,

  • C里面有6个卷积核,每个卷积核都是5*5的尺寸,使用全零填充

  • B使用批标准化

  • A使用relu激活函数

  • P使用最大池化,池化核是2*2,池化步长是2,使用全零填充

  • D把20%的神经元休眠

  • Flatten把卷积送过来的数据拉直

  • 送入128个神经元的全连接,过relu激活

  • 把20%的神经元休眠

  • 过10个神经元的全连接,过softmax函数使输出符合概率分布

在call函数中,调用__init__函数里搭建好的每层网络结构,从输入到输出过一次前向传播,返回推理结果y

用六步法写出的代码是这样的:

源码:p27_cifar10_baseline.py

## import部分
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)#解决输出数组时的省略情况

## train test 给训练集与测试集输入特征、训练集与测试集标签
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 model
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 配置训练方法,告诉训练时选择哪种优化器,选择哪个损失函数,选择哪种评测指标
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)

## model.fit执行训练过程,告诉训练集和测试集的输入特征和标签,告知每个batch是多少,告知要迭代多少次数据集,告知测试集,告知多少次数据集迭代用测试集验证准确率,使用回调函数实现断点续训
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打印出网络的结构和参数
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可视化
###############################################    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()

上述代码作为后一讲后续内容的基准代码,在介绍经典卷积神经网络结构时,我们只替换class model模块的内容其余代码不变

程序运行结果:

随着迭代次数的增加,准确率在不断的提高!

打印出了acc/loss可视化效果

image-20220320134410789

在weight.txt文件里记录了所有的可训练参数

image-20220320134719714

image-20220320135623664

image-20220320135754338

image-20220320135846710

image-20220320135929313

我们可以在任何平台复现出神经网络的前向传播实现应用