皆さんこんにちは
お元気ですか。
Twitter上で突然賑わった、Autogradについて
書いてみることにします。
Autogradとは
Autogradについての説明
github.com
Autogradはnumpyらしく書くことができ、その記載した式を微分してくれるライブラリです。(in Python)
現状、Pythonとtorch(lua)にて実装があるようです。
Theanoとの違いはシンボルを定義せず、数値計算した内容を直接渡すことができます。といったところでしょうか。正直自動微分は新しくないものです。(Theanoがありますので)
悲しいことにPythonのAutogradは現状、GPU演算を行うことができません。
testの中にGPU関係の内容はあるようですが、
一応featureにGPU operationsのサポートとして掲載されていますね。
Install
sudo pip install autograd
How to use
次はこの便利ツールの使い方を見てみます。
Tutrialを参考に、autogradを使ってみましょう。
基本的な文法はnumpyと同じです。(一部使えない文法はあります。)
numpyでは import numpy as npとかでimportしますが、
autogradでは少々異なります。簡単な内容について試してみます。
今回はx ** 2を微分してみます。
Easy Example
Source Code
import autograd.numpy as np from autograd import grad def x_pow(x): return np.power(x,2) grad_pow = grad(x_pow) print grad_pow(2) print (np.power(2.0001,2) - np.power(1.9999,2)) / 0.0002
標準出力
4.0 4.0
まず、インポートするのは以下が必要になります。
numpy を wrappingした内容、もうひとつは微分用のメソッドです。
import autograd.numpy as np from autograd import grad
次に必要なのは、微分する関数です。gradの引数には関数を与えるので以下の通りに実装すれば問題ありません。
因みにもう一度、gradをすると、2次微分を実行することができます。
grad(x_pow)
Neural Network Example
こちらは実例を見てみましょう。ソースコード全体は以下を見ていただくとして
注目するべきコードを抽出します。
autograd/neural_net.py at master · HIPS/autograd · GitHub
モデルコード
def make_nn_funs(layer_sizes, L2_reg): shapes = zip(layer_sizes[:-1], layer_sizes[1:]) N = sum((m+1)*n for m, n in shapes) def unpack_layers(W_vect): for m, n in shapes: yield W_vect[:m*n].reshape((m,n)), W_vect[m*n:m*n+n] W_vect = W_vect[(m+1)*n:] def predictions(W_vect, inputs): for W, b in unpack_layers(W_vect): outputs = np.dot(inputs, W) + b inputs = np.tanh(outputs) return outputs - logsumexp(outputs, axis=1, keepdims=True) def loss(W_vect, X, T): log_prior = -L2_reg * np.dot(W_vect, W_vect) log_lik = np.sum(predictions(W_vect, X) * T) return - log_prior - log_lik def frac_err(W_vect, X, T): return np.mean(np.argmax(T, axis=1) != np.argmax(predictions(W_vect, X), axis=1)) return N, predictions, loss, frac_err
学習部の抽出
loss_grad = grad(loss_fun) for epoch in range(num_epochs): print_perf(epoch, W) for idxs in batch_idxs: grad_W = loss_grad(W, train_images[idxs], train_labels[idxs]) cur_dir = momentum * cur_dir + (1.0 - momentum) * grad_W W -= learning_rate * cur_dir
モデル部分の関数(make_nn_funs)の部分で重要なのは、loss変数です。
このloss変数を定義し、微分するとWを更新する値を決定することができます。
つまり、Autogradはloss定義して微分して更新方法を決定することで、
あらゆるモデルを構築することができるライブラリです。科学技術演算のままできるのが良い。
感想
- 現状、GPUが使えないので、簡単な計算テストには向いているでしょう。
- 簡単にインストール、構築ができるので実験向き?
- 自動微分が新しいわけでは多分ない。
- Tutrialを読む限りnumpyの全てをサポートしているわけではないので、書き方に注意しましょう。