2018/12/13
個人開発 #2 Advent Calendar 2018 の13日目の記事です。
作曲におけるコード(和音)進行生成のためのツール Chord Worker を2018年12月13日に公開しました。
音楽アプリ Chord Worker のディープラーニング版を公開しました。ニューラルネットワークがコード進行をサジェストしてくれます。MIDI 出力も付けたので DAW でも使えるはず…!https://t.co/a7TGyVOFUf #chordworker pic.twitter.com/bDNc6Vd2VL
— tanikawa (@diatonic_codes) 2018年12月13日
主な機能・特徴は次の通りです。
詳細な仕組みはまとめる時間がなかったので省略しますが、気になる方は以前に書いた記事を読むとなんとなく把握できるかと思います。
このアプリではコード進行をリアルタイムにサジェストする必要があるため、サーバ側で推論を行うのは、ネットワークのラグなどの理由から現実的ではありません。そこで、Web ブラウザ側でニューラルネットの推論ができるライブラリを探していたところ、ちょうど Microsoft から ONNX.js というライブラリが公開されたので、これを使うことにしました。
ONNX (Open Neural Network Exchange) は、ニューラルネットのモデルを表現するフォーマットです。多くの有名なディープラーニングフレームワークが、この ONNX フォーマットへの変換をサポートしています。ONNX.js は、ONNX フォーマットのモデルを JavaScript で動作させるためのライブラリになります。
モデルの学習には Chainer を使いました。Chainer の場合、ONNX-Chainer を使えば、学習済みモデルを ONNX に変換できます。
ただ、過去の記事「ディープラーニングによるコード進行の予測」にてコード進行の予測モデルを組んだ際には、EmbedID -> LSTM -> Linear
という構成を採用したのですが、ONNX.js では EmdebID と LSTM をサポートしておらず、そのままではモデルを移植できません。そこで、本アプリでは次のような代替を考えました。
word2vec を使ってコード進行を学習し、コードの分散表現を獲得しました。学習方法は、通常の単語の分散表現を学習する手順と同様で、コード進行を半角区切りでテキスト化しておき、gensim などのツールで学習するだけです。
Web ブラウザでは、学習された各コードの分散表現を JavaScript の Object の形で保持しておき、これを EmbedID の代わりに使います。
データの例:
// どの調にも対応できるように、コード名は度数表記で格納
const chord2vec = {
'ⅠM7': [-0.3557768762111664, -0.0004484227974899113, ..., 0.31235525012016296],
'Ⅰm7': [-0.0884508565068245, -0.017984995618462563, ..., -0.07706872373819351],
...
};
LSTM の良いところは可変長を扱える点にありますが、今回のアプリで長い系列を扱うメリットをあまり感じなかったというのと、予測精度をシビアに見るつもりもないので、固定で8ステップ分のコード(の分散表現)を連結 (concat) して、Linear 層に渡す形式にしました。
入力が8ステップに満たない場合は、<PAD>
で埋めます。
8ステップというのは個人的な主観で決めたので、もっと良いステップ数があるかもしれません。
最終的にモデルの構成は次の図のような感じになりました。
ユーザビリティを考慮すると、モデルのダウンロード時間と推論処理の時間をできるだけ抑える必要があるので、小規模なモデルになっています。上記の構成で、モデルのファイルサイズは 2.2 MB、推論にかかる時間は MacBook Air 2015 の 11インチモデルの CPU でも 20〜40ms 程度だったので、とりあえず OK と判断しました。
ONNX.js が出てきて、Web ブラウザでディープラーニングのモデルを活用する敷居が低くなった印象ですが、まだまだ使えるオペレータが限られているので、今後のアップデートに期待したいところです。
Advent Calendar に間に合わせるために公開したので、いろいろと機能がひどいです1が、使ってみて何かフィードバックいただけると幸いです。
Windows だとコードを鳴らすと音割れするかもしれません。早急にボリューム機能を付けます。 ↩