Slide 1

Slide 1 text

魔術式シェル芸 「呪符式高速詠唱シェル芸」改善への提案手法

Slide 2

Slide 2 text

自己紹介 JavaScriptとシェル芸が好き、あとGo 最近は筋肉に憧れてる taka@SIではたらくフレンズ @amanoese

Slide 3

Slide 3 text

たいちょーさんの「呪符式高速詠唱シェル芸」の課題 呪符式高速詠唱シェル芸:https://www.slideshare.net/xztaityozx/ss-252108533 任意のコマンドをyukichantで変換 -> 手書き -> カメラで取り込み -> OCR -> 実行 ここの精度 $ echo unko $ echo unko yukichantで エンコード 画像取り込み yukichantで デコード 手書き cli-google-driver-ocr (Google Drive API)

Slide 4

Slide 4 text

課題①: yukichant 呪符式高速詠唱シェル芸:https://www.slideshare.net/xztaityozx/ss-252108533 yukichantはもともと、音声でバイナリデータを送るために設計されたエンコード・デコードツール => 手書きにするとデータ量が増大する => あたらしくエンコード・デコードツールつくればよい ここの精度 $ echo unko $ echo unko yukichantで エンコード cli-google-driver-ocr (Google Drive API) 画像取り込み yukichantで デコード 手書き

Slide 5

Slide 5 text

課題②: OCR(AI的なやつ) 呪符式高速詠唱シェル芸:https://www.slideshare.net/xztaityozx/ss-252108533 Google Drive のOCRを利用しているため、一般的な文字に最適化されて汎用的なモデル => 特定の文字を学習させれば認識精度があがるのでは? => 学習させる ここの精度 $ echo unko $ echo unko yukichantで エンコード 画像取り込み yukichantで デコード 手書き cli-google-driver-ocr (Google Drive API)

Slide 6

Slide 6 text

解決する

Slide 7

Slide 7 text

つくるもの $ echo unko $ echo unko xxxxで エンコード yyyyyyy 画像取り込み xxxxで デコード 手書き 1. 文字認識に適したあたらしいエンコード・デコードツール 2. 特定の文字を学習させたOCRモデル 1. 1. 2.

Slide 8

Slide 8 text

つくるもの1 $ echo unko $ echo unko runicで エンコード yyyyyyy 画像取り込み runicで デコード 手書き 1. 文字認識に適したあたらしいエンコード・デコードツール => runickを作った 2. 特定の文字を学習させたOCRモデル 1. 1.

Slide 9

Slide 9 text

yukichantのデメリットを消すエンコード・デコードツール https://github.com/amanoese/runick 任意のテキストをルーン文字に変換できる runick

Slide 10

Slide 10 text

つくるもの2 $ echo unko $ echo unko runickで エンコード tesseract 画像取り込み runickで デコード 手書き 1. 文字認識に適したあたらしいエンコード・デコードツール 2. 特定の文字を学習させたOCRモデル => tesseractを使ってみる 2.

Slide 11

Slide 11 text

https://tesseract-ocr.github.io/tessdoc/tess4/TrainingTesseract-4.00.html tesseractを利用して学習する 環境構築難しいのでDockerファイルにまとめました https://github.com/amanoese/tesstrain-docker

Slide 12

Slide 12 text

tesseractは追加学習する(学習済みの言語モデルに追加で学習させる)のが得意っぽい 手書きフォントで学習させてみて、もとのyukichantでも精度向上できるか試してみる tesseractを利用して学習する(追加学習) $ echo unko tesseract (日本語に手書き文字を追加) 画像取り込み 手書き ここを手書きフォント学習させた tessractに変える 2. $ echo unko yukichantで エンコード yukichantで デコード

Slide 13

Slide 13 text

tesseractを利用して学習する(追加学習) 手書きフォントを学習させてみる。 =>良い感じ

Slide 14

Slide 14 text

tesseractを利用して学習する(追加学習) 手書きフォントを学習させたモデルに、たいちょーさんの手書き文字を与えて検証 =>認識できない(一部の文字について認識精度の向上は見られる) =>たいちょーさんの手書きデータを学習していないためか?

Slide 15

Slide 15 text

たいちょーさんの手書きデータを入手できなかった 日本語だと文字数が多いため学習が難しいぽい 文字数の少ない日本語でない文字で、手書きの学習データをつくり学習させれば良い  ⇒ ルーン文字を採用する(魔法ぽいので)    ただし、ルーン文字はtesseractに学習済みデータがない。    また、ルーン文字は対応フォントも少ない 追加学習で精度があまり上がらなかった理由と解決 $ echo unko $ echo unko ᛢᛗᚼᚫᚷᚱᛈᛤᚻᛢ runikで エンコード tesseractで変換 (ルーン文字学習モデル) 画像取り込み runikで デコード 手書き 2.

Slide 16

Slide 16 text

学習データを作る 算数ノートとスキャナを買う がんばる

Slide 17

Slide 17 text

学習データを作る ## ルーン文字毎に画像を分割する $ identify 1.png|awk -F '[ x]' '{print "seq "0" "$3/12" "$3;print "seq "0" "$4/17" "$4}'|\ xargs -i bash -c '{} |xargs|tr " " , |sed "s/.*/{&}/"'|xargs|tr ' ' '+'|\ xargs -i bash -c 'echo -e {}\\n'|xargs -i echo 'convert 1.png -crop 72.5x72.5+{}'|\ head -216|awk '{print $0" "A"-"int((NR-1)/18)"-"(NR-1)%18".png"}' A="page-1"|bash ## ルーン文字毎にフォルダに分ける $ cat use-rune.txt|grep -o .|head -12|awk '{print "mv page-1-"NR-1"-* " $1"/"}'|bash

Slide 18

Slide 18 text

学習データを作る ## 学習させるルーン文字の文字列のリストを作る $ yes|head -200000|xargs -P12 -i bash -c 'cat use-rune.txt|shuf -e $(cat|grep -o .)|xargs|tr -d " "' > traning.txt ## ルーン文字の文字列をファイルを作成する $ cat traning.txt|awk '{ print > "output/"NR".gt.txt"}' ## ルーン文字の文字列をファイルを画像を作成する $ cat traning.txt|sed 's/./& /g'|awk 'BEGIN{srand('$RANDOM')}{printf "convert +append "; for(i=1;i<=NF;i++){printf $i"/page-*-"int(rand() * 17)".png "};print "output/"NR".png\n"}'|parallel ᛄᛤᛋᛞᛟᛖᚳᚹᚱᚻᚸᛈᛗᚦᛝᛣᚾᚢᛏᛠᛒᚫᛁᛉᚣᚼᚠᛥᛇᚷᛚᛢ とりあえず20万個のデータ作った (txtとpng合わせて40万ファイル)

Slide 19

Slide 19 text

学習させる $ make training MODEL_NAME=rune MAX_ITERATIONS=200000 > plot/rune.log … … Loaded 1/1 lines (1-1) of document data/rune-ground-truth/140071.lstmf Loaded 1/1 lines (1-1) of document data/rune-ground-truth/53234.lstmf Loaded 1/1 lines (1-1) of document data/rune-ground-truth/162477.lstmf 2 Percent improvement time=1086, best error was 2 @ 2481 At iteration 3567/16300/16300, Mean rms=0.06%, delta=0%, char train=0%, word train=0%, skip ratio=0%, New best char error = 0 wrote best model:data/rune/checkpoints/rune0_3567.checkpoint wrote checkpoint. Finished! Error rate = 0 Loaded file data/rune/checkpoints/rune_checkpoint, unpacking... 20万データ作成したけど16000暗いのデータでエラー率が0になり学習が終了 (ローカルミニマム(局所解)になってしまった?)

Slide 20

Slide 20 text

とりあえず、学習済みモデルから、未学習のデータを与えて見た結果 =>良い感じ   ただし読めないデータとの差は激しい   (多分うまく学習はできてないぽい) 学習結果 $ tesseract -l rune --tessdata-dir ./data/ kensyo.png stdout 2>/dev/null ᚼᚸᚾᛒᛄᛝᚱᛚᛠᚣᛖᛇᛏᛣᛢᚢᛤᛈᚦᛁᛉᛋᚫᛞᛗᚻᚠᛥᚳᚷᛟᚹ

Slide 21

Slide 21 text

学習結果をためす 学習済みモデルに実際に書いた手書きの文字を与えてみる =>だめでした $ tesseract -l rune --tessdata-dir ./data/ rune-ss-sample2.png stdout 2>/dev/null ᛥᛥᛥᛥ

Slide 22

Slide 22 text

1. 学習の仕方 a. 一旦クリーンなフォントで学んでから手書き文字を学習させたほうが良い? b. 文字データをふやす 2. QRコードから学ぶ 位置補正の仕組み ⇒ 魔法円でなんとかできないかな? 誤り訂正符号   ⇒ runickを改修 3. 呪符式高速詠唱シェル芸を改善 たいちょーさんの手書きデータがあれば追加学習できるのでほしい 今後やりたいこととか $ echo unko $ echo unko runikで エンコード tesseractで変換 (ルーン文字学習モデル) 画像取り込み runikで デコード 手書き 位置補正

Slide 23

Slide 23 text

EOF