TensorFlow 維度變換

2021-10-01 16:58:07 字數 3882 閱讀 1206

基本的維度變換包含了改變檢視 reshape,插入新維度 expand_dims,刪除維 squeeze,交換維度 transpose,複製資料 tile 等。

四、交換維度

五、資料複製

六、broadcasting(自動擴充套件)

張量的檢視就是我們理解張量的方式,比如shape 為[2,4,4,3]的張量a,我們從邏輯上可以理解為2 張,每張4 行4 列,每個位置有rgb 3 個通道的資料;

張量的儲存體現在張量在記憶體上儲存為一段連續的記憶體區域,對於同樣的儲存,我們可以有不同的理解方式,比如上述a,我們可以在不改變張量的儲存下,將張量a 理解為2 個樣本,每個樣本的特徵為長度48 的向量。

這就是儲存與檢視的關係。

在儲存資料時,記憶體並不支援這個維度層級概念,只能以平鋪方式按序寫入記憶體,因此這種層級關係需要人為管理,也就是說,每個張量的儲存順序需要人為跟蹤。

為了方便表達,我們把張量shape 中相對靠左側的維度叫做大維度,shape 中相對靠右側的維度叫做小維度,比如[2,4,4,3]的張量中,數量維度與通道數量相比,數量叫做大維度,通道數叫做小維度。

例如:在優先寫入小維度的設定下,張量 [2,4,4,3] 的記憶體布局為

為了能夠正確恢復出資料,必須保證張量的儲存順序與新檢視的維度順序一致,

例如根據數量-行-列-通道初始檢視儲存的張量,按照數量-行-列-通道(? − ℎ −w − ?)的順序可以獲得合法資料。

如果按著數量-畫素-通道(b − h ∗ w − c)的方式恢復檢視,也能得到合法的資料。但是如果按著數量-通道-畫素( − c − h ∗ w)的方式恢復資料,由於記憶體布局是按著數量-行-列-通道的順序,檢視維度與儲存維度順序相悖,提取的資料將是錯亂的。

改變檢視是神經網路中非常常見的操作,可以通過串聯多個reshape 操作來實現複雜

邏輯,但是在通過reshape 改變檢視時,必須始終記住張量的儲存順序,新檢視的維度順序不能與儲存順序相悖,否則需要通過交換維度操作將儲存順序同步過來。

舉個例子,對於shape 為[4,32,32,3]的資料,通過reshape 操作將shape 調整為[4,1024,3],此時檢視的維度順序為 ? − ????? − ?,張量的儲存順序為 [?, ℎ, w, ?]。

在 tensorflow 中,可以通過張量的ndim 和shape 成員屬性獲得張量的維度數和形

狀:通過 tf.reshape(x,new_shape),可以將張量的檢視任意的合法改變

當不知道填入什麼數字合適時,可以選用-1來替代,由python通過其他值進行推算得知具體值

例如將shape為[b,3,4]的輸入資料轉為 shape為[b,3*4]的資料:

增加乙個長度為1 的維度相當於給原有的資料增加乙個新維度的概念,維度長度為1,故資料並不需要改變,僅僅是改變資料的理解方式,因此它其實可以理解為改變檢視的一種特殊方式

通過tf.expand_dims(x, axis)可在指定的axis 軸前可以插入乙個新的維度:

可以看到插入乙個新維度後,資料的儲存順序並沒有改變,僅僅改變了資料的檢視。

需要注意的是,tf.expand_dims 的axis 為正時,表示在當前維度之前插入乙個新維度;為負時,表示當前維度之後插入乙個新的維度。以[?, ℎ, w, ?]張量為例,不同axis 引數的實際插入位置如圖所示:

是增加維度的逆操作,與增加維度一樣,刪除維度只能刪除長度為1 的維度,也不會改變張量的儲存。

可以通過tf.squeeze(x, axis)函式,axis 引數為待刪除的維度的索引號

如果不指定維度引數 axis,即 tf.squeeze(x),那麼他會預設刪除所有長度為1的維度

在實現演算法邏輯時,在保持維度順序不變的條件下,僅僅改變張量的理解方式是不夠的,有時需要直接調整的儲存順序,即交換維度(transpose)。通過交換維度,改變了張量的儲存順序,同時也改變了張量的檢視。

我們以[?, ℎ, w, ?]轉換到[?, ?, ℎ, w]為例,介紹如何使用tf.transpose(x, perm)函式完成維度交換操作,其中 perm 表示新維度的順序 list。

通過tf.transpose完成維度交換後,張量的儲存順序已經改變,檢視也隨之改變,後續的所有操作必須基於新的存續順序進行

tf.tile(x, multiples)函式完成資料在指定維度上的複製操作,multiples 分別指定了每個維度上面的複製倍數,對應位置為1 表明不複製,為2 表明新長度為原來的長度的2 倍,即資料複製乙份,以此類推。

broadcasting 也叫廣播機制(自動擴充套件也許更合適),它是一種輕量級張量複製的手段,在邏輯上擴充套件張量資料的形狀,但是只要在需要時才會執行實際儲存複製操作。對於大部分場景,broadcasting 機制都能通過優化手段避免實際複製資料而完成邏輯運算,從而相對於tf.tile 函式,減少了大量計算代價。

對於所有長度為1 的維度,broadcasting 的效果和tf.tile 一樣,都能在此維度上邏輯複製資料若干份,區別在於tf.tile 會建立乙個新的張量,執行複製io 操作,並儲存複製後的張量資料,broadcasting 並不會立即複製資料,它會邏輯上改變張量的形狀,使得檢視上變成了複製後的形broadcasting 會通過深度學習框架的優化手段避免實際複製資料而完成邏輯運算,至於怎麼實現的使用者不必關係,對於用於來說,broadcasting 和tf.tile 複製的最終效果是一樣的,操作對使用者透明,但是broadcasting 機制節省了大量計算資源,建議在運算過程中盡可能地利用broadcasting 提高計算效率。

broadcasting 機制的核心思想是普適性,即同乙份資料能普遍適合於其他位置。在驗證普適性之前,需要將張量shape 靠右對齊,然後進行普適性判斷:對於長度為1 的維度,預設這個資料普遍適合於當前維度的其他位置;對於不存在的維度,則在增加新維度後預設當前資料也是普適性於新維度的,從而可以擴充套件為更多維度數、其他長度的張量形狀。

在 c 維度上,張量已經有2 個特徵資料,新shape 對應維度長度為c(? ≠ 2,比如c=3),那麼當前維度上的這2 個特徵無法普適到其他長度,故不滿足普適性原則,無法應用 broadcasting 機制,將會觸發錯誤

在進行張量運算時,有些運算可以在處理不同shape 的張量時,會隱式自動呼叫 broadcasting 機制,如+,-,*,/等運算等,將參與運算的張量broadcasting 成乙個公共shape,再進行

tensorflow2 1的維度變換

函式的作用是將tensor變換為引數shape的形式,其中shape為乙個列表形式,特殊的一點是列表中可以存在 1 1代表的含義是不用我們自己指定這一維的大小,函式會自動計算,但列表只能存在乙個 1。如果存在多個 1,就是乙個存在多解的方程 a tf.random.normal 4 28,28 3 ...

tensorflow2 0 維度變換

a tf.random.normal 4,28,28,3 a 1 tf.reshape a,4,784,3 shape 1 a 1 tf.reshape a,4,1,3 shape 和1等價 a 2 tf.reshape a,4,784 3 shape 2 a 2 tf.reshape a,4,1 ...

TensorFlow2 維度變換

目錄tensorflow2教程完整教程目錄 更有python go pytorch tensorflow 爬蟲 人工智慧教學等著你 import tensorflow as tfa tf.random.normal 4,28,28,3 a.shape,a.ndim tensorshape 4,28,...