Signateの音声分類コンペに参加しました

機械学習のオンラインコンペを開催しているSignateというサービスの、音声分類のコンテストに参加しました。

そのときに作成した分類器の仕組み、どういう処理が性能向上に効果的だったかを軽くまとめます。

内容


会話の音声を男・女×子供・青年・老人の6分類して性能を競うという内容でした。

評価指標はMacro-F1という指標です。今回は数学的な話をしないので省略します。

ちなみに、結果は100位/170 でした。機械学習専門でやってる人はすごいな~というのが正直な感想です。

音声分類は全くやったことがなかったので初めてにしては頑張ったな〜と。

分類器の構成


音声データを120×180程度のスペクトログラムに変換し、その変換したデータをCNNに学習させるという方式です。最終的な分類器のイメージは以下の通りです。

性能向上のために工夫したこと

CNNの層・フィルタ数を増やす


最初は、そもそもスペクトログラムという特徴量が有効なのかを確認するために、Convolution層とPooling層を3つずつ組み合わせたシンプルなモデル構成で学習させていました。

層・フィルタ数は多ければ性能が上がることが知られている(もちろん限度・例外はある)ので、層を1層増やし、フィルタ数を3倍くらいにしたところ、性能指標が2%程度上昇しました。

Dropoutを追加する


なぜか最初はDropout層を組み込んでなかったというかなり致命的ミスをしてました。

そのため、訓練データの分類に適用しすぎて未知のデータの分類は良い性能にならない「オーバーフィッティング」になっていました。

Dropout層はオーバーフィッティングを防ぐための層です。受け取ったデータをランダムで何割か削って次の層に渡すことで、擬似的にアンサンブル学習(複数の分類器の結果を利用して判定を行う手法)を実現するため、性能が上がります。

適用した結果、性能指標が3%程度上がりました。工夫というより当たり前のことをやっていなかっただけでした。

Data Augmentation


Data Augmentationとは、元のデータにノイズを乗せたり、横にシフトしたデータを用いて学習させることにより、データの水増しができ、データ量が増えるため性能が上がり汎化性能も向上するというよく用いられる手法です。

今回はデータ反転、ノイズ、横方向にシフトしたデータで水増しをしました。その結果、性能指標が2.5%程度上昇しました。

モデルの変更


途中までは特徴量やDataAugmentationの効果を見るために、学習スピードをある程度早める必要がありましたが、やはりもっと層が深くフィルタ数も多い方がいいと考えました。

モデルをVGG16という有名なネットワークモデルに変更しました。VGG16を少し修正して、Convolution層3層・Pooling層1層・Dropout層1層のブロックを3つ並べて、結果出力用のGlobal Average Pooling層1層という構成にしました。
本当はResNet使いたかったが、CUDAが謎のエラー吐いてて使えませんでした。

性能指標の上昇はが0.5%程度でした。大きな効果ではなかったのは、そもそもスペクトログラムという特徴量での分類器の性能の限界だったんじゃないかな〜と考えています。