2017-07-10 10 views
3

TensorFlowオプティマイザ(Python)では、メソッドapply_denseがニューロンの重み(レイヤ接続)とバイアスウェイトに対して呼び出されますが、このメソッドでは両方を使用したいと思います。オプティマイザでバイアスとニューロンのウェイトを取得する方法は?

def _apply_dense(self, grad, weight): 
    ... 

例:完全に接続されたニューラルネットワークで、2つのニューロンと2つのニューロンを持つ隠れ層と、それぞれにバイアスがあります。

Neural network example

我々はレイヤ2で見てみるならば、我々はapply_denseにニューロンの重みのためのコールを取得する:

neuron weights

とバイアスの重みのためのコール:

bias weights

しかし、私は両方の行列を1回の呼び出しで必要とするかこのようなapply_denseまたは重み行列の:

all weights from one layer

X_2X_4、B_1X_4、... 2つのニューロン間の接続の重みのためだけの表記です。したがって、B_1X_4はB_1とX_4の間の重量のプレースホルダーではありません。

どのようにするには?ここでは、最小限の作業たとえば

MWE

勢いで確率的勾配降下オプティマイザの実装。各層ごとに、他のニューロンからのすべての着信接続の運動量が平均値に減少します(ndims == 2を参照)。私が必要とするのは、入力ニューロン接続からの拍動値だけでなく、(上記のような)入力バイアス接続からの拍動値の平均でもあります。シンプルな神経回路網については

from __future__ import absolute_import 
from __future__ import division 
from __future__ import print_function 

import tensorflow as tf 
from tensorflow.python.training import optimizer 


class SGDmomentum(optimizer.Optimizer): 
    def __init__(self, learning_rate=0.001, mu=0.9, use_locking=False, name="SGDmomentum"): 
     super(SGDmomentum, self).__init__(use_locking, name) 
     self._lr = learning_rate 
     self._mu = mu 

     self._lr_t = None 
     self._mu_t = None 

    def _create_slots(self, var_list): 
     for v in var_list: 
      self._zeros_slot(v, "a", self._name) 

    def _apply_dense(self, grad, weight): 
     learning_rate_t = tf.cast(self._lr_t, weight.dtype.base_dtype) 
     mu_t = tf.cast(self._mu_t, weight.dtype.base_dtype) 
     momentum = self.get_slot(weight, "a") 

     if momentum.get_shape().ndims == 2: # neuron weights 
      momentum_mean = tf.reduce_mean(momentum, axis=1, keep_dims=True) 
     elif momentum.get_shape().ndims == 1: # bias weights 
      momentum_mean = momentum 
     else: 
      momentum_mean = momentum 

     momentum_update = grad + (mu_t * momentum_mean) 
     momentum_t = tf.assign(momentum, momentum_update, use_locking=self._use_locking) 

     weight_update = learning_rate_t * momentum_t 
     weight_t = tf.assign_sub(weight, weight_update, use_locking=self._use_locking) 

     return tf.group(*[weight_t, momentum_t]) 

    def _prepare(self): 
     self._lr_t = tf.convert_to_tensor(self._lr, name="learning_rate") 
     self._mu_t = tf.convert_to_tensor(self._mu, name="momentum_term") 

https://raw.githubusercontent.com/aymericdamien/TensorFlow-Examples/master/examples/3_NeuralNetworks/multilayer_perceptron.py

+0

もっと明示する必要があります。どのような方法で呼んでいますか?最小の実例を教えていただけますか? –

+0

私はオプティマイザを実装しています。私はそのようなオプティマイザのMWEと、私の質問の観点からの要件の記述を追加しました。 – Spen

+0

私はあなたが何を求めているのか分かりません。あなたのネットワークでどのように体重を取得するか尋ねていますか? –

答えて

1

更新(のみカスタムSGDmomentumオプティマイザへオプティマイザを変更):私はより良い答えを与える(あるいは、少なくともいくつかのアイデア)しようとするでしょう、今私はあなたの目標についていくらか理解していますが、コメントで示唆するように、TensorFlowでこれを行う確実な方法はないでしょう。

TFは一般的な計算フレームワークなので、モデル内にどのような重みと偏りのペアがあるか(またはそれがまったくニューラルネットワークであるかどうか)を判断する良い方法はありません。ここに私が考えることができる問題へのいくつかの可能なアプローチがあります:

  • テンソルに注釈を付ける。これはおそらくあなたがモデルを制御できないと言っているので実用的ではありませんが、重み/バイアスの関係を表すためにテンソルに余分な属性を追加するのが簡単な方法です。たとえば、W.bias = BB.weight = Wのようにしてから、_apply_denseのチェックhasattr(weight, "bias")と(この意味ではもっと良いデザインがあるかもしれません)のようにすることができます。
  • TensorFlowの上に構築されたフレームワークを調べると、モデル構造に関するより良い情報が得られます。たとえば、Kerasは、独自のoptimizer classes(TensorFlowまたはTheanoに基づく)を実装するレイヤーベースのフレームワークです。私はコードやその拡張性にあまり慣れていませんが、おそらくあなたが使用するツールが増えています。
  • ネットワークの構造をオプティマイザから直接検出します。これは非常に複雑ですが、理論的には可能です。オプティマイザに渡された損失テンソルから、ノードのすべてに達するようにモデルグラフに登ることができるはずです(テンソルの.opと演算の.inputsを取る)。変数のテンソル乗算や加算を検出し、他のすべてをスキップ(アクティベーション、損失計算など)してネットワークの構造を決定することができます。モデルが期待したものと一致しない場合(たとえば、乗算がない場合や、後で追加しない場合の乗算がある場合)、そのモデルに対してオプティマイザを使用できないことを示す例外を発生させることができます。

古い答えは、保管のために続けました。

私はあなたがしようとしていることについて100%明確ではないので、あなたの質問に本当に答えるかどうかはわかりません。

のは、あなたがサイズNの出力にサイズMの入力を変換する緻密層を持っているとしましょう。あなたが表示さ慣例に従えば、あなたは W N×M重み行列N -sizedバイアスベクトルBを持っていると思います。次に、入力ベクトルサイズMX(又はサイズの入力のバッチM×K)を、X + W B、として層によって処理されます(バッチの場合、追加は「ブロードキャスト」オペレーションである)。 TensorFlowで:

X = ... # Input batch of size M x K 
W = ... # Weights of size N x M 
B = ... # Biases of size N 

Y = tf.matmul(W, X) + B[:, tf.newaxis] # Output of size N x K 
# Activation... 

必要であれば、あなたは常に、基本的Wに新しい行としてBを追加し、* W単一の拡張重み行列で一緒にWBを置くことができますしたがって、W *は、(N +1)×Mとなります。あなたのサイズN + 1(または(と* Xになるだろうので、次に、あなただけの、(それはバッチかどうか、新しい行)定数1を含む入力ベクトルXに新しい要素を追加する必要がありますバッチについてはN +1)×K)。製品W *・x *は、前と同じ結果になります。TensorFlowでは

X = ... # Input batch of size M x K 
W_star = ... # Extended weights of size (N + 1) x M 
# You can still have a "view" of the original W and B if you need it 
W = W_star[:N] 
B = W_star[-1] 

X_star = tf.concat([X, tf.ones_like(X[:1])], axis=0) 
Y = tf.matmul(W_star, X_star) # Output of size N x K 
# Activation... 

ここで、重みと偏りの勾配と更新を一緒に計算できます。このアプローチの欠点は、正則化を適用する場合、偏りではなくマトリックスの重み部分にのみ注意して適用する必要があるということです。

+0

私の質問への回答を考えていただきありがとうございます。悲しいことに、あなたは正しいです。これは私の質問に対する実際の答えではありません。私が解決しようとする問題は、オプティマイザの観点からは、ネットワークの見た目を制御できないということです。 Y = tf.matmul(W、X)+ B与えられたapply_denseの呼び出しでWとBを使いたいと思っています。私の質問への答えはオプティマイザの視点から来るだけで、あなたの答えのように外部から来ることはできません。制限は、ネットワークではなくオプティマイザのみを変更できることです。 – Spen

+0

@Spenさて、基本オプティマイザクラスを見てきました。あなたが今やりたいことを見ています。しかし、私はまだ理解していません、モデルがどのように見えるかを制御できない場合、実際にバイアスが存在することをどのように保証できますか?それとも、モデルはニューラルネットワークですか? TFでは、バイアスとウィジットは単なる2つの独立した変数オブジェクトになります。モデルを制御できない場合は、どちらがウェイトとバイアスのペアであるかを知る方法がわかりません。 – jdehesa

+0

はい、この問題もあります。私はちょうどそれが対応する重みとバイアスがお互いに来ていることと、重み行列が2の次元とバイアス行列の次元が1であると考えていたと思いました。しかし、おそらくあなたは正しいですし、保存されていませんテンソルフローでこれを行う方法。他のフレームワークでは、完全なネットワークにアクセスできるのでこれが可能ですが、テンソルフローではこのアクセスは可能ではないようです。恩恵は払われていて、あなたが唯一援助しようとしていたので、私はそれをあなたに授与します。 – Spen

関連する問題