keras疑問

爲什麼共享圖層後,輸出向量的形狀還不一樣

# 這一層可以輸入一個矩陣,並返回一個 64 維的向量
shared_lstm = LSTM(64)

# 當我們重用相同的圖層實例多次,圖層的權重也會被重用 (它其實就是同一層)
encoded_a = shared_lstm(tweet_a)
encoded_b = shared_lstm(tweet_b)

這裏重用了shared_lstm 層,但是如果要我們獲取輸出形狀時,有文章指出圖層的權重是一樣的,但是輸出形狀不一樣,這裏不太理解

assert shared_lstm.get_output_at(0) == encoded_a
assert shared_lstm.get_output_at(1) == encoded_b

雖然我們可以通過shared_lstm 的方法來獲取圖層,但是我不太理解,我的理解是輸出已經定義好了,所有的輸入的輸出都是一樣的,寫個代碼可以瞭解一下。


a = Input(shape=(280, 128))
b = Input(shape=(250, 128))

lstm = LSTM(32)
encoded_a = lstm(a)
encoded_b = lstm(b)

print(lstm.get_input_shape_at(0))
print(lstm.get_input_shape_at(1))

print(lstm.get_output_shape_at(0))
print(lstm.get_output_shape_at(1))

輸出結果:

(None, 280, 128)
(None, 250, 128)
(None, 32)
(None, 32)

其中如果a、b的input中,shape的後一維向量不一樣就會報錯,根據矩陣運算來說,後一維矩陣關係到後一個向量的行維數,如果不同,則兩次輸入得到的向量維數都是不一樣的,這是我的理解,也不知道對不對,
疑問:

  • 1、如果兩次調用通一個層,同一個輸入維數,用的是也是兩個層,那麼權重怎麼共享?
  • 2、對這個共享還是不太理解,我覺得共享就是權重也是共享的,這個權重對於同一個維數的輸入來說應該是一樣的。

Embedding層和Input層有啥區別

這兩個層都是作爲網絡模型的第一層,當然模型也可以不用這個層,所以我就很奇怪,這兩個層作爲第一層的作用是什麼?他們之間有什麼區別?

Input層 很多資料就說實例化一個keras張量,如下:

x = Input(shape=(32,))

明顯很多layers的輸出都是返回一個向量,

Embedding層:嵌入層將正整數(下標)轉換爲具有固定大小的向量,如[[4],[20]]->[[0.25,0.1],[0.6,-0.2]]
是不是很奇怪,這個怎麼轉換的?其實這裏的embeding 是詞向量化,但我不清楚 是不是用的word2vec,但大概是用的skip-word算法來構建的,將輸入作爲語料集,一定長度的窗口來滑動,訓練模型從而得到指定長度的輸出詞的相似性,輸出的是相關性較高的詞的概率,一共有窗口大小的長度,
如果輸入數據不需要詞的語義特徵語義,簡單使用Embedding層就可以得到一個對應的詞向量矩陣,但如果需要語義特徵,我們大可把訓練好的詞向量權重直接扔到Embedding層中即可
大家可以看下這個定義:

keras.layers.Embedding(input_dim, output_dim, embeddings_initializer='uniform', embeddings_regularizer=None, activity_regularizer=None, embeddings_constraint=None, mask_zero=False, input_length=None)

  • input_dim: int > 0。詞彙表大小, 即最大整數 index + 1,類似語料集分詞後詞彙大小。
  • output_dim: int >= 0。詞向量的維度。
  • input_length: 輸入序列的長度,當它是固定的時。 如果你需要連接 Flatten 和 Dense 層,則這個參數是必須的 (沒有它,dense 層的輸出尺寸就無法計算)
model = Sequential()
model.add(Embedding(4, 5, input_length=7))
model.compile('rmsprop','mse')
model.predict(np.array([[0,1,0,1,1,0,3]]))

輸出結果:

array([[[-0.03462106,  0.01587335, -0.04886673,  0.01961641,
          0.01314208],
        [ 0.02410911, -0.03580334,  0.02348015,  0.02070605,
          0.01584761],
        [-0.03462106,  0.01587335, -0.04886673,  0.01961641,
          0.01314208],
        [ 0.02410911, -0.03580334,  0.02348015,  0.02070605,
          0.01584761],
        [ 0.02410911, -0.03580334,  0.02348015,  0.02070605,
          0.01584761],
        [-0.03462106,  0.01587335, -0.04886673,  0.01961641,
          0.01314208],
        [ 0.00639332, -0.03460374,  0.01854259,  0.02507687,
          0.03259133]]], dtype=float32)

參數分析:

  • 4:3+1,一共有3個詞彙,0、1、3
  • 5:詞向量的維度
  • 7:輸入的長度

具體可以看下參考博客。

dot()

全稱是 tf.keras.backend.dot,表示兩個矩陣相乘得到一個新的矩陣。

  # dot product between tensors
    >>> x = K.placeholder(shape=(2, 3))
    >>> y = K.placeholder(shape=(3, 4))
    >>> xy = K.dot(x, y)
    >>> xy
    <tf.Tensor 'MatMul_9:0' shape=(2, 4) dtype=float32>

不過這些都是隻有形狀,也就是說並不知道這個矩陣的具體值是多少,可能跟我們線性代數裏的具體的矩陣不太一樣,畢竟這裏只是定義這麼一個相乘的操作。

Model類與Layer的區別

這裏的Layer包括我們自己定義的Layer Class。通常,我們使用Layer類來定義內部計算塊,並使用Model類來定義外部模型 - 即要訓練的對象。

Model類與Layer的區別:

它公開了內置的訓練,評估和預測循環(model.fit(),model.evaluate(),model.predict())。
它通過model.layers屬性公開其內層列表。
它公開了保存和序列化API。

參考博客

keras中文

keras:3Embedding層詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章