web-dev-qa-db-ja.com

tensorflowのテンソルのリストを合計します

レイヤー間の重みがリストに格納されているディープニューラルネットワークがあります。

_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>
>>> 
_

テンソルフローでそれを行うにはどうすればよいですか?

9
Donbeo

テンソルのリストを合計する標準的な方法は、 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)

(ただし、追加される値が大きい場合、TensorFlowがadd_nのそれぞれの値を保持するため、一連の tf.add() 演算を計算する方が効率的である場合があることに注意してくださいそれらのallが計算されるまでメモリ内の引数。add opsのチェーンにより、計算の一部を以前に実行できます。)

22
mrry

tf.nn.l2_loss()関数は、0次元のテンソルを返します。

しかし、それを各ウェイトテンソルに手動で適用する必要がないのはいいことです。そのため、ウェイトテンソルをリストに格納することは、問題を解決する1つの方法です(@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()は2乗演算を値に暗黙的に適用し、すべての2乗値に1/2を乗算します。したがって、tf.nn.l2_loss(layers[j].weights**2 for j in range(self.n_layers))のようなものを使用すると、実際には重みが高くなります。 4乗します。その結果、この損失項の導関数は奇妙なものになります。1/ 2から1をキャンセルせず(ただし、暗黙的にβを2倍にします)、重みは3乗されます。

1
mpacer