以前の記事で将棋盤の駒の位置を抽出する所まで出来ました。
ディープラーニング素人ながら、今回は駒ごとに写真を分類できるか挑戦してみたのでご紹介です。
駒のデータを用意
まず学習に必要な駒の写真を用意しないといけません。写真1枚に駒一つがそこそこ綺麗に写っていることが望ましいと思いますが、ネットの画像検索だと意外と見つかりません。そこで盤面全体の大きいサイズの写真を画像編集ソフトで1つ1つ分割しました。この作業は大変苦痛を伴いますが、とりあえず1駒あたり14枚のそれっぽい写真を用意しました。
CoreML&Visionによる駒の判定
後述にもありますが、Kerasのクラス分類実装を途中で断念したのでXCodeのCreate MLを使って*.mlmodel生成してiOSアプリで判定することにしました。
MacでCreate MLを起動してImage Classficationを選択します。
そして駒のデータを投入してトレーニングします。
単純作業なので詳しくは触れず、公式リンクだけ貼ります
Create MLの概要 - 機械学習 - Apple Developer
これで*.mlmodelファイルを手に入れました✌️
駒判定までの流れ
改めて整理して以下の流れを考えました。
- iOSアプリで将棋盤(駒)の写真を撮る
- バックエンド(Python FastAPI)に写真を送信
- PythonでOpenCVを使って駒ごとに写真を分割
- iOSアプリで各駒の写真を判定
サーバーサイドで下準備をしてアプリで判定するのは少し違和感があるかもしれませんが、3は既に作っててもったいないので流用します。FastAPIは特に理由はなく、DjangoでもFlaskでもWebAPIでアプリと連携できれば何でも良いです。
ちなみにOpenCVはiOSでも動作するので実際にアプリ化(商用化)するなら全てアプリ側で実装したいところです。
結果
前述の実装を一通り済ませたものがこちら(リンク先動画)。実装は1つ1つは大したことやってない&コード多いので載せてません。
後手番の駒はほぼ誤りで、先手番は歩が5枚正解、香が片方だけ正解してたりなかなか残念な感じです。
ただ精度の改善ポイントは結構明確で、
- 学習データが少ない
- 学習データの設定が適当(CoreMLのトレーニングに突っ込んだだけ)
- 学習データのカテゴリーを細かく分ける
といったことをやると良くなるのかなーと考えてます。3は何のことかと言うと、例えば成り銀は「成銀」とか「全」と駒の書体によって異なるので画像分類の時点では別物と判定すると学習効率が良いんじゃないか?という予想です。
その他 失敗した数々の試み
前に紹介した以下の書籍に学習済みデータを利用したクラス分類の実装が記載されています。
OpenCV側の実装はこれを流用できそうだったので、あとは学習済みデータ(*.pb)を用意すればいいのでは🤔と思ってとりあえずTensorflowの本を買いました。立ち読みで吟味した上でこの本を選びましたが、それでも初学者にはなかなか難し目です。
そしてKeras公式のクラス分類のチュートリアルに進み、どうにかpbファイルまで生成出来たのですがモデルの取り込みがどうもうまくいかなかったのでこちらの方法は断念しました。たぶんmodelのsave or load周りがおかしいかなとアタリをつけてる状況。
他にはTensorflowを動かすにあたりM1 Mac固有のエラーが出たり、pyenvとかのPythonよりbrewで入れた方が良いという記事を読んで入れ直してみたり・・などなどハマり所が多く大変でした。
あと.mlmodelを.onnxに変換する方法を模索していました。ここで結構時間かけてしまって、現時点でサポートされてないみたいなIssueを見つけてガーンってなりました。
https://github.com/onnx/onnxmltools
まとめ
将棋の駒判定は以前からアプリ化の構想があるのでまたリベンジしたいところです。学習データやCreate MLの設定、実装の見直しなどまだまだ改善の余地あります。あと持ち駒の判定も課題ですね。
そもそもCreate MLのObjectDetector使えば駒ごとに分割しなくてもよかったような気がしなくもないですが、まあOpenCVの勉強だったということで..
また積読が増えたので消化しないと(´-`).。oO