jarinosuke blog

about software engineering, mostly about iOS

swift-models の MNIST.swift を読む

swift-models

TensorFlow for Swift で実際に使うことができる機械学習のモデルを集めたレポジトリ

https://github.com/tensorflow/swift-models

2018/4/30 現在だと MNIST だけがある

MNIST についての説明は省略するが、MNIST 自体についてのチュートリアルはこれがおすすめ

https://www.tensorflow.org/versions/r1.1/get_started/mnist/beginners

swift-models の実際の実行方法は前に書いたブログを参考にしてほしい

ちなみに Xcode に結合された API doc はまだ見つからなかったので、以下のページを頻繁に使った

https://www.tensorflow.org/api_docs/swift/

MNIST.swift を読む

MNIST.swift はコマンドラインから実行されることを前提としている

内容はとても単純で main という関数を実行しているだけなので、main の1行目から読み進めていけばOK

1.教師データの準備

https://github.com/tensorflow/swift-models/blob/master/MNIST/MNIST.swift#L38-L53

これらの行ではファイルから実際の画像データとそれに対するラベルをロードして、Tensor オブジェクトにしている

readMnist 内で imageDatalabelData をロードする際に、それぞれ dropFirst しているのは何故なんだろう…

ロードされたデータは以下のような2次元配列となっている

ラベル: 1x60000 画像: 784x60000

要するに60000個の0-9でラベル付けされた画像がある

またロードされたラベルデータは0-9の値を取るので、one-hot Tensor に変換している

https://www.tensorflow.org/api_docs/swift/Structs/Tensor#/s:10TensorFlow0A0VAAs7NumericRzrlEACyxGACys5Int32VG15oneHotAtIndices_AG5depthx7onValuex03offK0Si4axistcfc

簡単にいうとこんな感じ

変換前: [6, 7, 3…] 変換後: [ [0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0] ... ]

2.ハイパーパラメータと学習パラメータの準備

https://github.com/tensorflow/swift-models/blob/master/MNIST/MNIST.swift#L55-L64

ハイパーパラメータには以下の3つが定義されている

  • イテレーションの回数
  • 学習率
  • 損失

また学習するパラメータは以下のように2段階に設定されている

  • 1層目
    • 重み w1
    • バイアス b1
  • 2層目
    • 重み w2
    • バイアス b2

3.学習ループ

ニューラルネットなので以下のようなループで進む

  • 3-1. 前方伝播 forward propagationで推測
  • 3-2. 誤差逆伝播 back propagation で誤差計測
  • 3-3. 最急降下法 gradient descent でパラメータ更新
  • 3-4. 3-1に戻る

3-1.前方伝播 forward propagationで推測

https://github.com/tensorflow/swift-models/blob/master/MNIST/MNIST.swift#L71-L75

Tensor のドット積にオペレータとして を使用している、単純な定数倍とは明確に区別したいためだろうか…

https://www.tensorflow.org/api_docs/swift/Protocols/TensorProtocol#/s:10TensorFlow0A8ProtocolPAAs7Numeric6ScalarRpzrlE003mehoixx_xtFZ

また sigmoid は標準関数としてサポートされている。他にも ReLU や soft-max などもされている

https://www.tensorflow.org/api_docs/swift/Functions#/s:10TensorFlow7sigmoidxxAA0A8ProtocolRzs19BinaryFloatingPoint6ScalarRpzlF

3-2.誤差逆伝播 back propagation で誤差計測

https://github.com/tensorflow/swift-models/blob/master/MNIST/MNIST.swift#L77-L83

ここでは Tensor の操作がいくつか出てくる

transpose

これは転置行列

https://www.tensorflow.org/api_docs/swift/Structs/Tensor2D#/s:10TensorFlow8Tensor2DVAAs7NumericRzrlE10transposedACyxGyF

withPermutations というのは与えられた順列を元に転置を作るぽい。デフォルトが none なので、デフォルトであれば普通の転置行列になるはず。詳細は以下

https://www.tensorflow.org/api_docs/python/tf/transpose

sum

これは任意の axis に sum をしてその axis を潰す ここでは1を指定しているので列方向に潰しているぽい

https://www.tensorflow.org/api_docs/swift/Structs/Tensor#/s:10TensorFlow0A0VAAs7NumericRzrlE3sumACyxGs5Int32V13squeezingAxesd_tF

3-3.最急降下法 gradient descent でパラメータ更新

https://github.com/tensorflow/swift-models/blob/master/MNIST/MNIST.swift#L85-L92

計算された損失に学習率をかけてパラメータを更新する

ここでの * は単純にスカラー倍を意味している

https://www.tensorflow.org/api_docs/swift/Structs/Tensor#/s:10TensorFlow0A0VAAs7NumericRzrlE1moiACyxGAF_xtFZ

まとめ

Swift API doc をみるのは面白い

https://www.tensorflow.org/api_docs/swift/

以下の stdlib/public も合わせて読む

https://github.com/google/swift/tree/tensorflow/stdlib/public/TensorFlow