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

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

全零填充

目的:希望卷积计算保持输入特征图的尺寸不变

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

使用全零填充 padding = “SAME”

不使用全零填充 padding = “VALID”

TF描述卷积层

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

批标准化(BN)

批标准化(Batch Normalization)

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

批标准化后,第k个卷积核的输出特征图(feature map)中第i个像素点

可以通过下面式子计算批标准化后的输出特征图

H’表示第k个卷积核,输出特征图中的第i个像素点

批标准化操作会让每个像素点进行减=均值除以标准差的自更新计算,对于第k个卷积核,batch张输出特征图中,所有数值的平均值和标准差

BN为每个卷积核引入可训练参数γ和β,调整批归一化的力度

池化

池化用于减少特征数据量

池化方法

  • 最大值池化可提取图片纹理
  • 均值池化可保证背景特征

TF描述池化:

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

舍弃

目的:缓解神经网络过拟合

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

TF描述池化:tf.keras.layers.Dropout(舍弃的概率)

卷积神经网络

卷积神经网络的主要模块

【卷积(Convolutional) -> 批标准化(BN) -> 激活(Activation) -> 池化(Pooling) ->】-> 全连接(FC)

卷积是什么:卷积就是特征提取器,就是CBAPD

model = tf.keras.models.Sequential([    Conv2D(filters = 6,kernel_size=(5,5),padding='same'),# 卷积层 C    BatchNormalization(),# 批标准化。 BN层 B    Activation('relu'), # 激活层 A    MaxPool2D(pool_size=(2,2),strides=2,padding='same') # 池化层 P    Dropout(0.2), # 舍弃。  dropout层 D])

Cifar10数据集

提供五万张32 * 32像素点的十分类彩色图片和标签,用于训练

提供一万张32 * 32像素点的十分类彩色图片和标签,用于测试

(每张图片有32行 32列像素点的红绿蓝三通道数据)

导入cifar10数据集

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

完整代码如下:

import tensorflow as tffrom matplotlib import pyplot as pltimport numpy as npnp.set_printoptions(threshold=np.inf)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)## 需要查看运行结果自行解除这一大段的注释



卷积神经网络搭建

·
搭建一个一层卷积,两层全连接的网络

使用5个5X5的卷积核 ( 5*5 conv,filter=6)过2X2的池化核,池化步长是2(2*2 pool,strides=2),过128个神经元的全连接层(Dense 128

由于cifar10是十分类,因此最后还要过一层十个神经元的全连接层

进行分析,分析思路CBAPD

C (核:6 * 6 * 5 ;步长:1 ;填充:same)

B (Yes) # 意为使用批标准化

A (relu)

P (max;核:2 * 2 ;步长:2 ; 填充:same)

D (0.2) # 把20%的神经元休眠

Flatten

Dense(神经元:128 ; 激活:relu ; Dropout:0.2)

Dense(神经元:10 ; 激活:softmax) # 过softmax函数使输出符合概率分布

代码实现如下:

from tensorflow.keras import Modelclass 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) # 按照20%比例休眠神经元        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

完整代码如下:

import tensorflow as tfimport osimport numpy as npfrom matplotlib import pyplot as pltfrom tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Densefrom tensorflow.keras import Modelnp.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.0class 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 ymodel = 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()
-------------load the model-----------------Epoch 1/51563/1563 [==============================] - 26s 16ms/step - loss: 1.2335 - sparse_categorical_accuracy: 0.5620 - val_loss: 1.2375 - val_sparse_categorical_accuracy: 0.5685Epoch 2/51563/1563 [==============================] - 24s 15ms/step - loss: 1.2030 - sparse_categorical_accuracy: 0.5734 - val_loss: 1.2196 - val_sparse_categorical_accuracy: 0.5750Epoch 3/51563/1563 [==============================] - 24s 15ms/step - loss: 1.1676 - sparse_categorical_accuracy: 0.5847 - val_loss: 1.2254 - val_sparse_categorical_accuracy: 0.5701Epoch 4/51563/1563 [==============================] - 23s 15ms/step - loss: 1.1474 - sparse_categorical_accuracy: 0.5944 - val_loss: 1.1421 - val_sparse_categorical_accuracy: 0.5985Epoch 5/51563/1563 [==============================] - 24s 15ms/step - loss: 1.1188 - sparse_categorical_accuracy: 0.6034 - val_loss: 1.0880 - val_sparse_categorical_accuracy: 0.6209Model: "baseline_1"_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================conv2d_8 (Conv2D)            multiple                  456       _________________________________________________________________batch_normalization_3 (Batch multiple                  24        _________________________________________________________________activation_3 (Activation)    multiple                  0         _________________________________________________________________max_pooling2d_6 (MaxPooling2 multiple                  0         _________________________________________________________________dropout_4 (Dropout)          multiple                  0         _________________________________________________________________flatten_3 (Flatten)          multiple                  0         _________________________________________________________________dense_8 (Dense)              multiple                  196736    _________________________________________________________________dropout_5 (Dropout)          multiple                  0         _________________________________________________________________dense_9 (Dense)              multiple                  1290      =================================================================Total params: 198,506Trainable params: 198,494Non-trainable params: 12_________________________________________________________________

经典卷积网络

下面使用六步法,分别实现LeNET、AlexNet,VGGNet,INceptionNet和ResNet卷积神经网络

LetNet

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

特点:通过共享卷积核减少了网络的参数

import tensorflow as tfimport osimport numpy as npfrom matplotlib import pyplot as pltfrom tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Densefrom tensorflow.keras import Modelnp.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.0class LeNet5(Model):    def __init__(self):        super(LeNet5, self).__init__()        self.c1 = Conv2D(filters=6, kernel_size=(5, 5),                         activation='sigmoid')        self.p1 = MaxPool2D(pool_size=(2, 2), strides=2)        self.c2 = Conv2D(filters=16, kernel_size=(5, 5),                         activation='sigmoid')        self.p2 = MaxPool2D(pool_size=(2, 2), strides=2)        self.flatten = Flatten()        self.f1 = Dense(120, activation='sigmoid')        self.f2 = Dense(84, activation='sigmoid')        self.f3 = Dense(10, activation='softmax')    def call(self, x):        x = self.c1(x)        x = self.p1(x)        x = self.c2(x)        x = self.p2(x)        x = self.flatten(x)        x = self.f1(x)        x = self.f2(x)        y = self.f3(x)        return ymodel = LeNet5()model.compile(optimizer='adam',              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),              metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/LeNet5.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()
-------------load the model-----------------Epoch 1/51563/1563 [==============================] - 14s 9ms/step - loss: 1.4006 - sparse_categorical_accuracy: 0.4928 - val_loss: 1.4194 - val_sparse_categorical_accuracy: 0.4890Epoch 2/51563/1563 [==============================] - 14s 9ms/step - loss: 1.3587 - sparse_categorical_accuracy: 0.5080 - val_loss: 1.3741 - val_sparse_categorical_accuracy: 0.5016Epoch 3/51563/1563 [==============================] - 14s 9ms/step - loss: 1.3173 - sparse_categorical_accuracy: 0.5259 - val_loss: 1.3523 - val_sparse_categorical_accuracy: 0.5183Epoch 4/51563/1563 [==============================] - 14s 9ms/step - loss: 1.2885 - sparse_categorical_accuracy: 0.5388 - val_loss: 1.3057 - val_sparse_categorical_accuracy: 0.5287Epoch 5/51563/1563 [==============================] - 15s 10ms/step - loss: 1.2573 - sparse_categorical_accuracy: 0.5479 - val_loss: 1.2753 - val_sparse_categorical_accuracy: 0.5411Model: "le_net5_1"_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================conv2d_9 (Conv2D)            multiple                  456       _________________________________________________________________max_pooling2d_7 (MaxPooling2 multiple                  0         _________________________________________________________________conv2d_10 (Conv2D)           multiple                  2416      _________________________________________________________________max_pooling2d_8 (MaxPooling2 multiple                  0         _________________________________________________________________flatten_4 (Flatten)          multiple                  0         _________________________________________________________________dense_10 (Dense)             multiple                  48120     _________________________________________________________________dense_11 (Dense)             multiple                  10164     _________________________________________________________________dense_12 (Dense)             multiple                  850       =================================================================Total params: 62,006Trainable params: 62,006Non-trainable params: 0_________________________________________________________________

AlexNet

Alex网络诞生于2012年,当年ImageNet竞赛冠军,Top5错误率为16.4%

AlexNet使用了激活函数relu,提升了训练速度,使用Dropout缓解了过拟合

import tensorflow as tfimport osimport numpy as npfrom matplotlib import pyplot as pltfrom tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Densefrom tensorflow.keras import Modelnp.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.0class AlexNet8(Model):    def __init__(self):        super(AlexNet8, self).__init__()        self.c1 = Conv2D(filters=96, kernel_size=(3, 3))        self.b1 = BatchNormalization()        self.a1 = Activation('relu')        self.p1 = MaxPool2D(pool_size=(3, 3), strides=2)        self.c2 = Conv2D(filters=256, kernel_size=(3, 3))        self.b2 = BatchNormalization()        self.a2 = Activation('relu')        self.p2 = MaxPool2D(pool_size=(3, 3), strides=2)        self.c3 = Conv2D(filters=384, kernel_size=(3, 3), padding='same',                         activation='relu')                                 self.c4 = Conv2D(filters=384, kernel_size=(3, 3), padding='same',                         activation='relu')                                 self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same',                         activation='relu')        self.p3 = MaxPool2D(pool_size=(3, 3), strides=2)        self.flatten = Flatten()        self.f1 = Dense(2048, activation='relu')        self.d1 = Dropout(0.5)        self.f2 = Dense(2048, activation='relu')        self.d2 = Dropout(0.5)        self.f3 = 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.c2(x)        x = self.b2(x)        x = self.a2(x)        x = self.p2(x)        x = self.c3(x)        x = self.c4(x)        x = self.c5(x)        x = self.p3(x)        x = self.flatten(x)        x = self.f1(x)        x = self.d1(x)        x = self.f2(x)        x = self.d2(x)        y = self.f3(x)        return ymodel = AlexNet8()model.compile(optimizer='adam',              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),              metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/AlexNet8.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()
-------------load the model-----------------Epoch 1/51563/1563 [==============================] - 356s 228ms/step - loss: 1.0504 - sparse_categorical_accuracy: 0.6369 - val_loss: 1.1432 - val_sparse_categorical_accuracy: 0.6150Epoch 2/51563/1563 [==============================] - 389s 249ms/step - loss: 0.9855 - sparse_categorical_accuracy: 0.6604 - val_loss: 1.1803 - val_sparse_categorical_accuracy: 0.5829Epoch 3/51563/1563 [==============================] - 337s 215ms/step - loss: 0.9361 - sparse_categorical_accuracy: 0.6803 - val_loss: 1.2742 - val_sparse_categorical_accuracy: 0.5517Epoch 4/51563/1563 [==============================] - 325s 208ms/step - loss: 0.8906 - sparse_categorical_accuracy: 0.6949 - val_loss: 1.0693 - val_sparse_categorical_accuracy: 0.6268Epoch 5/51563/1563 [==============================] - 332s 212ms/step - loss: 0.8532 - sparse_categorical_accuracy: 0.7078 - val_loss: 1.2640 - val_sparse_categorical_accuracy: 0.5811Model: "alex_net8_1"_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================conv2d_11 (Conv2D)           multiple                  2688      _________________________________________________________________batch_normalization_4 (Batch multiple                  384       _________________________________________________________________activation_4 (Activation)    multiple                  0         _________________________________________________________________max_pooling2d_9 (MaxPooling2 multiple                  0         _________________________________________________________________conv2d_12 (Conv2D)           multiple                  221440    _________________________________________________________________batch_normalization_5 (Batch multiple                  1024      _________________________________________________________________activation_5 (Activation)    multiple                  0         _________________________________________________________________max_pooling2d_10 (MaxPooling multiple                  0         _________________________________________________________________conv2d_13 (Conv2D)           multiple                  885120    _________________________________________________________________conv2d_14 (Conv2D)           multiple                  1327488   _________________________________________________________________conv2d_15 (Conv2D)           multiple                  884992    _________________________________________________________________max_pooling2d_11 (MaxPooling multiple                  0         _________________________________________________________________flatten_5 (Flatten)          multiple                  0         _________________________________________________________________dense_13 (Dense)             multiple                  2099200   _________________________________________________________________dropout_6 (Dropout)          multiple                  0         _________________________________________________________________dense_14 (Dense)             multiple                  4196352   _________________________________________________________________dropout_7 (Dropout)          multiple                  0         _________________________________________________________________dense_15 (Dense)             multiple                  20490     =================================================================Total params: 9,639,178Trainable params: 9,638,474Non-trainable params: 704_________________________________________________________________

VGGNet

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

使用了VGG卷积核,在减少了参数的同时提高之别准确率

import tensorflow as tfimport osimport numpy as npfrom matplotlib import pyplot as pltfrom tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Densefrom tensorflow.keras import Modelnp.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.0class AlexNet8(Model):    def __init__(self):        super(AlexNet8, self).__init__()        self.c1 = Conv2D(filters=96, kernel_size=(3, 3))        self.b1 = BatchNormalization()        self.a1 = Activation('relu')        self.p1 = MaxPool2D(pool_size=(3, 3), strides=2)        self.c2 = Conv2D(filters=256, kernel_size=(3, 3))        self.b2 = BatchNormalization()        self.a2 = Activation('relu')        self.p2 = MaxPool2D(pool_size=(3, 3), strides=2)        self.c3 = Conv2D(filters=384, kernel_size=(3, 3), padding='same',                         activation='relu')                                 self.c4 = Conv2D(filters=384, kernel_size=(3, 3), padding='same',                         activation='relu')                                 self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same',                         activation='relu')        self.p3 = MaxPool2D(pool_size=(3, 3), strides=2)        self.flatten = Flatten()        self.f1 = Dense(2048, activation='relu')        self.d1 = Dropout(0.5)        self.f2 = Dense(2048, activation='relu')        self.d2 = Dropout(0.5)        self.f3 = 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.c2(x)        x = self.b2(x)        x = self.a2(x)        x = self.p2(x)        x = self.c3(x)        x = self.c4(x)        x = self.c5(x)        x = self.p3(x)        x = self.flatten(x)        x = self.f1(x)        x = self.d1(x)        x = self.f2(x)        x = self.d2(x)        y = self.f3(x)        return ymodel = AlexNet8()model.compile(optimizer='adam',              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),              metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/AlexNet8.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()
-------------load the model-----------------Epoch 1/5 179/1563 [==>...........................] - ETA: 4:14 - loss: 0.8443 - sparse_categorical_accuracy: 0.7139

InceptionNet

诞生于2014年,当年ImageNet竞赛冠军,Top5错误率为6.67%

引入了Inception结构块,在同一网络内使用不同尺寸的卷积核,提升模型感知力

使用了批标准化,缓解了梯度消失

import tensorflow as tfimport osimport numpy as npfrom matplotlib import pyplot as pltfrom tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense, \    GlobalAveragePooling2Dfrom tensorflow.keras import Modelnp.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.0class ConvBNRelu(Model):    def __init__(self, ch, kernelsz=3, strides=1, padding='same'):        super(ConvBNRelu, self).__init__()        self.model = tf.keras.models.Sequential([            Conv2D(ch, kernelsz, strides=strides, padding=padding),            BatchNormalization(),            Activation('relu')        ])    def call(self, x):        x = self.model(x, training=False) #在training=False时,BN通过整个训练集计算均值、方差去做批归一化,training=True时,通过当前batch的均值、方差去做批归一化。推理时 training=False效果好        return xclass InceptionBlk(Model):    def __init__(self, ch, strides=1):        super(InceptionBlk, self).__init__()        self.ch = ch        self.strides = strides        self.c1 = ConvBNRelu(ch, kernelsz=1, strides=strides)        self.c2_1 = ConvBNRelu(ch, kernelsz=1, strides=strides)        self.c2_2 = ConvBNRelu(ch, kernelsz=3, strides=1)        self.c3_1 = ConvBNRelu(ch, kernelsz=1, strides=strides)        self.c3_2 = ConvBNRelu(ch, kernelsz=5, strides=1)        self.p4_1 = MaxPool2D(3, strides=1, padding='same')        self.c4_2 = ConvBNRelu(ch, kernelsz=1, strides=strides)    def call(self, x):        x1 = self.c1(x)        x2_1 = self.c2_1(x)        x2_2 = self.c2_2(x2_1)        x3_1 = self.c3_1(x)        x3_2 = self.c3_2(x3_1)        x4_1 = self.p4_1(x)        x4_2 = self.c4_2(x4_1)        # concat along axis=channel        x = tf.concat([x1, x2_2, x3_2, x4_2], axis=3)        return xclass Inception10(Model):    def __init__(self, num_blocks, num_classes, init_ch=16, **kwargs):        super(Inception10, self).__init__(**kwargs)        self.in_channels = init_ch        self.out_channels = init_ch        self.num_blocks = num_blocks        self.init_ch = init_ch        self.c1 = ConvBNRelu(init_ch)        self.blocks = tf.keras.models.Sequential()        for block_id in range(num_blocks):            for layer_id in range(2):                if layer_id == 0:                    block = InceptionBlk(self.out_channels, strides=2)                else:                    block = InceptionBlk(self.out_channels, strides=1)                self.blocks.add(block)            # enlarger out_channels per block            self.out_channels *= 2        self.p1 = GlobalAveragePooling2D()        self.f1 = Dense(num_classes, activation='softmax')    def call(self, x):        x = self.c1(x)        x = self.blocks(x)        x = self.p1(x)        y = self.f1(x)        return ymodel = Inception10(num_blocks=2, num_classes=10)model.compile(optimizer='adam',              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),              metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/Inception10.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()

ResNet

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

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

有效缓解神经网络模型堆叠造成退化的问题,使得神经网络可以向更深层次发展

import tensorflow as tfimport osimport numpy as npfrom matplotlib import pyplot as pltfrom tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Densefrom tensorflow.keras import Modelnp.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.0class ResnetBlock(Model):    def __init__(self, filters, strides=1, residual_path=False):        super(ResnetBlock, self).__init__()        self.filters = filters        self.strides = strides        self.residual_path = residual_path        self.c1 = Conv2D(filters, (3, 3), strides=strides, padding='same', use_bias=False)        self.b1 = BatchNormalization()        self.a1 = Activation('relu')        self.c2 = Conv2D(filters, (3, 3), strides=1, padding='same', use_bias=False)        self.b2 = BatchNormalization()        # residual_path为True时,对输入进行下采样,即用1x1的卷积核做卷积操作,保证x能和F(x)维度相同,顺利相加        if residual_path:            self.down_c1 = Conv2D(filters, (1, 1), strides=strides, padding='same', use_bias=False)            self.down_b1 = BatchNormalization()                self.a2 = Activation('relu')    def call(self, inputs):        residual = inputs  # residual等于输入值本身,即residual=x        # 将输入通过卷积、BN层、激活层,计算F(x)        x = self.c1(inputs)        x = self.b1(x)        x = self.a1(x)        x = self.c2(x)        y = self.b2(x)        if self.residual_path:            residual = self.down_c1(inputs)            residual = self.down_b1(residual)        out = self.a2(y + residual)  # 最后输出的是两部分的和,即F(x)+x或F(x)+Wx,再过激活函数        return outclass ResNet18(Model):    def __init__(self, block_list, initial_filters=64):  # block_list表示每个block有几个卷积层        super(ResNet18, self).__init__()        self.num_blocks = len(block_list)  # 共有几个block        self.block_list = block_list        self.out_filters = initial_filters        self.c1 = Conv2D(self.out_filters, (3, 3), strides=1, padding='same', use_bias=False)        self.b1 = BatchNormalization()        self.a1 = Activation('relu')        self.blocks = tf.keras.models.Sequential()        # 构建ResNet网络结构        for block_id in range(len(block_list)):  # 第几个resnet block            for layer_id in range(block_list[block_id]):  # 第几个卷积层                if block_id != 0 and layer_id == 0:  # 对除第一个block以外的每个block的输入进行下采样                    block = ResnetBlock(self.out_filters, strides=2, residual_path=True)                else:                    block = ResnetBlock(self.out_filters, residual_path=False)                self.blocks.add(block)  # 将构建好的block加入resnet            self.out_filters *= 2  # 下一个block的卷积核数是上一个block的2倍        self.p1 = tf.keras.layers.GlobalAveragePooling2D()        self.f1 = tf.keras.layers.Dense(10, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())    def call(self, inputs):        x = self.c1(inputs)        x = self.b1(x)        x = self.a1(x)        x = self.blocks(x)        x = self.p1(x)        y = self.f1(x)        return ymodel = ResNet18([2, 2, 2, 2])model.compile(optimizer='adam',              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),              metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/ResNet18.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()

经典卷积网络总结


版权声明
作者:萌狼蓝天
QQ:3447902411(仅限技术交流,添加请说明方向)
转载请注明原文链接:https://www.cnblogs.com/mllt/p/jjsjwl.html