更詳細講解:Python裡對於shape()的理解
在筆者debug深度學習相關代碼的時候,很容易出現shape()這樣形式的東西,用來告知輸出數據的形式,由於shape()裡出現的數字數量不同,還經常有shape(?,64,512)這樣的數據存在,因此上網查了一些信息,作出比較通俗易懂的解釋:
import numpy as np
a = np.array([[[1,2,3],[4,5,6]]])
print(a.shape)
(1, 2, 3)
表示該數組有1個,是2行3列的數組。每一個shape裡的數字對應數組中的一對中括號,第一個數字1表示最外層的中括號。以此類推,數字2表示第二層中括號,數字3表示最裡層的中括號。如果定義array時去掉了最外層的括號那麼輸出的shape為(2, 3)。
有幾個中括號就為幾維數組,即shape後的結果中就有幾個數。
因此在上文中,有三對中括號,是3維數組,shape()中有3個數。
a = np.array([1,2]) #a.shape值(2,),意思是一維數組,數組中有2個元素。
b = np.array([[1],[2]]) #b.shape值是(2,1),意思是一個二維數組,每行有1個元素。
c = np.array([[1,2]]) #c.shape值是(1,2),意思是一個二維數組,每行有2個元素。
而在debug相關程序時,可能會出現shape(?,2,3)這便代表數組每一個都是2行3列的,前面這個“?”便代表批處理個數,若為1則有1個,為2則有兩個,但是在debug的時候不知道有幾個,所以以“?”的形式顯示。
from keras.models import Input,Model
from keras.layers import Dense,Conv2D,TimeDistributed
input_ = Input(shape=(12,32,32,3))
out = TimeDistributed(Conv2D(filters=32,kernel_size=(3,3),padding='same'))(input_)
model = Model(inputs=input_,outputs=out)
model.summary()
而這裡,shape()中有四個數。第一個12代表就是時間序列,32,32,3指的是高,寬,通道數。卷積操作使用TimeDistributed就相當與這12個時間序列共享一個卷積層參數信息,無論時間序列值為多少,參數總量還是一定的。此處一共有896個參數,卷積核weights有3×3×3×32=864個,卷積核bias有32個。
關於TimeDistributed有一個比較通俗的示例解釋:
考慮一批32個樣本,其中每個樣本是一個由16個維度組成的10個向量的序列。該層的批輸入形狀然後(32, 10, 16)。
可以這麼理解,輸入數據是一個特征方程,X1+X2+…+X10=Y,從矩陣的角度看,拿出未知數,就是10個向量,每個向量有16個維度,這16個維度是評價Y的16個特征方向。
TimeDistributed層的作用就是把Dense層應用到這10個具體的向量上,對每一個向量進行了一個Dense操作,假設是下面這段代碼:
model = Sequential()model.add(TimeDistributed(Dense(8), input_shape=(10, 16)))
輸出還是10個向量,但是輸出的維度由16變成了8,也就是(32,10,8)。
TimeDistributed層給予了模型一種一對多,多對多的能力,增加了模型的維度。