深度学习技术之卷积神经网络

卷积神经网络

1. 导入需要的库

导入numpy、pandas,tensorflow、sklearn等库,以及导入matplotlib的pyplot模块。从sklearn库的datasets模块中导入load_iris函数,以及从sklearn库的model_selection模块中导入train_test_split函数。从TensorFlow库中导入Keras模块。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sklearn 
import tensorflow as tf
from tensorflow import keras

2. 加载并显示两张图像

2.1 加载图像

使用了sklearn.datasets.load_sample_image函数来加载两个预先定义的样本图像,并将图像的像素值从0-255的范围缩放到0-1的范围。

china = load_sample_image("china.jpg") / 255
flower = load_sample_image("flower.jpg") / 255

2.2 创建子图

在Matplotlib中创建了两个新的子图,三个数值分别代表行数、列数以及子图的位置。(从左到右,从上到下)。

plt.subplot(1,2,1)
plt.imshow(china)
plt.subplot(1,2,2)
plt.imshow(flower)

运行结果:
在这里插入图片描述

2.3 打印图像形状

打印出“china.jpg”图像的形状,即图像的高度、宽度和颜色通道数。

print("china.jpg的维度: ",china.shape)
print("flower.jpg的维度: ",flower.shape)

运行结果:
在这里插入图片描述

2.4 打印合并后的图像数组的形状

将两个图像合并为一个NumPy数组,其中第一个元素是“china.jpg”图像,第二个元素是“flower.jpg”图像,计算并存储了合并后的图像数组的形状,并打印出合并后的图像数组的形状,即数据集中图像的数量和每个图像的高度、宽度和颜色通道数。

images = np.array([china,flower])
images_shape = images.shape
print("数据集的维度: ",images_shape)

运行结果:
在这里插入图片描述

3. 卷积层

3.1 定义变量

3.1.1 卷积核的大小(u)

u通常表示卷积核(也称为过滤器)的边长。在这里,u被设置为7,意味着卷积核是一个7x7的矩阵。

在图像处理中,卷积核用于检测图像中的特定模式或特征。卷积核的大小(u)决定了它可以检测的特征的大小。

u = 7 # 卷积核边长
3.1.2 滑动步长(s)

s通常表示卷积核的滑动步长(stride)。在这里,s被设置为1,这意味着在每一步,卷积核都会在输入图像上滑动一个像素。

滑动步长(s)决定了卷积核在图像上移动的步长。较小的滑动步长可以提高特征的分辨率,但会增加计算成本。

s = 1 # 滑动步长
3.1.3 输出特征图的数量(p)

p通常表示输出特征图的数量。在这里,p被设置为5,意味着卷积操作将生成5个不同的特征图。

输出特征图的数量(p)决定了卷积操作将生成多少个特征图。每个特征图都捕获了图像的不同方面或特征。

p = 5 # 输出特征图数目

3.2 卷积层形式

input_shape: 输入数据的形状,它是一个元组,代表输入特征图的尺寸加上通道数。

activation: 激活函数,这里使用的是 ReLU(修正线性单元)激活函数。

padding: padding 策略,“SAME” 表示使用边缘填充,使得输出特征图的尺寸与输入相同。

conv = keras.layers.Conv2D(filters = p, kernel_size = u, strides = s, padding="SAME", activation="relu", input_shape=images_shape)

3.3 打印张量

image_after_conv = conv(images)
print("卷积后的张量大小: ", image_after_conv.shape)

运行结果:
在这里插入图片描述

4. 池化层

4.1 最大池化层

最大池化(Max Pooling)是一种池化操作,它通过在局部区域中取最大值来减少数据的维度。

pool_max = keras.layers.MaxPool2D(pool_size=2)
image_after_pool_max = pool_max(image_after_conv)
print("最大汇聚后的张量大小: ",image_after_pool_max.shape)

运行结果:
在这里插入图片描述

4.2 全局平均池化层

全局平均池化(Global Average Pooling)是一种池化操作,它计算整个特征图的平均值,这通常用于卷积神经网络的末端,以减少特征图的空间维度到1x1,即每个特征图只保留一个平均值。这种方法可以用来减少参数数量并防止过拟合。

pool_global_avg = keras.layers.GlobalAvgPool2D()
image_after_pool_global_avg = pool_global_avg(image_after_conv)
print("全局平均汇聚后的张量大小: ",image_after_pool_global_avg.shape)

运行结果:
在这里插入图片描述

4.3 平均池化层

平均池化(Average Pooling)是一种池化操作,它计算每个局部区域内的平均值,并使用这些平均值来减少数据的维度。

pool_avg = keras.layers.AvgPool2D(pool_size=2)
image_after_pool_avg = pool_avg(image_after_conv)
print("平均汇聚后的张量大小: ",image_after_pool_avg.shape)

运行结果:
在这里插入图片描述

5. 搭建卷积神经网络进行手写数字识别

5.1 导入并对数据进行预处理

5.1.1 读取数据并存储

从指定路径读取训练数据和测试数据,并将它们存储在 train_Data 和 test_Data 变量中。这些数据是以 CSV 格式存储的,并且指定了 header=None,这意味着 CSV 文件中没有标题行。

path = "E:/工坊/深度学习/"
train_Data = pd.read_csv(path+'train.csv', header = None) # 训练数据
test_Data = pd.read_csv(path+'test.csv', header = None) # 测试数据
5.1.2 归一化

对训练数据进行处理,将像素值归一化到 [0, 1] 范围内,并将图像数据与标签分离。

X, y = train_Data.iloc[:,1:].values/255, train_Data.iloc[:,0].values #数据归一化
5.1.3 分割验证集和训练集

X_valid 和 y_valid 分别存储验证集的图像数据和标签,而 X_train 和 y_train 存储训练集的图像数据和标签。reshape 函数用于将数据从一维数组转换为三维数组,其中每个图像是一个 28x28 的矩阵。打印出的形状信息可以帮助确认数据的维度是否正确。

X_valid, X_train = X[:5000].reshape(5000,28,28) , X[5000:].reshape(55000,28,28) #验证集与训练集
y_valid, y_train = y[:5000], y[5000:]
5.1.4 归一化

test_Data.iloc[:,1:] 表示您想要获取所有行的第二列到最后一列的数据,这些列包含图像的像素值。test_Data.iloc[:,0] 则表示您想要获取所有行的第一列数据,这列包含图像的标签。

X_test,y_test = test_Data.iloc[:,1:].values.reshape(10000,28,28)/255, test_Data.iloc[:,0].values #测试集
5.1.5 打印形状

打印 X_train、X_valid 和 X_test 变量的形状。这些变量分别代表训练数据、验证数据和测试数据。

print(X_train.shape)
print(X_valid.shape)
print(X_test.shape)

运行结果:
在这里插入图片描述

5.2 搭建卷积神经网络

5.2.1 定义一个卷积神经网络(CNN)

Flatten():这个层将3D输出张量(特征图)展平为1D特征向量,这是后续的全连接层所必需的。

Dropout(0.25):这个层在每次训练更新时随机地将输入单元的25%设置为0,这有助于防止过拟合。

Dense(128, activation=“relu”):这是一个有128个单元的全连接层,并使用ReLU激活函数。

Dropout(0.5):另一个具有更高丢弃率(0.5)的全连接层。

model_cnn_mnist = keras.models.Sequential([
    keras.layers.Conv2D(32, kernel_size=3, padding="same", activation="relu"), # 第一个卷积层
    keras.layers.Conv2D(64, kernel_size=3, padding="same", activation="relu"), # 第二个卷积层
    keras.layers.MaxPool2D(pool_size=2), # 最大池化层
    keras.layers.Flatten(),
    keras.layers.Dropout(0.25),
    keras.layers.Dense(128, activation="relu"),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(10, activation="softmax")
])
5.2.2 重塑(reshape)

reshape 方法被用于改变数组的形状,而不改变其数据。

# 假设 X_train, X_valid, X_test 是您当前的图像数据
X_train = X_train.reshape(-1, 28, 28, 1)
X_valid = X_valid.reshape(-1, 28, 28, 1)
X_test = X_test.reshape(-1, 28, 28, 1)
5.2.3 编译和训练模型

compile 方法用于配置模型的学习过程。

fit 方法用于训练模型。

evaluate 方法用于评估模型的性能。

执行这些代码后,模型将经历编译、训练和评估的过程,将能够看到每个周期在验证集上的准确率,以及最终在测试集上的损失和准确率。

model_cnn_mnist.compile(loss="sparse_categorical_crossentropy", optimizer="nadam", metrics=["accuracy"])
model_cnn_mnist.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
model_cnn_mnist.evaluate(X_test, y_test, batch_size=1)

运行结果:
在这里插入图片描述

5.2.4 评估性能

evaluate:这是模型实例的方法,用于评估模型的性能。它计算模型在编译时指定的损失函数和指标(在这个案例中是准确率)。

model_cnn_mnist.evaluate(X_test, y_test, batch_size=1)

运行结果:
在这里插入图片描述

6. 利用函数式API与子类API搭建复杂神经网络

6.1 残差层

6.1.1 残差连接

残差连接(Residual Connection)是深度学习中的一种常见网络架构,它允许在网络层之间直接添加输入到输出,这种连接可以帮助梯度在网络中顺畅传播,从而缓解了深层网络训练中的梯度消失和梯度爆炸问题。

ResidualUnit 类实现了一个残差单元,其中包含了主要的前向传播路径(main_layers)和一个跳跃连接(skip_layers)。

filters: 卷积层中的过滤器(卷积核)数量。

strides: 卷积层的步长,默认为1。当步长大于1时,会应用下采样。

class ResidualUnit(keras.layers.Layer):
    def __init__(self, filters, strides=1, activation="relu"):
        super().__init__()
        self.activation = keras.activations.get(activation)
        
        self.main_layers = [
            keras.layers.Conv2D(filters, 3, strides=strides, padding = "SAME", use_bias = False), 
            keras.layers.BatchNormalization(),
            self.activation,
            keras.layers.Conv2D(filters, 3, strides=1, padding = "SAME", use_bias = False),
            keras.layers.BatchNormalization()]
        
        # 当滑动步长s = 1时,残差连接直接将输入与卷积结果相加,skip_layers为空,即实线连接
        self.skip_layers = [] 
        
        # 当滑动步长s = 2时,残差连接无法直接将输入与卷积结果相加,需要对输入进行卷积处理,即虚线连接
        if strides > 1:
            self.skip_layers = [
                keras.layers.Conv2D(filters, 1, strides=strides, padding = "SAME", use_bias = False),
                keras.layers.BatchNormalization()]

    def call(self, inputs):
        Z = inputs
        for layer in self.main_layers:
            Z = layer(Z)
        skip_Z = inputs
        for layer in self.skip_layers:
            skip_Z = layer(skip_Z)
        return self.activation(Z + skip_Z)

6.2 搭建完整的ResNet-34神经网络

6.2.1 创建一个顺序模型

模型中的层会依次堆叠。

model = keras.models.Sequential()
6.2.2 向模型中添加层

批量归一化层:有助于加速训练过程和稳定网络。

model.add(keras.layers.Conv2D(64, 7, strides=2, padding = "SAME", use_bias = False)) # 添加第一个卷积层
model.add(keras.layers.BatchNormalization()) # 添加批量归一化层
model.add(keras.layers.Activation("relu")) # 添加ReLU激活函数
model.add(keras.layers.MaxPool2D(pool_size=3, strides=2, padding="SAME")) # 添加最大池化层
6.2.3 构建一个深度残差网络

构建一个深度残差网络,其中的残差单元允许模型在增加深度时仍然能够有效地训练。通过逐渐增加过滤器的数量,模型能够捕捉到更复杂的特征,同时通过步长的变化来调整特征图的尺寸。这种设计使得模型能够在不牺牲性能的情况下增加深度,这是残差网络的一个重要特性。

prev_filters = 64 # 初始化前一个块的过滤器数量为64
for filters in [64] * 3 + [128] * 4 + [256] * 6 + [512] * 3: # 遍历一系列的过滤器数量
    strides = 1 if filters == prev_filters else 2    #在每次特征图数目扩展时,设置滑动步长为2
    model.add(ResidualUnit(filters, strides=strides))
    prev_filters = filters
6.2.3 添加几层用于分类任务

model.add(keras.layers.GlobalAvgPool2D()): 这层会在每个特征图上计算全局平均池化,即将每个特征图的的所有值平均成一个单一的值。

model.add(keras.layers.Flatten()): 这层将上一个层的输出展平成一个一维向量。

model.add(keras.layers.Dense(10, activation=“softmax”)): 这是最后一个全连接层,它将一维的输入向量映射到一个长度为10的输出向量,每个元素对应一个类别。

activation="softmax"表示使用softmax激活函数,它会将输出向量转换为概率分布,每个元素都是相应类别的预测概率。

model.add(keras.layers.GlobalAvgPool2D())
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(10, activation="softmax"))
6.2.4 编译和训练模型

compile 方法用于配置模型的学习过程。

fit 方法用于训练模型。

model.compile(loss="sparse_categorical_crossentropy", optimizer="nadam", metrics=["accuracy"])
model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))

运行结果:
在这里插入图片描述

6.2.5 评估性能

evaluate:这是模型实例的方法,用于评估模型的性能。它计算模型在编译时指定的损失函数和指标(在这个案例中是准确率)。

model.evaluate(X_test,y_test, batch_size=1)

运行结果:
在这里插入图片描述

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值