PyToch 深度学习 || 3. 卷积神经网络 | 3.1 深度学习中的卷积操作

news2024/11/23 17:09:16

深度学习中的卷积操作

文章目录

  • 深度学习中的卷积操作
    • 1. 卷积
    • 2. 一维卷积
      • 2.1 使用nn.functional库中conv1d
      • 2.2 使用nn库中的Conv1d
    • 3. 二维卷积
      • 3.1 nn.functional.conv2d
      • 3.2 nn.Conv2d

1. 卷积

加权求和是一种非常重要的运算,可以整合局部数字特征进而是提取局部信息的重要手段。这种加权求和的形式被称作卷积或者滤波,对于两个信号 f ( x ) f(x) f(x) g ( x ) g(x) g(x),卷积操作表示为

f ( x ) ∗ g ( x ) = ∫ − ∞ + ∞ f ( τ ) g ( x − τ ) d τ f(x)*g(x)=\int^{+\infty}_{-\infty}f(\tau)g(x-\tau)d\tau f(x)g(x)=+f(τ)g(xτ)dτ

卷积在物理现象中类似于波的叠加。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

常用的卷积有1Dconv,2Dconv 和 3Dconv,这些卷积的区别仅在于滑动的方向不一样,而与卷积核的形状无关。1Dconv 滑动的方向仅为水平方向,2Dconv 沿着水平和竖直方向滑动。卷积后的形状遵循如下公式

h = ( h − kennel size + 2 ∗ padding ) / stride + 1 w = ( w − kennel size + 2 ∗ padding ) / stride + 1 h = (h - \text{kennel size}+2*\text{padding}) / \text{stride} + 1\\ w = (w - \text{kennel size}+2*\text{padding}) / \text{stride} + 1 h=(hkennel size+2padding)/stride+1w=(wkennel size+2padding)/stride+1

其中,padding 为边界填充 0 的行列数,stride 为滑动步长。

2. 一维卷积

2.1 使用nn.functional库中conv1d

该函数的优势可以设定核中的权重,尽管这个在网络中不是必须的。

用法:

torch.nn.functional.conv1d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1) → Tensor

参数:

  • input-形状(minibatch,in_channels,iW)的输入张量

  • weight-形状(out_channels,groupsin_channels,kW)的过滤器

  • bias-形状 (out_channels) 的可选偏差。默认值:None

  • stride-卷积核的步幅。可以是单个数字或 one-element 元组 (sW,) 。默认值:1

  • padding-输入两侧的隐式填充。可以是字符串 {‘valid’, ‘same’}、单个数字或 one-element 元组 (padW,) 。默认值:0 padding=‘valid’ 与无填充相同。 padding=‘same’ 填充输入,使输出具有作为输入的形状。但是,此模式不支持 1 以外的任何步幅值。

一维卷积可以对单个向量进行卷积操作

在这里插入图片描述

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F

a=range(16)
x = Variable(torch.Tensor(a))
'''
a: range(0, 16)
x: tensor([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13.,
        14., 15.])
'''

x=x.view(1,1,16)
'''
x variable: tensor([[[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13., 14., 15.]]])
'''

b=torch.ones(3)
b[0]=0.1
b[1]=0.2
b[2]=0.3
weights = Variable(b)
weights=weights.view(1,1,3)
'''
weights: tensor([[[0.1000, 0.2000, 0.3000]]])
'''

y=F.conv1d(x, weights, padding=0)
'''
y: tensor([[[0.8000, 1.4000, 2.0000, 2.6000, 3.2000, 3.8000, 4.4000, 5.0000, 5.6000, 6.2000, 6.8000, 7.4000, 8.0000, 8.6000]]])
'''
y
tensor([[[0.8000, 1.4000, 2.0000, 2.6000, 3.2000, 3.8000, 4.4000, 5.0000,
          5.6000, 6.2000, 6.8000, 7.4000, 8.0000, 8.6000]]])

1Dconv 同样可以对多个向量进行一维卷积操作
在这里插入图片描述

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F

a=range(16)
x = Variable(torch.Tensor(a))
'''
a: range(0, 16)
x: tensor([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13.,
        14., 15.])
'''

x=x.view(1,2,8)
'''
x variable: tensor([[[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.]
                     [ 8.,  9., 10., 11., 12., 13., 14., 15.]]])
'''

b=torch.ones(6)
b[0]=0.1
b[1]=0.2
b[2]=0.3
b[3]=0.1
b[4]=0.2
b[5]=0.3

weights = Variable(b)
weights=weights.view(1,2,3)
'''
weights: tensor([[[0.1000, 0.2000, 0.3000]
                  [0.1000, 0.2000, 0.3000]]])
'''

y=F.conv1d(x, weights, padding=0)
'''
y: tensor([[[ 6.4000,  7.6000,  8.8000, 10.0000, 11.2000, 12.4000]]])
'''
y
tensor([[[ 6.4000,  7.6000,  8.8000, 10.0000, 11.2000, 12.4000]]])

2.2 使用nn库中的Conv1d

在深度学习中,滤波器的初始权重并没有多大意义,因此,初始权重采用随机数和权重共享的方式,不必设定权重的值,而nn.Conv1d正是为了达到此目的而产生的。

用法:

torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’)

参数:

  • in_channel:输入的通道数,信号一般为一维

  • out_channel:输出的通道数

  • kernel_size:卷积核的大小

  • stride:步长

  • padding:0填充

import time

import torch
import torch.nn as nn

'''
Description: torch.nn.Conv1d
input:(batch_size,in_channel,length)
output:(batch_size,out_channel,length)
shape of kernel:(channel*kernel_size)
out_channel :the num of kernel--> how much kernel do you need?
'''
#(batch_size,in_channel,length)
input =torch.ones(1,1,6)
print(input)
model =nn.Conv1d(in_channels=1,
                 out_channels=1,#可以设定多个滤波器,共享权重
                 kernel_size=3,
                 padding=0)
# (batch_size,out_channel,length)
output =model(input)
print(output)
tensor([[[1., 1., 1., 1., 1., 1.]]])
tensor([[[-0.2018, -0.2018, -0.2018, -0.2018]]],
       grad_fn=<ConvolutionBackward0>)
import time

import torch
import torch.nn as nn

'''
Description: torch.nn.Conv1d
input:(batch_size,in_channel,length)
output:(batch_size,out_channel,length)
shape of kernel:(channel*kernel_size)
out_channel :the num of kernel--> how much kernel do you need?
'''
#(batch_size,in_channel,length)
input =torch.ones(1,1,6)
print(input)
model =nn.Conv1d(in_channels=1,
                 out_channels=2,#可以设定多个滤波器,共享权重
                 kernel_size=3,
                 padding=0)
# (batch_size,out_channel,length)
output =model(input)
print(output)
tensor([[[1., 1., 1., 1., 1., 1.]]])
tensor([[[-1.4254, -1.4254, -1.4254, -1.4254],
         [ 0.4811,  0.4811,  0.4811,  0.4811]]],
       grad_fn=<ConvolutionBackward0>)
import time

import torch
import torch.nn as nn

'''
Description: torch.nn.Conv1d
input:(batch_size,in_channel,length)
output:(batch_size,out_channel,length)
shape of kernel:(channel*kernel_size)
out_channel :the num of kernel--> how much kernel do you need?
'''
#(batch_size,in_channel,length)
input =torch.ones(4,2,6)
print(input)
model =nn.Conv1d(in_channels=2,
                 out_channels=4,#可以设定多个滤波器,共享权重
                 kernel_size=3,
                 padding=0)
# (batch_size,out_channel,length)
output =model(input)
print(output)
tensor([[[1., 1., 1., 1., 1., 1.],
         [1., 1., 1., 1., 1., 1.]],

        [[1., 1., 1., 1., 1., 1.],
         [1., 1., 1., 1., 1., 1.]],

        [[1., 1., 1., 1., 1., 1.],
         [1., 1., 1., 1., 1., 1.]],

        [[1., 1., 1., 1., 1., 1.],
         [1., 1., 1., 1., 1., 1.]]])
tensor([[[-0.4742, -0.4742, -0.4742, -0.4742],
         [ 1.0267,  1.0267,  1.0267,  1.0267],
         [-0.8237, -0.8237, -0.8237, -0.8237],
         [ 0.2031,  0.2031,  0.2031,  0.2031]],

        [[-0.4742, -0.4742, -0.4742, -0.4742],
         [ 1.0267,  1.0267,  1.0267,  1.0267],
         [-0.8237, -0.8237, -0.8237, -0.8237],
         [ 0.2031,  0.2031,  0.2031,  0.2031]],

        [[-0.4742, -0.4742, -0.4742, -0.4742],
         [ 1.0267,  1.0267,  1.0267,  1.0267],
         [-0.8237, -0.8237, -0.8237, -0.8237],
         [ 0.2031,  0.2031,  0.2031,  0.2031]],

        [[-0.4742, -0.4742, -0.4742, -0.4742],
         [ 1.0267,  1.0267,  1.0267,  1.0267],
         [-0.8237, -0.8237, -0.8237, -0.8237],
         [ 0.2031,  0.2031,  0.2031,  0.2031]]],
       grad_fn=<ConvolutionBackward0>)

3. 二维卷积

3.1 nn.functional.conv2d

卷积的方式有多种,主要区别在于卷积核与图像矩阵边界匹配的方式和加权求和后值的位置分配不同,下图尽通过一组图来展示卷积的过程。
在这里插入图片描述

在这里插入图片描述

torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)

其中input代表的是输入图像/矩阵(这里限制输入必须是以[minibatch,channel,H,W]这样的shape输入)
weight代表的是卷积核(同样是要求以上面的shape输入)
stride代表的是卷积核在输入图像上移动的步长
padding代表的是进行卷积之前是否对输入图像进行边缘填充(默认不填充)

import torch 
import torch.nn.functional as F

#卷积操作
input = torch.tensor([[1,2,0,3,1],
                      [0,1,2,3,1],
                      [1,2,1,0,0],
                      [5,2,3,1,1],
                      [2,1,0,1,1]])

kernel = torch.tensor([[1,2,1],
                       [0,1,0],
                       [2,1,0]])

print(input)   # [5,5]
print('\n', kernel)  # [3,3]
input = torch.reshape(input, (1, 1, 5, 5)) # (batch, channal, width, heiht)
kernel = torch.reshape(kernel, (1, 1, 3, 3)) # (batch, channal, width, heiht)

# stride=1,卷积核每次移动一个元素
output1 = F.conv2d(input, kernel, stride=1)
print("\n stride=1,不进行padding,卷积操作后:")
print(output1) # (5-3+2*0)/1 + 1 = 3

# padding=1, 边界填充一格,元素设置为0,扩充完之后是一个7*7的矩阵

output2 = F.conv2d(input, kernel, stride=1, padding=1)
'''
[[0,0,0,0,0,0,0]
 [0,1,2,0,3,1,0],
 [0,0,1,2,3,1,0],
 [0,1,2,1,0,0,0],
 [0,5,2,3,1,1,0],
 [0,2,1,0,1,1,0]
 [0,0,0,0,0,0,0]]
'''
print("\n stride=1,padding=1,卷积操作后:")
print(output2) # (5-3+2*1)/1 + 1 = 5

# stride=2,卷积核每次移动2个元素
output3 = F.conv2d(input, kernel, stride=2)
print("\n stride=2,不进行padding,卷积操作后:")
print(output3) # (5-3+2*0)/2 + 1 = 2
tensor([[1, 2, 0, 3, 1],
        [0, 1, 2, 3, 1],
        [1, 2, 1, 0, 0],
        [5, 2, 3, 1, 1],
        [2, 1, 0, 1, 1]])

 tensor([[1, 2, 1],
        [0, 1, 0],
        [2, 1, 0]])

 stride=1,不进行padding,卷积操作后:
tensor([[[[10, 12, 12],
          [18, 16, 16],
          [13,  9,  3]]]])

 stride=1,padding=1,卷积操作后:
tensor([[[[ 1,  3,  4, 10,  8],
          [ 5, 10, 12, 12,  6],
          [ 7, 18, 16, 16,  8],
          [11, 13,  9,  3,  4],
          [14, 13,  9,  7,  4]]]])

 stride=2,不进行padding,卷积操作后:
tensor([[[[10, 12],
          [13,  3]]]])

3.2 nn.Conv2d

深度学习中一般不需要刻意设定卷积核的权重,可以使用nn.Conv2d,将关注点放在输入和输出上的数目上。

函数:

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
import torch

x = torch.randn(3,1,5,4) # [batch, channel, height, width]
print('3 批数据单通道矩阵:')
print(x)

conv = torch.nn.Conv2d(in_channels=1, out_channels=4, kernel_size=(2,3), stride=1, padding=0)
res = conv(x) # (5-2+2*0)/1+1 =4; (4-3+2*0)/1+1=2

print(res.shape)    # torch.Size([3, 4, 4, 2])
3 批数据单通道矩阵:
tensor([[[[-0.2597, -0.2103,  0.0358, -1.0163],
          [ 0.9965,  0.0855, -0.7477, -1.5901],
          [ 2.2799, -1.1986, -2.2921, -0.8996],
          [ 1.2546, -0.2645, -0.0734,  2.1464],
          [ 0.4333, -1.4566,  1.4044,  0.9502]]],


        [[[-0.5962, -0.0100,  1.2836,  1.5562],
          [ 0.7060,  0.9727,  0.3383, -0.8690],
          [ 0.2354,  0.2068, -1.1025,  2.9323],
          [-0.8895, -0.9010,  1.4417, -0.3452],
          [ 1.3244,  1.5612, -2.3033,  0.5028]]],


        [[[ 1.3851, -0.9373,  1.4245,  0.9449],
          [-1.7409, -1.2329,  0.4447,  0.8167],
          [ 1.4936, -0.2248,  1.3076, -1.7958],
          [ 1.2098,  0.6465,  0.0848,  0.8640],
          [-0.0291, -0.3277,  2.0227, -0.7025]]]])
torch.Size([3, 4, 4, 2])

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux CentOS监控系统的运行情况工具 - top/htop/glances/sar/nmon

在CentOS系统中&#xff0c;您可以使用以下工具来监控系统的运行情况&#xff1a; 1. top&#xff1a; top 是一个命令行工具&#xff0c;用于实时监控系统的进程、CPU、内存和负载情况。您可以使用以下命令来启动 top&#xff1a; top 输出 2. htop&#xff1a; htop 是一…

WSL 2 环境配置

WSL 2 环境配置 wsl2是windows内置的linux子系统&#xff0c;安装步骤如下&#xff1a; Win10 版本号为 2004&#xff08;内部版本19041或更高&#xff09;即可&#xff0c;如果低于此版本可使用 Windows 10 易升工具手动升级。下载 Windows 10 易升工具&#xff1a; https:…

DAY52:动态规划(十七)子序列问题:最长递增子序列+最长连续递增序列+最长重复子数组

文章目录 300.最长递增子序列&#xff08;注意初始化和结果取值&#xff09;思路DP数组含义递推公式初始化最开始的写法debug测试&#xff1a;解答错误debug测试2&#xff1a;result初始值 修改完整版总结 674.最长连续递增序列思路1&#xff1a;滑动窗口思路2&#xff1a;动态…

【Leetcode】54.螺旋矩阵

一、题目 1、题目描述 给你一个 m m m 行 n n n 列的矩阵 matrix,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例1: 输入:matrix =

安防监控视频汇聚EasyCVR修改录像计划等待时间较长,是什么原因?

安防监控视频EasyCVR视频融合汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检…

项目——负载均衡在线OJ

目录 项目介绍开发环境所用技术项目宏观结构编写思路1. 编写compile_server1.1 编译模块编写1.2 运行功能1.3compile_runner 编译与运行1.4 编写compile_server.cpp调用compile_run模块&#xff0c;形成网络服务 2. 编写基于MVC的oj_server2.1 oj_server.cpp的编写2.2 oj_model…

Unity进阶--对象池数据场景管理器笔记

文章目录 泛型单例类泛型单例类&#xff08;不带组件版&#xff09;对象池管理器数据管理器场景管理器 泛型单例类 using System.Collections; using System.Collections.Generic;public abstract class ManagersSingle<T> where T : new() {private static T instance;…

OSCP 学习:Kali Linux 基本命令

Bash 环境 环境变量 当我们开启新的bash时候&#xff0c;它会拥有自己的环境变量 我是这样理解 环境变量的&#xff1a; 每个程序都有自己运行的地址 我们用一个变量来储存它的地址 这个变量就叫环境变量 Kali 最常用的环境变量 就是 $PATH。这个我们可以用这个变量进行不正当…

selenium浏览器驱动下载

Chrome谷歌浏览器 下载地址&#xff1a;http://chromedriver.storage.googleapis.com/index.html 不同的Chrome的版本对应的chromedriver.exe 版本也不一样&#xff0c;下载时不要搞错了。 如果是最新的Chrome, 下载最新的chromedriver.exe 就可以了。 Firefox火狐浏览器 驱…

B073-封装工具类 服务模块(后台)

目录 拿当前登录人信息工具类服务模块业务分析表结构后端代码后台代码覆写删除-加详情一起删调整前端Data&#xff0c;handleAdd和编辑框覆写新增编辑按钮展示详情资源&#xff1a;多图上传和回显图片 拿当前登录人信息工具类 工具类准备&#xff1a;LoginContext: 登录上下文…

前端性能测试

目录 前言&#xff1a; 前端性能 1、优化 2、Lighthouse 使用 4、Lighthouse 报告参数的标准 5、更多产品 前言&#xff1a; 前端性能测试是一个广泛的领域&#xff0c;它旨在评估前端应用程序的性能和可靠性。前端性能测试需要使用各种测试工具和技术&#xff0c;包括浏…

功率信号源的基本工作原理、用途和应用方法

功率信号源是一种可以产生恒定或可变功率输出的测试设备。在电子实验中&#xff0c;功率信号源广泛应用于各种不同的应用&#xff0c;下面安泰电子就来介绍功率信号源的基本工作原理、用途和应用方法。 功率信号源的基本工作原理 功率信号源的基本工作原理是将电能转换成信号能…

【前端实习评审】对小说详情模块的产品原型有一定的自己理解

大家好&#xff0c;本篇文章分享一下【校招VIP】免费商业项目“推推”第一期书籍详情模块前端同学的文档作品。该同学来自中国科学院大学计算机技术专业。 本项目亮点难点&#xff1a;1 热门书籍在更新点的访问压力 2 书籍更新通知的及时性和有效性 3 书荒:同好推荐的可能性 4…

血压诊断米家智能血压计方案

智能血压计产品介绍: 智能血压计是一种基于蓝牙技术的便携式血压测量设备。它通过无线连接与智能手机或其他设备同步并联接到APP端&#xff08;米家&#xff09;&#xff0c;可以准确测量用户的血压数据&#xff0c;并通过手机应用程序进行记录和分析。 智能血压计产品结构: 智…

Win10的两个实用技巧系列之蓝屏代码大全及解决方案、更改应用优先级的技巧

Win10怎么设置程序优先级? Win10更改应用优先级的技巧 Win10怎么设置程序优先级&#xff1f;Win10系统中任务管理器想要设置优先级&#xff0c;该怎么设置呢&#xff1f;下面我们就来看看Win10更改应用优先级的技巧 有些Win10用户想要调整程序优先级&#xff0c;以确保某些…

Sentinel限流中间件

目录 介绍 Sentinel 的特征 Sentinel 的组成 实战使用 简单实例 配置本地控制台 使用可视化ui配置简单流控 配置异步任务限流 使用注解定义限流资源 SpringCloud整合Sentinel 简单整合 并发线程流控 关联模式 整合openFeign使用 介绍 随着微服务的流行&#xff0…

iOS私钥证书和证书profile文件的生成攻略

在使用uniapp打包ios app的时候&#xff0c;要求我们提供一个私钥证书和一个证书profile文件&#xff0c;私钥证书可以使用mac电脑的钥匙串访问程序来生成&#xff0c;也可以使用香蕉云编来生成。证书profile文件可以直接在苹果开发者中心生成。 有部分刚接触ios开发的同学们&…

Easy-Es笔记

一、Easy-ES概述 Easy-Es&#xff08;简称EE&#xff09;是一款ElasticSearch-ORM框架&#xff0c;在原生 RestHighLevelClient 的基础上&#xff0c;只做增强不做改变&#xff0c;为简化开发、提高效率而生。Easy-Es采用和MP一致的语法设计&#xff0c;能够显著降低ElasticSea…

各种拉格朗日函数

目录 一&#xff0c;拉格朗日函数 二&#xff0c;部分拉格朗日函数 三&#xff0c;增广拉格朗日函数 一&#xff0c;拉格朗日函数 以三元函数为例&#xff1a; 求f(x,y,z)的极值&#xff0c;s.t.g(x,y,z)0 拉格朗日函数L(x,y,z,a) f(x,y,z) a * g(x,y,z) 在极值点处一…

(学习日记)2023.06.09

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…