搭建卷积神经网络
卷积等概念
卷积的概念
一种有效提取特征的方法
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()
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)
——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]) # 回调函数实现断点续训
——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()


上图是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()
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~