使用Keras實(shí)現(xiàn)Tensor的相乘和相加代碼
前言
最近在寫行為識(shí)別的代碼,涉及到兩個(gè)網(wǎng)絡(luò)的融合,這個(gè)融合是有加權(quán)的網(wǎng)絡(luò)結(jié)果的融合,所以需要對(duì)網(wǎng)絡(luò)的結(jié)果進(jìn)行加權(quán)(相乘)和融合(相加)。
最初的想法
最初的想法是用Keras.layers.Add和Keras.layers.Multiply來做,后來發(fā)現(xiàn)這樣會(huì)報(bào)錯(cuò)。
rate_rgb = k.variable(np.ones((1024,),dtype='float32')*0.8) rate_esti = k.variable(np.ones((1024,),dtype='float32')*0.2) weight_gru1 = Multiply()([rate_rgb,gru1]) weight_gru2 = Multiply()([rate_esti,gru2]) last = Add()([weight_gru1,weight_gru2])
這么寫會(huì)報(bào)錯(cuò),如下
AttributeError: 'Variable' object has no attribute '_keras_history'
正確做法
后來在網(wǎng)上參考大神的博客,改為如下
weight_1 = Lambda(lambda x:x*0.8) weight_2 = Lambda(lambda x:x*0.2) weight_gru1 = weight_1(gru1) weight_gru2 = weight_2(gru2) last = Add()([weight_gru1,weight_gru2])
這樣就沒問題了。
補(bǔ)充知識(shí):Keras天坑:想當(dāng)然的對(duì)層的直接運(yùn)算帶來的問題
天坑
keras如何操作某一層的值(如讓某一層的值取反加1等)?keras如何將某一層的神經(jīng)元拆分以便進(jìn)一步操作(如取輸入的向量的第一個(gè)元素乘別的層)?keras如何重用某一層的值(如輸入層和輸出層乘積作為最終輸出)?
這些問題都指向同一個(gè)答案,即使用Lambda層。
另外,如果想要更加靈活地操作層的話,推薦使用函數(shù)式模型寫法,而不是序列式。
Keras當(dāng)中,任何的操作都是以網(wǎng)絡(luò)層為單位,操作的實(shí)現(xiàn)都是新添一層,不管是加減一個(gè)常數(shù)還是做乘法,或者是對(duì)兩層的簡(jiǎn)單拼接。所以,將一層單獨(dú)劈一半出來,是一件難事。強(qiáng)調(diào),Keras的最小操作單位是Layer,每次操作的是整個(gè)batch。自然,在keras中,每個(gè)層都是對(duì)象,可以通過dir(Layer對(duì)象)來查看具有哪些屬性。然而,Backend中Tensorflow的最小操作單位是Tensor,而你搞不清楚到底是Layer和Tensor時(shí),盲目而想當(dāng)然地進(jìn)行層的操作,就會(huì)出問題。到底是什么?通過type和shape是看不出來的。
如果你只是想對(duì)流經(jīng)該層的數(shù)據(jù)做個(gè)變換,而這個(gè)變換本身沒有什么需要學(xué)習(xí)的參數(shù),那么直接用Lambda Layer是最合適的了。
也就是說,對(duì)每一層的加減乘除都得用keras的函數(shù),你不能簡(jiǎn)單使用形如 ‘new_layer' =1−= 1-=1−'layer'這樣的表達(dá)方式來對(duì)層進(jìn)行操作。
當(dāng)遇到如下報(bào)錯(cuò)信息:
AttributeError: 'NoneType' object has no attribute '_inbound_nodes'
或
TypeError: 'Tensor' object is not callable
等等
這是就要考慮一下將程序中層的操作改成Lambda的方式表達(dá)。
使用Lambda編寫自己的層
Lamda層怎么用?官方文檔給了這樣一個(gè)例子。
# add a x -> x^2 layer model.add(Lambda(lambda x: x ** 2)) # add a layer that returns the concatenation # of the positive part of the input and # the opposite of the negative part def antirectifier(x): x -= K.mean(x, axis=1, keepdims=True) x = K.l2_normalize(x, axis=1) pos = K.relu(x) neg = K.relu(-x) return K.concatenate([pos, neg], axis=1) def antirectifier_output_shape(input_shape): shape = list(input_shape) assert len(shape) == 2 # only valid for 2D tensors shape[-1] *= 2 return tuple(shape) model.add(Lambda(antirectifier, output_shape=antirectifier_output_shape))
乍一看,有點(diǎn)懵逼,什么亂七八糟的。事實(shí)上,很簡(jiǎn)單,假設(shè)L0和L1是兩層,你只要將你形如下面這樣的表達(dá):
L1 = F(L0);
改成
L1 = Lambda( lambda L0:F(L0) ) (L0)
即可。為了看得清楚,多加了幾個(gè)空格。
事實(shí)上,無非就是將原來的變換,通過Lambda(lambda 輸入:表達(dá)式)這樣的方式,改成了Lambda型函數(shù),再把輸入傳進(jìn)去,放在尾巴上即可。
參考
https://keras-cn.readthedocs.io/en/latest/layers/core_layer/#lambda
(個(gè)人覺得這份文檔某些地方比官方中文要完整許多)
keras許多簡(jiǎn)單操作,都需要新建一個(gè)層,使用Lambda可以很好完成需求。當(dāng)你不知道有這個(gè)東西存在的時(shí)候,就會(huì)走不少?gòu)澛贰?/p>
以上這篇使用Keras實(shí)現(xiàn)Tensor的相乘和相加代碼就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python 有效的括號(hào)的實(shí)現(xiàn)代碼示例
這篇文章主要介紹了python 有效的括號(hào)的實(shí)現(xiàn)代碼示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11python實(shí)現(xiàn)自動(dòng)發(fā)送報(bào)警監(jiān)控郵件
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)自動(dòng)發(fā)送報(bào)警監(jiān)控郵件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06使用Python實(shí)現(xiàn)在Word文檔中進(jìn)行郵件合并
郵件合并是現(xiàn)代辦公中一項(xiàng)顯著提升效率的技術(shù),它巧妙地將大量個(gè)體數(shù)據(jù)與預(yù)設(shè)的文檔模板相結(jié)合,實(shí)現(xiàn)了一次性批量生成定制化文檔,下面我們就來看看如何使用Python實(shí)現(xiàn)在Word文檔中進(jìn)行郵件合并吧2024-04-04教你如何用python操作攝像頭以及對(duì)視頻流的處理
這篇文章主要介紹了教你如何用python操作攝像頭以及對(duì)視頻流的處理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10pandas實(shí)現(xiàn)to_sql將DataFrame保存到數(shù)據(jù)庫(kù)中
這篇文章主要介紹了pandas實(shí)現(xiàn)to_sql將DataFrame保存到數(shù)據(jù)庫(kù)中,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07使用Python根據(jù)一個(gè)列表的順序?qū)ζ渌斜磉M(jìn)行排序
這篇文章主要介紹了使用Python根據(jù)一個(gè)列表的順序?qū)ζ渌斜磉M(jìn)行排序,根據(jù)列表B中每個(gè)元素的下標(biāo)來獲取列表A中對(duì)應(yīng)位置的元素,將其作為排序依據(jù)即可,需要的朋友可以參考下2023-10-10python的數(shù)據(jù)與matlab互通問題:SciPy
這篇文章主要介紹了python的數(shù)據(jù)與matlab互通問題SciPy,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12