【 SONY発 】プログラム実行中 に 動的 に ニューラル・ネットワーク を 構築できる 深層ニューラルネットワーク構築ライブラリ Neural Network Libraries

  • 12
    いいね
  • 0
    コメント

SONY が、深層ニューラルネットワーク構築用の Pythonライブラリ を 無償公開 しました。
(C++ライブラリもあり)

※ 但し、Python 2系 のようです。

日本企業大手 が ついに、AI開発のプラットフォーム市場 に 乗り出しました。

プログラム実行中 に、ドロップアウト率 や 中間層の数 など のパラメータ を 動的 に 受け取って、プログラム内部 で ネットワークを構築する 動的グラフ(dynamic graph)を 定義 すること も できるようです。

dynamic graph に ついて は、本Qiita記事で、解説しています)

公式Webページ では、X'periaスマホ や SONY不動産 など、
SONYグループの商用サービス に、実際 に このライブラリ が 利用されている 事例 が 紹介されています。

インタフェース は、以下の例を見てわかるよう に、TensorFlowライク な、プログラマには馴染みやすい コード・スタイル です。

( コード例 )

NNabla by Examples

This tutorial demonstrates how you can write a script to train a neural network by using a simple hand digits classification task.

  • 部品 となる 定義済み関数 の インポート
Tutorial
import nnabla as nn

import nnabla.functions as F
import nnabla.parametric_functions as PF
import nnabla.solvers as S
from nnabla.monitor import tile_images
  • データセット の インポート
Tutorial
import numpy as np
import matplotlib.pyplot as plt
import tiny_digits

( データを可視化する場合、matplotlibもインポート )

Tutorial
%matplotlib inline

np.random.seed(0)
imshow_opt = dict(cmap='gray', interpolation='nearest')

ロジスティック回帰の例

  • 0〜9の数字 が 用意された MNISTデータセット を 使う

The tiny_digits module is located under this folder.

It provides some utilities for loading a handwritten-digit classification dataset (MNIST) available in scikit-learn.

Tutorial
digits = tiny_digits.load_digits(n_class=10)
tiny_digits.plot_stats(digits)

data = tiny_digits.data_iterator_tiny_digits(digits, batch_size=64, shuffle=True)

A minibatch is as follows.
img and label are in numpy.ndarray.

Tutorial
img, label = data.next()
plt.imshow(tile_images(img), **imshow_opt)
print "labels:", label.reshape(8, 8)
print "Label shape:", label.shape
  • 順方向の演算定義
Tutorial
# Forward pass
x = nn.Variable(img.shape)  # Define an image variable
with nn.parameter_scope("affine1"):
    y = PF.affine(x, 10)  # Output is 10 class
  • コスト関数(損失関数)の定義
Tutorial
# Building a loss graph
t = nn.Variable(label.shape)  # Define an target variable
loss = F.mean(F.softmax_cross_entropy(y, t))  # Softmax Xentropy fits multi-class classification problems

print "Printing shapes of variables"
print x.shape
print y.shape
print t.shape
print loss.shape  # empty tuple means scalar
  • 入力データの変数への格納
Tutorial
# Set data
x.d = img
t.d = label
  • 順方向演算の実行
Tutorial
# Execute a forward pass
loss.forward()
# Showing results
print "Prediction score of 0-th image:", y.d[0]
print "Loss:", loss.d
Tutorial
for param in nn.get_parameters().values():
   param.grad.zero()
  • 逆方向(誤差逆伝播)演算の実行
Tutorial
# Compute backward
loss.backward()
# Showing gradients.
for name, param in nn.get_parameters().items():
    print name, param.shape, param.g.flat[:20]  # Showing first 20.
  • 誤差修正アルゴリズムの設定 ( 以下 では、SGD(確率的勾配降下法)を 選択している )
Tutorial
# Create a solver (gradient-based optimizer)
learning_rate = 1e-3
solver = S.Sgd(learning_rate)
solver.set_parameters(nn.get_parameters())  # Set parameter variables to be updated.
  • 学習を実行(1ステップ分)
Tutorial
# One step of training
x.d, t.d = data.next()
loss.forward()
solver.zero_grad()  # Initialize gradients of all parameters to zero.
loss.backward()
solver.weight_decay(1e-5)  # Applying weight decay as an regularization
solver.update()
print loss.d

Next block iterates optimization steps, and shows the loss decreases.

  • 1,000個の学習用データ を、L回帰モデル に 与えて 学習させる。
  • データ を 100個与えるたびに、その時点の損失関数の値 を Terminal に 出力させる。
Tutorial
for i in range(1000):
    x.d, t.d = data.next()
    loss.forward()
    solver.zero_grad()  # Initialize gradients of all parameters to zero.
    loss.backward()
    solver.weight_decay(1e-5)  # Applying weight decay as an regularization
    solver.update()
    if i % 100 == 0:  # Print for each 10 iterations
        print i, loss.d
  • 学習済みのL回帰モデル に、学習時に与えなかった新しいデータ を 入力する。
  • L回帰モデルの出力値(1次元ベクトル) を、8行8列の行列形式 に 変換後、予測結果 を 出力する。

Show prediction

The following code displays training results.

Tutorial
x.d, t.d = data.next()  # Here we predict images from training set although it's useless.
y.forward()  # You can execute a sub graph.
plt.imshow(tile_images(x.d), **imshow_opt)
print "prediction:"
print y.d.argmax(axis=1).reshape(8, 8)  # Taking a class index based on prediction score.

( 予測結果の出力例 )

結果の例
prediction:
[[5 0 1 9 0 1 3 3]
 [2 4 1 7 4 5 6 5]
 [7 7 9 7 9 0 7 3]
 [5 3 7 6 6 8 0 9]
 [0 1 3 5 5 5 4 9]
 [1 0 0 8 5 1 8 8]
 [7 5 0 7 6 9 0 0]
 [0 6 2 6 4 4 2 6]]

先行ライブラリ に 対する 強み

プログラム実行中 に、ドロップアウト率 や 中間層の数 など のパラメータ を 動的 に 受け取って、プログラム内部 で ネットワークを構築する 動的グラフ(dynamic graph)を 定義 すること も できるようです。

動的なグラフ の 記述 が 可能

Dynamic Computation Graph Support

Static computation graph which has been used in general is a method to build a computation graph before executing the graph.

On the other hand, dynamic computation graph enables flexible runtime network construction.

動的グラフ と 静的 static グラフ、どちらも記述可能

The Library can use both paradigms of static and dynamic graph.

(例) 動的グラフの定義コード

動的グラフの定義コード(例)
x.d = <set data>
t.d = <set label>
drop_depth = np.random.rand(<num_stochastic_layers>) < <layer_drop_ratio>
with nn.auto_forward():
   h = F.relu(PF.convolution(x, <hidden_size>, (3, 3), pad=(1, 1), name='conv0'))
   for i in range(<num_stochastic_layers>):
       if drop_depth[i]:
           continue  # Stochastically drop a layer
       h2 = F.relu(PF.convolution(x, <hidden_size>, (3, 3), pad=(1, 1), 
                                  name='conv%d' % (i + 1)))
       h = F.add2(h, h2)
   y = PF.affine(h, <target_size>, name='classification')
   loss = F.mean(F.softmax_cross_entropy(y, t))
# Backward computation (can also be done in dynamically executed graph)
loss.backward()

コード中の以下で、ネットワークのパラメータ を 動的 に 受け取っている。

<num_stochastic_layers>
<layer_drop_ratio>
<hidden_size>
<target_size>

また、以下のコード を 与えることも 可能です。

NNabla allows you to define static and dynamic neural networks. Static neural networks have a fixed layer architecture, i.e., a static computation graph. In contrast, dynamic neural networks use a dynamic computation graph, e.g., randomly dropping layers for each minibatch.

This tutorial compares both computation graphs.

( 中略 )

Dynamic computation graph

Now, we will use a dynamic computation graph, where the neural network is setup each time we want to do a forward/backward pass through it.

This allows us to, e.g., randomly dropout layers or to have network architectures that depend on input data.

In this example, we will use for simplicity the same neural network structure and only dynamically create it.

For example, adding a if np.random.rand() > dropout_probability: into cnn() allows to dropout layers.

First, we setup the solver and the data iterator for the training:

nn.clear_parameters()
solver = S.Adam(alpha=1e-3)
solver.set_parameters(nn.get_parameters())

loss = []
def epoch_end_callback(epoch):
   global loss
   print "[", epoch, np.mean(loss), itr, "]",
   loss = []
data = data_iterator_tiny_digits(digits, batch_size=16, shuffle=True)
data.register_epoch_end_callback(epoch_end_callback)

なお、affineという関数 が 定義されている。

関数 が 持つ 言葉の意味を、参考まで に 抑えて おきたい と 思います。

( 参考 )「アフィン変換」とは?

幾何学の分野で、ある図形を回転させたり引き延ばしたりする変換をアフィン変換と呼ぶ。

もう少しきちんと説明すると、「アフィン変換とは平行移動と線形変換を組み合わせた変換」のこと。

多層ニューラルネットワーク における 「アフィン変換」

Affineレイヤ

ニューラルネットワークの順伝播で行う行列の内積は、幾何学の分野では「アフィン変換」と呼はれます。

そのため、ここでは、アフィン変換を行う処理を 「Affine レイヤ」という名前で実装していきます。参考書籍より引用

計算式

アフィン変換(線形変換+平行移動)して活性化関数に食わせる。

ニューラルネットワークで使用される層には、多種多様なものがあります。
具体例として、 $tanh$層について述べます。

$tanh$層
$tanh(Wx+b)$ は以下により構成されます。

1.「重み」行列 $WW$ による線形変換
2. ベクトル $bb$ による並進
3. $tanh$ の各点適用

次のように、連続的な変換としてこれを視覚化することができます:

アフィン変換につづく単調活性化関数の各点適用により構成される、多くの他の標準的な層についても、ストーリーは同様です。


報道記事

2017年6月27日 付で、日本経済新聞(朝刊1面)を始めて、各報道機関・Webニュースサイトが 一斉 に 報じています。


公式Webページ

SONY公式ウェブページ での 略称 を 見る限り、Neural Network Libraries は、NNABLA と 呼ぶようです。

Neural Network Libraries allows you to define a computation graph (neural network) intuitively with less amount of code.

Dynamic computation graph support

Dynamic computation graph used enables flexible runtime network construction.

The Library can use both paradigms of static and dynamic graph.


GitHubリポジトリ

https://github.com/sony/nnabla

NNabla - Neural Network Libraries NNabla is a deep learning framework that is intended to be used for research, development and production.

We aim it running everywhere like desktop PCs, HPC clusters, embedded devices and production servers. - https://nnabla.org/


使い方マニュアル

http://nnabla.readthedocs.io/en/latest/

NNabla

NNabla is deep learning framework that is intended to be used for research, development, and production.

We aim it running everywhere like desktop PCs, HPC clusters, embedded devices and production servers.

This document describes how to use the Python API and C++ API, the contribution guide for developers, and the license term of this software.

The Python API is more suitable for fast prototyping and experimentation of deep learning systems, while the C++ API is for deploying inference or training algorithms into embedded systems and servers (The documentation is not available so far. We will make it available soon).

The framework is designed modularity and extensibility in mind.

Community contributors can add a new operator or optimizer module of neural networks, and a specialized implementation of neural network modules for a specific target device as an extension.

  • Python Package
  • Python Package Installation
  • Python API Tutorial
  • Python API Examples
  • Python API Reference
  • C++ API