Keras搭建卷积神经网络模型

Keras搭建卷积神经网络

卷积就是特征提取器,就是CBAPD。

1.卷积Conv2D

TensorFlow给出了计算卷积的函数:

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.批标准化BN(Batch Normalization)

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

《Keras搭建卷积神经网络模型》
BN 操作将原本偏移的特征数据,重新拉回到0均值,使进入激活函数的数据分布在激活函数线性区(如sigmod作为激活函数,则数据之分布在0附近的那些导数较大的,近似于线性的区域,如下图),使得输入数据的微小变化,更明显地体现到激活函数的输出,提升了激活函数对输入数据的区分力;
《Keras搭建卷积神经网络模型》
但是,这种简单的特征数据标准化,使特征数据完全满足标准正态分布,集中在激活函数中心的线性区域,使激活函数丧失了非线性特性;
因此,在BN 操作中为每个卷积核引入了两个可训练的参数:缩放因子和偏移因子。如图:
《Keras搭建卷积神经网络模型》
反向传播时,这两个参数会与其它待训练参数一同被训练优化,使标准正态分布后的数据通过这两个参数,优化了特征数据的宽窄和偏移量,保证了网络的非线性表达力。
BN 层位于卷积层之后,激活层之前,语句为:

tf.keras.layers.BatchNormalization()

3.激活Activation

在有BN层存在时,激活函数不再卷积层写,而在此处的激活层,格式为:

使用relu作为激活函数
Activation(‘relu’)

4.池化Pool2D

池化操作用于减少卷积神经网络中特征数据量,池化的主要方法有最大值池化和均值池化:最大值池化可以提取图片纹理;均值池化可保留背景特征。

最大池化函数格式为:

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

均值池化函数格式为:

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

5.舍弃Dropout

为了缓解神经网络过拟合,在神经网络训练过程中,常把隐藏层的部分神经元按照一定比例从神经网络中临时舍弃;在使用神经网络时,再把所有神经元恢复到神经网络中。
TensorFlow提供了Dropout函数:

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

总结

《Keras搭建卷积神经网络模型》在这五步完成后再进行全连接网络层,即完成了卷积神经网络的搭建。

实例如下:
《Keras搭建卷积神经网络模型》
代码如下(数据集代码内会自己下载,这里因为网络比较复杂,所以推荐使用class自建网络结构):

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()
    原文作者:NNNJY
    原文地址: https://blog.csdn.net/qq_35925375/article/details/115206387
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞