卷积神经网络(CNN)原理与实现

  • 卷积神经网络(CNN)
    • 卷积神经网络原理
    • 卷积神经网络的数学推导
    • 卷积层反向传播算法数学推导
    • 卷积层实现代码

卷积神经网络(CNN)

卷积神经网络原理

卷积神经网络是一种用于图像、语音、自然语言等数据的深度学习模型,其核心思想是使用卷积操作提取输入数据的特征,从而实现数据分类、目标检测、图像分割等任务。

卷积操作是卷积神经网络的核心操作,它通过卷积核(也称为滤波器)对输入数据进行卷积运算,提取出输入数据的特征。具体来说,卷积操作对于每个位置,将卷积核中的值与输入数据的对应位置相乘,然后将所有乘积相加得到输出数据的对应位置的值。卷积核的大小、步长和填充方式都可以影响卷积操作的输出结果。

卷积神经网络通常包括卷积层、池化层、全连接层等多个层次。卷积层用于提取输入数据的特征,通过多个卷积核进行卷积操作,得到多个特征图(feature map)。池化层用于降低特征图的空间分辨率,减少计算量和参数数量。全连接层用于将特征图映射到目标类别,通常包含多个神经元,并使用softmax函数进行输出。

卷积神经网络在训练过程中通常使用反向传播算法进行梯度下降优化。反向传播算法可以通过将目标函数的梯度反向传递回网络中的每个神经元,计算每个神经元的梯度,并使用梯度下降更新网络参数,从而最小化目标函数。

卷积神经网络的数学推导

卷积神经网络(CNN)的核心操作是卷积(convolution),卷积的本质是信号处理中的一种数学运算,将两个函数进行叠加并积分,得到一个新的函数。

在CNN中,卷积的输入是一个二维矩阵(通常是图像)和一个卷积核(也称为滤波器)。卷积核是一个小的二维矩阵,大小通常为3x3或5x5,其内部的数值是需要通过训练学习得到的。
在这里插入图片描述

下面是卷积的数学推导过程:

设输入矩阵为 X ∈ R H × W X\in R^{H\times W} XRH×W,卷积核为 K ∈ R K h × K w K\in R^{K_h\times K_w} KRKh×Kw,其中 H H H表示矩阵的高度, W W W表示矩阵的宽度, K h K_h Kh表示卷积核的高度, K w K_w Kw表示卷积核的宽度。

在进行卷积操作时,将卷积核沿着输入矩阵的每个位置进行滑动,对应位置的元素相乘并相加,得到输出矩阵 Y ∈ R ( H − K h + 1 ) × ( W − K w + 1 ) Y\in R^{(H-K_h+1)\times(W-K_w+1)} YR(HKh+1)×(WKw+1)。具体来说,输出矩阵 Y Y Y的第 i i i行第 j j j列的元素为:

y i , j = ∑ m = 1 K h ∑ n = 1 K w x i + m − 1 , j + n − 1 k m , n y_{i,j}=\sum\limits_{m=1}^{K_h}\sum\limits_{n=1}^{K_w}x_{i+m-1,j+n-1}k_{m,n} yi,j=m=1Khn=1Kwxi+m1,j+n1km,n

其中, x i + m − 1 , j + n − 1 x_{i+m-1,j+n-1} xi+m1,j+n1表示输入矩阵 X X X的第 i + m − 1 i+m-1 i+m1行第 j + n − 1 j+n-1 j+n1列的元素, k m , n k_{m,n} km,n表示卷积核 K K K的第 m m m行第 n n n列的元素。

需要注意的是,在卷积操作时通常还会进行填充(padding)和步长(stride)的设置。填充是在输入矩阵的边缘添加一些额外的元素,使得卷积操作后输出矩阵的大小与输入矩阵相同;步长是在滑动卷积核时的间隔,可以控制输出矩阵的大小。

卷积神经网络通常会在卷积层后加入激活函数,如ReLU函数,来增加非线性能力。此外,卷积神经网络还可以通过池化(pooling)层来减小特征图的大小,从而减少计算量和参数数量。池化层通常采用最大池化(max pooling)或平均池化(average pooling)操作,对每个特征图的每个小区域进行取最大值或取平均值的操作,从而得到更小的特征图。

卷积神经网络的数学推导主要是通过卷积操作、激活函数和池化操作实现。在卷积神经网络中,每个卷积层通常包含多个卷积核,每个卷积核对应一个特征图(也称为卷积映射)。因此,每个卷积层输出的是多个特征图,这些特征图可以进一步传递到下一层进行计算。

在进行卷积神经网络的训练过程中,通常采用反向传播算法(backpropagation)来求解模型参数。反向传播算法基于梯度下降的思想,通过计算损失函数对模型参数的偏导数(梯度),从而不断更新模型参数,使得模型能够更好地拟合训练数据。

总之,卷积神经网络的数学推导涉及到卷积操作、激活函数和池化操作,这些操作是卷积神经网络的核心。在进行训练时,通常采用反向传播算法来求解模型参数,从而使得模型能够更好地拟合训练数据。

卷积层反向传播算法数学推导

卷积层反向传播算法是卷积神经网络中最为核心的算法之一,其目的是求解每个卷积核的权重参数和偏置项的梯度,从而进行模型参数的更新。

卷积层反向传播算法的数学推导主要分为两个步骤:前向传播和反向传播。前向传播通过卷积操作和激活函数对输入数据进行处理,得到输出数据;反向传播根据误差对输出数据的梯度,利用卷积操作对输入数据的梯度进行计算,进而求解每个卷积核的梯度。

下面是卷积层反向传播算法的数学推导:

假设输入数据为 X X X,卷积核为 W W W,偏置项为 b b b,输出数据为 Y Y Y。其中, X X X W W W 的维度分别为 C i n × H i n × W i n C_{in} \times H_{in} \times W_{in} Cin×Hin×Win C o u t × C i n × K h × K w C_{out} \times C_{in} \times K_h \times K_w Cout×Cin×Kh×Kw Y Y Y 的维度为 C o u t × H o u t × W o u t C_{out} \times H_{out} \times W_{out} Cout×Hout×Wout K h K_h Kh K w K_w Kw 分别表示卷积核的高度和宽度, H o u t H_{out} Hout W o u t W_{out} Wout 分别表示输出数据的高度和宽度。

前向传播的数学表达式为:

Y k , i , j = σ ( ∑ c = 1 C i n ∑ p = 1 K h ∑ q = 1 K w X c , i + p − 1 , j + q − 1 W k , c , p , q + b k ) Y_{k,i,j}=\sigma(\sum_{c=1}^{C_{in}}\sum_{p=1}^{K_h}\sum_{q=1}^{K_w}X_{c,i+p-1,j+q-1}W_{k,c,p,q}+b_k) Yk,i,j=σ(c=1Cinp=1Khq=1KwXc,i+p1,j+q1Wk,c,p,q+bk)

其中, σ \sigma σ 表示激活函数。这里使用了 k k k i i i j j j 分别表示第 k k k 个特征图、第 i i i 行、第 j j j 列的像素点。通过前向传播,我们可以得到输出数据 Y Y Y

反向传播的数学表达式为:

∂ L ∂ X c , i , j = ∑ k = 1 C o u t ∑ p = 1 K h ∑ q = 1 K w W k , c , p , q ∂ L ∂ Y k , i + p − 1 , j + q − 1 \frac{\partial L}{\partial X_{c,i,j}}=\sum_{k=1}^{C_{out}}\sum_{p=1}^{K_h}\sum_{q=1}^{K_w}W_{k,c,p,q}\frac{\partial L}{\partial Y_{k,i+p-1,j+q-1}} Xc,i,jL=k=1Coutp=1Khq=1KwWk,c,p,qYk,i+p1,j+q1L

∂ L ∂ W k , c , p , q = ∑ i = 1 H o u t ∑ j = 1 W o u t X c , i + p − 1 , j + q − 1 ∂ L ∂ Y k , i , j \frac{\partial L}{\partial W_{k,c,p,q}}=\sum_{i=1}^{H_{out}}\sum_{j=1}^{W_{out}}X_{c,i+p-1,j+q-1}\frac{\partial L}{\partial Y_{k,i,j}} Wk,c,p,qL=i=1Houtj=1WoutXc,i+p1,j+q1Yk,i,jL

∂ L ∂ b k = ∑ i = 1 H o u t ∑ j = 1 W o u t ∂ L ∂ Y k , i , j \frac{\partial L}{\partial b_k}=\sum_{i=1}^{H_{out}}\sum_{j=1}^{W_{out}}\frac{\partial L}{\partial Y_{k,i,j}} bkL=i=1Houtj=1WoutYk,i,jL

其中, L L L 表示损失函数。通过反向传播,我们可以求解出每个卷积核的梯度,从而进行模型参数的更新。

解释一下上述公式的含义:

首先,由于卷积操作是可微分的,因此可以通过链式法则来求解输入数据 X X X 的梯度。假设 L L L 表示损失函数,则 Y Y Y L L L 的梯度为 ∂ L ∂ Y k , i , j \frac{\partial L}{\partial Y_{k,i,j}} Yk,i,jL,因此可以通过卷积操作来计算 X X X L L L 的梯度。

反向传播中第一个公式表示, X c , i , j X_{c,i,j} Xc,i,j L L L 的梯度等于所有输出数据 Y k , i + p − 1 , j + q − 1 Y_{k,i+p-1,j+q-1} Yk,i+p1,j+q1 L L L 的梯度乘以对应的权重 W k , c , p , q W_{k,c,p,q} Wk,c,p,q 的和。其中, k k k 取遍所有特征图, p p p q q q 分别表示卷积核在 H H H W W W 方向上的偏移量。

反向传播中第二个公式表示, W k , c , p , q W_{k,c,p,q} Wk,c,p,q L L L 的梯度等于所有输入数据 X c , i + p − 1 , j + q − 1 X_{c,i+p-1,j+q-1} Xc,i+p1,j+q1 L L L 的梯度乘以对应的输出数据 Y k , i , j Y_{k,i,j} Yk,i,j 的和。同样地, k k k 取遍所有特征图, i i i j j j 分别表示输出数据在 H H H W W W 方向上的偏移量。(解释与公式矛盾)

反向传播中第三个公式表示, b k b_k bk L L L 的梯度等于所有输出数据 Y k , i , j Y_{k,i,j} Yk,i,j L L L 的梯度的和。

在实际应用中,通常会采用基于梯度下降的优化算法来进行模型参数的更新。在卷积层反向传播算法中,可以通过上述公式计算出每个卷积核的梯度,然后利用梯度下降算法对模型参数进行更新,从而提高模型的性能。

卷积层实现代码

下面是一个使用 NumPy 实现的简单 Conv2d 类的示例代码:

import numpy as npclass Conv2d:def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, bias=True):self.in_channels = in_channelsself.out_channels = out_channelsself.kernel_size = kernel_sizeself.stride = strideself.padding = paddingself.bias = bias# 初始化卷积核和偏置项self.weights = np.random.randn(out_channels, in_channels, kernel_size, kernel_size)self.bias_values = np.zeros(out_channels)def forward(self, x):# 计算输出大小out_h = int((x.shape[2] + 2*self.padding - self.kernel_size) / self.stride + 1)out_w = int((x.shape[3] + 2*self.padding - self.kernel_size) / self.stride + 1)# 对输入数据进行填充x = np.pad(x, [(0, 0), (0, 0), (self.padding, self.padding), (self.padding, self.padding)], mode='constant')# 初始化输出数据output = np.zeros((x.shape[0], self.out_channels, out_h, out_w))# 对每个通道进行卷积操作for i in range(self.out_channels):# 对每个像素进行卷积操作for h in range(out_h):for w in range(out_w):# 计算卷积结果conv = np.sum(x[:, :, h*self.stride:h*self.stride+self.kernel_size, w*self.stride:w*self.stride+self.kernel_size] * self.weights[i, :, :, :], axis=(1,2,3))# 加上偏置项conv += self.bias_values[i]# 存储卷积结果output[:, i, h, w] = convreturn output

这个示例实现了一个简单的 Conv2d 类,其构造函数接受输入通道数、输出通道数、卷积核大小、步长、填充和偏置项等参数。在构造函数中,我们随机初始化了卷积核和偏置项。

forward 函数接受输入数据 x,并根据卷积核大小、步长和填充对输入数据进行填充。然后,我们对每个通道和每个像素进行卷积操作,并将结果存储在输出数据中。在卷积操作中,我们使用 NumPy 的数组乘法和求和操作实现了卷积运算,并加上了偏置项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/268709.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql中的事务

什么是事务: 多条sql语句,要么全部成功,要么全部失败。 事务的特性: 1:原子性(Atomic): 组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有操作都成功,整个事务才会…

算法学习系列(三十八):超级源点问题

目录 引言一、题目描述二、解题思路三、示例代码 引言 关于最短路问题不论是竞赛、找工作、笔试面试、机试考的都是挺多的,所以还是非常的重要,最重要的就是模板首先背过,然后通过刷题见各种各样的题,具体难点就是如何建图、怎么…

【牛客面试必刷TOP101】Day25.BM38 在二叉树中找到两个节点的最近公共祖先和BM40 重建二叉树

作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:牛客面试必刷TOP101 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!&…

什么是智能合约

前言:在介绍智能合约的前提下,需要先介绍一下区块链 一.什么是区块链 区块链实质上是一个去中心化、分布式的可进行交易的数据库或账本,具有下列典型特征: 去中心化:简单来说,在网络上一个或多个服务器瘫…

IPC对象、消息队列 、共享内存

我要成为嵌入式高手之3月4日Linux高编第十四天!! 消息队列、共享内存、信号灯: 一、IPC对象 内存文件,如何查看? 1、ipcs: 查看系统中的IP对象的消息队列、共享内存、信号灯信息 2、ipcrm:…

蓝桥杯倒计时 41天 - 二分答案-最大通过数-妮妮的月饼工厂

最大通过数 思路&#xff1a;假设左边能通过 x 关&#xff0c;右边能通过 y 关&#xff0c;x∈[0,n]&#xff0c;通过二分&#xff0c;在前缀和中枚举右边通过的关卡数&#xff0c;保存 xy 的最大值。 #include<bits/stdc.h> using namespace std; typedef long long ll…

产品营销展示型wordpress外贸网站模板

工艺品wordpress外贸主题 简约大气的wordpress外贸主题&#xff0c;适合做工艺品进出品外贸的公司官网使用。 https://www.jianzhanpress.com/?p5377 餐饮设备wordpress外贸主题 简洁的wordpress外贸主题&#xff0c;适合食品机械、餐饮设备公司使用。 https://www.jianzh…

洛谷 B3620 x 进制转 10 进制

题目描述 给一个小整数 x 和一个 x 进制的数 S。将 S 转为 10 进制数。对于超过十进制的数码&#xff0c;用 A&#xff0c;B&#xff0c;…… 表示。 输入格式 第一行一个整数 x; 第二行一个字符串 S。 输出格式 输出仅包含一个整数&#xff0c;表示答案。 输入输出样例…

leetcode 移除链表元素

本题中&#xff0c;我们是要移除链表的某一个节点&#xff0c;为了确保统一操作&#xff0c;我们需要使用虚拟头节点&#xff0c;这样我们删除节点的时候&#xff0c;就是把这个要删除的节点&#xff08;当前节点cur&#xff09;的前一个节点pre&#xff0c;使得pre.next指向要…

sqlserver保存微信Emoji表情

首先将数据库字段&#xff0c;设置类型为 nvarchar(200)一个emoji表情&#xff0c;占4字节就可以了&#xff0c;web前端展示不用改任何东西&#xff0c;直接提交数据保存&#xff1b;回显也会没有问题&#xff0c;C#代码不用做任何处理&#xff1b; 不哭不闹要睡觉&#x1f31…

执行一条 select 语句,期间发生了什么?

大家好我是苏麟 , 今天开始又开一个坑 MySQL原理 . 资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) 执行一条 select 语句&#xff0c;期间发生了什么&#xff1f; 学习 SQL 的时候&#xff0c;大家肯定第一个先学到的就是 select 查询语句了&#xff…

UCSF DOCK 分子对接详细案例(04)-基于RDKit描述符的分子从头设计DOCK_D3N

欢迎浏览我的CSND博客&#xff01; Blockbuater_drug …点击进入 文章目录 前言一、 软件及操作环境二、研究目的三、结构文件准备四、 DOCK/RDKit中 de novo design4.1 de novo design - refine_D3N4.2 对输出重新评分 总结参考资料 前言 本文是UCSF DOCK的使用案例分享&…

Windows服务器:通过nginx反向代理配置HTTPS、安装SSL证书

先看下效果&#xff1a; 原来的是 http&#xff0c;配置好后 https 也能用了&#xff0c;并且显示为安全链接。 首先需要 SSL证书 。 SSL 证书是跟域名绑定的&#xff0c;还有有效期。 windows 下双击可以查看相关信息。 下载的证书是分 Apache、IIS、Tomcat 和 Nginx 的。 我…

uniapp实现-审批流程效果

一、实现思路 需要要定义一个变量, 记录当前激活的步骤。通过数组的长度来循环数据&#xff0c;如果有就采用3元一次进行选择。 把循环里面的变量【name、status、time】, 全部替换为取出的那一项的值。然后继续下一次循环。 虚拟的数据都是请求来的, 组装为好渲染的格式。 二…

linux中对信号的认识

信号的概念与相关知识认识 信号是向目标进程发送消息通知的的一种机制。 信号可以以异步的方式发送给进程&#xff0c;也就是说&#xff0c;进程无需主动等待&#xff0c;而是在任何时间都可以接收到信号。 信号的种类 用kill-l命令查看系统定义的信号列表&#xff1a; 前台…

thinkphp学习11-数据库的查询表达式

比较查询 查询表达式支持大部分常用的 SQL 语句&#xff0c;语法格式如下 where(字段名,查询表达式,查询条件);在查询数据进行筛选时&#xff0c;我们采用 where()方法&#xff0c;比如 id79&#xff1b; $user1 Db::name(user)->where(id, 79)->find(); $user2 Db::…

巧用二进制实现俄罗斯方块小游戏

效果预览 思想 首先建立两个数组board、tetris用来存储当前已经堆积在棋盘的方块与正在下落的方块。 这两个是一维数组当需要在页面画棋盘时就对其每一项转成二进制&#xff08;看计算属性tetrisBoard&#xff09;&#xff0c;其中1&#xff08;红色&#xff09;0&#xff08;…

加密与安全_深入了解Hmac算法(消息认证码)

文章目录 PreHMAC概述常见的Hmac算法Code随机的key的生成 KeyGeneratorHmacMD5用Hmac算法取代原有的自定义的加盐算法 HmacMD5 VS MD5HmacSHA256 Pre 加密与安全_深入了解哈希算法中我们提到&#xff0c; 存储用户的哈希口令时&#xff0c;要加盐存储&#xff0c;目的就在于抵…

现货黄金价格今日行情怎样把握?

由于受到各种经济和政治因素的影响&#xff0c;国际市场上的黄金价格&#xff0c;每天的行情走势都在不断地波动&#xff0c;有时候行情上涨&#xff0c;有时候行情下跌&#xff0c;如果投资者不懂得灵活地应对&#xff0c;在哪一种行情中都有可能亏损&#xff0c;但如果投资者…

Linux系统CPU模式部署Qwen1.5-14B

Qwen1.5已适配Ollama。 Ollama 是一个命令行聊天机器人&#xff0c;它使得几乎可以在任何地方使用大型语言模型变得简单。 下载 Ollma 安装文件 访问以下网站&#xff1a;https://ollama.com/download/linux 执行&#xff1a;curl -fsSL https://ollama.com/install.sh | sh…