日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

union和union all有什么区别_Pytorch中Linear与Conv1d(kernel=1)的区别

發布時間:2023/12/19 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 union和union all有什么区别_Pytorch中Linear与Conv1d(kernel=1)的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

191214 說明:

很抱歉,突然發現圖中第三行多畫了一列叉,事實上,生成 output(0,0) 數據只用到了input[:,0] 以及 weights[0,:]。比較懶,就不再畫了,圖中第三行的第一個矩陣應該和第二行的第一個矩陣相同。

此外至于評論區中有人提到得到的結果一樣。為此我做了一個小實驗,驗證經過一步簡單優化后,模型參數之間的差異。使用的代碼如下:

import torch import torch.nn as nn from copy import deepcopySMALL = 1e-7class Model(nn.Module):def __init__(self):super().__init__()self.conv = nn.Conv1d(3, 2, 1)self.linear = nn.Linear(3, 2)params = deepcopy(self.conv.state_dict())params['weight'] = params['weight'].reshape(2, 3)self.linear.load_state_dict(params)self.optim0 = torch.optim.Adam(lr=0.5, params=self.conv.parameters())self.optim1 = torch.optim.Adam(lr=0.5, params=self.linear.parameters())def test(self, tensor):assert (self.conv.weight.flatten().eq(self.linear.weight.flatten())).all(), 'Initial weights are different'assert (self.conv.bias.flatten().eq(self.linear.bias.flatten())).all(), 'Initial biases are different'# get out tensorc_out = self.conv(tensor.transpose(1, 2)).transpose(1, 2)l_out = self.linear(tensor)# set optim targetc_target = c_out.sum(2).mean()l_target = l_out.sum(2).mean()# apply one step optimizationself.optim0.zero_grad()c_target.backward()self.optim0.step()self.optim1.zero_grad()l_target.backward()self.optim1.step()# if conv1d(kernel=1) behaves the same as linear, # their parameters should be the same after applying # one-step optimizationa = self.conv.weight.data.flatten()b = self.linear.weight.data.flatten()c = self.conv.bias.data.flatten()d = self.linear.bias.data.flatten()assert torch.add(a, -b).abs().lt(SMALL).all(), 'After a step, weights are different'assert torch.add(c, -d).abs().lt(SMALL).all(), 'After a step, biases are different'if __name__ == "__main__":gen = torch.Generator()for seed in range(1000):gen.manual_seed(seed)tensor = torch.rand((10, 3, 3), generator=gen)model = Model()model.test(tensor)

代碼做的事情主要是:1)給定隨機種子,生成隨機的 tensor,2)建模并使得兩個矩陣的初始參數相等。3)用 Adam 進行一次簡單的優化,并比較優化后的參數。

這里做最后的參數比較的時候,用 torch.eq 是肯定無法通過的,經過觀察,發現最后的weights 確實很接近。經過幾次測試發現,兩者在一步優化后,在 1e-6 誤差內可以通過測試,但是無法通過 1e-7 誤差的測試。

因此,這里有兩種可能,第一,這個weights的誤差僅僅是因為計算誤差導致的,pytorch 在計算兩者的時候,本質上是一樣。第二,pytorch 在計算 conv1d 的時候確實如文檔說的使用了cross-relation operation,但是這個operation在簡單的case中,帶來的gradients和linear確實存在微小的區別,從而使得其行為不一樣。但是得說明的是,經過一個大 N 級別的優化過程,conv1d 和 linear 帶來的區別會是顯著的。因此,最起碼的,在使用 pytorch 進行計算時,不可將兩者視為等同。

通過本次實驗以及基于自己在復現 VRP-RL 的經驗,我偏向認為 conv1d 的行為和 linear 是不同的。歡迎進一步討論。

-------

最近在復現VRP下的DRL算法,當考慮C個顧客的問題,以及batch的大小為N,相應的地圖數據的shape是(N, C, 2),其中第三維分別存儲物理坐標(x,y)信息。

原文使用Conv1d with kernel_size=1來作為encoder,將原始數據映射到embedding_size=M的維度上去,得到數據形狀為(N, C, M)。

作為一個調包俠,從來都只在乎輸入和輸出的形狀,怎么方便怎么來。因為pytorch的Conv1d的API的輸入數據需要將1維和2維調換,即(N, 2, C),覺得麻煩,而且誤以為kernel=1的時候的Conv1d和Linear是完全一樣的,然后就順手用了一個Linear Layer 去做為embedding。唯一的區別僅僅在于這個encoder的選擇,結果就是和benchmark對比,花費時間更長且效果更差。

然后去Stack Overflow上面去找找看答案,發現遇到這種問題的不僅我一個(見帖子),這里就根據pytorch的API一起探索一下conv1d(kernel=1)和linear分別究竟做了什么,以及產生區別的原因。

首先我們看最簡單的Linear layer如下,

然后我們看Conv1d的API如下

有興趣的小伙伴可以推導一下公式,不難發現,假設考慮都是叉乘操作,結合軸變化,當kernel=1的時候,Conv1d和Linear的output中各元素是共源的,也就是說,對于entry(i,j),生成他們數據的原始數據來源是一樣的,結果應該沒什么區別。神級畫手只能幫到這里了(1為Linear,2為假設的Conv1d,3為實際的Conv1d):

如此這般,那問題很可能就出在集結方式了!Linear這邊,確實就是普通的叉乘操作。這時候,Conv1d中紅色的這個cross-correlation很可能就是問題的關鍵了。wiki和百度鏈接如下,具體計算公式可以在鏈接里面找到:

wiki?www.wikiwand.comInsignal processing,cross-correlationis ameasure of similarityof two series as a function of the displacement of one relative to the other. This is also known as aslidingdot productorsliding inner-product.互相關函數_百度百科?baike.baidu.com互相關函數是信號分析里的概念,表示的是兩個時間序列之間的相關程度,即描述信號 x (t),y (t) 在任意兩個不同時刻 t1,t2 的取值之間的相關程度。描述兩個不同的信號之間的相關性時,這兩個信號可以是隨機信號,也可以是確知信號。

這不就是明擺著這個操作會體現兩個序列間的相關性嗎?在VRP問題中,相當于提前集結了x和y的信息,并通過學習weights與歷史信息中其他點作對比,大致估計當前點所在的位置,對于VRP問題,各個物理點x以及y之間的相關程度對于問題的求解是一個很重要的信息,當兩個位置的坐標更相近的時候,更有可能考慮這兩點相連,因此,使用Conv1d layer對問題的求解有更好的幫助。

小結,當同組數據中,各數據在每一維度的相關性比較重要的時候,Conv1d能提取這些數據并反映出來,這是普通的Linear layer做不到的。同時,做一個naive的調包俠是不可取的,仔細研究每一個API的內部運行機制才能避免寫低效甚至錯誤的代碼。

總結

以上是生活随笔為你收集整理的union和union all有什么区别_Pytorch中Linear与Conv1d(kernel=1)的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。