最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

pytorch中的nn.Unfold()函數(shù)和fold()函數(shù)解讀

 更新時(shí)間:2023年08月02日 10:53:32   作者:halo_wm  
這篇文章主要介紹了pytorch中的nn.Unfold()函數(shù)和fold()函數(shù)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

pytorch的nn.Unfold()函數(shù)和fold()函數(shù)

1.nn.Unfold()函數(shù)

描述:pytorch中的nn.Unfold()函數(shù),在圖像處理領(lǐng)域,經(jīng)常需要用到卷積操作,但是有時(shí)我們只需要在圖片上進(jìn)行滑動(dòng)的窗口操作,將圖片切割成patch,而不需要進(jìn)行卷積核和圖片值的卷積乘法操作。

這是就需要用到nn.Unfold()函數(shù),該函數(shù)是從一個(gè)batch圖片中,提取出滑動(dòng)的局部區(qū)域塊,也就是卷積操作中的提取kernel filter對(duì)應(yīng)的滑動(dòng)窗口。

torch.nn.Unfold(kernel_size,dilation=1,paddding=0,stride=1)

該函數(shù)的輸入是(bs,c,h,w),其中bs為batch-size,C是channel的個(gè)數(shù)。

而該函數(shù)的輸出是(bs,Cxkernel_size[0]xkernel_size[1],L)其中L是特征圖或者圖片的尺寸根據(jù)kernel_size的長寬滑動(dòng)裁剪后得到的多個(gè)patch的數(shù)量。

import torch.nn as nn
import torch
batches_img=torch.rand(1,2,4,4)#模擬圖片數(shù)據(jù)(bs,2,4,4),通道數(shù)C為2
print("batches_img:\n",batches_img)
nn_Unfold=nn.Unfold(kernel_size=(2,2),dilation=1,padding=0,stride=2)
patche_img=nn_Unfold(batches_img)
print("patche_img.shape:",patche_img.shape)
print("patch_img:\n",patche_img)

該方法的主要應(yīng)用場景是將圖片切割成不同的patch,配合一下代碼實(shí)現(xiàn)

#上面的代碼能夠獲取到patch_img,(bs,C*K*K,L),L代表的是將每張圖片分割成多少塊
reshape_patche_img=patche_img.view(batches_img.shape[0],batches_img.shape[1],2,2,-1)
print(reshape_patche_img.shape)#[bs, C, k, k, L]
reshape_patche_img=reshape_patche_img.permute(0,4,1,2,3)#[N, L, C, k, k]
print(reshape_patche_img.shape)

結(jié)果:

2.nn.Fold()函數(shù)

該函數(shù)是nn.Unfold()函數(shù)的逆操作。

fold = torch.nn.Fold(output_size=(4, 4), kernel_size=(2, 2), stride=2)
inputs_restore = fold(patches)
print(inputs_restore)
print(inputs_restore.size())

nn.functional.fold/unfold

官方文檔:fold, unfold

作用:fold和unfold的作用恰好相反,unfold是用一個(gè)滑窗來提取圖像中的像素值,類似于卷積操作,但是只提取不計(jì)算,fold恰好相反將滑窗提取的值返回為一個(gè)圖像

nn.functional.unfold(input, kernel_size, dilation=1, padding=0, stride=1)
  • input: 輸入tensor
  • kernel_size: 提取時(shí)的滑窗大小
  • dilation: 滑窗是否有空洞
  • padding: 是否對(duì)原圖進(jìn)行填充
  • stride: 滑窗移動(dòng)的步長

下面舉一個(gè)例子直觀解釋

x = torch.Tensor([[[[  1,  2,  3,  4],
   					[  5,  6,  7,  8],
   					[  9, 10, 11, 12],
   					[ 13, 14, 15, 16]]]])
x = F.unfold(x, kernel_size=(2, 2), padding=0, stride=2) 
print(x)
print(x.size())
'''
tensor([[[ 1.,  3.,  9., 11.],
         [ 2.,  4., 10., 12.],
         [ 5.,  7., 13., 15.],
         [ 6.,  8., 14., 16.]]])
torch.Size([1, 4, 4])
'''

執(zhí)行過程很簡單,用一個(gè) 2 × 2 的窗在圖上滑動(dòng),步長為2,第一次覆蓋的內(nèi)容為1256,第二次為3478,以此類推,每次滑窗的結(jié)果用一個(gè)列向量表示,列數(shù)就是滑窗提取的次數(shù)。

如果我們要得到每次滑窗的結(jié)果,例如第一次提取的結(jié)果,用表達(dá)式x[:,:,0]即可

nn.functional.fold(input, output_size, kernel_size, dilation=1, padding=0, stride=1)
  • input: 輸入tensor
  • output_size: 輸出圖像的大?。ū仨氈付ǎ?/li>
  • kernel_size: 在圖像中填充的形狀
  • dilation: 滑窗是否有空洞
  • padding: 是否對(duì)原圖進(jìn)行填充
  • stride: 存放窗的tensor時(shí)移動(dòng)的步長

網(wǎng)上很少有講這個(gè)函數(shù)的,都說是unfold的逆過程,我們依然用幾個(gè)例子來對(duì)其進(jìn)行詳細(xì)的解釋

1. 第一個(gè)例子

x = torch.Tensor([[[[  1,  2,  3,  4],
   					[  5,  6,  7,  8],
   					[  9, 10, 11, 12],
   					[ 13, 14, 15, 16]]]])
x = F.unfold(x, kernel_size=(2, 2), padding=0, stride=2) 
x = F.fold(x, output_size=(4,4), kernel_size=(2,2), padding=0, stride=2)
'''
tensor([[[ 1.,  3.,  9., 11.],
         [ 2.,  4., 10., 12.],
         [ 5.,  7., 13., 15.],
         [ 6.,  8., 14., 16.]]])
torch.Size([1, 4, 4])
tensor([[[[ 1.,  2.,  3.,  4.],
          [ 5.,  6.,  7.,  8.],
          [ 9., 10., 11., 12.],
          [13., 14., 15., 16.]]]])
torch.Size([1, 1, 4, 4])
'''

fold函數(shù)是如何執(zhí)行的呢,他會(huì)提取unfold函數(shù)的每一列,首先提取1256這一列,然后根據(jù)kernel_size的大小將1256重新resize并填到output的第一個(gè)位置,如下

[[ 1.,  2.,  0.,  0.],
 [ 5.,  6.,  0.,  0.],
 [ 0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0.]]

隨后提取第二列2.6.10.14,resize為 2 × 2 2\times 2 2×2的形狀,根據(jù)步長為2添加到output的下一個(gè)位置,并以此類推

[[ 1.,  2.,  3.,  4.],
 [ 5.,  6.,  7.,  8.],
 [ 0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0.]]

注意:output,kernel以及stride必須滿足一定的關(guān)系(參考文檔)

知道原理以后我們可以自由操作上述tensor,但是注意,如果步長等設(shè)置不合適的話,最后的結(jié)果是有overlap的,下面我們展示兩個(gè)例子

2. 第二個(gè)例子

自由操作tensor

x = torch.Tensor([[[[  1,  2,  3,  4],
   					[  5,  6,  7,  8],
   					[  9, 10, 11, 12],
   					[ 13, 14, 15, 16]]]])
x = F.unfold(x, kernel_size=(2, 2), padding=0, stride=2) 
x = F.fold(x, output_size=(4,4), kernel_size=(4,1), padding=0, stride=1)
'''
tensor([[[ 1.,  3.,  9., 11.],
         [ 2.,  4., 10., 12.],
         [ 5.,  7., 13., 15.],
         [ 6.,  8., 14., 16.]]])
torch.Size([1, 4, 4])
# tensor又變回了原來的樣子
tensor([[[[ 1.,  3.,  9., 11.],
          [ 2.,  4., 10., 12.],
          [ 5.,  7., 13., 15.],
          [ 6.,  8., 14., 16.]]]])
torch.Size([1, 1, 4, 4])
'''

overlap的情況

根據(jù)上述講的可以自己推一下

x = torch.Tensor([[[[  1,  2,  3,  4],
   					[  5,  6,  7,  8],
   					[  9, 10, 11, 12],
   					[ 13, 14, 15, 16]]]])
x = F.unfold(x, kernel_size=(2, 2), padding=0, stride=2) 
x = F.fold(x, output_size=(3,3), kernel_size=(2,2), padding=0, stride=1)
'''
tensor([[[ 1.,  3.,  9., 11.],
         [ 2.,  4., 10., 12.],
         [ 5.,  7., 13., 15.],
         [ 6.,  8., 14., 16.]]])
torch.Size([1, 4, 4])
tensor([[[[ 1.,  5.,  4.],
          [14., 34., 20.],
          [13., 29., 16.]]]])
torch.Size([1, 1, 3, 3])
'''

3. kernel size小于列向量的情況

上面講了,fold每次都會(huì)對(duì)列向量進(jìn)行提取,之前的例子都是kernel size等于列向量,如果我們的kernel size小于列向量就會(huì)出現(xiàn)以下情況

x = torch.Tensor([[[[  1,  2,  3,  4],
   					[  5,  6,  7,  8],
   					[  9, 10, 11, 12],
   					[ 13, 14, 15, 16]]]])
x = F.unfold(x, kernel_size=(2, 2), padding=0, stride=2) 
x = F.fold(x, output_size=(2,2), kernel_size=(1,1), padding=0, stride=1)
'''
tensor([[[ 1.,  3.,  9., 11.],
         [ 2.,  4., 10., 12.],
         [ 5.,  7., 13., 15.],
         [ 6.,  8., 14., 16.]]])
torch.Size([1, 4, 4])
tensor([[[[ 1.,  3.],
          [ 9., 11.]],
         [[ 2.,  4.],
          [10., 12.]],
         [[ 5.,  7.],
          [13., 15.]],
         [[ 6.,  8.],
          [14., 16.]]]])
torch.Size([1, 4, 2, 2])
'''

解釋一下,我們第一次提取的應(yīng)該是1256,但是由于我們的kernel太小了, 1 × 1 = 1 ,只能提取一個(gè)元素,因此就是1,我們的output size是 2 × 2 ,步長為1,所以第一次提取的結(jié)果如下

[[  1,  0],
 [  0,  0]]

第二次提取時(shí),就需要移動(dòng)了,提取的不是列向量中的2,而是橫向移動(dòng)的3,接著放到剛才那個(gè)元素后面

[[  1,  3],
 [  0,  0]]

之后的過程以此類推,直到我們提取到11,這時(shí)我們的行向量提取完了,但是列向量沒有,所以我們從第二列開始重復(fù)剛才的過程即可,可以看到最終我們輸出向量大小為[1,4,2,2],4就是我們提取了4次行向量,兩個(gè)2就是每次提取的大?。磑utput size)

最后加一個(gè)復(fù)雜的具有padding的例子

padding就是在對(duì)tensor進(jìn)行操作之前在tensor四周補(bǔ)0或其他的值。例子中僅對(duì)unfold進(jìn)行padding,如果對(duì)fold進(jìn)行padding也同理

x = torch.Tensor([[[[  1,  2,  3,  4,  5,  6, 7,  8],
   					[  9, 10, 11, 12, 13, 14, 15, 16],
   					[ 17, 18, 19, 20, 21, 22, 23, 24],
   					[ 25, 26, 27, 28, 29, 30, 31, 32],
   					[ 33, 34, 35, 36, 37, 38, 39, 40],
   					[ 41, 42, 43, 44, 45, 46, 47, 48],
   					[ 49, 50, 51, 52, 53, 54, 55, 56],
   					[ 57, 58, 59, 60, 61, 62, 63, 64]]]])
x = F.unfold(x, kernel_size=(6,6), padding=1, stride=4) 
x = F.fold(x, output_size=(12,12), kernel_size=(6,6), padding=0, stride=6)
'''
tensor([[[ 0.,  0.,  0., 28.],
         [ 0.,  0., 25., 29.],
         [ 0.,  0., 26., 30.],
         [ 0.,  0., 27., 31.],
         [ 0.,  0., 28., 32.],
         [ 0.,  0., 29.,  0.],
         [ 0.,  4.,  0., 36.],
         [ 1.,  5., 33., 37.],
         [ 2.,  6., 34., 38.],
         [ 3.,  7., 35., 39.],
         [ 4.,  8., 36., 40.],
         [ 5.,  0., 37.,  0.],
         [ 0., 12.,  0., 44.],
         [ 9., 13., 41., 45.],
         [10., 14., 42., 46.],
         [11., 15., 43., 47.],
         [12., 16., 44., 48.],
         [13.,  0., 45.,  0.],
         [ 0., 20.,  0., 52.],
         [17., 21., 49., 53.],
         [18., 22., 50., 54.],
         [19., 23., 51., 55.],
         [20., 24., 52., 56.],
         [21.,  0., 53.,  0.],
         [ 0., 28.,  0., 60.],
         [25., 29., 57., 61.],
         [26., 30., 58., 62.],
         [27., 31., 59., 63.],
         [28., 32., 60., 64.],
         [29.,  0., 61.,  0.],
         [ 0., 36.,  0.,  0.],
         [33., 37.,  0.,  0.],
         [34., 38.,  0.,  0.],
         [35., 39.,  0.,  0.],
         [36., 40.,  0.,  0.],
         [37.,  0.,  0.,  0.]]])
torch.Size([1, 36, 4])
tensor([[[[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  1.,  2.,  3.,  4.,  5.,  4.,  5.,  6.,  7.,  8.,  0.],
          [ 0.,  9., 10., 11., 12., 13., 12., 13., 14., 15., 16.,  0.],
          [ 0., 17., 18., 19., 20., 21., 20., 21., 22., 23., 24.,  0.],
          [ 0., 25., 26., 27., 28., 29., 28., 29., 30., 31., 32.,  0.],
          [ 0., 33., 34., 35., 36., 37., 36., 37., 38., 39., 40.,  0.],
          [ 0., 25., 26., 27., 28., 29., 28., 29., 30., 31., 32.,  0.],
          [ 0., 33., 34., 35., 36., 37., 36., 37., 38., 39., 40.,  0.],
          [ 0., 41., 42., 43., 44., 45., 44., 45., 46., 47., 48.,  0.],
          [ 0., 49., 50., 51., 52., 53., 52., 53., 54., 55., 56.,  0.],
          [ 0., 57., 58., 59., 60., 61., 60., 61., 62., 63., 64.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]]]])
torch.Size([1, 1, 12, 12])
'''

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python串口通信的接收與發(fā)送的實(shí)現(xiàn)

    Python串口通信的接收與發(fā)送的實(shí)現(xiàn)

    串口通信是指通過串口進(jìn)行數(shù)據(jù)傳輸?shù)囊环N通信方式,本文就來介紹一下Python串口通信的接收與發(fā)送的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • Pycharm如何返回上一次編輯處的快捷鍵

    Pycharm如何返回上一次編輯處的快捷鍵

    這篇文章主要介紹了Pycharm如何返回上一次編輯處的快捷鍵問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • python基于celery實(shí)現(xiàn)異步任務(wù)周期任務(wù)定時(shí)任務(wù)

    python基于celery實(shí)現(xiàn)異步任務(wù)周期任務(wù)定時(shí)任務(wù)

    這篇文章主要介紹了python基于celery實(shí)現(xiàn)異步任務(wù)周期任務(wù)定時(shí)任務(wù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Python堆棧的具體使用

    Python堆棧的具體使用

    本文主要介紹了Python堆棧的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • python 實(shí)現(xiàn)提取某個(gè)索引中某個(gè)時(shí)間段的數(shù)據(jù)方法

    python 實(shí)現(xiàn)提取某個(gè)索引中某個(gè)時(shí)間段的數(shù)據(jù)方法

    今天小編就為大家分享一篇python 實(shí)現(xiàn)提取某個(gè)索引中某個(gè)時(shí)間段的數(shù)據(jù)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • python中的內(nèi)置globals()函數(shù)實(shí)例詳解

    python中的內(nèi)置globals()函數(shù)實(shí)例詳解

    globals()函數(shù)是Python中的內(nèi)置函數(shù),用于返回當(dāng)前模塊中定義的全局變量的字典,它可以用于動(dòng)態(tài)批量處理全局變量/函數(shù)、調(diào)試時(shí)快速排查全局狀態(tài)問題,以及框架/庫的底層實(shí)現(xiàn),本文介紹python中的內(nèi)置globals()函數(shù),感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • python 實(shí)現(xiàn)在Excel末尾增加新行

    python 實(shí)現(xiàn)在Excel末尾增加新行

    下面小編就為大家分享一篇python 實(shí)現(xiàn)在Excel末尾增加新行,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • pandas處理csv文件的方法步驟

    pandas處理csv文件的方法步驟

    這篇文章主要介紹了pandas處理csv文件的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • pygame中blit()參數(shù)的使用及臟矩形動(dòng)畫形成的說明

    pygame中blit()參數(shù)的使用及臟矩形動(dòng)畫形成的說明

    這篇文章主要介紹了pygame中blit()參數(shù)的使用及臟矩形動(dòng)畫形成的說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Python對(duì)于json數(shù)據(jù)鍵值對(duì)遍歷

    Python對(duì)于json數(shù)據(jù)鍵值對(duì)遍歷

    這篇文章主要介紹了一文搞定Python中對(duì)于json數(shù)據(jù)鍵值對(duì)遍歷,Python中可以通過字典或者列表的遍歷方式來遍歷JSON格式的數(shù)據(jù)中的鍵值對(duì),具體的遍歷方法取決于你將JSON數(shù)據(jù)解析后得到了一個(gè)字典對(duì)象還是一個(gè)列表對(duì)象,以及JSON數(shù)據(jù)的結(jié)構(gòu),需要的朋友可以參考下
    2023-04-04

最新評(píng)論

中山市| 米脂县| 贵州省| 怀远县| 丹寨县| 疏勒县| 新源县| 龙陵县| 岳西县| 山阴县| 区。| 曲靖市| 房山区| 比如县| 尼玛县| 威信县| 琼海市| 绍兴市| 洮南市| 凌源市| 志丹县| 内黄县| 黎城县| 惠水县| 黑龙江省| 井陉县| 嘉峪关市| 临泉县| 彭水| 日照市| 红桥区| 甘肃省| 襄城县| 巩留县| 蛟河市| 长沙市| 西和县| 东安县| 尉犁县| 邢台县| 安化县|