初めましてOOZAWAと申します。
Tensorflowが神経netの係数を学習する仕組みに関して複数の実装例を見ても理解できませんでした。
その中の典型的な実例として
<<落ちこぼれないためのTensorFlow Tutorialコード>>
https://qiita.com/TomokIshii/items/92a266b805d7eee02b1d
を挙げられます。
ネット係数の変数としての本体と更新場所を特定できないのです。
理論上
tf.train.GradientDescentOptimizer(0.001).minimize(loss)
の中でネット係数の学習(更新)を実施すべきと思いますが、
tf.trainは修飾子で、GradientDescentOptimizer(...)が外在的なメソッドに過ぎず、現在ネットの係数が含まれていないはず。
それでは何処でネット係数の更新が行われるのでしょうか。
NNのlayerの形成コードの典型な例*
python
1last_layer = self.input_x 2for weight,bias in zip(self.W_list,self.encoding_b_list): 3 hidden = tf.sigmoid(tf.matmul(last_layer,weight) + bias) 4 last_layer = hidden 5 6self.hidden = hidden 7
weightはテンポラリー変数で各layer共用で、self.W_listの一部分のコピーです。
for文で各layerの計算を行い、tf.sigmoid(...)に渡したのはself.W_listの断片的なコピー値しかないのです。
因みに、このweightは各layerが共用する変数で、訓練のforward過程において利用できますが、
back propagation段階ではもう消えているはずです。
なので、各layerのweight値に対する最適化のデータ実体が存在しないように感じます。
さて、tensorflowは何を根拠にして、NNの各layerのパラメータarrayを生成し、実体を確保したのでしょうか。これこそ自分にとって一番不思議な処です。
★上記のような各layer変数(array)の実体がなければ、樹状グラフの形成という話もないでしょう?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
tensorflowのコードからでは学習する仕組みの理解は難しいと思います。学習する一連の演算をまとめて関数として提供されているので、公式ドキュメントから理解するしかない上、断片的なので全体像の理解には不向きかと思います。
しっかりと裏側の仕組みを理解したいのであれば、「ゼロから作るDeepLearnig」を読破することをお薦めします。これをもとに学習の一連の演算を理解してからtensorflowのコードを眺めると裏側でどのような処理が行われているのかがイメージできるようになります。私自身、tensorflowの解説本から理解しようとしてモヤモヤしていましたが、先の本でベースを固めたおかげでかなりクリアになりました
投稿2019/01/07 04:20
総合スコア3376
0
ベストアンサー
どのタイミングでということであれば、記事中の以下の行を実行した際に重みが更新されます。
train_step.run({x: batch_xs, y_: batch_ys})
Back Propagation による重みの更新は TensorFlow の内部で行われるため、ライブラリを使う側が重みを更新するコードを記述する必要がありません。そのため、記事中にはそのようなコードはないです。
投稿2019/01/06 13:42
総合スコア21956
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/07 03:38
2019/01/09 12:54 編集
2019/01/07 06:17 編集
2019/01/07 09:28 編集
2019/01/07 09:56 編集
2019/01/09 13:38 編集
2019/01/09 13:58
2019/01/09 16:10 編集
2019/01/11 01:59 編集
2019/01/11 03:06 編集
2019/01/11 15:12
0
例えば掛け算と足し算の2項演算の樹構造を記憶するプログラムはこんな感じ。
Python
1class Var(): 2 def __init__(self, variable_name: str) -> None: 3 super().__init__() 4 self.variable_name = variable_name 5 6 def __str__(self): 7 return self.variable_name 8 9 def __mul__(self, other): 10 return BinOp(self, other, '×') 11 12 def __add__(self, other): 13 return BinOp(self, other, '+') 14 15 16class BinOp(): 17 def __init__(self, a, b, op) -> None: 18 super().__init__() 19 self.left = a 20 self.right = b 21 self.op = op 22 23 def __str__(self) -> str: 24 return ' '.join(map(str, ['(', self.left, self.op, self.right, ')'])) 25 26 def __mul__(self, other): 27 return BinOp(self, other, '×') 28 29 def __add__(self, other): 30 return BinOp(self, other, '+') 31 32 33expr = Var('w') * Var('x') + Var('y') * Var('z') 34print(expr) 35print() 36print(expr.left) # => expr が保持する左の項 37print(expr.op) # => expr が保持する演算子 38print(expr.right) # => expr が保持する右の項 39print() 40print(expr.left.left) # => expr が保持する左の項の左の項 41print(expr.left.op) # => expr が保持する左の項の演算子 42print(expr.left.right) # => expr が保持する左の項の右の項
実行結果
plain
1( ( w × x ) + ( y × z ) ) 2 3( w × x ) 4+ 5( y × z ) 6 7w 8× 9x
Node('w') * Node('x') + Node('y') * Node('z')
というコードで計算をしているわけじゃないことに注目。
minimize(loss)
に渡るloss
は計算結果が格納されているのではなくて、このような、その値をどうやって計算するかという構造を含んでいるオブジェクト。
投稿2019/01/07 12:39
編集2019/01/07 12:41総合スコア11038
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/07 09:26
2019/01/10 22:39