PyTorch實現二維卷積與邊緣檢測:從原理到實戰

本文通過PyTorch實現二維互相關運算、自定義卷積層,并演示如何通過卷積核檢測圖像邊緣。同時,我們將訓練一個卷積核參數,使其能夠從數據中學習邊緣特征。


1. 二維互相關運算的實現

互相關運算(Cross-Correlation)是卷積操作的基礎。以下代碼實現了二維互相關運算:

import torch
from torch import nndef corr2d(x, k):h, w = k.shapey = torch.zeros((x.shape[0] - h + 1, x.shape[1] - w + 1))for i in range(y.shape[0]):for j in range(y.shape[1]):y[i, j] = (x[i:i+h, j:j+w] * k).sum()  # 逐元素相乘后求和return y

驗證輸出
輸入矩陣和卷積核如下,輸出結果為互相關運算后的張量:

x = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
k = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
print(corr2d(x, k))

輸出

tensor([[19., 25.],[37., 43.]])

2. 自定義二維卷積層

通過繼承nn.Module實現一個自定義卷積層,包含可學習的權重和偏置:

class Conv2D(nn.Module):def __init__(self, kernel_size):super().__init__()self.weight = nn.Parameter(torch.rand(kernel_size))self.bias = nn.Parameter(torch.zeros(1))def forward(self, x):return corr2d(x, self.weight) + self.bias

3. 邊緣檢測應用

3.1 構造輸入圖像

創建一個6x8的矩陣,中間4列為黑色(值為0),兩側為白色(值為1):

x = torch.ones(6, 8)
x[:, 2:6] = 0
print(x)

輸出

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

3.2 定義卷積核

使用卷積核[[1, -1]]檢測垂直邊緣:

k = torch.tensor([[1.0, -1.0]])
y = corr2d(x, k)
print(y)

輸出

tensor([[ 0.,  1.,  0.,  0.,  0., -1.,  0.],[ 0.,  1.,  0.,  0.,  0., -1.,  0.],[ 0.,  1.,  0.,  0.,  0., -1.,  0.],[ 0.,  1.,  0.,  0.,  0., -1.,  0.],[ 0.,  1.,  0.,  0.,  0., -1.,  0.],[ 0.,  1.,  0.,  0.,  0., -1.,  0.]])
  • 結果解釋
    輸出中1表示從白到黑的邊緣,-1表示從黑到白的邊緣。

3.3 水平邊緣檢測

若將輸入矩陣轉置,原卷積核無法檢測水平邊緣:

print(corr2d(x.T, k))

輸出:全零矩陣(無法檢測到水平邊緣)

tensor([[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],...])

4. 學習卷積核參數

使用PyTorch內置的nn.Conv2d,通過梯度下降學習卷積核參數:

# 定義模型
conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(1, 2), bias=False)# 調整輸入輸出形狀
x = x.reshape((1, 1, 6, 8))  # (batch_size, channels, height, width)
y = y.reshape((1, 1, 6, 7))# 訓練過程
for i in range(10):y_hat = conv2d(x)loss = (y_hat - y).pow(2)conv2d.zero_grad()loss.sum().backward()conv2d.weight.data[:] -= 3e-2 * conv2d.weight.grad  # 更新權重if (i+1) % 2 == 0:print(f'batch{i+1}, loss{loss.sum():.3f}')

輸出

batch2, loss5.270
batch4, loss0.884
batch6, loss0.148
batch8, loss0.025
batch10, loss0.004

4.1 查看學習后的卷積核

訓練后的權重接近理想值[1, -1]

print(conv2d.weight.data.reshape((1, 2)))

輸出

tensor([[ 0.9883, -0.9878]])

5. 總結

  1. 互相關運算:通過逐窗口計算實現基礎的卷積操作。

  2. 邊緣檢測:方向特定的卷積核可提取圖像邊緣特征。

  3. 參數學習:利用梯度下降可自動學習卷積核參數,無需手動設計。

完整代碼已驗證,讀者可自行調整輸入或卷積核探索更多效果。


提示:實際項目中建議使用PyTorch內置的高效卷積層(如nn.Conv2d),而非手動實現,以充分利用GPU加速。

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

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

相關文章

數字政府網絡架構建設方案

數字政府網絡架構建設方案 一、引言 隨著信息技術的快速發展,數字政府建設已成為提升政府治理能力和服務水平的關鍵。網絡架構作為數字政府的核心基礎設施,對于保障數據安全、提高服務效率、促進信息共享具有重要意義。本方案旨在為數字政府網絡架構建…

Python map函數介紹

在 Python 里,map() 是一個內置函數,其用途是將指定的函數應用于可迭代對象(像列表、元組等)的每個元素,最終返回一個新的迭代器。此迭代器所包含的元素是原可迭代對象中每個元素經過指定函數處理后的結果。map() 函數…

【服務器端表單字符驗證】

文章目錄 一、實驗目的二、核心代碼實現三、調試關鍵問題四、總結 一、實驗目的 掌握JSP表單驗證在服務器端的實現技術&#xff0c;實現對用戶輸入字符的非空及長度為5的驗證&#xff0c;返回對應提示信息并優化用戶交互。 二、核心代碼實現 前端表單 <form action"…

dify windos,linux下載安裝部署,提供百度云盤地址

dify下載安裝 dify1.0.1 windos安裝包百度云盤地址 通過網盤分享的文件&#xff1a;dify-1.0.1.zip 鏈接: 百度網盤 請輸入提取碼 提取碼: 1234 dify安裝包 linux安裝包百度云盤地址 通過網盤分享的文件&#xff1a;dify-1.0.1.tar.gz 鏈接: 百度網盤 請輸入提取碼 提取碼…

C++ Primer 5e 習題2.5: 指出如下字面量常量的類型

Exercise 2.5: Determine the type of each of the following literals. Explain the differences among the literals in each of the four examples: (a) ‘a’, L’a’, “a”, L"a" (b) 10, 10u, 10L, 10uL, 012, 0xC © 3.14, 3.14f, 3.14L (d) 10, 10u, 10…

CFS 調度器兩種調度類型普通調度 和 組調度

在 Linux 的 CFS&#xff08;Completely Fair Scheduler&#xff09; 調度器中&#xff0c;確實存在兩種調度類型&#xff1a;普通調度 和 組調度。這兩種調度類型分別適用于不同的場景&#xff0c;并通過三個關鍵維度&#xff08;權重、搶占優先級、最大配額&#xff09;來影響…

AF3 ProteinDataset類的_get_masked_sequence方法解讀

AlphaFold3 protein_dataset模塊 ProteinDataset 類 _get_masked_sequence 方法屬于作用是為需要預測的殘基生成掩碼。該掩碼以二進制張量形式呈現,其中 1 代表需要預測的部分,0 代表其他部分。此方法會依據多個參數來選定要掩碼的殘基,這些參數包含 mask_whole_chains、mas…

【音視頻】SDL渲染YUV格式像素

SDL視頻顯示的流程 實現流程 準備視頻文件 準備一個格式為yuv420p&#xff0c;分辨率為320x240的yuv數據&#xff0c;并且將視頻文件放入項目構建的目錄下&#xff1a; 初始化SDL 初始化SDL的視頻模塊 //初始化 SDL if(SDL_Init(SDL_INIT_VIDEO)) {fprintf( stderr, "…

關于群暉安裝tailscale后無法直鏈的問題

問題是我局域網的ipv6無法正確獲取到ip, 通過命令可以看到ipv6沒有ip tailscale netcheck C:\Users\Administrator>tailscale netcheck 2025/04/12 23:43:34 attempting to fetch a DERPMap from https://controlplane.tailscale.comReport:* Time: 2025-04-12T15:43:38.27…

[數據結構]Trie字典樹

GPT的介紹 &#x1f9e0; 一句話總結&#xff1a; 字典樹是一種專門用來存很多字符串的“超級前綴樹”&#xff0c;查找某個字符串或前綴的時候&#xff0c;特別快&#xff01; ?? 舉個生活例子&#xff08;類比&#xff09;&#xff1a; 你想做一個詞典&#xff08;Dictio…

04-算法打卡-數組-二分查找-leetcode(69)-第四天

1 題目地址 69. x 的平方根 - 力扣&#xff08;LeetCode&#xff09;69. x 的平方根 - 給你一個非負整數 x &#xff0c;計算并返回 x 的 算術平方根 。由于返回類型是整數&#xff0c;結果只保留 整數部分 &#xff0c;小數部分將被 舍去 。注意&#xff1a;不允許使用任何內…

AI領域再突破,永洪科技榮獲“2025人工智能+創新案例”獎

在2025年的今天&#xff0c;人工智能已從技術概念全面滲透至產業核心。中國作為全球AI技術應用的前沿陣地&#xff0c;正通過“人工智能”行動加速推進技術與實體經濟深度融合。 這一背景下&#xff0c;永洪科技憑借其“國內某頭部ICT人力資源板塊GenAI項目”榮獲“2025全國企業…

反序列化漏洞介紹與挖掘指南

目錄 反序列化漏洞介紹與挖掘指南 一、漏洞核心原理與危害 二、漏洞成因與常見場景 1. 漏洞根源 2. 高危場景 三、漏洞挖掘方法論 1. 靜態分析 2. 動態測試 3. 利用鏈構造 四、防御與修復策略 1. 代碼層防護 2. 架構優化 3. 運維實踐 五、工具與資源推薦 總結 反…

從零開始的C++編程 2(類和對象下)

目錄 1.構造函數初始化列表 2.類型轉換 3.static成員 4.友元 5.內部類 6.匿名對象 1.構造函數初始化列表 ①之前我們實現構造函數時&#xff0c;初始化成員變量主要使?函數體內賦值&#xff0c;構造函數初始化還有?種?式&#xff0c;就是初始化列表&#xff0c;初始化…

Profibus DP主站轉ModbusTCP網關通訊秘籍

Profibus DP主站轉ModbusTCP網關通訊秘籍 在現代工業自動化領域&#xff0c;不同設備間的數據通訊和系統集成至關重要。Profibus DP和Modbus TCP是兩種廣泛應用的工業通信協議&#xff0c;各有其獨特的優勢和適用場景。然而&#xff0c;由于歷史原因或設備制造商的差異&#x…

【力扣hot100題】(092)最長回文串

有點難度&#xff0c;一開始想到的兩種方法都不對&#xff0c;花了不少時間。 先說之前的方法&#xff1a; ① 遍歷每個點&#xff0c;每個點向外擴張&#xff0c;如果左等于右就一直擴展直到不等。 這個方法可是可以&#xff0c;但我沒有考慮到兩個相同字母也是回文串的情況…

14 - VDMA彩條顯示實驗

文章目錄 1 實驗任務2 系統框圖3 硬件設計4 軟件設計 1 實驗任務 本實驗任務是PS端寫彩條數據至DDR3內存中&#xff0c;然后通過PL端的VDMA IP核將彩條數據通過HDMI接口輸出顯示。 2 系統框圖 本實驗是用HDMI接口固定輸出1080P的彩條圖&#xff0c;所以&#xff1a; rgb2lc…

HarmonyOS-ArkUIV2裝飾器-@Param:組件外部輸入

上文我們了解了@Local裝飾器 ,講明了Local裝飾器不允許外部傳入值對其進行初始化。詳見: HarmonyOS-ArkUI V2裝飾器@Local裝飾器:組件內部狀態-CSDN博客。 但總有場景是需要外部組件傳值過來,然后本組件接收這個值這種場景的。而且很多情況下,一個狀態變量的作用范圍會是…

Java從入門到“放棄”(精通)之旅——運算符③

&#x1f31f;Java從入門到“放棄”&#xff08;精通&#xff09;之旅&#x1f680;&#xff1a;運算符深度解析 引言&#xff1a;運算符的本質與價值 作為Java語言的核心組成部分&#xff0c;運算符是構建程序邏輯的基礎元素。它們不僅僅是簡單的數學符號&#xff0c;更是程…

【sgSpliter】自定義組件:可調整寬度、高度、折疊的分割線

sgSpliter.vue <template><!-- 注意&#xff1a;父組件position必須是relative、absolute或fixed&#xff0c;不建議直接在綁定:data后面用"{屬性}"&#xff0c;建議單獨在script中聲明data&#xff0c;避免拖拽過程重復調用 --><div :class"$…