手書き数式認識ソフト、tegashiki開発その2
ここでやった事概要
- Ramer–Douglas–Peucker algorithmを前処理で掛けて頂点を減らす
- EncoderにTCN(dilated convolutionを使ったモデル)を試す
- データの処理にバグを見つけて直す
- drop outやweightのregularizeを掛けてoverfitting対策をするもあまり成果無し
- ここまで試したモデルをissueにまとめたmodel history note #1
2019/05/25
maskつきsparse_softmaxはweightsを指定すれば実現できるのではないか?と理解して試してみたら実現出来たヽ(´ー`)ノ weightsのドキュメントがサンプル単位にしかつけられなさそうに見えるが、ちゃんとsample, sequenceの二つのdimでもつけられた。
今日はrdpで試してみる。ただ思ったよりmaxのsequence lenが減らないな。 epsilon 0.05のトレーニングセットで3193ー>1948。 ただ大多数はもっとずっと少なさそうだが。 なお、一回試すのに20分かかるので試行錯誤はせず先に進む。 効果が大きそうなら他のepsilonも試そう。
うおっ!ずっとgithubに保存してるつもりだったcolab、保存出来てなかった! 最初の一回のcommitはどこかからやっておかないとダメなのか。
さて、rdpで減らしたデータでやってみた所、accuracyは0.39まで上がったが、傾向はそんなに変わらず。 やはりすぐにオーバーフィットしてしまう。 パラメータ減らした版の傾向はこれまで同様いまいち。
そういえばaverage poolingを挟んでいる奴、長さが短くなったので無しの方が良いんじゃないか?と思い試す。 長さは最大のだと1900くらいあるのもあるのでGRUでは学習出来ないだろうが、全体的にはもっと短いのが多いので。 >メモリ不足で実行できず
うーん、だいたいはそんな長くないはずなんだよな、とヒストグラムを見ると500以下が8131、500以上が1731。 500以下だけでもいいという気もするが、データを用意するのがちょっとめんどい。
ゆとりとしては、やはりdilated convolutionを試したいな、という気がしてきたのでその辺を真面目に読み直す。 理屈はちょっと理解出来た。
という事で、An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence ModelingのTCNというモデルをベースに直してみようかな、と思い始める。 やってみよう。
TCNの実装自体はdilated convolutionのサポートが既にkerasに入っているので簡単だったが、decoderのinitial stateが無いなぁ。 これどう作るのがいいんだろう? dilatedの最後のレイヤにFCつけて作ればいいか?とりあえずinitは無しでやってみる。
attentionの所でメモリ消費が多くなりすぎる。うーん。とりあえずdilatedをmaxpoolingして1/10にしてみるか。 maxpoolingではシーケンスの区切りがどうなるのか良く分からんので不安もあるが、dilatedで見た物を減らしているのでこれまでよりは良かろう。
と試したら動いたはいいが全く学習が進まない。何が悪いのかなぁ。とりあえずmaxpoolingをaverage poolingにしてみるか。 >結果変わらず
やっぱなんかバグってる気がするな。gradientが伝播してない感じだ。
バグを直したらトレーニングは進むようになった。スコアはあんま良くなさそうだが、もう少し回してみる。 accuracy 0.31くらいまでは行った。 ただあんまりオーバーフィットも出来てなさそうなのでreguralization入れてもそんな良くならなさそうだなぁ。
そのあとずっと回してたらそれなりにtrainingのlossは下がり始めた。 これならdropout入れてみてもいいかもしれない。
プール行きながら回していた。4万stepまで来ても微妙にaccuracyが上がり続けている。 現在0.335。ただvalidationのlossはもう下がってない。スコア的にはRNN+Attentionの方がまだ良いが、結構近い所までは来ている。 ふーむ、評価が難しいな。動きを見ているとlearning rateはもうちょっと上げても良いかもしれない。 まぁ今日の所はこのくらいにしておいてやるか。
2019/05/26
今日はTCNベースのモデルに、learning rate上げて(0.001)、dropoutを入れてみよう(tcn_dropout)。 これがまぁまぁいい線行くようならdilatedの層を増やしたりいろいろいじってみても良い気はしている。
全然training lossが下がらない。0.001は大きすぎか。
0.0009に戻してトレーニング。5万ステップまで回してacc 0.3419だがまだ上がり続けてるなぁ。 validation lossはもう下げ止まってるのだが。 もう少し回してみるか。 さらに6万ステップまで回して見たがあまり変わらない。 ちょっとこれ以上の精査はするだけの価値を感じないのでここまでとしよう。 TCN-RNNはTCNにdropoutを入れてacc 0.342。
これまのTCNじゃないCNN+RNNだった奴をCNN-RNN-RNN、略してCNN-RNN2と呼ぼう。 今の所CNN-RNN2が一時的には一番スコアが高いので、これにdropoutを入れてみよう。 今回はencoderだけじゃなくてdecoderの方にも0.2のdropoutを入れてみる。 こちらの方が学習はピーキーだが、学習は早いので筋が良いかもしれない、という気はしている。 dropoutを入れて安定的にvalidation lossが下がるようになればこちらをベースにした方が良さそうか。
CNN-RNN2、dropout入れて学習してみたら最大のaccが0.3228に低下。 なんかこれ、前回はたまたま良いスコアが出ただけっぽい挙動だな。いまいち安定してない。
モデルの試行錯誤が増えてきてどれがどのモデルか分からなくなってきたのでissueにメモを残す。
https://github.com/karino2/tegashiki/issues/1
やはりTCNベースの方が可能性を感じるな、という事で、TCNの最後のtimestepの結果を使ってdecoderのinit stateを作る、というのをやってみる。 これはTCNでclassificationなどを解く時に使っている方法なので、悪くないはず(ただし現状はdepthが足りてないので最初の方は見れてないはずなので、あとでdepthを増やす)。
2019/05/27
昨晩流したtcn_drop2_initstateは、序盤早く改善してたので期待してたが、収束が早いだけで最終的なスコアはacc 0.33くらいだった。 どう評価すべきかは難しいが、スコアはスコアという事で。
今日はdilatedの層を増やす事にする。initstateに渡している数字が、入力の後ろの方のpaddingしか見れてないんじゃないか、という気がしていたので。
4.5万ステップくらい回してacc 0.344でオーバーフィットし始めている感じ。 これが今まででは一番筋が良いモデルな気がするが、結局スコアとしては0.344くらいが限界、という気がする。 dropoutを入れてもそんなには変わってるように見えない。
training lossはまだまだ下がりそうなので、やはりトレーニングセットが足りない、という話と思う。
結局ベクトルデータが足りない。どうするのがいいかなぁ。
まずは一番楽な、augmentationとかで水増ししてみたい。 まずデータ点減らす為にrdpでeplison 0.05にしているが、0.07とかも混ぜるか? これに点にノイズを足すのと、回転を足すのでどうにかしたい。
回転はどこを中心に回転するのが良いかなぁ。理論上はどこでも良さそうだよな。
reguralizationを他にも足せないだろうか?dropoutは改善したかどうか微妙だったが。 l2 reguralizationとか入れてみるか。
なんかcolabがご機嫌ナナメでつながらないのでいったん中断。 戻って来たらだいたい先ほど回してたdepthを8にしたのが最後まで終わっててacc 0.347。 あまり差は無いが、これが一番筋が良い気はする。
次はl2 regularizationを強めに、とりあえず0.1で入れられる所に全部入れてみる。(tcn_regular)
収束は早くなったが、結果のスコアは変わらず。regularizationは入れた方が良さそうだが。 accは0.34くらいまで。
ここまでで、全体的にはまだまだ満足いくスコアに行ってない。 もうちょっと短い所を当てていく方がいいんじゃないか?という気がしてきた。 そういう訳で、stroke長が500以下の物だけでトレーニングしてみようかな。 これならavg pooling無しでもいけるのでは?という事でそういうモデルを作って動かしてみよう。
お、フィルタリングしようとしてたら、なんかTFRecordのstrokeの値がおかしい? うが!praserのコードがバグってて、x, y, typeと渡らずにx1, x2, …, xn, y1, …, yn, t1, …, tnと並んだ物をreshapeした物が渡ってた! これではストロークはほとんど見れてないようなもんじゃないか…
直して流す。(tcn_regular_fixparser)
2019/05/28
昨日流したの、accが0.335とか。変わらんやん。マジで? この結果は信じがたいなぁ。
とりあえずcnn-rnn2で流してみよう。TCNがちゃんと出来てないだけ、という可能性は十分あるので。
お、改善した。0.407弱くらい。今回のスコアはまぁまぁ安定しているのでこれでいける気がする。 TCNはなんでダメなのか良く分からんが、こちらはちゃんと入力を見ていそう。
飯の間回していた所、training setには完全にfitting出来ている事を確認。オーバーフィットだけど。 これは大きな進歩だな。
とりあえず以前は意味の無かったパラメータ数削る、というの(cnnrnn2-fixparser-small)を流しつつ、今後の方針を考えよう。
トレーニングセットには十分当てられるようになったので、モデルの表現力よりもオーバーフィットの方が問題だろう。 パラメータ数が多すぎる、という問題とトレーニングセットが少なすぎる、という問題があるとは思う。 パラメータ数を削ったモデルを今流しているのでこの結果を見ればそちらの方向はいろいろ分かるだろう。
トレーニングセットの数が少ない、というのは最初から懸念している所で、個人的にはaugmentationをいろいろやる、という路線と、 自分でアプリ作ってデータ集める、という路線を考えている。 特に自力で集める、というのは結構いい気がしている。 自分で作ればデータの信頼度も大分高くなるし、UIを工夫すれば、一つの数式ごとに10回ずつ描くようにすれば、 100個の数式で1000データ。 結構1万データのオーダーならコツコツ作ればなんとかなる範囲に思う。
しかも自分で作れば、各ストロークと対応するtexの記号の組を作れるので、途中までに切ったデータも作れるんじゃないか。 こちらの方が実際のユースケースに近いし、これでデータを自動で水増し出来れば、大分トレーニングセットが少ない問題は解決出来るんじゃないか。 ただアプリ作るのはかったるいし、数作るならアプリは結構ちゃんと作りこむ必要があるので、楽では無いよな。
とりあえずaugmentation入れて効果のほどを見てから判断かなぁ。
パラメータ数を減らしたモデルもオーバーフィットの度合いは大差無く、ただスコアが悪くなっているだけに見える。 ただ定性的にはそんなに変わらないし、パラメータが少ない方が試行錯誤の結果は分かりやすく出るだろうから、しばらくこのモデルをいろいろいじってみるかなぁ。
cnnrnn2-fixparser-small acc=0.379
思ったよりもオーバーフィットが減らないので、もっと強いregularizationを掛けたい。 l2の0.1は結構大きい気もするが、dropoutはもっと増やしている人も結構見かけるので、これを0.5にしてもう一度やってみるかなぁ。
やってみた。全然変わらんね。 cnnrnn2-small-drop05 acc=0.377
切り分けの為に、極端にdropoutを一回かけてみよう。0.9で。cnnrnn2-small-drop09。
うーん、なんか何やってもvalidation lossの動きが同じ感じになるなぁ。 trainig setのlossの下がり方はスムーズになっているが、それがvlidation setのlossの動きを改善してない。 acc=0.355
これ、データセットで何か大きく違いがあるんじゃないかね。 やはり全部混ぜてsplitする方がいいんじゃないか?
ちょっとvalidation setのデータを時間かけて見直すのはやってもいいかもしれない。
やってみた。そんな変な事は無い。ただこの問題は相当難しいね。ここまで難しいのを推測するのに苦戦しているのは、まぁ仕方ないな、という気はした。
subtaskとして各シンボルだけのがあるので、これからやる方がいいかもなぁ。
よし、明日はシンボルのみのサブタスクのデータセットを準備しよう。
ここまでの雑感
どうもトレーニングセットもテストセットも、複雑すぎる式が多い。 組み合わせの数が膨大な割にトレーニングセットが少ないので、どうしても系列を丸暗記する方に学習が進んでしまいがち。
一方で学習はちゃんと動いていて納得できる挙動はしている。 モデルの基礎的な設計や周辺の足場のコードはそれなりに完成してきている気がする。
モデルはまだまだ工夫の余地はあるけれど、そもそもにデータセット回りを改善出来た方が効きそう。
次スレに続く。 手書き数式認識ソフト、tegashiki開発その3