ニューラルネットワークでもやもやしたアニメーションを作る


Unity Advent Calendar 2019 その3の12/8の記事です。
急いで用意した雑な文章なので雰囲気だけ感じてください!

deepではないニューラルネットで次のような関数を作ります。
$f\left(u,v,p,q\right)=\left(R,G,B,A\right)$
$u,v$: テクスチャマッピングのUV座標
$p,q$: 時間で動く変数。例えば$t$を時間として$p=\sin\left(5t\right),q=\cos\left(7t\right)$など。

この関数をニューラルネットとして、フラグメントシェーダ内に適当に実装します:

fixed4 frag (v2f i) : SV_Target {
  half t = _Time.y * 0.2;
  half p = sin(t * 5);
  half q = cos(t * 7);
  half4 input = half4(1 - i.uv.y, i.uv.x, p, q);
  half4x4 w1 = ...; half4 b1 = ...;
  half4x4 w2 = ...; half4 b2 = ...;
  ...
  half4 out0 = tanh(mul(input, w0) + b0);
  half4 out1 = tanh(mul(input, w1) + b1);
  half4 out2 = mul(out0, w2) + b2;
  half4 out3 = mul(out1, w3) + b3;
  half4 out4 = out2 + out3;
  fixed4 output = tanh(out4) * 0.5 + 0.5;
  return output;
}

適当にパラメータを調整すると、もやもや動くアニメーションになります。

これだけだとあまり綺麗ではないので、適当な学習セットを用意して学習します。例えば以下のようなイメージで学習セットを用意します。どうせ大まかな色くらいしか学習できないので入力は何でも良いです。
$f\left(u,v,1,1\right)=$ $f\left(u,v,1,-1\right)=$
$f\left(u,v,-1,-1\right)=$ $f\left(u,v,-1,1\right)=$

これをTensorFlowなどを使って適当に学習させると、
$f\left(u,v,1,1\right)=$ $f\left(u,v,1,-1\right)=$
$f\left(u,v,-1,-1\right)=$ $f\left(u,v,-1,1\right)=$

のようになります。アニメーションさせると、

(早送りで分かりづらいですが、滑らかな感じのアニメーションです)

という感じになります。使いみちがあるのかどうかはわかりません。$p$ と $q$ は時間以外に例えばマウスの位置等を入れてみるのも良いかもしれません。モデルや学習方法ももう少し工夫したほうが良いと思います。やっつけ仕事になってしまいましたが、Unity Advent Calendar 2019 その3の12/8の記事でした。