【動手學深度學習】6.2. 圖像卷積


目錄

    • 6.2. 圖像卷積
      • 1)互相關運算
      • 2)卷積層
      • 3)圖像中目標的邊緣檢測
      • 4)學習卷積核
      • 5)互相關與卷積
      • 6)特征映射和感受野
      • 7)小結


.

6.2. 圖像卷積

卷積神經網絡的設計是用于探索圖像數據,本節我們將以圖像為例。

.

1)互相關運算

嚴格說,卷積層是個錯誤叫法,因為它所表達的運算其實是互相關運算(cross-correlation),而不是卷積運算。根據前面描述,在卷積層中,輸入張量和核張量通過互相關運算產生輸出張量。

首先,暫時忽略通道(第三維),看看如何處理二維圖像數據和隱藏表示。在下圖中,輸入3x3的二維張量,卷積核是2x2的,而卷積核窗口(或卷積窗口)的形狀由卷積核決定,即2x2。

圖6.2.1 二維互相關運算。
在這里插入圖片描述

圖中,陰影部分是第一個元素:0 * 0 + 1 * 1 + 3 * 2 + 4 * 3 = 19

在二維互相關運算中,卷積窗口從輸入張量的左上角開始,從左到右、從上到下滑動。當卷積窗口滑動到新一個位置時,包含在該窗口中的部分張量與卷積核張量進行按元素相乘,得到的張量再求和得到一個單一的標量值,由此我們得出了這一位置的輸出張量值。在如上例子中,輸出張量的四個元素由二維互相關運算得到,這個輸出高度為2、寬度為2,如下所示:

  • 0 * 0 + 1 * 1 + 3 * 2 + 4 * 3 = 19

  • 1 * 0 + 2 * 1 + 4 * 2 + 5 * 3 = 25

  • 3 * 0 + 4 * 1 + 6 * 2 + 7 * 3 = 37

  • 4 * 0 + 5 * 1 + 7 * 2 + 8 * 3 = 43

注意,輸出大小略小于輸入大小

卷積后輸出變小,是因為卷積核只能在圖像內部完整地滑動,邊緣部分無法處理,所以輸出尺寸會減小。所以,輸出大小等于輸入大小 nh×nwn_h \times n_wnh?×nw? 減去卷積核大小 kh×kwk_h \times k_wkh?×kw?,即 (輸入大小 - 卷積核大小 + 1)

(nh?kh+1)×(nw?kw+1).(6.2.2)(n_h - k_h + 1) \times (n_w - k_w + 1). \tag{6.2.2} (nh??kh?+1)×(nw??kw?+1).(6.2.2)

這是因為我們需要足夠的空間在圖像上“移動”卷積核。

稍后,我們將看到如何通過在圖像邊界周圍填充零來保證有足夠的空間移動卷積核,從而保持輸出大小不變。接下來,我們在 corr2d 函數中實現如上過程,該函數接受輸入張量 xxx 和卷積核張量 kkk,并返回輸出張量 yyy

import torch
from torch import nn
from d2l import torch as d2ldef corr2d(X, K):  #@save"""計算二維互相關運算"""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]])
corr2d(X, K)# 輸出:
tensor([[19., 25.],[37., 43.]])

卷積層對輸入卷積核權重進行互相關運算,并在添加標量偏置之后產生輸出。 所以,卷積層中的兩個被訓練的參數是卷積核權重和標量偏置。

.

2)卷積層

基于上面定義的corr2d函數實現二維卷積層。在__init__構造函數中,將weightbias聲明為兩個模型參數。前向傳播函數調用corr2d函數并添加偏置。

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

高度和寬度分別為 h 和 w 的卷積核可以被稱為 h × w 卷積h × w 卷積核

將帶有 h × w 卷積核的卷積層稱為 h × w 卷積層

.

3)圖像中目標的邊緣檢測

如下,是卷積層的一個簡單應用:通過找到像素變化的位置,來檢測圖像中不同顏色的邊緣。

首先,我們構造一個 6x8 像素的黑白圖像。中間四列為黑色(0),其余像素為白色(1)。

X = torch.ones((6, 8))
X[:, 2:6] = 0
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.]])

接下來,構造一個1x2 的卷積核 K。當進行互相關運算時,如果水平相鄰的兩元素相同,則輸出為零,否則輸出為非零。

K = torch.tensor([[1.0, -1.0]])

現在,我們對參數 X(輸入)和 K(卷積核)執行互相關運算。如下所示,輸出 Y 中的 1 代表從白色到黑色的邊緣,-1 代表從黑色到白色的邊緣,其他情況的輸出為 0。

Y = corr2d(X, K)
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.]])

現在我們將輸入的二維圖像轉置,再進行如上的互相關運算。其輸出如下,之前檢測到的垂直邊緣消失了。不出所料,這個卷積核 K 只可以檢測垂直邊緣,無法檢測水平邊緣

corr2d(X.t(), K)# 輸出:
tensor([[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.]])

.

4)學習卷積核

通過僅查看“輸入-輸出”對,來學習由X**生成Y的卷積核:**監督學習 + 梯度下降

  • 初始化卷積核為隨機值

  • 前向傳播:使用卷積核對輸入 X 做卷積 → 得到預測輸出 Y_hat

  • 計算損失(誤差):計算預測值和真實值之間的差距(均方誤差)

  • 反向傳播求梯度:自動計算損失對卷積核權重的梯度(告訴我們:“這個卷積核該往哪個方向調才能更接近正確答案?”)

  • 更新卷積核:用梯度下降法更新卷積核參數,逐步減小誤差

重復迭代以上過程。卷積核會越來越優。

為了簡單起見,我們在此使用內置的二維卷積層,并忽略偏置。

# 構造一個二維卷積層,它具有1個輸出通道和形狀為(1, 2)的卷積核
conv2d = nn.Conv2d(1, 1, kernel_size=(1, 2), bias=False)# 輸入和輸出都reshape成四維格式 (批量大小, 通道, 高度, 寬度)
X = X.reshape((1, 1, 6, 8))
Y = Y.reshape((1, 1, 6, 7))
lr = 3e-2  # 學習率for i in range(10):Y_hat = conv2d(X)  # 前向傳播:得到預測輸出l = (Y_hat - Y) ** 2  # 計算平方誤差(損失)conv2d.zero_grad()  # 清空之前的梯度l.sum().backward()  # 反向傳播,計算梯度:自動計算損失對模型中所有可訓練參數的梯度,并將這些梯度保存在 .grad 屬性中# 更新卷積核權重conv2d.weight.data[:] -= lr * conv2d.weight.gradif (i + 1) % 2 == 0:print(f'epoch {i+1}, loss {l.sum():.3f}')

輸出:

epoch 2, loss 6.422
epoch 4, loss 1.225
epoch 6, loss 0.266
epoch 8, loss 0.070
epoch 10, loss 0.022

10次迭代后,誤差降到足夠低。現在來看看所學的卷積核的權重張量。

conv2d.weight.data.reshape((1, 2))# 輸出
tensor([[ 1.0010, -0.9739]])

學習到的卷積核權重,非常接近之前定義的卷積核K。

.

5)互相關與卷積

卷積運算可通過翻轉卷積核后執行互相關運算得到。但在實際中,由于卷積核由數據學習而來,互相關與卷積對輸出結果無實質影響。因此,深度學習中常將互相關稱為“卷積”。為保持術語一致,本書也采用此慣例,并將卷積核中的參數稱為“元素”。

問題一:為什么卷積運算可通過翻轉卷積核后執行互相關運算得到?

下面對比下卷積(Convolution)和互相關(Cross-correlation)的公式,并說明它們的區別。

概念數學定義深度學習中的做法
互相關不翻轉,直接滑動計算被稱作“卷積”
卷積先翻轉核,再滑動計算實際不翻轉,直接算

a.互相關(Cross-correlation):

  • 互相關運算,如公式(6.1.3):

[H]i,j=u+∑a=?ΔΔ∑b=?ΔΔ[V]a,b[X]i+a,j+b.(同6.1.3)[\mathbf{H}]_{i,j} = u + \sum_{a=-\Delta}^{\Delta} \sum_{b=-\Delta}^{\Delta} [\mathbf{V}]_{a,b} [\mathbf{X}]_{i+a,j+b}. \tag{同6.1.3} [H]i,j?=u+a=?ΔΔ?b=?ΔΔ?[V]a,b?[X]i+a,j+b?.(6.1.3)

  • 操作:卷積核 V\mathbf{V}V 直接在輸入 X\mathbf{X}X 上滑動,對應位置相乘求和。

  • 沒有翻轉核。

  • 深度學習框架(如 PyTorch、TensorFlow)中實際實現的就是這個。

b.卷積(Convolution):

  • 卷積運算,如公式(6.1.6):

(f?g)(i,j)=∑a∑bf(a,b)?g(i?a,j?b)(f * g)(i, j) = \sum_a \sum_b f(a, b) \cdot g(i - a, j - b) (f?g)(i,j)=a?b?f(a,b)?g(i?a,j?b)

  • 或等價地:

(V?X)i,j=∑a∑bVa,b?Xi?a,j?b(\mathbf{V} * \mathbf{X})_{i,j} = \sum_a \sum_b \mathbf{V}_{a,b} \cdot \mathbf{X}_{i-a,j-b} (V?X)i,j?=a?b?Va,b??Xi?a,j?b?

  • 關鍵區別:相當于先把卷積核翻轉 180°180^\circ180°(上下 + 左右翻),再與輸入做互相關。

  • 數學意義上的“卷積”要求這種“減號”形式。

問題二:為什么互相關與卷積對輸出結果無實質影響?

  • 雖然數學上卷積要翻轉核,互相關不翻轉,但在深度學習中,卷積核是通過訓練數據自動學習出來的,而不是人為設定的。

關鍵點:

  • 如用互相關運算:網絡會學到一個特定的 K

  • 如用嚴格卷積運算:需將核翻轉后再用,所以如果想得到同樣的輸出,應該用翻轉后的核 K′=flip(K)

  • 但!由于卷積核是可學習的:如果強制執行“嚴格卷積”,那么網絡會自動學習出一個“翻轉過的核”來補償這個差異。換句話說,它會學會等效于原來互相關所用的核。

最后,輸出結果是一樣的輸出

.

6)特征映射和感受野

圖6.2.1 中輸出的卷積層有時被稱為特征映射(feature map),因為它可以被視為一個輸入映射到下一層的空間維度的轉換器。卷積神經網絡中,對于某一層的任意元素 x,其感受野(receptive field)是指在前向傳播期間可能影響 x 計算的所有元素(來自所有先前層)。

注意,感受野可能大于輸入的實際大小。用 圖6.2.1 為來解釋感受野:給定 2 x 2 卷積核,陰影輸出元素值19的感受野是輸入陰影部分的四個元素。假設之前輸出為 Y,其大小為 2 x 2,現在我們在其后附加一個卷積層,該卷積層以 Y 為輸入,輸出單個元素 z。在這種情況下,Y 上的 z 的感受野包括 Y 的所有四個元素,而輸入的感受野包括最初所有九個輸入元素。

隨著卷積神經網絡的層數加深,每一個特征圖上的元素“看到”的輸入區域(即感受野)會變大。因此,深層的神經元可以捕捉更大范圍的上下文信息。

.

7)小結

  • 二維卷積層的核心計算是二維互相關運算。最簡單的形式是,對二維輸入數據和卷積核執行互相關操作,然后添加一個偏置。

  • 我們可以設計一個卷積核來檢測圖像的邊緣。

  • 我們可以從數據中學習卷積核的參數。

  • 學習卷積核時,無論用嚴格卷積運算或互相關運算,卷積層的輸出不會受太大影響。

  • 當需要檢測輸入特征中更廣區域時,我們可以構建一個更深的卷積網絡。

.


聲明:資源可能存在第三方來源,若有侵權請聯系刪除!

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

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

相關文章

游戲引擎中的Billboard技術

一.視覺公告板為解決場景中Mesh網格面數過多問題,使用2D平面Mesh替換為3D平面Mesh的技術即為Billboard技術.常用于場景中植被,樹葉,粒子系統等對面數有要求的場景.二.Billboard著色器實現著色器輸入參數:攝像機坐標,網格坐標,攝像機觀察方向著色器輸出:實際2D平面隨視角不變

vue-admin-template權限管理

在基于 vue-admin-template 實現權限管理時,通常需要結合角色權限模型和動態路由機制,以滿足不同用戶角色對頁面訪問權限的控制需求。分為路由頁面權限和按鈕權限:下面是具體實現思路的思維導圖和具體代碼流程:0.實現邏輯思維導圖…

微信小程序,事件總線(Event Bus) 實現

1、util.js文件/*** 事件總線*/ function createEventBus() {// 私有事件存儲對象,通過閉包保持私有性const events {};return {/*** 監聽事件,只執行一次* param {string} eventName - 事件名稱* param {Function} callback - 回調函數*/once(eventNam…

OpenCV結構光三維重建類cv::structured_light::GrayCodePattern

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 算法描述 cv::structured_light::GrayCodePattern 是 OpenCV 庫中用于結構光三維重建 的一個類,屬于 OpenCV 的 structured_light 模塊。 它用于…

變頻器實習DAY35 引腳電平測試 退耦電阻

目錄變頻器實習DAY35一、工作內容1.1 硬性平臺RO7測試二、學習內容2.1 退耦電阻核心原理:2大特性抑制干擾四大關鍵作用選型:4個核心參數典型應用場景四大常見誤區附學習參考網址歡迎大家有問題評論交流 (* ^ ω ^)變頻器實習DAY35 一、工作內容 1.1 硬性…

C++標準庫算法:從零基礎到精通

算法庫的核心理念與設計哲學 C標準庫算法的設計遵循著一個令人稱道的哲學:算法與容器的分離。這種設計并非偶然,而是經過深思熟慮的結果。傳統的面向對象設計可能會將排序功能綁定到特定的容器類中,但C標準庫卻選擇了一條更加優雅的道路——…

為什么存入數據庫的中文會變成亂碼

從產生、傳輸、處理到最終存儲的整個生命周期中采用統一且正確的字符集編碼。具體原因紛繁復雜,主要歸結為:客戶端操作系統或應用與數據庫服務端字符集編碼不一致、Web應用服務器到數據庫驅動的連接層編碼配置缺失或錯誤、數據庫本身及其表、字段各層級的…

13種常見機器學習算法面試總結(含問題與優質回答)

目錄 1. K近鄰(K-NN) 2. 線性回歸(一元/多元) 3. 邏輯回歸 4. 決策樹 5. 集成學習之隨機森林 6. 貝葉斯(樸素/高斯) 7. SVM(支持向量機) 8. K-means聚類 9. DBSCAN 10. TF-…

sfc_os!SfcValidateFileSignature函數分析之WINTRUST!SoftpubLoadMessage

第一部分:0: kd> kc# 00 WINTRUST!SoftpubLoadMessage 01 WINTRUST!_VerifyTrust 02 WINTRUST!WinVerifyTrust 03 sfc_os!SfcValidateFileSignature 04 sfc_os!SfcGetValidationData 05 sfc_os!SfcValidateDLL 06 sfc_os!SfcQueueValidationThread 07 kernel32!B…

python寫上位機并打包250824

1.python寫的串口上位機軟件程序 import serial import serial.tools.list_ports import tkinter as tk from tkinter import ttk, scrolledtext, messagebox, filedialog import threading import time from datetime import datetime class SerialPortAssistant: def init(se…

Wagtail CRX 簡介

Wagtail CRX(前身為 CodeRed CMS,由 CodeRed Corp 開發)是一個基于 Wagtail 的 CMS 擴展包,主要用于快速構建營銷型網站,提供預置組件和增強功能。最新版本為 5.0.1(發布于 2025 年 5 月 9 日)。…

docker compose 安裝zabbix 7

docker compose 安裝zabbix 7 1.環境 # hostnamectlStatic hostname: ky10Icon name: computer-vmChassis: vmMachine ID: f554764e21b74c2fa057d9aaa296af63Boot ID: 4c155f0185c24a14970ab5ea60de34f4Virtualization: vmwareOperating System: Kylin Linux Advanced Server…

EtherCAT的幾種郵箱通信介紹

1. COE(CANopen over EtherCAT)技術特點:直接復用 CANopen 的對象字典(Object Dictionary)機制,通過 EtherCAT 的郵箱通信實現非周期性數據交換,同時支持過程數據對象(PDO&#xff0…

【Java】springboot的自動配置

如果你用過 Spring Boot,一定對 “引入依賴就能用” 的體驗印象深刻 —— 加個spring-boot-starter-web就有了 Web 環境,這個是 SpringBoot 的自動裝配(Auto-Configuration)機制。自動裝配的核心注解自動裝配的邏輯看似復雜&#…

高通機型QPST平臺線刷教程 線刷全分區 只通過引導文件提取單分區 寫入單分區

高通芯片機型刷機平臺很多,除過一些廠家專用的平臺外。qpst是高通芯片類通用刷寫平臺。其操作簡單 可以刷寫完整固件。也可以通過單個引導文件來讀取 提取整個分區。而且包含讀寫基帶qcn等等的一些功能。 qpst工具下載 QPST 的不同版本可在多個開源平臺或技術論壇中…

ES_預處理

1. 預處理的核心概念:什么是 Ingest Pipeline? 想象一下數據進入 Elasticsearch 的旅程。原始數據(Raw Data)往往并不完美:格式可能混亂,字段可能缺失,或者需要被豐富和轉換后才能發揮最大的價值…

我從零開始學習C語言(15)- 基本類型 PART2

開始學習第七章其余部分。7.3.4 轉義序列正如在前面示例中見到的那樣,字符常量通常是用單引號括起來的單個字符。然而,一些特殊符號(比如換行符)是無法采用上述方式書寫的,因為它們不可見(非打印字符&#…

K8S的部署與常用管理

一、k8s的部署 1.1.集群環境初始化 1.1.1.所有主機禁用swap [rootk8s- ~]# systemctl mask dev-nvme0n1p3.swap [rootk8s- ~]# swapoff -a [rootk8s- ~]# systemctl status dev-nvme0n1p3.swap [rootk8s- ~]# vim /etc/fstab 內容: 注釋swap 1.1.2.安裝k8s部署工…

2025年機械工程與自動化技術國際會議(ICMEAT 2025)

2025年機械工程與自動化技術國際會議(ICMEAT 2025) 2025 International Conference on Mechanical Engineering and Automation Technology一、大會信息會議簡稱:ICMEAT 2025 大會地點:中國杭州 審稿通知:投稿后2-3日內…

高數 不定積分(4-3):分部積分法

文章目錄寫在前面分部積分法😕 一個小問題? 分部積分法是怎么來的?🌰 幾個小例子? 最終總結!后話寫在前面 文章傳送門:高數 不定積分(4-2):換元積分法 今天再更一篇:) 上篇文章&…