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

计算机视觉:卷积神经网络(CNN)基本概念(二)

第一章:计算机视觉中图像的基础认知
第二章:计算机视觉:卷积神经网络(CNN)基本概念(一)
第三章:计算机视觉:卷积神经网络(CNN)基本概念(二)
第四章:搭建一个经典的LeNet5神经网络(附代码)
第五章:计算机视觉:神经网络实战之手势识别(附代码)

接上一篇《计算机视觉:卷积神经网络(CNN)基本概念(一)》

二、图像特征

三、什么是卷积神经网络?

四、什么是灰度图像、灰度值?

灰度图像是只包含亮度信息的图像,没有颜色信息。灰度值(Gray Value)是指图像中每个像素点的亮度值,用于表示该像素的明暗程度。在灰度图像中,每个像素的灰度值通常是一个介于 0 和 255 之间的整数,其中:

  • 0 表示黑色(最暗)
  • 255 表示白色(最亮)
  • 中间值 表示不同程度的灰色

灰度值的计算

对于彩色图像(通常表示为 RGB 格式),可以通过将红、绿、蓝三个通道的值转换为单个灰度值来生成灰度图像。常见的灰度值计算公式包括:

  • 加权平均法:Gray=0.299×R+0.587×G+0.114×B,这个公式考虑了人眼对不同颜色的敏感度,其中红色的权重最低,绿色的权重最高。
  • 平均法:Gray=(R+G+B) / 3,这个公式简单地取三个通道值的平均值。
  • 最大值法:Gray=max(R,G,B),这个公式取三个通道值中的最大值作为灰度值。

五、特征抽取的具体过程

卷积操作

  • 定义:输入图像与卷积核进行卷积运算,生成特征图。
  • 示例:一个 3x3 的卷积核在 64x64 的图像上滑动,计算每个位置的加权和,生成一个新的 62x62 的特征图。
  • 公式:高度 H = (图片高度 - 卷积核的高度 + 2 * 填充圈数) / 卷积核移动步长 + 1

激活函数

  • 定义:通过激活函数(如 ReLU)引入非线性,使网络能够学习更复杂的模式。
  • 示例:ReLU 激活函数将负值变为 0,正值保持不变。

池化操作

  • 定义:通过池化操作(如最大池化)减少特征图的尺寸,保留最重要的信息。
  • 示例:2x2 的最大池化操作将 62x62 的特征图降采样为 31x31 的特征图。

多层卷积和池化

  • 定义:通过多层卷积和池化操作,逐步提取更高层次的特征。
  • 示例:第二个卷积层会生成 64 个新的特征图,每个特征图捕捉了更复杂的局部特征。

展平

  • 定义:最终,将多维的特征图展平成一维向量,输入到全连接层进行分类。假设经过卷积和池化操作后,得到的特征图的尺寸为 H×W×C,其中 H 是高度,W 是宽度,C 是通道数。展平操作将特征图展平成一个一维向量,尺寸为 H×W×C。
  • 为什么要展平?,也就是为什么要改变形状,
    - 展平不会改变像素值!
    - 展平不会改变数据本身的信息!
    - 展平为了对口型!
    - 展平为了科学计算!
    - 展平为了矩阵相乘!
  • 示例:假设经过卷积和池化操作后,得到的特征图的尺寸为 31x31x64,展平成 61184 维的向量。

全连接

  1. 全连接层的定义
    • 在全连接层中,每个神经元都接收前一层所有神经元的输出,并通过加权求和和激活函数来计算自己的输出。

在这里插入图片描述

  1. 全连接层的结构
    在这里插入图片描述

  2. 全连接层的作用

    1. 特征整合
      全连接层可以整合前一层的特征,将局部特征组合成全局特征。这对于分类任务尤为重要,因为它需要综合考虑输入数据的所有信息来做出最终的决策。
      卷积层和池化层提取的是图像的局部特征,而全连接层可以将这些局部特征整合成全局特征。这对于分类任务非常重要,因为最终的分类决策需要综合考虑图像的所有信息。
    2. 分类和回归
      全连接层通常用于神经网络的最后几层,用于输出最终的分类结果或回归值。例如,在图像分类任务中,全连接层可以将卷积层提取的特征图展平成一维向量,然后通过多层全连接层进行分类。
      全连接层的输出层通常用于分类任务,将前一层的特征映射到类别标签。在手写数字识别任务中,全连接层的输出层将特征映射到 10 个类别(0 到 9)。
    3. 非线性变换
      全连接层通过激活函数引入非线性,使神经网络能够学习更复杂的模式和关系。常见的激活函数包括 ReLU、Sigmoid、Tanh 等。
    4. 参数学习
      全连接层的权重和偏置是通过反向传播算法进行学习的。在训练过程中,损失函数的梯度会通过全连接层传递,更新权重和偏置,从而使模型逐渐优化。

六、CNN的简单案例

这段代码实现一个简单的神经网络模型,用于拟合正弦函数 sin(x), 有4 层全连接层,CNN学习非线性关系。我们可以用一个简单的神经网络来学习这个关系。假设神经网络的结构如下:
输入层:1 个节点
隐藏层:3个隐藏层,第一个隐藏层50个节点,第二个隐藏层80 个节点,第三个隐藏层50 个节点,使用 ReLU 激活函数
输出层:1 个节点,使用线性激活函数

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt# 数据准备
# 使用 numpy 库生成从 −2π 到 2π 的等间距数字序列 x,共有1000个点。
x = np.linspace(-2 * np.pi, 2 * np.pi, 1000)
# 计算每个 x 值对应的 sin(x) 值,并存储在 y 中。
y = np.sin(x)
# 然后将这些数据转换为 PyTorch 张量并调整形状以适应后续的神经网络输入要求:
x_tensor = torch.tensor(x, dtype=torch.float32).view(-1, 1)
y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1)# 定义神经网络模型
# 定义了一个名为 SimpleNN 的类,继承自 torch.nn.Module,它是一个简单的全连接神经网络模型,包含4层线性变换(全连接层),每层之间使用ReLU激活函数。
class SimpleNN(nn.Module):def __init__(self):super(SimpleNN, self).__init__()self.fc1 = nn.Linear(1, 50)self.fc2 = nn.Linear(50, 80)self.fc3 = nn.Linear(80, 50)self.fc4 = nn.Linear(50, 1)self.relu = nn.ReLU()def forward(self, x):x = self.relu(self.fc1(x))x = self.relu(self.fc2(x))x = self.relu(self.fc3(x))x = self.fc4(x)return x# 训练模型
# 初始化一个 SimpleNN 模型实例、均方误差(MSE)损失函数以及Adam优化器。
model = SimpleNN()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)
# 在每个训练周期中,先清除之前的梯度(optimizer.zero_grad()),
# 然后通过模型前向传播得到预测输出(outputs),计算损失值(loss),
# 执行反向传播更新模型权重(loss.backward() 和 optimizer.step())。
for epoch in range(2000):optimizer.zero_grad()outputs = model(x_tensor)loss = criterion(outputs, y_tensor)loss.backward()optimizer.step()# 每200个周期打印一次当前的损失值,观察训练过程中的收敛情况。if (epoch + 1) % 200 == 0:print(f'Epoch [{epoch+1}/2000], Loss: {loss.item():.4f}')# 测试模型并绘图
# 将模型设置为评估模式(model.eval())
model.eval()
with torch.no_grad():# 在不启用自动求导的情况下(torch.no_grad()),用训练好的模型对输入数据 x_tensor 进行预测。predictions = model(x_tensor)# 使用 matplotlib 绘制原始的正弦曲线和模型的预测曲线,比较两者的拟合效果。这有助于直观地了解模型的拟合程度。
plt.scatter(x, y, label='True Data')
plt.plot(x, predictions.numpy(), color='red', label='Predictions')
plt.legend()
plt.show()

输出结果,从拟合曲线上看,CNN 学习得很好,在这个例子中,神经网络通过隐藏层的 ReLU 激活函数学会了输入 x 和输出 y=sin(x) 之间的非线性关系。通过训练,模型能够很好地拟合这个非线性函数。

Epoch [200/2000], Loss: 0.0002
Epoch [400/2000], Loss: 0.0005
Epoch [600/2000], Loss: 0.0000
Epoch [800/2000], Loss: 0.0003
Epoch [1000/2000], Loss: 0.0000
Epoch [1200/2000], Loss: 0.0003
Epoch [1400/2000], Loss: 0.0006
Epoch [1600/2000], Loss: 0.0007
Epoch [1800/2000], Loss: 0.0002
Epoch [2000/2000], Loss: 0.0002

在这里插入图片描述
现在把 上面 4 层全链接,改层 2 层,
神经网络的结构如下:
输入层:1 个节点
隐藏层:1个隐藏层,50 个节点,使用 ReLU 激活函数
输出层:1 个节点,使用线性激活函数
看看是什么效果:

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt# 数据准备
x = np.linspace(-2 * np.pi, 2 * np.pi, 1000)
y = np.sin(x)
x_tensor = torch.tensor(x, dtype=torch.float32).view(-1, 1)
y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1)# 定义神经网络模型
class SimpleNN(nn.Module):def __init__(self):super(SimpleNN, self).__init__()self.fc1 = nn.Linear(1, 50)self.fc4 = nn.Linear(50, 1)self.relu = nn.ReLU()def forward(self, x):x = self.relu(self.fc1(x))x = self.fc4(x)return x# 训练模型
model = SimpleNN()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)for epoch in range(2000):optimizer.zero_grad()outputs = model(x_tensor)loss = criterion(outputs, y_tensor)loss.backward()optimizer.step()if (epoch + 1) % 200 == 0:print(f'Epoch [{epoch+1}/2000], Loss: {loss.item():.4f}')# 测试模型并绘图
model.eval()
with torch.no_grad():predictions = model(x_tensor)plt.scatter(x, y, label='True Data')
plt.plot(x, predictions.numpy(), color='red', label='Predictions')
plt.legend()
plt.show()

输出结果,很明显,只有 2 层的情况下,CNN 只学习到x和 y 的一部分非线性关系。

Epoch [200/2000], Loss: 0.1304
Epoch [400/2000], Loss: 0.0929
Epoch [600/2000], Loss: 0.0745
Epoch [800/2000], Loss: 0.0720
Epoch [1000/2000], Loss: 0.0718
Epoch [1200/2000], Loss: 0.0713
Epoch [1400/2000], Loss: 0.0708
Epoch [1600/2000], Loss: 0.0707
Epoch [1800/2000], Loss: 0.0706
Epoch [2000/2000], Loss: 0.0706

在这里插入图片描述
浅层网络(2层)损失:0.0706 → 拟合不足
深层网络(4层)损失:0.0002 → 近乎完美拟合

为什么CNN需要多层卷积?
浅层学习局部特征(边缘、纹理)
深层学习全局语义(物体部件、整体结构)

相关文章:

计算机视觉:卷积神经网络(CNN)基本概念(二)

第一章:计算机视觉中图像的基础认知 第二章:计算机视觉:卷积神经网络(CNN)基本概念(一) 第三章:计算机视觉:卷积神经网络(CNN)基本概念(二) 第四章:搭建一个经典的LeNet5神经网络(附代码) 第五章&#xff1…...

【第7章:注意力机制与Transformer模型—7.4 NLP领域的BERT、GPT系列模型】

当你在2017年第一次听说Transformer时,可能不会想到这个模型会在短短三年内彻底改变NLP领域。想象一下,原本需要数周训练的翻译模型,现在用Transformer架构几天就能达到更好的效果;那些让程序员们头疼的梯度消失问题,突然变得不再重要。这一切的魔法钥匙,都藏在一个叫做&…...

[代码调试]安装Text2Image(stable diffusion)模型环境的踩坑记录

文章目录 一、xFormers版本问题1、先确认下自己torch版本所对应的cuda版本2.安装对应版本(1) 到对应官网下载包本地安装(2)代码安装 二、attn_mask尺寸错误三、diffusers四、Huggingface 配置基于stable diffusion预训练模型的环境,记录踩坑记录 一、xFormers版本问…...

大数据SQL调优专题——Flink执行原理

引入 上一篇我们了解了Spark,相比起MapReduce来说,它确实已经快了超级多了,但是人类的欲望是没有止境的,这也是推动人类进步的动力。 Flink就是为了满足实时响应的场景需求诞生的。 其实在Flink之前,实时处理其实已…...

Oracle 12c中在同一组列上创建多个索引

在数据库管理与优化领域,索引是提高查询性能的关键工具之一。然而,在某些情况下,单一类型的索引可能不足以满足所有查询的需求。Oracle 12c引入了一个强大的新特性:允许在同一组列上创建多个索引,但仅一个可见&#xf…...

线程安全的集合类

文章目录 多线程环境使⽤`ArrayList`线程不安全线程安全可以使用 `ReentrantLock` 或 `synchronized`来保护 `ArrayList` 的访问。使用同步包装器使用 `CopyOnWriteArrayList`**“写时复制”机制**多线程环境使⽤队列多线程环境使⽤哈希表HashtableConcurrentHashMapHashMap、H…...

【如何实现 JavaScript 的防抖和节流?】

如何实现 JavaScript 的防抖和节流? 前言 防抖(Debounce)和节流(Throttle)是 JavaScript 中优化高频事件处理的两种常用技术。它们可以有效减少事件处理函数的调用次数,提升性能并改善用户体验。本文将详…...

C#中File类的Copy()方法或FileInfo类的CopyTo()方法的参数overwrite取false和true的区别

当调用 System.IO.File.Copy 方法时,第三个参数 overwrite 控制着如果目标位置已经存在同名文件的情况下如何处理。 1、当 overwrite 设置为 true 在这种情况下,即使目标路径下已经有相同名称的文件,该方法也会无条件地覆盖现有的文件。这不…...

力扣 买卖股票的最佳时机

贪心算法典型例题。 题目 做过股票交易的都知道,想获取最大利润,就得从最低点买入,最高点卖出。这题刚好可以用暴力,一个数组中找到最大的数跟最小的数,然后注意一下最小的数在最大的数前面即可。从一个数组中选两个数…...

蚁剑(AutSword)的下载安装与报错解决

蚁剑(AutSword)的下载安装与报错解决 1.下载 唯一官方github下载地址 GitHub - AntSwordProject/AntSword-Loader: AntSword 加载器 2.安装 打开并且进入到下面的界面 下载需要的的版本 进行初始化 3.报错 出现下面的报错 4.解决方法 出现上面报错…...

【全栈开发】----Mysql基本配置与使用

本篇是在已下载Mysql的情况下进行的,若还未下载或未创建Mysql服务,请转到这篇: 2024 年 MySQL 8.0.40 安装配置、Workbench汉化教程最简易(保姆级)_mysql8.0.40下载安装教程-CSDN博客 本文对于mysql的操作均使用控制台sql原生代码…...

Spring Boot项目的基本设计步骤和相关要点介绍

以下是一个关于Spring Boot项目的基本设计步骤和相关要点介绍,我们以一个简单的示例应用——员工管理系统为例进行说明: 一、项目概述 员工管理系统旨在实现对公司员工信息的有效管理,包括员工基本信息录入、查询、更新以及删除等功能。通过Spring Boot框架来快速搭建后端…...

【Spring快速入门】不断更新...

一、Java基础 1、注解 1.3、自定义注解 springboot项目中自定义注解的使用总结、java自定义注解实战(常用注解DEMO)_springboot在类或者方法上加自定义注解-CSDN博客 同平台的新林。大佬就总结的很好,最近写得项目利用aop切面编程中的Aut…...

nodejs版本管理,使用 nvm 删除node版本,要删除 Node.js 的某个版本详细操作

要删除 Node.js 的某个版本并保持 Node Version Manager (nvm) 的管理整洁,可以按以下步骤操作: 步骤 1:查看已安装的 Node.js 版本 nvm ls这会列出你通过 nvm 安装的所有 Node.js 版本。输出类似于: -> v18.17.1v16.20…...

HTML之JavaScript DOM(document)编程处理事件

HTML之JavaScript DOM&#xff08;document&#xff09;编程处理事件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…...

5.【线性代数】—— 转置,置换和向量空间

五 转置&#xff0c;置换和向量空间 1. 置换矩阵2. 转置矩阵3. 对称矩阵4. 向量空间4.1 向量空间4.2 子空间 1. 置换矩阵 定义&#xff1a; 用于行互换的矩阵P。 之前进行ALU分解时&#xff0c;可能存在该行主元为0&#xff0c;要进行行互换&#xff0c;即PALU 性质&#xff1…...

移动通信发展史

概念解释 第一代网络通信 1G 第二代网络通信 2G 第三代网络通信 3G 第四代网络通信 4G 4g网络有很高的速率和很低的延时——高到500M的上传和1G的下载 日常中的4G只是用到了4G技术 运营商 移动-从民企到国企 联通-南方教育口有人 电信 铁通&#xff1a;成立于 2000 年…...

Python MoviePy 视频处理全攻略:从入门到实战案例

第1章 环境安装与配置 # 案例1&#xff1a;安装MoviePy及FFmpeg !pip install moviepy # Windows安装FFmpeg&#xff1a;https://ffmpeg.org/download.html # Linux: sudo apt-get install ffmpeg# 验证安装 from moviepy.editor import * print("MoviePy版本:", __…...

uniapp webview嵌入外部h5网页后的消息通知

最近开发了个oa系统&#xff0c;pc端的表单使用form-create开发&#xff0c;form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成组件。移动端使用uniapp开发&#xff0c;但是因为form-create移动端只支持vant&#xff0c;不支持uniapp。官…...

macos安装jmeter测试软件

java环境安装 a. 验证安装环境 java -version # 如果有版本信息&#xff0c;说明已安装 b. 安装jdk # 安装 Homebrew&#xff08;如未安装&#xff09; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # 安装 O…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...