pytorch學習-11卷積神經網絡(高級篇)

2.線性模型

3.梯度下降算法

4.反向傳播(用pytorch算梯度)

5.用pytorch實現線性回歸

6.logistic回歸

7.處理多維特征的輸入

8.加載數據集

9.多分類問題

10.卷積神經網絡(基礎篇)

11.卷積神經網絡(高級篇)_嗶哩嗶哩_bilibili

11.1 GoogleNet

????????GoogleNet其創新的Inception模塊而聞名,這種模塊允許網絡在同一層次中進行不同尺寸的卷積操作,從而捕捉不同尺度的特征。

11.1.2?Inception模塊

????????它的主要思想是在同一層次中使用不同大小的卷積核進行特征提取,從而能夠捕捉不同尺度的特征。設計神經網絡時以模塊為單位去組裝整個網絡結構,在神經網絡中多次重復使用該模塊,因此將其封裝為類,來減少代碼量。該模塊構成如下圖所示:

?

11.1.3 1*1convolution

? ? ? ??1x1卷積是一種在卷積神經網絡中使用的特殊類型的卷積操作。它的主要作用是調整特征圖的維度(即通道數),同時保持特征圖的空間尺寸(高度和寬度),此外,它還能跨通道的特征整合(不同通道的卷積結果最后求和)。例如,數據集為3*3*3經過3*1*1的卷積操作后,輸出結果為1*3*3,如下圖所示:

?

????????1x1卷積的計算量相對較小,因為卷積核的大小為1x1,只需要進行簡單的點乘和加法操作。這使得1x1卷積在深層網絡中非常有用,可以作為其他卷積操作的降維或升維層,提高整體網絡的計算效率。如下圖所示:經過1*1卷積后下方操作次數減少許多

?

11.1.4 Inception模塊的實現

課上的Inception模塊結構如下:?

  • 平均池化路徑
    • 3x3平均池化。
    • 1x1卷積降維。
  • 1x1卷積:用于降維。
  • 5x5卷積路徑
    • 1x1卷積降維。
    • 5x5卷積提取特征。?
  • 3x3卷積路徑
    • 1x1卷積降維。
    • 3x3卷積提取特征。
    • ?3x3卷積提取特征。

最后再將每條路徑所得張量,沿著channel的方向整合成一個張量?

????????

?????????代碼演示:

import torch
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt#1.準備數據
#1.1 定義transform
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307),(0.3081))])#1.2 下載數據
trainset = datasets.MNIST('../dataset/mnist',train=True,download=True,transform=transform)
#1.3 定義dataloader
train_loader = DataLoader(trainset,batch_size=64,shuffle=True)#1.4測試集
testset=datasets.MNIST(root='../dataset/mnist',train=False,download=True,transform=transform)
test_loader = DataLoader(testset,batch_size=64,shuffle=False)#2.定義網絡#2.1 定義inception模塊class Inception(torch.nn.Module):def __init__(self,in_channels):super(Inception,self).__init__()#2.1.1 平均池化路徑,所用到的1x1的卷積層self.branch_pool = torch.nn.Conv2d(in_channels,24,kernel_size=1)#輸入通道為in_channels,輸出通道為24,卷積核大小為1x1#2.1.2 1x1卷積路徑,僅用到1x1的卷積層self.branch1x1 = torch.nn.Conv2d(in_channels,16,kernel_size=1)#輸入通道為in_channels,輸出通道為16,卷積核大小為1x1#2.1.3 5x5卷積路徑 ,用到1X1和5x5的卷積層self.branch5x5_1 = torch.nn.Conv2d(in_channels,16,kernel_size=1)#輸入通道為in_channels,輸出通道為16,卷積核大小為1x1self.branch5x5_2 = torch.nn.Conv2d(16,24,kernel_size=5,padding=2)#輸入通道為16,輸出通道為24,卷積核大小為5x5,padding為2(保證輸出尺寸不變)#2.1.4 3x3卷積路徑,用到1x1、3x3的卷積層、3x3的卷積層self.branch3x3_1 = torch.nn.Conv2d(in_channels,16,kernel_size=1)#輸入通道為in_channels,輸出通道為16,卷積核大小為1x1self.branch3x3_2 = torch.nn.Conv2d(16,24,kernel_size=3,padding=1)#輸入通道為16,輸出通道為24,卷積核大小為3x3,padding為1(保證輸出尺寸不變)self.branch3x3_3 = torch.nn.Conv2d(24,24,kernel_size=3,padding=1)#輸入通道為24,輸出通道為24,卷積核大小為3x3,padding為1(保證輸出尺寸不變)def forward(self,x):#2.1.1 平均池化路徑,先經過平均池化,再經過1x1卷積branch_pool=F.avg_pool2d(x,kernel_size=3,stride=1,padding=1)#輸入為x,池化核大小為3x3,步長為1,padding為1branch_pool=self.branch_pool(branch_pool)#輸入為branch_pool,卷積核大小為1x1,輸出通道為24#2.1.2 1x1卷積路徑,直接經過1x1卷積branch1x1=self.branch1x1(x)#輸入為x,卷積核大小為1x1,輸出通道為16#2.1.3 5x5卷積路徑,先經過1x1卷積,再經過5x5卷積branch5x5=self.branch5x5_1(x)#輸入為x,卷積核大小為1x1,輸出通道為16branch5x5=self.branch5x5_2(branch5x5)#輸入為branch5x5,卷積核大小為5x5,輸出通道為24,padding為2#2.1.4 3x3卷積路徑,先經過1x1卷積,再經過3x3卷積,再經過3x3卷積branch3x3=self.branch3x3_1(x)#輸入為x,卷積核大小為1x1,輸出通道為16branch3x3=self.branch3x3_2(branch3x3)#輸入為branch3x3,卷積核大小為3x3,輸出通道為24,padding為1branch3x3=self.branch3x3_3(branch3x3)#輸入為branch3x3,卷積核大小為3x3,輸出通道為24,padding為1#2.1.5 將所有路徑的輸出拼接起來outputs=[branch_pool,branch1x1,branch5x5,branch3x3]return torch.cat(outputs,dim=1)#將outputs中的元素沿著dim=1方向(即通道維度)拼接起來,輸出為(batch_size,88,28,28)#2.2 定義網絡結構
class Net(torch.nn.Module):def __init__(self):super(Net,self).__init__()self.conv1=torch.nn.Conv2d(1,10,kernel_size=5)self.conv2=torch.nn.Conv2d(88,20,kernel_size=5)self.inception1=Inception(in_channels=10)self.inception2=Inception(in_channels=20)self.maxpool=torch.nn.MaxPool2d(2)self.fc1=torch.nn.Linear(88*4*4,10)def forward(self,x):#獲取batch_sizein_size=x.size(0)x=F.relu(self.maxpool(self.conv1(x)))x=self.inception1(x)x=F.relu(self.maxpool(self.conv2(x)))x=self.inception2(x)x=x.view(in_size,-1)x=self.fc1(x)return xmodel=Net()
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)#3.定義損失函數和優化器
criterion=torch.nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)#4.訓練網絡
#4.1 訓練函數
def train(epoch):running_loss=0.0for i,data in enumerate(train_loader,0):inputs,labels=datainputs,labels=inputs.to(device),labels.to(device)optimizer.zero_grad()#forward + backward + updateoutputs=model(inputs)loss=criterion(outputs,labels)loss.backward()optimizer.step()running_loss+=loss.item()if i%300==299:print('[%d, %5d] loss: %.3f' %(epoch+1,i+1,running_loss/300))running_loss=0.0#4.2 測試函數
acuracy_list=[]
def Net_test():correct=0total=0with torch.no_grad():for data in test_loader:inputs,targets=datainputs,targets=inputs.to(device),targets.to(device)outputs=model(inputs)_,predicted=torch.max(outputs.data,1)total+=targets.size(0)correct+=predicted.eq(targets.data).sum().item()print('Accuracy of the network  test : %.2f %%' % (100.0*correct/total))acuracy_list.append(100.0*correct/total)#4.開始訓練
for epoch in range(10):train(epoch)Net_test()#5.繪制準確率變化圖
epochs=list(range(len(acuracy_list)))
plt.plot(epochs,acuracy_list)
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.title('Accuracy of the network')
plt.show()

????????運行結果:

?

11.2??ResidualNet(ResNet)

11.2.1深度帶來的問題

  • 一是vanishing/exploding gradient,導致了訓練十分難收斂,這類問題能夠通過normalized initialization 和intermediate normalization layers解決;
  • 另一個是被稱為degradation的退化現象。對合適的深度模型繼續增加層數,模型準確率會下滑(不是overfit造成),training error和test error都會很高,相應的現象在CIFAR-10和ImageNet都有出現。

????????當梯度小于1時,由于backword()求梯度時遵循鏈式法則,致使梯度相乘后不斷減小最終出現梯度消失,影響所求權重(W^{`}=W-\alpha G ),使得訓練不充分,最終導致準確率下降。下圖為深度增加而導致錯誤率增大

11.2.2 殘差結構


? ? ? ? 普通直連的卷積神經網絡和?ResNet?的最大區別在于,ResNet 有很多旁路的支線將輸入直接連到后面的層,使得后面的層可以直接學習殘差,這種結構也被稱shortcut connections

????????傳統的卷積層或全連接層在信息傳遞時,或多或少會存在信息丟失、損耗等問題。ResNet 在某種程度上解決了這個問題,通過直接輸入信息繞道傳到輸出,保護信息的完整性,整個網絡則只需要學習輸入、輸出差別的那一部分,簡化學習目標和難度。注意:實線部分是深度未發生變化的連接,虛線部分是深度發生變化的連接。 對應深度有變化的連接有兩種解決方案:?

  • 使用 zero-pading 進行提升深度 parameter-free。
  • 使用 1*1的卷積核提升維度 有卷積核的運算時間。

????????兩種方法,使用下面一種方法效果更好,但是運行會更耗時,一般還是更傾向于第一種方案節約運算成本。

?

11.2.3? 殘差塊

在正常的神經網絡中就是一層連一層,如下圖所示:

????????假定某段神經網絡的輸入是 x,期望輸出是 H(x),即 H(x) 是期望的復雜潛在映射,但學習難度大;如果我們直接把輸入 x 傳到輸出作為初始結果,通過下圖“shortcut connections”,那么此時我們需要學習的目標就是 F(x)=H(x)-x,于是 ResNet 相當于將學習目標改變了,不再是學習一個完整的輸出,而是最優解 H(X) 全等映射 x 的差值,即殘差 F(x) = H(x) - x

????????此時,梯度的計算公式\frac{\partial ( H(x))}{x}= \frac{\partial ( F(x))}{x}+1,確保梯度大于等于1,就不會造成梯度消失。

?11.2.4 ResNet 結構

Residual Block 實現

值得注意的是,我們需要輸入通道和輸出通道一致

第一層中先做卷積在做relu(conv1(x)),第二層中做卷積conv2(y),最后返回relu(x+y)

????????代碼演示:

import torch
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt#1.準備數據
#1.1 定義transform
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307),(0.3081))])#1.2 下載數據
trainset = datasets.MNIST('../dataset/mnist',train=True,download=True,transform=transform)
#1.3 定義dataloader
train_loader = DataLoader(trainset,batch_size=64,shuffle=True)#1.4測試集
testset=datasets.MNIST(root='../dataset/mnist',train=False,download=True,transform=transform)
test_loader = DataLoader(testset,batch_size=64,shuffle=False)#2.定義網絡
#2.1 定義殘差塊
class ResidualBlock(torch.nn.Module):def __init__(self, channels):super(ResidualBlock, self).__init__()self.channels = channelsself.conv1 =torch.nn.Conv2d(channels, channels,kernel_size=3, padding=1)self.conv2 = torch.nn.Conv2d(channels, channels,kernel_size=3, padding=1)def forward(self, x):y = F.relu(self.conv1(x))y = self.conv2(y)return F.relu(x + y)# 注:這里的x + y是殘差單元的核心,即殘差單元的輸出等于輸入與殘差單元輸出的和,# 其中殘差單元輸出經過兩次卷積后與輸入相加,再經過激活函數ReLU。#2.2 定義網絡結構
class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = torch.nn.Conv2d(1, 16, kernel_size=5)self.conv2 = torch.nn.Conv2d(16, 32, kernel_size=5)self.mp = torch.nn.MaxPool2d(2)self.rblock1 = ResidualBlock(16)self.rblock2 = ResidualBlock(32)self.fc =torch.nn.Linear(512, 10)def forward(self, x):in_size = x.size(0)x = self.mp(F.relu(self.conv1(x)))x = self.rblock1(x)x = self.mp(F.relu(self.conv2(x)))x = self.rblock2(x)x = x.view(in_size, -1)x = self.fc(x)return xmodel=Net()
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)#3.定義損失函數和優化器
criterion=torch.nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)#4.訓練網絡
#4.1 訓練函數
def train(epoch):running_loss=0.0for i,data in enumerate(train_loader,0):inputs,labels=datainputs,labels=inputs.to(device),labels.to(device)optimizer.zero_grad()#forward + backward + updateoutputs=model(inputs)loss=criterion(outputs,labels)loss.backward()optimizer.step()running_loss+=loss.item()if i%300==299:print('[%d, %5d] loss: %.3f' %(epoch+1,i+1,running_loss/300))running_loss=0.0#4.2 測試函數
acuracy_list=[]
def Net_test():correct=0total=0with torch.no_grad():for data in test_loader:inputs,targets=datainputs,targets=inputs.to(device),targets.to(device)outputs=model(inputs)_,predicted=torch.max(outputs.data,1)total+=targets.size(0)correct+=predicted.eq(targets.data).sum().item()print('Accuracy of the network  test : %.2f %%' % (100.0*correct/total))acuracy_list.append(100.0*correct/total)#4.開始訓練
for epoch in range(10):train(epoch)Net_test()#5.繪制準確率變化圖
epochs=list(range(len(acuracy_list)))
plt.plot(epochs,acuracy_list)
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.title('Accuracy of the network')
plt.show()

????????運行結果:

?

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

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

相關文章

ubuntu 安裝QT

在 Ubuntu 系統上安裝 Qt 可以通過以下步驟完成,以下是詳細的安裝指南 : 1. 安裝前的準備工作 在開始安裝 Qt 之前,需要確保你的 Ubuntu 系統已經更新到最新版本,并且安裝了一些必要的依賴。 1.1 更新系統 首先,打…

CppCon 2018 學習:RAPID PROTOTYPING OF GRAPHICS SHADERS IN

這段內容在講**著色器(Shader)**的基礎概念,尤其是它在現代 GPU(圖形處理單元)中的作用。以下是逐條解釋與理解: “Depicting depth perception in 3D models or illustrations by varying levels of darkn…

Angular v20版本正式發布

過去幾年對 Angular 來說很具變革性,我們推出了像 Signals 這樣的反應性功能和 Zoneless 應用的強大能力。我們希望這些功能可以幫助 Angular 社區構建下一代的 Web 應用,實現快速上市和強大的性能。 我們的旅程才剛剛開始!Angular v20 是最新的發布版本,我們花費了無數個小…

Oracle如何使用序列 Oracle序列使用教程

Oracle序列(sequence)是一種數據庫項,能夠生成一個整數序列。通常用于填充數字類型的主鍵列。 Oracle序列 Oracle序列使用教程: 1、創建序列: CREATE SEQUENCE sequence_name[START WITH start_num][INCREMENT BY incr…

深入探索 Vanna:讓數據庫交互更智能

深入探索 Vanna:讓數據庫交互更智能 在數字化時代,與數據庫進行高效交互是許多開發者、數據分析師和企業面臨的挑戰。傳統的 SQL 查詢編寫不僅需要對數據庫結構有深入的了解,還需要花費大量的時間和精力來調試和優化。Vanna,一個…

C#上位機之網口通信與協議!

文章目錄前言一、網口通信概念二、使用網口通信準備三、使用步驟前言 C#上位機之網口通信與協議! 一、網口通信概念 定義 :Socket 可以理解為一個通信端點,它提供了應用程序與網絡之間的接口,使得應用程序能夠在網絡上發送和接收…

Android Studio 創建類時如何自動添加類注釋

打開IDEA或AS,點擊菜單欄File——Settings——Editor——File and Code Templates。 點擊右邊Tab頁的Includes,選擇File Header,修改類頭模版,如圖: 記得選中Project,否則默認是整個AS都會進行設置

C++11:shared_ptr的設計哲學(原理+源碼):內存安全和性能的架構權衡

0.簡介 在C編程世界中,內存管理是一把雙刃劍,手動管理帶來了極致的內存控制能力,但也帶來了像內存泄漏,野指針等問題;自動垃圾回收雖然安全,但卻會帶來一定的性能損耗。本文將介紹C11引入shared_ptr&#…

Mysql EXPLAIN 執行計劃

EXPLAIN SELECT SQl。。。。界面filtered儲引擎返回的數據在經過服務器層 WHERE 條件過濾后,剩余數據占總行數的百分比估計值rows * filtered/100 越接近100%效率越高rowspossible_keys 可能選擇的索引key最終決定選擇的行partitions問了哪些分區select_type查詢…

力扣刷題記錄【1】146.LRU緩存

前言: 請你設計并實現一個滿足 LRU (最近最少使用) 緩存 約束的數據結構。 實現 LRUCache 類: LRUCache(int capacity) 以 正整數 作為容量 capacity 初始化 LRU 緩存int get(int key) 如果關鍵字 key 存在于緩存中,則返回關鍵字的值&…

西門子S7-1200 PLC主流通信方法及應用

一、通信基礎 1. 網絡術語與設備 - 關鍵設備:交換機、路由器、網關等。 - 物理接口:RS-485(支持多點通信)、RS-232C(點對點串行通信)。 2. OSI參考模型 - 核心框架:理解協議分層&…

MySQL實現任意級子目錄的主要方案以及區別

常見的實現方案及區別 1. 鄰接表(Adjacency List) 方案描述: 每條記錄存儲一個節點的父節點ID。 表結構大致: id INT PRIMARY KEY, name VARCHAR(...), parent_id INT -- 指向父節點的ID,根節點為NULL或0優點&…

Linux網絡socket套接字(完)(5)

文章目錄前言一、多進程版的Tcp網絡程序捕捉SIGCHLD信號讓孫子進程提供服務二、多線程版的Tcp網絡程序三、線程池版的Tcp網絡程序四、Tcp協議通訊流程通訊流程總覽三次握手的過程數據傳輸的過程四次揮手的過程總結前言 結束嘍,至少這個Tcp套接字有關內容要結束了~ ?…

Web3 Study Log 003

Web3 Study Log 003 2025-7-5 這幾天各種各樣的瑣事,處理完了,真的煩,估計能消停一段時間了… 今天終于能夠坐下來好好學習,今天學習了chainlink的使用,能夠獲取 ETH/USD 實時價格,然后寫了一個簡單的眾…

Kotlin:2.1.20 的新特性

一、概述 The Kotlin 2.1.20 release is here! Here are the main highlights: Kotlin 2.1.20發布了,主要亮點如下: K2 compiler updates: updates to the new kapt and Lombok pluginsKotlin Multiplatform: new DSL to replace Gradle’s Application …

設計模式 | 觀察者模式

觀察者模式(Observer Pattern)是行為型設計模式中的事件通知專家,它定義了對象間一種一對多的依賴關系,當一個對象狀態改變時,所有依賴它的對象都會自動收到通知并更新。這種模式實現了發布-訂閱機制,是事件…

Apache Struts2 遠程命令執行漏洞(S2-052)

一、漏洞概述 S2-052 是 Apache Struts2 框架中一個高危的遠程代碼執行漏洞(CVE-2017-9805),由安全研究人員于 2017 年發現并公開。該漏洞源于 Struts2 的 REST 插件在使用 XStream 組件處理 XML 反序列化時,未對用戶輸入的 XML 數…

RS觸發器Multisim電路仿真——硬件工程師筆記

目錄 1 RS觸發器基礎知識 1.1 工作原理 1.2 電路結構 1.3 特點 1.4 應用 1.5 設計考慮 1.6 總結 2 與非門實現基本RS觸發器 2.1 電路結構 2.2 工作原理 2.3 特點 2.4 總結 3 或非門實現基本RS觸發器 3.1 電路結構 3.2 工作原理 3.3 特點 3.4 總結 4 與非門實…

提示技術系列(12)——程序輔助語言模型

什么是提示技術? 提示技術是實現提示工程目標的具體技術手段,是提示工程中的“工具庫”。 什么又是提示工程? 提示工程是指通過設計、優化和迭代輸入到大語言模型(LLM)的提示(Prompt)&#xff…

明遠智睿H618:開啟多場景智慧生活新時代

在數字化浪潮的推動下,智能設備正深刻地改變著我們的生活方式。明遠智睿H618以其強大的功能和卓越的性能,在家庭娛樂、商業展示、教育培訓和智能家居控制等多個領域展現出巨大的應用潛力,開啟了多場景智慧生活的新時代。 家庭娛樂&#xff1…