由於keras中許多網路並不支援mask,但最近本菜需要在自己的網路中實現mask,如果想讓keras中的自定義函式支援mask,就必須要實現comput_mask方法,因為在官方的文件中我並沒有找到想要的東西,因此只能通過看原始碼的方式來學習,下面這一段就是keras中masking層的原始碼:
在compute_mask方法中,any函式實現的是按位規約,not_equal函式的功能正如其名,是逐個元素對比兩個張量的不相等情況。class
masking
(layer)
: def __init__
(self, mask_value=0.,
**kwargs)
:super
(masking, self)
.__init__
(**kwargs)
self.supports_masking = true
self.mask_value = mask_value
def compute_mask
(self, inputs, mask=none)
: output_mask =k.
any(k.
not_equal
(inputs, self.mask_value)
, axis=-1
)return output_mask
def call
(self, inputs)
: boolean_mask =k.
any(k.
not_equal
(inputs, self.mask_value)
, axis=-1
, keepdims=true)
return inputs *k.
cast
(boolean_mask,k.
dtype
(inputs)
) def get_config
(self)
: config =
base_config =
super
(masking, self)
.get_config()
return
dict
(list
(base_config.
items()
)+list
(config.
items()
))def compute_output_shape
(self, input_shape)
:return input_shape
這裡面有幾個疑惑,第乙個是mask_value是乙個常數,而inputs是乙個張量,為什麼這兩者可以進行比較。我猜想是mask_value進行了擴充套件,簡單測試如下:# x: 張量或變數 axis: 執行歸約操作的軸 keepdims: 是否放棄或廣播歸約的軸。
keras.backend.
any(x, axis=none, keepdims=false)
# x: 張量或變數 y: 張量或變數
keras.backend.
not_equal
(x, y)
第二個疑惑是compute_mask()函式是向下傳遞mask,那麼這個函式到底向下傳遞的是什麼呢,從**來看是對第乙個維度進行了規約,我們也跑一下程式驗證一下from keras import backend as
kimport tensorflow as tf
# inputs =k.
constant([
1,2,
3])inputs =k.
constant([
[1,2
,3],
[1,2
,0],
[0,0
,0]]
)mask_value =
0output_mask =k.
not_equal
(inputs, mask_value)
(output_mask)
with tf.
session()
as sess:
(output_mask.
eval()
)# 輸出結果如下:
tensor
("notequal:0"
, shape=(3
,3), dtype=bool)
[[ true true true]
[ true true false]
[false false false]]
# 由此可以看出的確是進行了擴充套件
這樣乙個(3,3)的矩陣被規約成了(1,3)的矩陣,第三個維度位false,也就表明了這個維度對應的特徵將會被mask,這個矩陣也會作為mask的返回值傳遞下去。再來看一下官方給出的例子from keras import backend as
kimport tensorflow as tf
# inputs =k.
constant([
1,2,
3])inputs =k.
constant([
[1,2
,3],
[1,0
,0]]
)mask_value =
0output_mask =k.
any(k.
not_equal
(inputs, mask_value)
, axis=-1
(output_mask)
with tf.
session()
as sess:
(output_mask.
eval()
)# 輸出結果如下:
tensor
("any:0"
, shape=(3
,), dtype=bool)
[ true true false]
這裡masking層的輸入是格式是input_shape=(timesteps, features),由剛才的測試結果可以得出,向下傳遞的mask維度應該是(1,timesteps),這樣我們就可以根據傳遞下去的mask值來對lstm層中的一些timesteps進行遮蔽。model =
sequential()
model.
add(
masking
(mask_value=
0., input_shape=
(timesteps, features)))
model.
add(
lstm(32
))
綜上,不那麼嚴謹的得出結論,對於支援mask的網路層,在各層之間傳遞資料的同時,也傳遞著乙個bool型的mask矩陣,矩陣中的true與false決定著對應位置的特徵是否被遮蔽,並且這個矩陣的維度是(1,timesteps)。因此,在自定義函式中,我們要根據需求自己改變mask矩陣並繼續傳遞下去,來作為下一層的mask,這裡要注意的是,mask是不考慮batch_size的,也就是說我們只需要針對單個樣本寫好mask的傳遞函式就可以了。
keras中啟用函式的使用
兩種方式 一 通過keras封裝的網路層中的activation引數指定 例如,下面的卷積層中的指定的啟用函式為relu函式 from keras.model import sequential from keras.layers import conv2d from keras.layers im...
keras keras中的mask操作
最常見的一種情況,在nlp問題的句子補全方法中,按照一定的長度,對句子進行填補和擷取操作.一般使用keras.preprocessing.sequence包中的pad sequences方法,在句子前面或者後面補0.但是這些零是我們不需要的,只是為了組成可以計算的結構才填補的.因此計算過程中,我們希...
Deeplearning中mask的作用
搬運自 我認為,在實踐中,我們需要mask的最重要的原因之一是,我們要batchize多個句子作為乙個輸入,即輸入了一批句子的模型做乙個向前計算。像這樣的成像案例 兩個句子 i like cats.he does not like cats.然後我們通過詞彙表中的索引將每個單詞轉換為int 1i 2...