Monthly Hacker's Blog

プログラミングや機械学習の記事を中心に書きます。

NNablaのImage Augmentationを試してみた

NNablaがリリースされて1ヶ月以上経ちました。研究室の先輩が開発のコアメンバーということもあり、リリース直後から注目していたのですが、しばらくpython2系のみ対応ということで手を出せずにいました。

先日、件の先輩に「3系に対応したのでぜひ使ってくれ、image augmentationがイチオシだ」と教えていただいたので、早速試してみました。

github.com

NNablaのimage augmentationの特徴

GPUで計算を高速化できることが特徴です。前処理をnumpyなどを用いてCPU上で計算することもできますが、NNablaではレイヤーの一種として各種augmentationを用意しているので、GPUが使えるときはGPU上で計算してくれます。

augmentation一覧

今回はNNablaにある数字のサンプル(MNISTを8x8に縮小したもの)を使っていきます。
f:id:d-higurashi:20170803204414p:plain

Random Crop

f:id:d-higurashi:20170803204646p:plain

  • x(N-D array)
    • 入力
  • shape(tuple of int)
    • 切抜き後の画像サイズ
  • base_axis(int)
    • 説明なし
  • seed(int)
    • 乱数のシード値
  • n_outputs
    • 説明なし
  • output
    • 説明なし
cropped = F.random_crop(x, (6, 6))

画像を切り抜くRandom Cropです。この関数に限らず、base_axisという引数があります。ドキュメントに説明がありませんが、デフォルトの値が1なので、画像で言うとチャンネルを表すaxisを指定するのかと思います。

同様にn_outputsとoutputも説明がありません。こちらは意味の検討もつかないので、ドキュメントが更新されるのを待ちましょう。

Random Flip

f:id:d-higurashi:20170803204713p:plain

  • x(N-D array)
    • 入力
  • axes(repeated int64)
    • 反転させる軸
  • base_axis(int)
    • 説明なし
  • seed(int)
    • 乱数のシード値
  • n_outputs
    • 説明なし
  • output
    • 説明なし
flipped = F.random_flip(x)

画像の左右上下を反転させるRandom Flipです。チャンネル軸でも反転できると思いますが、画像認識では使うことはないでしょう。

Random Shift

f:id:d-higurashi:20170803204728p:plain

  • x(N-D array)
    • 入力
  • shifts(repeated int64)
    • 縦、横方向の移動させる最大幅
  • border_mode(string)
    • 値が存在しないピクセルの補間方法
  • base_axis(int)
    • 説明なし
  • seed(int)
    • 乱数のシード値
  • n_outputs
    • 説明なし
  • output
    • 説明なし
shifted = F.random_shift(x, (2, 2))

画像を上下左右に移動させるRandom Shiftです。注意すべき引数はborder_modeです。例えば、画像を右に3だけ移動させると、左端の3列は値が存在しません。そういったピクセルにどのような値を入れるかを指定する引数です。nearestとreflectが選べます。

Image Augmentation

f:id:d-higurashi:20170803204742p:plain

  • x(N-D array)
    • 入力
  • shape(tuple of int)
    • 切抜き後の画像サイズ
  • pad(tuple of int)
    • パディングする
  • min_scale(float)
    • 拡大縮小時の倍率の最小値
  • max_scale(float)
    • 拡大縮小時の倍率の最大値
  • angle(float)
    • 回転時の角度の最大幅
  • aspect_ratio(float)
    • ある辺の長さを1としたときのもう1辺の長さの最大値
  • distortion
    • 歪みの最大値
  • flip_lr(bool)
    • 左右反転するかどうか
  • flip_ud(bool)
    • 上下反転するかどうか
  • brightness(float)
    • 輝度調整の際に足す値の最大幅
  • brightness_each(bool)
    • 全チャンネルで同じ値で輝度調整するかどうか
  • contrast(float)
    • コントラスト調整の際に乗/除算する値の最大値
  • contrast_center(float)
    • 輝度の中心とする値
  • contrast_each(bool)
    • 全チャンネルで同じ値でコントラスト調整するかどうか
  • noise(float)
    • ノイズとして加える正規分布の標準偏差
  • seed(int)
    • 乱数のシード値
  • n_outputs
    • 説明なし
  • output
    • 説明なし
augmented = F.image_augmentation(x, (1, 7, 7),
                                 min_scale=0.9, max_scale=1.1,
                                 angle=0.3, aspect_ratio=1.3, distortion=0.2,
                                 flip_lr=True, brightness=1,
                                 brightness_each=True,
                                 contrast=1.1, contrast_center=1)

様々なaugmentを一気にできるImage Augmentationです。ただ、shiftやborder_modeはないのか、という点が疑問です。shiftはrandom_shiftとの併用でいいですが、border_modeなしで回転で生じる空白はどのように補間しているのでしょうか。おそらく0埋めだと思います。

distortionですが、勉強不足で歪みを表すパラメータが何か分からないので、ご存知の方はコメントやTwitterで教えてください。

最後に

NNablaはdata augmentationの部分で他のフレームワークと差をつけていくつもりなのかもしれません。特に他のフレームワークであまり対応していないFFTやCQTがあると音声研究で重宝しそうです。音楽のイメージの強いSONYですので、ぜひ実装して欲しいところです。