当前位置: 首页 > news >正文

【深度学习】 零基础介绍卷积神经网络(CNN)

零基础介绍

卷积神经网络(CNN,Convolutional Neural Network)是深度学习中的一种神经网络,特别擅长处理图像和视频等有空间结构的数据。

假设我们在做一个“照片分类”的任务,比如判断一张照片中是猫还是狗。下面用一个通俗的例子来解释CNN的工作原理。

  1. 看图的方式:模拟人眼
    当我们看一张图片时,并不是从头到尾一口气看完的,而是我们的眼睛会专注于某个小区域,然后逐渐移到其他地方。CNN就是模仿这种“局部视野”的方式来处理图像。它通过滑动一个小窗口(称为“卷积核”)来查看图片的不同部分。

  2. 卷积层(Convolutional Layer)
    卷积层的作用就是使用多个卷积核对图像进行扫描。这些卷积核可以看作是一个小的滤镜,它们能提取图像中的特征。假设我们有一张猫的照片,卷积核可能会学习到猫的耳朵形状、眼睛的位置、毛发的纹理等特征。每次卷积操作之后,图像会变成一个包含这些特征的“特征图”(feature map)。

    例如,如果我们有一张3×3的卷积核(就是一个3×3的小矩阵),它会遍历图像的每个部分,计算卷积核和图片的局部区域的点积,产生一个新的值。这就像你用滤镜滤镜了一小块区域。

  3. 激活函数(ReLU)
    卷积层提取到特征之后,接下来会通过一个叫做ReLU(Rectified Linear Unit)的激活函数。ReLU会把负数变为零,保留正数。简单来说,就是“过滤”掉一些不重要的信息,保留对分类有帮助的特征。

  4. 池化层(Pooling Layer)
    池化层的作用是将卷积层生成的特征图进行下采样,减少图像的大小和计算量。通常有两种常用的池化方式:

    最大池化(Max Pooling):从每个小区域中选出最大的值。
    平均池化(Average Pooling):从每个小区域中计算平均值。

    池化的作用就是保留图像中最重要的信息,同时减少不必要的细节,就像是在提炼出最精华的部分。

  5. 全连接层(Fully Connected Layer)
    在经过多个卷积层和池化层之后,CNN会将图像的特征汇聚起来,传递到全连接层。这个层的作用类似于神经网络的最终决策阶段,负责根据之前提取到的特征做出最终的分类决策。比如根据猫耳朵、眼睛、毛发的纹理等信息,最终判断出这是猫还是狗。

  6. 输出层(Output Layer)
    最后,输出层会根据神经网络的结果给出分类结果。如果是猫,输出1;如果是狗,输出0。这个结果就是CNN根据图像学习到的特征做出的决策。

总结:
CNN通过逐层提取图像的特征,模拟人类如何观察图像,最终做出分类决策。它的优势在于能够自动学习图像中的有用特征,而不需要人工提取这些特征,这使得CNN特别适合图像处理任务。

比喻:
你可以把CNN想象成一个侦探,它通过从图片的各个细节(耳朵、眼睛、毛发等)收集线索,最终推理出这是一只猫还是狗。每一个卷积核就像是侦探手中的放大镜,帮助他专注于图片中的不同部分,池化层则是帮助侦探筛选出最重要的线索。最终,侦探通过这些线索得出了结论。

写个CNN最简单的代码

假设我们的输入图像是一个 3x3 的矩阵,卷积核(滤波器)是一个 2x2 的矩阵。

  1. 输入:
    1 2 3
    4 5 6
    7 8 9

  2. 卷积核(滤波器)
    1 0
    0 1

  3. 在卷积操作中,卷积核会在输入图像上滑动,并计算卷积核和当前区域的点积

    步骤:
    我们从输入图像的左上角开始,把卷积核放在图像的最左上角,然后计算卷积核与图像覆盖区域的点积。卷积核的每个元素与对应区域的每个元素相乘,然后求和。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  4. 结果
    通过这些卷积操作,我们得到了一个 2x2 的特征图(Feature Map):
    在这里插入图片描述

代码如下:

import numpy as np# 输入图像
image = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])# 卷积核(滤波器)
kernel = np.array([[1, 0],[0, 1]])# 输出特征图的尺寸
output_height = image.shape[0] - kernel.shape[0] + 1
output_width = image.shape[1] - kernel.shape[1] + 1# 创建一个空的输出特征图
output = np.zeros((output_height, output_width))# 执行卷积操作
for i in range(output_height):for j in range(output_width):# 计算当前区域的点积region = image[i:i+kernel.shape[0], j:j+kernel.shape[1]]output[i, j] = np.sum(region * kernel)print("卷积结果(特征图):")
print(output)

输出结果:

卷积结果(特征图):
[[ 6. 8.]
[12. 14.]]


接下来正式介绍CNN!
在这里插入图片描述

一. 概述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

二. 搭建CNN

在这里插入图片描述

1. 输入层

在这里插入图片描述

2. 卷积层

在这里插入图片描述

对于灰度图:
在这里插入图片描述
对于彩色图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 激活层

在这里插入图片描述

4. 池化层

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. 全连接层

在这里插入图片描述

6. 网络搭建小结

在这里插入图片描述

7. 损失函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8. 梯度下降

在这里插入图片描述
在这里插入图片描述

8. 反向传播

在这里插入图片描述

在这里插入图片描述

9. 模型评估与正则化

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

10. 尝试搭建自己的第一个CNN

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三. 经典CNN结构

在这里插入图片描述

在这里插入图片描述

四. 猫狗识别项目实践

1. Paddle实现版本:

import paddle
import paddle.fluid as fluid
import numpy as np
from PIL import Image
import sys
from multiprocessing import cpu_count
import matplotlib.pyplot as plt
import os
BATCH_SIZE = 128
# 用于训练的数据提供器
train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.cifar.train10(),buf_size = BATCH_SIZE * 100),batch_size = BATCH_SIZE)#用于测试的数据提供器
test_reader = paddle.batch(paddle.dataset.cifar.test10(),batch_size = BATCH_SIZE
)
def  convolutional_neural_network(img):# 第一个卷积 - 池化层conv1 = fluid.layers.conv2d(input= img, # 输入图像num_filters =20,      #卷积核的大小filter_size = 5,    #卷积核数量,它与输出的通道相同act = 'relu')     #激活函数pool1 = fluid.layers.pool2d(input = conv1,  # 输入pool_size = 2, #池化核大小pool_type = 'max', # 池化类型pool_stride = 2)  # 池化步长conv_pool_1 = fluid.layers.batch_norm(pool1)# 第二个卷积 - 池化层conv2 = fluid.layers.conv2d(input= conv_pool_1, # 输入图像num_filters =50,      #卷积核的大小filter_size = 5,    #卷积核数量,它与输出的通道相同act = 'relu')     #激活函数pool2 = fluid.layers.pool2d(input = conv2,  # 输入pool_size = 2, #池化核大小pool_type = 'max', # 池化类型pool_stride = 2)  # 池化步长conv_pool_2 = fluid.layers.batch_norm(pool2)# 第三个卷积 - 池化层conv3 = fluid.layers.conv2d(input= conv_pool_2, # 输入图像num_filters =50,      #卷积核的大小filter_size = 5,    #卷积核数量,它与输出的通道相同act = 'relu')     #激活函数pool3 = fluid.layers.pool2d(input = conv3,  # 输入pool_size = 2, #池化核大小pool_type = 'max', # 池化类型pool_stride = 2)  # 池化步长# 以softmax 为激活函数的全连接输出层,10类数据输出10个数字prediction = fluid.layers.fc(input = pool3,size = 10,act = 'softmax')return prediction
paddle.enable_static()
# 3 代表图像RGB三通道,32✖32的彩色图片
data_shape = [3,32,32]
# 定义全局变量 image 和 label 
images = fluid.layers.data(name = 'images',shape = data_shape,dtype = 'float32')
label = fluid.layers.data(name = 'label',shape=[1],dtype = 'int64')
# 获取分类器,用cnn分类
predict = convolutional_neural_network(images)
cost = fluid.layers.cross_entropy(input=predict,label = label)
avg_cost = fluid.layers.mean(cost)
acc = fluid.layers.accuracy(input=predict,label = label)
optimizer = fluid.optimizer.Adam(learning_rate =0.001)
optimizer.minimize(avg_cost)
place =  fluid.CUDAPlace(0)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
feeder = fluid.DataFeeder(feed_list=[images,label],place = place)
EPOCH_NUM = 15
for pass_id in range(EPOCH_NUM):train_cost = 0for batch_id,data in enumerate(train_reader()):train_cost,train_acc = exe.run(program = fluid.default_main_program(),feed = feeder.feed(data),fetch_list =[avg_cost,acc])if batch_id % 100 ==0:print('Pass: %d, Batch: %d, Cost: %0.5f, Accuarcy: %0.5f'%(pass_id,batch_id,train_cost[0],train_acc[0]))test_costs = []test_accs = []for batch_id,data in enumerate(test_reader()):test_cost,test_acc = exe.run(program = fluid.default_main_program(),feed = feeder.feed(data),fetch_list = [avg_cost,acc])test_costs.append(test_cost[0])test_accs.append(test_acc[0])# 求测试结果的平均值test_cost = (sum(test_costs) / len(test_costs))                         #计算误差平均值(误差和/误差的个数)test_acc = (sum(test_accs) / len(test_accs))                            #计算准确率平均值( 准确率的和/准确率的个数)print('Test:%d, Cost:%0.5f, ACC:%0.5f' % (pass_id, test_cost, test_acc))model_save_dir = "/home/aistudio/data/catdog.inference.model"if not os.path.exists(model_save_dir):os.makedirs(model_save_dir)fluid.io.save_inference_model(model_save_dir,['images'],[predict],exe)
infer_exe = fluid.Executor(place)
inference_scope = fluid.core.Scope() 
def load_image(file):#打开图片im = Image.open(file)#将图片调整为跟训练数据一样的大小  32*32im = im.resize((32, 32), Image.ANTIALIAS)#建立图片矩阵 类型为float32im = np.array(im).astype(np.float32)#矩阵转置 im = im.transpose((2, 0, 1))                               #将像素值从【0-255】转换为【0-1】im = im / 255.0    im = np.expand_dims(im, axis=0)return im
with fluid.scope_guard(inference_scope):#从指定目录中加载 推理model(inference model)[inference_program, # 预测用的programfeed_target_names,  fetch_targets] = fluid.io.load_inference_model(model_save_dir,infer_exe)  infer_path='/home/aistudio/data/cat.png'img = Image.open(infer_path)plt.imshow(img)   plt.show()    img = load_image(infer_path)results = infer_exe.run(inference_program,               feed={feed_target_names[0]: img}, fetch_list=fetch_targets)        label_list = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse","ship", "truck"]print("infer results: %s" % label_list[np.argmax(results[0])])

在这里插入图片描述

2. Keras 和 TensorFlow实现版本

完整CNN代码:

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras.optimizers import Adam# 构建一个简单的CNN模型
model = Sequential()# 第一个卷积层:使用32个3x3的卷积核,激活函数为ReLU,输入图像尺寸为64x64x3(RGB图像)
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)))# 第一个池化层:使用2x2的池化窗口,减少空间尺寸
model.add(MaxPooling2D(pool_size=(2, 2)))# 第二个卷积层:使用64个3x3的卷积核,激活函数为ReLU
model.add(Conv2D(64, (3, 3), activation='relu'))# 第二个池化层:同样使用2x2的池化窗口
model.add(MaxPooling2D(pool_size=(2, 2)))# 第三个卷积层:使用128个3x3的卷积核,激活函数为ReLU
model.add(Conv2D(128, (3, 3), activation='relu'))# 第三个池化层:同样使用2x2的池化窗口
model.add(MaxPooling2D(pool_size=(2, 2)))# 将3D的卷积输出展平为1D的向量
model.add(Flatten())# 添加一个全连接层:512个神经元,激活函数为ReLU
model.add(Dense(512, activation='relu'))# 添加一个Dropout层:随机丢弃30%的神经元,防止过拟合
model.add(Dropout(0.3))# 添加输出层:2个神经元(分类为猫或狗),使用Softmax激活函数
model.add(Dense(2, activation='softmax'))# 编译模型:使用Adam优化器,损失函数为交叉熵,评估指标为准确率
model.compile(optimizer=Adam(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])# 打印模型总结,查看模型结构
model.summary()

代码逐行解释:
tensorflow 是深度学习的框架,keras 是其中的高级API,用于构建神经网络。
Sequential 是模型的线性堆叠结构,表示网络各层按顺序堆叠。
Conv2D 是卷积层,用于图像特征提取。
MaxPooling2D 是池化层,用于降维,减少计算量。
Flatten 是将多维数据转换为一维向量,方便进入全连接层。
Dense 是全连接层,用于决策输出。
Dropout 是一种正则化技术,随机丢弃神经元,防止模型过拟合。
Adam 是一种常用的优化算法,用于调整网络中的权重。

model = Sequential()

这行代码创建了一个空的 Sequential 模型,表示我们将按顺序添加各个网络层。

model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)))

Conv2D(32, (3, 3)):这是一个卷积层,使用 32 个 3x3 的卷积核。
activation=‘relu’:激活函数使用 ReLU(Rectified Linear Unit),它可以帮助模型引入非线性。
input_shape=(64, 64, 3):输入图像的大小为 64x64 像素,3 个颜色通道(RGB)。
卷积层的作用是通过卷积核对图像进行扫描,提取局部特征,如边缘、纹理等。

model.add(MaxPooling2D(pool_size=(2, 2)))

MaxPooling2D(pool_size=(2, 2)):这是一个池化层,使用 2x2 的窗口来对图像进行降维。池化层通常将图像的空间尺寸缩小一半,减少计算量,并保留最重要的特征。

model.add(Flatten())

Flatten():将卷积层和池化层输出的 3D 张量(如 64x64x128)展平成 1D 向量(如 512),准备输入到全连接层。

model.add(Dense(512, activation='relu'))

Dense(512):全连接层,包含 512 个神经元,每个神经元与前一层的每个神经元都有连接。
activation=‘relu’:使用 ReLU 激活函数。
全连接层的作用是结合从卷积层提取到的所有特征,进行更高层次的抽象和决策。

model.add(Dropout(0.3))

Dropout(0.3):这是一个 Dropout 层,随机丢弃 30% 的神经元,防止模型过拟合。过拟合是指模型过于依赖训练数据,导致对新数据的预测效果差。

model.add(Dense(2, activation='softmax'))

Dense(2):输出层,包含 2 个神经元,因为我们要分类的是 2 类(比如猫和狗)。
activation=‘softmax’:使用 Softmax 激活函数,它将输出转化为概率值,表示属于每个类别的概率。

model.compile(optimizer=Adam(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])

optimizer=Adam():使用 Adam 优化器,自动调整学习率以最小化损失。
loss=‘sparse_categorical_crossentropy’:使用交叉熵作为损失函数,适用于多分类任务。
sparse 表示目标标签是整数。
metrics=[‘accuracy’]:我们会评估模型的准确率。

model.summary()

model.summary():输出模型的结构,显示各层的类型、输出形状和参数数量

提问检测环节

  1. CNN 的基本组成部分有哪些?
  2. 卷积层(Convolutional Layer):作用是什么?如何提取特征?
  3. 池化层(Pooling Layer):种类、作用及原理(如 MaxPooling 和 AveragePooling)。
  4. 为什么池化层没有参数?
  5. 激活函数(Activation Function):常见的 ReLU、Sigmoid、Softmax 等作用和区别。
  6. 全连接层(Fully Connected Layer):为什么需要展平(Flatten)?
  7. Dropout:在什么场景使用?如何防止过拟合?
  8. 简述 CNN 的基本组成部分及其功能。
  9. 什么是池化?它对特征图有何作用?
  10. SGD、Adam、RMSprop 的特点与适用场景。
  11. 准确率(Accuracy)、损失(Loss)、混淆矩阵(Confusion Matrix)的解读。
  12. 过拟合模型的表现特点。
  13. 为什么 Adam 优化器适合深层网络?

你都答对了吗?

感谢点赞关注👍

http://www.lryc.cn/news/504312.html

相关文章:

  • Coze概述
  • 康佳Android面试题及参考答案(多张原理图)
  • 2022 年 3 月青少年软编等考 C 语言四级真题解析
  • 关于24年408真题的疑问
  • 【容器】k8s学习笔记基础部分(三万字超详细)
  • dayjs(2kb)和momentjs(70kb)关系详述及项目中如何选择讲解
  • 【Python网络爬虫笔记】11- Xpath精准定位元素
  • 6.python列表
  • Android中bindService和startService启动服务有何区别
  • 超牛免费 机械臂模型、工业机器人模型下载网站集合
  • 引领未来的变革:15种前沿RAG技术及其应用探索
  • Scala泛型应用场景
  • AI监控赋能健身馆与游泳馆全方位守护,提升安全效率
  • Avalonia实战实例二:添加三种状态的Svg图片按钮
  • 基于注意力的几何感知的深度学习对接模型 GAABind - 评测
  • arcGIS使用笔记(无人机tif合并、导出、去除黑边、重采样)
  • Color-Light-Control-and-Four-Way-Responder based on STM32F103C8T6
  • openGauss开源数据库实战二十八
  • Vue3之响应式系统详解
  • Kafka 的配置文件
  • 【系统思辨】分散注意
  • 单幅图像合成 360° 3D 场景的新方法:PanoDreamer,可同时生成全景图像和相应的深度信息。
  • Python课设-谁为影狂-豆瓣数据【数据获取与预处理课设】
  • 关卡选择与布局器
  • 评估一套呼叫中心大模型呼出机器人的投入回报比?
  • 面向对象的 CLI:使用 Fire 简化类和对象的方法暴露 (中英双语)
  • flutter控件buildDragTargetWidget详解
  • 使用webrtc-streamer查看实时监控
  • 【数据分享】2014-2024年我国POI兴趣点数据(免费获取/来源于OSM地图)
  • Leetcode 3389. Minimum Operations to Make Character Frequencies Equal