2015-12-29 216 views
7

我有一個深層神經網絡,其中層之間的權重存儲在列表中。總結張量流量張量列表

layers[j].weights我想在我的成本函數中包含嶺懲罰。然後我需要使用類似 tf.nn.l2_loss(layers[j].weights**2 for j in range(self.n_layers))的東西,即所有權重的平方和。

尤其是權重被定義爲:

>>> avs.layers 
[<neural_network.Layer object at 0x10a4b2a90>, <neural_network.Layer object at 0x10ac85080>, <neural_network.Layer object at 0x10b0f3278>, <neural_network.Layer object at 0x10b0eacf8>, <neural_network.Layer object at 0x10b145588>, <neural_network.Layer object at 0x10b165048>, <neural_network.Layer object at 0x10b155ba8>] 
>>> 
>>> avs.layers[0].weights 
<tensorflow.python.ops.variables.Variable object at 0x10b026748> 
>>> 

我如何能做到這一點的tensorflow?

+0

我認爲你需要從這些權重中創建一個新的張量,並在成本公式中使用它。 – fabrizioM

回答

16

對張量列表進行求和的標準方法是使用tf.add_n()操作,該操作需要張量列表(每個張量具有相同的大小和形狀)並生成一個包含總和的單張量。

對於您所遇到的特定問題,我假定每個layers[j].weights都可以具有不同的大小。因此,在求和之前,你需要將每個元素縮減爲一個標量,例如使用tf.nn.l2_loss()函數本身:

weights = [layers[j].weights for j in range(self.n_layers)] 
losses = [tf.nn.l2_loss(w) for w in weights] 
total_loss = tf.add_n(losses) 

(但請注意,如果要添加的值很大,您可能會發現更有效的計算tf.add()操作的順序,因爲TensorFlow保持每個add_n的值在內存參數,直到他們的所有已計算。的add OPS鏈允許一些計算的早期發生。)

0

tf.nn.l2_loss()函數返回0尺寸的張量。

但是不需要手動將它應用到每個權重張量上,因此將權重張量存儲在列表中是解決問題的一種方法(正如@mrry所指出的那樣)。

但是,而不需要每次都寫了,你可以做的是使用下面的函數

def l2_loss_sum(list_o_tensors): 
    return tf.add_n([tf.nn.l2_loss(t) for t in list_o_tensors]) 

在你的情況下,這看起來像:

total_loss = l2_loss_sum([layers[j].weights for j in range(self.n_layers)]) 

而且,tf.nn.l2_loss()含蓄將平方運算應用於值並將所有平方值乘以1/2,所以你使用類似tf.nn.l2_loss(layers[j].weights**2 for j in range(self.n_layers))的東西,你實際上會將權重提高到第4次方。結果你的這個損失項的派生將是奇怪的:它不會取消1/2到1(但會隱含地將你的β加倍),並且權重將被立方化。