卷積神經網絡-卷積的分類

卷積的定義

????????卷積是圖像處理中最核心的操作之一,其本質是通過卷積核(濾波器)與圖像進行滑動窗口計算(像素值乘積之和),實現對圖像特征的提取、增強或抑制。

一、二維卷積--針對二維矩陣進行處理

1.1單通道

? ? ? ? 見得最多的卷積形式,它只有一個通道。

形式:

解釋:這里的卷積不是旁邊綠色的矩陣圖,右邊綠色的矩陣圖叫做特征圖(feature map),一般是卷積核與原圖進行卷積后的結果圖。這里的卷積核是

[0,1,2]

[2,2,0]

[0,1,2]?

卷積的過程就是從上到下,從左到右依次開卷,然后乘積求和相加。

1.2多通道

? ? ? ? 多通道卷積的通道數不在局限于1個,它的通道數是多個的,一般用在圖像為多通道圖像上,每一個通道的原圖形像素值與對應通道的卷積核進行計算,最后再進行多通道的合并(元素相加,在通道上進行特征融合)。

形式:

# 第1個子核(對應輸入的R通道)
[[w11, w12, w13],[w21, w22, w23],[w31, w32, w33]
]# 第2個子核(對應輸入的G通道)
[[u11, u12, u13],[u21, u22, u23],[u31, u32, u33]
]# 第3個子核(對應輸入的B通道)
[[v11, v12, v13],[v21, v22, v23],[v31, v32, v33]
]

二、三維卷積

????????在空間的長、寬兩個維度基礎上,再增加一個深度(或時間)維度進行卷積操作。

核心特點:

  • 卷積核是三維的:比如尺寸為?3×3×3(長 × 寬 × 深度),像一個 “小立方體”。
  • 作用對象是三維數據:比如視頻的連續幀(寬 × 高 × 時間幀)、CT/MRI 的立體醫學影像(長 × 寬 × 切片層)等。

三、反卷積

? ? ? ? 卷積的反向操作,但不是嚴格反向。卷積是將原圖的特征進行提取,會把原圖變小。卷積為計算Y。

? ? ? ? 反卷積也稱為轉置卷積,它是將小尺寸的特征圖恢復為大尺寸。反卷積為計算X。

四、膨脹卷積

? ? ? ? 膨脹卷積也叫空洞卷積,主要是為了讓卷積核的元素之間插入空格進行膨脹,擴大感受野。一般膨脹率參數L默認為1,公式為L-1。

????????感受野(Receptive Field)輸出特征圖上的一個像素點,對應輸入圖像(或原始數據)中多大范圍的區域

API:nn.Conv2d(dilation = 2)? -----這表示空一格

代碼:

import torch
import torch.nn as nn
def test():c1 = nn.Conv2d(in_chanels=3,out_chanels=1,kernel_size=3,stride=1,paddiong=0,dilation=2)out = c1(input_data)print(out.shape)if __name__ == '__main__':input_data = torch.randn(1,3,7,7)  #1表示批次,3表示通道,7表示高度,7表示寬度test()

結果:

torch.Size([1, 1, 3, 3])??

解釋:特征圖out根據公式可以得到現在的寬高,torchsize里的參數分別表示(batch,channel,height,weight)

?計算公式:

五、可分離卷積

5.1空間可分離卷積

? ? ? ? 將卷積核拆分成可以用數學公式相乘得到的兩個卷積核。用這兩個分別的獨立的核對原圖形進行操作。

? ? ? ? 拆分的目的:降低計算量。

API:nn.Conv2d(kernel_size = (x,y))

代碼:

def test1():c1 = nn.Conv2d(in_channels=3,out_channels=1,kernel_size=(3,1),stride=1,padding=0,dilation=1)out = c1(input_data)print(out.shape)c2 = nn.Conv2d(in_channels=1,out_channels=1,kernel_size=(1,3),stride=1,padding=0,dilation=1)out1 = c2(out)print(out1.shape)if __name__ == '__main__':input_data = torch.randn(1,3,7,7)  #1表示批次,3表示通道,7表示高度,7表示寬度test1()

結果:

torch.Size([1, 1, 5, 7])
torch.Size([1, 1, 5, 5])

根據結果可以觀察到,最終的結果仍然是一樣的,計算公式可以用上圖計算得到。

#可分離卷積的另一種寫法
class SeparbleConv(nn.Module):def __init__(self):super(SeparbleConv,self).__init__()self.c1 = nn.Conv2d(in_channels=32,out_channels=64,kernel_size=(3,1),stride=1,padding=0,dilation=1)self.c2 = nn.Conv2d(in_channels=64,out_channels=16,kernel_size=(1,3),stride=1,padding=0,dilation=1)def forward(self,x):x = self.c1(x)out = self.c2(x)return outif __name__ == '__main__':input_data = torch.randn(1,32,214,214)model = SeparbleConv()out = model(input_data)print(out.shape)weight_desc = model.named_parameters()for name, param in weight_desc:print(name, param.shape)

結果:

?torch.Size([1, 16, 212, 212])
c1.weight torch.Size([64, 32, 3, 1])
c1.bias torch.Size([64])
c2.weight torch.Size([16, 64, 1, 3])
c2.bias torch.Size([16])

5.2深度可分離卷積

? ? ? ? 深度可分離卷積的卷積核分為兩部分,一部分為深度卷積核,一部分為1*1卷積(點卷積)。

卷積過程:

(1)輸入圖的每一個通道都有對應的卷積核,通道數有多少,卷積核的個數就有多少。

(2)對前一個深度可分離卷積的結果進行1*1卷積,對上一個特征圖進行特征融合,形成新的特征圖結果。這里不會改變形狀大小,只是把重要的特征凸顯出來,不重要的信息逐漸抹去。

注意:深度卷積時,要對其進行分組。

分組是為了減少參數量和計算量,如果仍按照傳統的全連接層網絡創建的話,參數會多的多。

eg:

傳統卷積中,每個輸出通道都依賴于所有輸入通道的信息。 例如:輸入 64 通道,輸出 128 通道,傳統卷積需要 64×128 個 3×3 卷積核,總參數量為 64×128×3×3 = 73,728。 這種 “全連接” 方式計算開銷極大,尤其在深層網絡中會導致參數量爆炸。

分組卷積將輸入通道和輸出通道按組隔離,每組內獨立進行卷積,最后拼接結果。 例如:同樣是輸入 64 通道、輸出 128 通道,若設置groups=2

  • 輸入被分為 2 組(每組 32 通道);

  • 輸出也被分為 2 組(每組 64 通道);

  • 每組內的卷積:每個輸出通道只連接到對應的輸入組(如第一組的 64 個輸出通道僅由第一組的 32 個輸入通道計算得到)。

此時,每組需要 32×64 個 3×3 卷積核,兩組總參數量為 2×(32×64×3×3) = 36,864,相比傳統卷積減少近一半!

?代碼驗證:

#深度可分離卷積
class depthConv(nn.Module):def __init__(self):super(depthConv,self).__init__()self.c1 = nn.Conv2d(in_channels=8,out_channels=8,  #參數量3*3*1*1*8 = 72kernel_size=(3,3),stride=1,padding=0,dilation=1,groups=8)  #分組卷積# 這里的c1是深度可分離卷積中的depthwise卷積# 下面的c2是深度可分離卷積中的pointwise卷積self.c2 = nn.Conv2d(in_channels=8,out_channels=8,  #參數量8*8*1*1 =64kernel_size=(1,1),stride=1,padding=0,dilation=1,)def forward(self,x):x = self.c1(x)out = self.c2(x)return out#普通卷積
class Conv(nn.Module):def __init__(self):super(Conv,self).__init__()self.c1 = nn.Conv2d(in_channels=8,out_channels=8,  #參數量3*3*8*8 = 576kernel_size=(3,3),stride=1,padding=0,dilation=1,)def forward(self,x):out = self.c1(x)return outif __name__ == '__main__':input_data = torch.randn(1,8,32,32)  #1表示批次,8表示通道,7表示高度,7表示寬度model = depthConv()out = model(input_data)print(out.shape)moedl2 = Conv()out2 = moedl2(input_data)print(out2.shape)#打印權重參數weight = model.named_parameters()for name,para in weight:print(name,para.shape)print('------------------------')weight2 = moedl2.named_parameters()for name,para in weight2:print(name,para.shape)

結果:

?torch.Size([1, 8, 30, 30])
torch.Size([1, 8, 30, 30])
c1.weight torch.Size([8, 1, 3, 3])
c1.bias torch.Size([8])
c2.weight torch.Size([8, 8, 1, 1])
c2.bias torch.Size([8])
------------------------
c1.weight torch.Size([8, 8, 3, 3])
c1.bias torch.Size([8])

六、扁平卷積

? ? ? ? 將標準卷積拆分成3個1*1的卷積核,然后分別對輸入層進行卷積計算。

七、分組卷積

? ? ? ? 將卷積分組放到兩個GPU中并發執行。這里的分組和前邊深度可分離卷積的分組一樣,都是為了解決參數量和計算量的問題。

代碼:

#分組卷積
class GroupConv(nn.Module):def __init__(self):super(GroupConv,self).__init__()self.c1 = nn.Conv2d(in_channels=32,out_channels=256,  #參數量4*32*3*3*8 = 9216kernel_size=3,stride=1,padding=0,dilation=1,groups=8)def forward(self,x):out = self.c1(x)return outclass Conv(nn.Module):def __init__(self):super(Conv,self).__init__()self.c1 = nn.Conv2d(in_channels=32,out_channels=256,  #參數量32*256*3*3 = 73728kernel_size=3,stride=1,padding=0,dilation=1,groups=1)def forward(self,x):out = self.c1(x)return out
if __name__ == '__main__':input_data = torch.randn(1,32,512,512)  #1表示批次,32表示通道,512表示高度,512表示寬度model = Conv()  #普通卷積out = model(input_data)print(out.shape)model1 = GroupConv() #分組卷積out = model1(input_data)print(out.shape)weight_group = model1.named_parameters()for name,weight in weight_group:print(name,weight.shape)print('上面的是分組權重信息,下面的是普通全連接權重信息------------------------')weight = model.named_parameters()for name,weight in weight:print(name,weight.shape)

結果:

torch.Size([1, 256, 510, 510])
torch.Size([1, 256, 510, 510])
c1.weight torch.Size([256, 4, 3, 3])
c1.bias torch.Size([256])
上面的是分組權重信息,下面的是普通全連接權重信息------------------------
c1.weight torch.Size([256, 32, 3, 3])
c1.bias torch.Size([256])

八、混洗分組卷積

???????? 分組卷積中最終結果會按照原先的順序進行合并組合,阻礙了模型在訓練時特征信息在通道間流動,削弱了特征表示。混洗分組卷積,主要是將分組卷積后的計算結果混合交叉在一起輸出。

九、整體結構--卷積神經網絡案例

?根據該圖定義一個可以識別手寫數字的卷積神經網絡案例:

步驟:

(1)導入數據集

(2)加載數據集

(3)構建網絡模型

(4)定義設備、輪次、學習率、優化器、損失函數、數據加載器;

(5)開始訓練

(6)模型保存----在代碼中暫未體現

(7)模型預測----在代碼中暫未體現

代碼:

import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import datasets,transforms
import os
from torchvision.datasets import MNIST
import torch.optim as optim#定義數據預處理
#數據地址
file_path = os.path.relpath(os.path.join(os.path.dirname(__file__), 'data'))  
#定義數據集
train_data = MNIST(root=file_path,train=True,transform=transforms.ToTensor(),download=False)
#查看文件類別,標簽
class_names = train_data.classes
print(class_names)#定義數據加載器
train_loader = DataLoader(train_data,batch_size=32,shuffle=True,drop_last=True)
#當設置 drop_last=True 時:
# 如果訓練數據總量不能被 batch_size 整除,最后一個樣本數量不足 batch_size 的批次會被丟棄。
# 如果設置為 False,最后一個樣本數量不足 batch_size 的批次會被保留,但可能會導致訓練結果不穩定。#定義網絡結構
class MyNet(nn.Module):def __init__(self):super(MyNet,self).__init__()#定義網絡結構self.c1 = nn.Sequential(nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5),nn.ReLU())self.s2 = nn.AdaptiveAvgPool2d(14)  #自適應地調整為指定大小(這里是 14×14),而無需手動計算核大小、步長等參數。self.c3 = nn.Sequential(nn.Conv2d(in_channels=6,out_channels=16,kernel_size=5),nn.ReLU())self.s4 = nn.AdaptiveAvgPool2d(5)self.l5 = nn.Sequential(nn.Linear(16*5*5,120),nn.ReLU())self.l6 = nn.Sequential(nn.Linear(120,84),nn.ReLU())self.l7 = nn.Linear(84,10)def forward(self,x):#前向傳播x = self.c1(x)x = self.s2(x)x = self.c3(x)x = self.s4(x)x = x.view(x.size(0),-1)x = self.l5(x)x = self.l6(x)out = self.l7(x)return out#定義設備、學習率等參數
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = MyNet()
model.to(device)epochs = 20
lr = 0.001
opt = optim.Adam(model.parameters(),lr=lr)
criterion = nn.CrossEntropyLoss()#訓練
for epoch in range(epochs):model.train()total_loss = 0acc_total = 0for i,(x,y) in enumerate(train_loader):x,y = x.to(device),y.to(device)opt.zero_grad()  #梯度清零out = model(x)out = torch.argmax(out, dim=1)acc_total += (out == y).sum().item()loss = criterion(out,y)total_loss += loss.item()loss.backward() #反向傳播opt.step()if i%10 == 0: #每訓練10個batch打印一次print(f'epoch:{epoch},loss:{loss.item()}')print("epoch:", epoch, "loss:", total_loss/ len(train_loader.dataset), "acc:", acc_total / len(train_loader.dataset))

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/91454.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/91454.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/91454.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

全網首發:使用GIT下載時崩潰退出,是因為機械硬盤

前面有幾篇文章,說是GIT下載會退出。開始以為是虛擬機問題。把家里的虛擬機復制到公司,照樣崩潰。后來認為是內存不足。昨天在家里下載代碼,也崩潰退出。心里覺得奇怪,試了一次,還是退出。差別在哪里?之前是…

YAML 自動化用例中 GET vs POST 請求的參數寫法差異

GET 請求:用 params 傳參(附加在 URL 上) config:name: "GET 查詢用戶信息"base_url: "https://api.example.com"teststeps:- name: "根據 userId 查詢用戶信息"request:method: GETurl: /api/user/detailpara…

使用 SeaTunnel 建立從 MySQL 到 Databend 的數據同步管道

SeaTunnel 是一個非常易用、超高性能的分布式數據集成平臺,支持實時海量數據同步。 每天可穩定高效地同步數百億數據,已被近百家企業應用于生產,在國內較為普及。 Databend 是一款開源、彈性、低成本,基于對象存儲也可以做實時分…

linux服務器換ip后客戶端無法從服務器下載數據到本地問題處理

服務器換ip后客戶端無法從服務器下載數據到本地,根據上圖提示,讓用戶清理下~/.ssh/known_hosts文件,下載恢復正常。

從0到1實現Shell!Linux進程程序替換詳解

目錄從0到1實現Shell!Linux進程程序替換詳解 🚀引言:為什么進程需要"變身術"?一、程序替換:進程的"換衣服"魔法 🔄1.1 什么是程序替換?1.2 程序替換的原理:內存…

暑期算法訓練.2

目錄 6.力扣 11.盛水最多的容器 6.1 題目解析: 6.2 算法思路: 6.2.1 暴力解法: 6.2.2 優化算法: 6.3 代碼演示: ?編輯 6.4 總結反思: 7.力扣 611.有效的三角形個數 7.1 題目解析: 7.2…

華為OD 消消樂游戲

1. 題意 游戲規則:輸入一個只包含英文字母的字符串,字符串中的兩個字母如果相鄰且相同,就可以消除。 在字符串上反復執行消除的動作,直到無法繼續消除為止,此時游戲結束。 輸出最終得到的字符串長度。 輸入 輸入原始…

小白學HTML,操作HTML文件篇(2)

目錄 一、添加多媒體 1.添加網頁圖片 2.添加網頁音頻 3.添加網頁視頻 二、創建容器 1. 標簽 2.布局 三、創建表格 1.表格標簽 2.添加表格表頭 3.添加表格標題 一、添加多媒體 在 HTML 網頁中可以輕松地使用標簽來添加圖片、音頻、視頻等多媒體,而這些多媒體并…

微服務架構中實現跨服務的字段級權限統一控制

結合集中式權限管理、分布式上下文傳遞、動態策略執行等技術 ??一、核心架構設計?? ??1. 分層控制模型?? ??網關層??:統一校驗用戶身份與基礎權限,攔截非法請求。 ??服務層??:基于用戶權限動態過濾數據字段,實現業務級控制。 ??策略中心??:集中管理權…

【實現100個unity特效之27】使用unity的ShaderGraph實現一個帶裁剪邊緣光的裁剪效果(2d3d通用)

文章目錄普通裁剪效果1、創建一個Lit Shader Graph2、ShaderGraph前置配置3、添加節點4、效果5、修改裁剪方向帶邊緣色的裁剪1、在裁剪的基礎上添加裁剪邊緣光2、邊緣的亮度3、修改裁剪方向4、效果5、我們可以代碼控制它的變化,如下2D3D游戲通用專欄推薦完結普通裁剪…

Android Scoped Storage適配完全指南

Android Scoped Storage適配完全指南關鍵詞:Android、Scoped Storage、適配、存儲權限、文件訪問摘要:本文將全面介紹Android Scoped Storage的相關知識,從背景出發,詳細解釋核心概念,闡述其原理和架構,給出…

Typecho集成PHPMailer實現郵件訂閱功能完整指南

文章目錄 Typecho使用PHPMailer實現文章推送訂閱功能詳解 1. 背景與需求分析 1.1 為什么選擇PHPMailer 1.2 功能需求 2. 環境準備與配置 2.1 安裝PHPMailer 2.2 數據庫設計 3. 核心功能實現 3.1 郵件服務封裝類 3.2 訂閱功能實現 3.2.1 訂閱表單處理 3.2.2 確認訂閱處理 3.3 文…

無線-二層組網-直接轉發

文章目錄無線二層組網直接轉發🏡作者主頁:點擊! 🤖Datacom專欄:點擊! ??創作時間:2025年07月16日08點00分 無線二層組網 直接轉發 本地轉發中所有的沿途都需要配置對應VLAN的通過&#xff…

gin go-kratos go-zero框架對比

Gin、Go-Kratos 和 Go-Zero 是 Go 語言中三種常見的服務框架,它們在定位、設計理念、復雜度和適用場景上差異較大。下面我們從功能定位、設計理念、優劣對比、使用建議等維度進行深入對比。🧭 一句話總結框架定位Gin輕量級、高性能的 HTTP 路由框架Go-Kr…

4G模塊 A7670發送英文短信到手機

命令說明ATi顯示產品的標志信息 ATCIMI查詢IMSI ATCICCID從SIM卡讀取ICCID ATCGSN查詢產品序列號 ATCPIN查詢卡狀態 ATCSQ查詢信號強度 ATCGATT查詢當前PS域狀態 ATCREG查詢GPRS注冊狀態 ATCEREG查詢4G注冊狀態 ATCGPADDR查詢PDP地址 ATCMGF選擇短信格式 ATCMGS發送短信流程第一…

歸并排序遞歸法和非遞歸法的簡單簡單介紹

基本思想: 歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合并,得到完全有序的序列;即先使每個…

webrtc之子帶分割下——SplittingFilter源碼分析

文章目錄前言一、頻帶分割過程1.SplittingFilter的創建2.頻帶分割整體流程1)分割時機2)分割規則3)分割核心代碼3.頻帶合并二、算法實現1.實現原理介紹2.All pass QMF系統源碼1)提高精度2)經過串聯全通濾波器3&#xff…

Java運維之Tomcat升級

Tomcat升級準備工作 下述所有過程中,包含了兩種升級方式,一種是備份舊版本的 bin 和 lib,將新版本的 bin 和 lib 對舊版本進行覆蓋;另一種是直接備份舊版本的Tomcat包,運行新版本,將舊版本的配置文件(conf/ * )和應用(webapps/ * )等同步到新版本。 1. 到官網下載指…

MySQL的可重復讀隔離級別實現原理分析

MySQL 的 可重復讀(Repeatable Read, RR) 隔離級別主要通過 多版本并發控制(Multi-Version Concurrency Control, MVCC) 和 鎖機制(特別是間隙鎖) 來實現的。其核心目標是:在一個事務內&#xf…

利用Java自定義格式,循環導出數據、圖片到excel

利用Java自定義格式,循環導出數據、圖片到excel1、自定義格式循環導出數據1.1.設置格式1.1.1、居中樣式1.1.2、應用樣式到合并區域1.1.3、合并單元格1.1.4、設置列寬1.2、寫入數據1.2.1、創建標簽頭部1.2.2、寫入標簽內容2、自定義格式循環導出圖片2.1、設置格式并插…