2019年04月17日

超入門 Swift for TensorFlow

エモトです.GWは引きこもろうと思ってます.

深層学習のコードを書くときは,Python + TensorFlow を使っています.Python は書きやすい言語だと思いますが,コード量が増えてくると,もっとモダンな言語で描きたい,コンパイラが欲しいと思います.私が完璧にPythonを理解してないのもありますが,ちょっと他の言語に浮気しました.

Swift For TensorFlow

Swift for TensorFlow は,Python 向けに開発された数値計算ライブラリ TensorFlow を Swift で利用することができます.一般的に多いラッパーではなく,Swift コンパイラを拡張したものになります.また,Swift は Python を使用することができるので,Python の豊富な数値計算ライブラリを使用できます.

インストール

公式サイトの Install Swift for TensorFlow に従えばインストールできます.なお,最近Swift 5がリリースされましたが,最新版の Xcode では上手くできず,Xcode 10.1 (Swift 4.2) で確認しました.

Google Colab を使おう

ローカル環境でインストール可能ですが,普段 iOS アプリ開発を行っていると,標準と拡張のコンパイラの管理が面倒になります.一先ずは,Google Colab を使用した方がおすすめです(ただし,補完などの補助機能がXcodeより貧弱なのが辛い).

これも公式の Using Swift for TensorFlow にて,Swiftが実行可能な blank Swift notebook が公開されているので,それを自身のドライブにコピーすれば,すぐに使えます.

以降のソースコードは,Colab上で動作確認したものです.

SwiftでPythonを使う

Swift for TensorFlow を使う前に,Swift 自体の機能で Python を使ってみました.Python の豊富な数値計算ライブラリを使用できます.SwiftでNumPyが動くのは,何か不思議な感じです.
import Python
PythonLibrary.useVersion(3, 6)

let np = Python.import("numpy")

let a = np.array([[1, 0], [0, 1]])
let b = np.array([[2], [3]])
let c = np.matmul(a, b)

Swift For TensorFlow を使ってみた

Swift For TensorFlow を使って,XOR を簡単な NN で学習しました.Keras もしくは TensorFlow2 を触っていれば,あまり違和感ない感じでした.
import Foundation
import TensorFlow

struct XOR: Layer {
  
  var layer1: Dense<Float>
  var layer2: Dense<Float>
  
  init(hiddenSize:Int = 2){
    self.layer1 = Dense(inputSize: 2,
                        outputSize: hiddenSize,
                        activation: sigmoid)
    self.layer2 = Dense(inputSize: hiddenSize,
                        outputSize: 1, 
                        activation: sigmoid)
  }
  
  @differentiable
  func applied(to input: Tensor<Float>, in context: Context) -> Tensor<Float> {
    return input.sequenced(in: context, through: layer1, layer2)
    }
}

let x: Tensor<Float> = [[0, 0], [0, 1], [1, 0], [1, 1]]
let y: Tensor<Float> = [[0], [1], [1], [0]]

var model = XOR()
let optimizer = SGD<XOR, Float>(learningRate: 0.1)
let context = Context(learningPhase: .training)

for _ in 1...5000 {
  let dmodel = model.gradient { m -> Tensor<Float> in
    let t = m.applied(to: x, in: context)
    let loss = sigmoidCrossEntropy(logits: t, labels: y)
    return loss
  }
  optimizer.update(&model.allDifferentiableVariables, along: dmodel)
}

let inference = round(model.inferring(from: x))
print(inference)

パフォーマンスは?

上記コードを Google Colab (CPU) で計算したところ,約13秒程度で終わりました.比較として,Python + TensorFlow2 (Keras) でもほぼ同様なモデルと学習方法で XOR を計算したところ,約6秒でした.コンパイラ言語であるSwiftの方が早いかと思いましたが,今回はPython版の方が早かったです.理由は分かりませんが,複雑な反復処理を行っていない,Swiftは複数のライブラリの読み込みがネックになった?のかなと.ColabのSwiftコンパイル時の最適化オプションなどは未調査です.

まとめ

Swift For TensorFlowを使用して,Swiftでも機械学習のコードを実装できました.まだまだPython版の方が良いかなと思いました.TensorFlow自体の更新頻度が高いうえに,Swiftもアップデートの頻度が高いので,安定性があるかは怪しいところです.また,入門エントリーが公式ぐらいしかないので,ちょっと調べ物は大変です.とはいえ,慣れたSwiftを使うことができる,実行する前にコンパイラが動くというメリットは感じました.


posted by Seesaa京都スタッフ at 16:00| Comment(0) | iOS | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

×

この広告は180日以上新しい記事の投稿がないブログに表示されております。