搭建卷积神经网络

卷积等概念

卷积的概念

一种有效提取特征的方法

1、对单通道图像:一般用一个正方形的卷积核,按指定步长,在输入特征图上滑动,遍历输入特征图中的每个像素点。每一个步长,卷积核会与输入特征图出现重合区域,重合区域对应元素相乘、求和再加上偏置项得到输出特征的一个像素点。利用大小为 3×3×1 的卷积核对 5×5×1 的单通道图像做卷积计算得到相应结果。

 

2、对彩色RGB图像(多通道):卷积核通道数与输入特征一致,套接后在对应位置上进行乘加和操作,如图 5-5 所示,利用三通道卷积核对三通道的彩色特征图做卷积计算。

感受野

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

第一种:原始图像5*5,先用3*3卷积核作用(步长1)得到3*3输出图像,每个像素点感受野为3,再用3*3卷积核作用,得到1*1输出图像,感受野为5(对于原始图像

第二种:直接对原始图像用5*5卷积核作用得到1*1输出图像,感受野为5。

当我们采用尺寸不同的卷积核时,最大的区别就是感受野的大小不同,所以经常会采用多层小卷积核来替换一层大卷积核,在保持感受野相同的情况下减少参数量和计算量,例如十分常见的用 2 层 3 * 3 卷积核来替换 1 层 5 * 5 卷积核的方法

 全零填充

为了保持输出图像尺寸与输入图像一致,经常会在输入图像周围进行全零填充,如图 所示,在 5×5 的输入图像周围填 0,则输出特征尺寸同为 5×5。

在 Tensorflow 框架中,用参数 padding = ‘SAME’或 padding = ‘VALID’表示是否进行全零填充。
                                                                                                                                                          输出图像特征尺寸

 批标准化(Batch Normalization)

对一小批数据在网络各层的输出做标准化处理(标准化使数据符合 0 均值,1 为标准差的分布。) 

 Batch Normalization 将神经网络每层的输入都调整到均值为 0,方差为 1 的标准正态分布,其目的解决神经网络中梯度消失的问题, BN 操作通常位于卷积层之后,激活层之前。

池化(pooling)

池化的作用减少特征数量(降维)。最大值池化可提取图片纹理,均值池化可保留背景特征。

 舍弃(Dropout)

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

卷积神经网络的主要模块

卷积层、BN 层、激活函数、池化层、全连接层
 

构建卷积神经网络步骤

构建神经网络“八股”套路

  • 导入 tensorflow 及 keras、numpy 等所需模块。

  • 读取数据集

  • 搭建网络模型

  • 对搭建好的网络进行编译(model.compile)

  • 将数据输入编译好的网络来进行训练(model.fit)

  • 将神经网络模型的具体信息打印出来(model.summary)

以cifar10图片分类为例,展示图像分类全过程

复制代码
  1 """
  2 ######## 【1、导入文件】
  3 """
  4 import tensorflow as tf
  5 import os
  6 import numpy as np
  7 from matplotlib import pyplot as plt
  8 from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
  9 from tensorflow.keras import Model
 10 
 11 np.set_printoptions(threshold=np.inf)
 12 
 13 """
 14 ####### 【2、读取数据集】导入图片特征x、图片标签y
 15 """
 16 cifar10 = tf.keras.datasets.cifar10    # 下载数据集
 17 (x_train, y_train), (x_test, y_test) = cifar10.load_data()  # 导入训练集和测试集
 18 x_train, x_test = x_train / 255.0, x_test / 255.0  # 将0-255像素转化为0-1
 19 
 20 """
 21 ######## 【3、搭建网络模型】
 22 """
 23 class Baseline(Model):
 24     def __init__(self):
 25         super(Baseline, self).__init__()
 26         self.c1 = Conv2D(filters=6, kernel_size=(5, 5), padding='same')  # 卷积层
 27         self.b1 = BatchNormalization()  # BN层
 28         self.a1 = Activation('relu')  # 激活层
 29         self.p1 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')  # 池化层
 30         self.d1 = Dropout(0.2)  # dropout层
 31 
 32         self.flatten = Flatten()   # 拉直层(将二维特征拉直成一维)
 33         self.f1 = Dense(128, activation='relu')  # 全连接层
 34         self.d2 = Dropout(0.2)  # dropout层
 35         self.f2 = Dense(10, activation='softmax')
 36 
 37     def call(self, x):
 38         x = self.c1(x)
 39         x = self.b1(x)
 40         x = self.a1(x)
 41         x = self.p1(x)
 42         x = self.d1(x)
 43 
 44         x = self.flatten(x)
 45         x = self.f1(x)
 46         x = self.d2(x)
 47         y = self.f2(x)
 48         return y
 49 
 50 
 51 model = Baseline()
 52 
 53 """
 54 ####### 【4、model.compile】 编译网络(指定优化器、损失函数)
 55 """
 56 model.compile(optimizer='adam',
 57               loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
 58               metrics=['sparse_categorical_accuracy'])
 59 
 60 checkpoint_save_path = "./checkpoint/Baseline.ckpt"
 61 if os.path.exists(checkpoint_save_path + '.index'):
 62     print('-------------load the model-----------------')
 63     model.load_weights(checkpoint_save_path)
 64 
 65 cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
 66                                                  save_weights_only=True,
 67                                                  save_best_only=True)
 68 
 69 """
 70 ####### 【5、model.fit】 断点续训(将数据输入编译好的网络来训练)
 71 """
 72 history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,
 73                     callbacks=[cp_callback])
 74 """
 75 ####### 【6、model.summary】 将神经网络模型的具体信息打印出来
 76 """
 77 model.summary()
 78 # print(model.trainable_variables)
 79 file = open('./weights.txt', 'w')
 80 for v in model.trainable_variables:
 81     file.write(str(v.name) + '\n')
 82     file.write(str(v.shape) + '\n')
 83     file.write(str(v.numpy()) + '\n')
 84 file.close()
 85 
 86 """
 87 ####### 【acc/loss可视化】
 88 """
 89 acc = history.history['sparse_categorical_accuracy']
 90 val_acc = history.history['val_sparse_categorical_accuracy']
 91 loss = history.history['loss']
 92 val_loss = history.history['val_loss']
 93 
 94 plt.subplot(1, 2, 1)
 95 plt.plot(acc, label='Training Accuracy')
 96 plt.plot(val_acc, label='Validation Accuracy')
 97 plt.title('Training and Validation Accuracy')
 98 plt.legend()
 99 
100 plt.subplot(1, 2, 2)
101 plt.plot(loss, label='Training Loss')
102 plt.plot(val_loss, label='Validation Loss')
103 plt.title('Training and Validation Loss')
104 plt.legend()
105 plt.show()
cifar10图像分类
复制代码

1、导入tensorflow 及 keras、numpy 等所需模块

2、读取数据集

指定输入网络的训练集和测试集,如指定训练集的输入 x_train 和标签y_train,测试集的输入 x_test 和标签 y_test
MNIST、cifar10 等数据集本来就封装在tensorflow模块中,可以直接从sklearn中引入,但是在实际应用中,大多需要从图片和标签文件中读取所需的数据集。

① 网上已有资源的数据集:

Cifar10数据集:
提供 5万张 32*32 像素点的十分类彩色图片和标签,用于训练。
提供 1万张 32*32 像素点的十分类彩色图片和标签,用于测试。
复制代码
1 """
2 ####### 【2、读取数据集】导入图片特征x、图片标签y
3 """
4 cifar10 = tf.keras.datasets.cifar10    # 下载数据集
5 (x_train, y_train), (x_test, y_test) = cifar10.load_data()  # 导入训练集和测试集
6 x_train, x_test = x_train / 255.0, x_test / 255.0  # 将0-255像素转化为0-1
网上数据集读取
复制代码

②自制数据集

利用自己的图片和标签文件来自制数据集

未完待续……

3、搭建网络模型

当网络结构比较简单时,可以利用 keras 模块中的tf.keras.Sequential 来搭建顺序网络模型;但是当网络不再是简单的顺序结构,而是有其它特殊结构出现时(例如 ResNet 中的跳连结构),便需要利用 class 来定义自己的网络结构。前者使用起来更加方便,但实际应用中往往需要利用后者来搭建网络。
 

复制代码
 1 """
 2 ######## 【3、搭建网络模型】
 3 """
 4 class Baseline(Model):
 5     def __init__(self):     # 初始化模型
 6         super(Baseline, self).__init__()
 7         self.c1 = Conv2D(filters=6, kernel_size=(5, 5), padding='same')  # C卷积层
 8         self.b1 = BatchNormalization()  # B 批标准化层
 9         self.a1 = Activation('relu')  # A 激活层
10         self.p1 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')  # P 池化层
11         self.d1 = Dropout(0.2)  # D dropout层
12 
13         self.flatten = Flatten()   # 拉直层(将二维特征拉直成一维)
14         self.f1 = Dense(128, activation='relu')  # 全连接层
15         self.d2 = Dropout(0.2)  # dropout层
16         self.f2 = Dense(10, activation='softmax')  # 第2个全连接层
17 
18     def call(self, x):     # 调用初始化模型函数,进行前向传播,返回输出y
19         x = self.c1(x)
20         x = self.b1(x)
21         x = self.a1(x)
22         x = self.p1(x)
23         x = self.d1(x)
24 
25         x = self.flatten(x)
26         x = self.f1(x)
27         x = self.d2(x)
28         y = self.f2(x)
29         return y
30 
31 
32 model = Baseline()    # 建立神经网络模型对象
搭建神经网络
复制代码

4、对搭建好的网络进行编译(model.compile)

Compile 用于配置神经网络的训练方法,告知训练时使用的优化器、损失函数和准确率评测标准。

复制代码
 1 """
 2 ####### 【4、model.compile】 编译网络(指定优化器、损失函数)
 3 """
 4 model.compile(optimizer='adam',
 5               loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
 6               metrics=['sparse_categorical_accuracy'])
 7 
 8 checkpoint_save_path = "./checkpoint/Baseline.ckpt"
 9 if os.path.exists(checkpoint_save_path + '.index'):
10     print('-------------load the model-----------------')
11     model.load_weights(checkpoint_save_path)
12 
13 cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
14                                                  save_weights_only=True,
15                                                  save_best_only=True)
compile
复制代码
——Model.compile( optimizer = 优化器,loss = 损失函数,metrics = [“准确率”]) 
 
其中:
(1)optimizer 可以是字符串形式给出的优化器名字,也可以是函数形式,使用函数形式可以设置学习率、动量和超参数。 
包括4种优化器,每种优化器都有2种表达方式(优化器名字or函数形式)
① ‘sgd’or tf.optimizers.SGD( lr=学习率,decay=学习率衰减率,momentum=动量参数)
② ‘adagrad’or tf.keras.optimizers.Adagrad(lr=学习率,decay=学习率衰减率)
③ ‘adadelta’or tf.keras.optimizers.Adadelta(lr=学习率,decay=学习率衰减率)
④ ‘adam’or tf.keras.optimizers.Adam (lr=学习率,decay=学习率衰减率)
 
(2)loss 可以是字符串形式给出的损失函数的名字,也可以是函数形式。
可选项包括:
①  ‘mse’
②  tf.keras.losses.MeanSquaredError()‘sparse_categorical_crossentropy
③  tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
     损失函数常需要经过 softmax 等函数将输出转化为概率分布的形式。from_logits 则用来标注该损失函数是否需要转换为概率的形式,取 False 时表示转化为概率分布,取 True 时表示没有转化为概率分布,直接输出。
 
(3)Metrics 标注网络评测指标。
①  ‘accuracy’:y_和 y 都是数值,如 y_=[1] y=[1]。
②  ‘categorical_accuracy’:y_和 y 都是以独热码和概率分布表示。如 y_=[0, 1, 0], y=[0.256, 0.695, 0.048]。
③  ‘sparse_ categorical_accuracy’:y_是以数值形式给出,y 是以独热码形式给出。如 y_=[1],y=[0.256, 0.695, 0.048]。

5、将数据输入编译好的网络来进行训练(model.fit)

告知训练集和测试集的输入值和标签、每个 batch 的大小(batchsize)和数据集的迭代次数(epoch)。

复制代码
1 """
2 ####### 【5、model.fit】 执行训练过程(将数据输入编译好的网络来训练)
3 """
4 history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,
5                     callbacks=[cp_callback])   # 回调函数实现断点续训
fit
复制代码
——model.fit(训练集的输入特征, 训练集的标签, batch_size, epochs,validation_data = (测试集的输入特征,测试集的标签),
                                                                                   validataion_split = 从测试集划分多少比例给训练集,
                                                                                   validation_freq = 测试的 epoch 间隔次数) 

6、将神经网络模型的具体信息打印出来(model.summary)

打印网络结构,统计参数数目
复制代码
 1 """
 2 ####### 【6、model.summary】 将神经网络模型的具体信息打印出来
 3 """
 4 model.summary()
 5 # print(model.trainable_variables)
 6 file = open('./weights.txt', 'w')   # 保存模型参数
 7 for v in model.trainable_variables:
 8     file.write(str(v.name) + '\n')
 9     file.write(str(v.shape) + '\n')
10     file.write(str(v.numpy()) + '\n')
11 file.close()
summary 
复制代码
 
 
上图是model.summary()对鸢尾花分类网络的网络结构和参数统计,对于一个输入为4输出为3的全连接网络,共有15个参数。

 acc/loss可视化

复制代码
 1 """
 2 ####### 【acc/loss可视化】
 3 """
 4 acc = history.history['sparse_categorical_accuracy']
 5 val_acc = history.history['val_sparse_categorical_accuracy']
 6 loss = history.history['loss']
 7 val_loss = history.history['val_loss']
 8 
 9 plt.subplot(1, 2, 1)
10 plt.plot(acc, label='Training Accuracy')
11 plt.plot(val_acc, label='Validation Accuracy')
12 plt.title('Training and Validation Accuracy')
13 plt.legend()
14 
15 plt.subplot(1, 2, 2)
16 plt.plot(loss, label='Training Loss')
17 plt.plot(val_loss, label='Validation Loss')
18 plt.title('Training and Validation Loss')
19 plt.legend()
20 plt.show()
acc/loss
复制代码

 

posted @   小占敲代码  阅读(396)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示