91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 互聯網科技 > 
  • 是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

發布時間:2020-08-09 02:13:51 來源:ITPUB博客 閱讀:222 作者:京東云技術新知 欄目:互聯網科技

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試 是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

作者:京東AI研究院 張建浩

煉丹師在轉換模型的時候,經常會發現給轉換前后的模型輸入同樣的圖片,模型結果有微小的差別。其中的原因有數值算法的誤差、不同 jpeg 解碼庫產生的結果不同等等,也有不同框架內部對某些算子的實現差異。

在給 ONNX 貢獻 Resize 算子的 spec 的時候,我發現 Resize 是一個突出體現了框架實現差異的算子——多種 Resize 類型、不統一的超參數、將錯就錯的歷史遺留 bug 和其它極易被忽略的問題集中在一起,導致幾乎每個框架的 Resize 操作的結果都有差異,而 ONNX 是一個神經網絡模型的中間格式,它應該盡量保留原始框架的算子的語義。經過查看相關論文和各種框架的源代碼,我分析和總結了 Resize 操作眾多的實現方式。最終為 ONNX 貢獻了一個較為完善的、標準化的 Resize 算子的 spec,它包含多個(基本)正交的參數,TensorFlow 1.x、TensorFlow 2.x、PyTorch、OpenCV 的 resize/interpolation 方法都可以用這個算子 100% 無損的表達。 本文將簡單介紹各種 resize 操作的共同流程,并分析是哪些因素引起了不同框架 resize 操作的不同。

多維 tensor (例如二維圖像)的 resize 操作是用多個在一維 tensor 上進行的 resize 操作組合出來的,所以我們只討論一維 tensor 上的 resize 操作,經過分析各個框架的源代碼,我發現它的流程可以總結如下:

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

1

先討論w和f,w(i)是第 i 個像素點的坐標,乍一看, w(i)完全可以等于i本身,其實沒有這么簡單。例如一個長度為 3 的 tensor,如果第i個像素點的坐標等于i本身,那么三個像素點在tensor 中的位置就如下圖中最左邊的樣子,橫線的長度代表一維 tensor 的長度,圓圈代表像素點:

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

三個像素點沒有對稱地分布在 tensor 上,而是往左偏了。出于直覺,我們覺得這不是一件特別好的事情。在各種框架中,有兩種常見的方法來解決這個問題:

一個是選取w(i)=i+0.5,以一個長度為 3 的一維 tensor 為例,它第 0 個像素點在 0.5 位置,第 1 個像素點在 1.5 位置,第 2 個像素點在 2.5 位置,這稱為 half_pixel,也就是上圖中中間的方法。這種方法中,

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

(這很符合直覺)。另一個是仍讓w(i)=i,但改變函數f,使

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

仍以長度為 3 的一維 tensor 為例,這種方法相當于在 resize 時砍掉了最右邊長度為 1 的部分,使像素點的分布“被”對稱了。這稱為 align_corner,也就是上圖中最右邊的方法,在各種框架的 resize 方法的參數里常見的 align_corner=True/False 就是它了,它的名字來源于它可以讓 tensor 中第一個和最后一個像素(即 corner)在縮放后保持不變。


那如果我們不采用這兩種方法,一定要使用“直覺不好”的 asymmetric 方法,究竟會發生什么呢?TensorFlow 1.x 就給我們提供了這樣一個反面典型,它在 align_corner=False 時的實現是錯的,原因就是使用了上圖中錯誤的 asymmetric 方法,這會導致奇怪的縮放結果,這篇博客中???? https://hackernoon.com/how-tensorflows-tf-image-resize-stole-60-days-of-my-life-aba5eb093f35,

作者用 TensorFlow 1.x 訓練的超分辨率神經網絡總是出現奇怪的問題,最終他發現問題根源是 TensorFlow 錯誤的 resize 實現,他還給了一個形象的例子:把 16x16 的下圖左側圖像縮小到 4x4,本應得到如下圖右側所示的圖像,而 TensorFlow 1.x 卻給出了下圖中間的奇怪結果,圖像的對稱性被完全破壞了,其中的原因就如上文所述。TensorFlow 1.x 的 resize 結果和其它框架不同的一大原因就是它錯誤的 resize 實現,好在 TensorFlow 2.x 已經修復了這個問題。

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

2

接下來討論另外兩個函數g和h,nearest, linear, cubic 這三種常見的 resize 的不同方式,是在g和h上有所不同。如上文所述,函數  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試  得到離  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試  最近的像素點,nearest 只需要找最近的一個像素點,linear 要找最近的兩個(左右各一個),cubic 要找最近的四個(左右各兩個);函數h(a,r)是計算這一個/兩個/四個像素點的加權平均值,其中權值是由r確定的(如上文所述,r是  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試 距左側像素點的距離)。對 nearest/linear/cubic 的每一種來說,如何從r得到各個像素點的權值都有各自標準的實現,nearest resize 不必說,對于 linear resize,兩個像素點的權值是  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試  。對 cubic 來說,四個像素點的權值是

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試


[1]其中A是一個固定的參數,它的取值卻是每個框架不同,兩個常見的選擇是 -0.5 (TensorFlow 部分版本的實現)和 -0.75(PyTorch)。因為A沒有統一的標準取值,所以各個框架的 cubic resize 結果不同是常見的事情。

補充一句題外話:cubic resize 的權值計算起來比 linear resize 復雜的多,所以它的耗時肯定會長一些,但產生的圖像性質更好(這篇 paper ???? https://arxiv.org/abs/1812.0118 7 發現圖片預處理使用 cubic resize 可以提升分類網絡準確率)。

還有一個會引起 cubic resize 結果差異的細節是,cubic resize 需要找到  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試  的左右各兩個最相鄰的像素點,但  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試  左右兩側不一定能保證各有兩個像素點(假設某種情況下計算得到  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試  ,那么它左邊只有一個像素點),此時也有兩種現存的不同方法,一種是對圖像做 edge padding,即認為仍從左邊找到了兩個像素點,并且這兩個像素點的值都是第一個像素點的值;另一種是認為找到了三個而不是四個像素點,并對三個像素點的權值做歸一化。

3

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

小結

總結一下,各個框架 Resize 操作的結果不同的原因是多種多樣的,例如 TensorFlow 用了自己發明的錯誤實現、cubic resize 中參數 A 沒有固定的取值、非整數的

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

是否自動取整等等。

ONNX Resize 算子的 spec 就是基于上面的分析寫出來的,具體的描述在???? https://github.com/onnx/onnx/bl ob/master/docs/Operators.md#Resize

Python 版的參考實現在 ???? https://github.com/onnx/onnx/bl ob/master/onnx/backend/test/case/node/resize.py

其中比較核心的屬性 coordinate_transformation_mode 是把w、f和  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試  復合得到的單個函數  是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試 ,即

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

在這里沒有用獨立的函數w和f的原因除了看起來更簡單之外,也有解決現實問題的考慮——有一些框架的某些 resize 實現沒有使用

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

的形式,而是直接讓

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

雖然這顯然是不合理的(coordinate_transformation_mode=tf_half_pixel_for_nn 就描述了這樣一個不合理的實現),但也只能承認它們的存在。相比起來,上一個版本的 ONNX Resize 算子 spec 的制定者沒有意識到 Resize 算子的復雜性,完全模仿了 TensorFlow 的實現,不僅和其它框架的結果不一致,而且連 TensorFlow 的 bug 也一并模仿了。

現在 TensorFlow、PyTorch 都支持了導出這一版本的 Resize 算子,TensorRT 等部署框架也支持導入和運行這個 Resize 算子。自己創造的東西能被眾多知名的框架跟進,我感到非常大的成就感。

參考: https://ieeexplore.ieee.org/doc ument/1163711

歡迎點擊“ 京東智聯云 ”了解更多精彩內容!

是什么引起了各個框架 Resize 操作的結果不同?——來自 ONNX 的標準化嘗試

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

安吉县| 宜兴市| 昌乐县| 寿光市| 新营市| 长泰县| 河曲县| 阜平县| 彝良县| 巴南区| 郸城县| 新绛县| 榆中县| 仙桃市| 琼中| 信阳市| 扎兰屯市| 安岳县| 裕民县| 天津市| 宜昌市| 遂平县| 南昌市| 团风县| 社旗县| 民县| 合肥市| 启东市| 武义县| 巴南区| 黄梅县| 新泰市| 容城县| 北川| 江门市| 彭山县| 华容县| 红桥区| 资阳市| 高阳县| 凌云县|