突然だが、本ホームページの管理人である自分は技術ブログ記事的なものを上げてみたくなり、細く長く取り組んでいるとあるシステム開発の経験を記事として書いてみることにした。なお、自分が書いたコードはこちらに公開してあるので、詳細に興味がある方はご参照頂きたい。
私は棋譜の読み書きが苦手だ。周囲の同程度の棋力のチェスプレイヤーと比べても特に苦手だと感じている。ちなみに目隠しチェスも苦手である。これは自分がチェス盤のビジュアライゼーションを不得意としていることが原因だと思う。
このために特にストレスを感じるのは、大会で書いた棋譜をデジタルデータに起こす時である。棋譜用紙とスマホの入力画面の間を何度も行き来する必要があり、大変ストレスを感じている。棋譜を読むのが得意な方は、読むと同時にある程度内容を理解できるため、かなりまとまった単位で一度に打ち込めるために自分ほど苦労していないように見える。全く羨ましい限りである。
私はこの課題を解決するため、手書きチェス棋譜画像からの棋譜データ生成システムの開発に着手することにした。私の本職はソフトウェアエンジニアであり、つまりは技術者の一人である。直面する課題に対して個人の能力に頼らない汎用的な装置による解決を模索したのは自然なことだったと思う。
開発を始めたのは2023年の4月頃と記憶している。画像認識なのだから、やはり流行りの機械学習を使った手法が有望だろうと考え、その方向で検討した。当時の私はその手の技術に疎く、まずはメジャーな機械学習フレームワークの中でもとっつきやすそうな Keras の Handwriting recognition というチュートリアルから始めた。そこで一般的な手書き文字認識の手法について学ぶことができた。また、画像認識を実行する際には認識対象だけを抜き取った Bounding Box というものに分け、それぞれに対して更に詳細な認識を行うことが一般的であることを知った。
棋譜を1手ごとに Bounding box に分けるため、棋譜用紙の罫線を認識するための手法を Canny法を含めていくつか試した。罫線認識は一見簡単そうに見えたが、実際にやってみると意外と意図した出力が得られずに苦労した。結果的に途中で罫線の検出は諦め、ひとまず棋譜用紙の形は決まっているのだからと、事前にそれぞれの手の書かれた範囲を静的に定義し、スキャナで取り込んだ歪みや位置のずれが少ない画像のその範囲を Bounding box とした。ゆくゆくはスマホで撮ったカメラ画像から認識したいと思ったが、まずは簡単な問題を解いてから難しいケースへ拡張していく作戦を取った。

(罫線が途切れていると誤認識されている箇所がある、罫線と手書き文字部分の分離がない、等の課題により実用に耐えない)


(罫線の外へはみ出す場合がある、罫線に下側に文字が偏ることが多い、等の適切なマージンを取るための工夫がされている)
次に、適切なモデルを作成するため、既存手法について調査した。インターネットの海を漁ると、専攻研究として Digitization of Handwritten Chess Scoresheets with a BiLSTM Network – PMC という論文を見つけた。そこに記載されていた内容をリファレンスとして BiLSTM モデルの学習、推論のためのコードを書いた。論文にある通り、まずは一般的な手書き文字の公開データセットである IAM データセットを用いてモデルを事前学習し、更に手書きチェス棋譜の公開データセットである HCS データセットを用いて追加学習を行った。
ここで機械学習について少し整理をしておく。機械学習とは、大量のデータを用いてそこに潜むパターンを探し出し(学習)、未知のデータを判断するルール(モデル)を獲得することである。この時、学習に用いるデータを学習データ、未知のデータのサンプルとして評価(テスト)で用いるデータを評価データと呼ぶ。学習のやり方は様々な手法があるが、ここで利用したのは学習データの正解を事前に設定し、学習データを入力とした時に正解とできるだけ近い出力を行うモデルを一定のルールに従って計算で探索する方法である。BiLSTM はモデルの型の種類であり、時系列データを扱うことに長けている。棋譜データは時系列的なつながりがあるため BiLSTM と相性が良い。また、学習データの正解を人力で作成することをアノテーションという。
モデルを一から自分で書いて学習まで済ませたことは初めてだったため、モデルを評価する際はかなりの興奮を覚えた記憶がある。しかしながら、結果は全くもって実用に耐えるものではなかった。学習に使用した公開データセットでは一定の性能が出たが、自分の手持ちの日本チェス連盟棋譜用紙のデータでは精度はとても低かった。その後いくつか改善案を試したがあまり効果がなく、何となくやる気が途切れて1年程開発を中断していたと記憶している。
しかし、2024 年後半ごろにふとやる気が戻り、開発を再開した。フレッシュな気持ちでソースコードを改めて確認すると、学習時と推論時で使っているモデルの出力ベクトルからテキストへの変換方法に不一致があることに気が付いた。その点を修正すると、かなり精度がましになった。


モデル開発に一定の区切りがついたところで、python-chess ライブラリを用いて有効手を挙げ、その中からモデルの推論結果と最も類似する手を選ぶスクリプトを書き、棋譜に書かれた手を通しで入力して棋譜データを生成してみた。この時、類似度の評価にはレーベンシュタイン距離を用いたが、これはひとまず文字列類似度を評価する一般的な手法の中で最も簡単そうなものを出発点として選んだに過ぎない。
出力された棋譜は実際の棋譜とは全くもって違う出力であった。ゲームのどこかで間違えた時点で、その後は有効手の中から無理やり手を選び続けたような棋譜になってしまった。とはいえ、課題はありつつも当初やりたかった手書き棋譜画像から棋譜データ (PGN) を出力するところまで一通りの系を完成させることができた。

一通りの系ができたことから、ここからは精度をいかに上げるかという検討段階に入った。まずは学習データが圧倒的に足りなかったので、この大幅な増量が必要だと考えた。しかしながら、元々棋譜を読むのが苦手だから本システムの開発に着手したというのに、大量の棋譜を読んでアノテーションしていく作業を思うと極めて憂鬱であった。そこで、その作業負担を軽減するためにアノテーションを補助するツールの開発に取り掛かった。
棋譜を入力する際に自分が最もストレスに感じるのは、視線を棋譜と入力画面の間で何度も行き来させる必要があることだった。よって、視線をほぼ動かさずに入力できるGUIツールを作成した。棋譜画像から1手ごとにその範囲だけを表示し、その直下に棋譜テキストの入力を配置した。これにより、ほぼストレスなくアノテーションを行うことができるようになった。

しかしながら、このツールを作ってある程度アノテーションを進めたところで、再度開発を中断した。理由は同じく何となくやる気がなくなったためである。棋譜データを見れば見るほどチェスプレイヤーの文字の汚さと書き間違いの多さを理解し、実用に耐えるシステムを作ることが難しいと感じたことも理由として多少あったが、それは元々ある程度綺麗な文字で書かれた、間違いがほぼ無い棋譜のみを対象としようと決めていたことから、やる気が出ない言い訳に過ぎなかったと思う。いずれにせよ、その2024年11月頃を最後に開発は止まった。
そして現在 2025年2月、自分の行っていた開発の意義を大きく揺るがす出来事が起きた。別の用途で契約して遊んでいた ChatGPT 4o に軽い気持ちで手書き棋譜認識を試しに行わせてみたところ、衝撃的に高い精度の棋譜データを出力したのである。棋譜の画像と「This is a handwriting chess game record. Make a PGN of this game. 」という短いプロンプトを入力しただけで、実用に耐えそうな棋譜データが生成された。試行錯誤とともに自分が開発していたシステムよりも、広く一般的な用途向けに提供されている大規模言語モデル(LLM)サービスの方が精度が高いという衝撃は大きく、これが破壊的イノベーションだと思った。


(17手目の白番以外は正しい)
のんびり気が向いた時に趣味として少しずつ開発を進めていたものとはいえ、自分がこのシステム開発にかけた時間は100時間近いだろう。それを否定された衝撃はかなり大きい。自分は AI 技術の熱狂に対して懐疑的な一人であったが、意識を大きく変えるべきかもしれない。
話の本筋から離れるが、ChatGPT をはじめとする大規模言語モデルの凄さは、曖昧な指示に対しても的確な出力をする点だと思う。自分がそうであったように、従来の AI モデルでやりたいことを実現するに技術的な知識が必要になり、その勉強コストが負担である。しかしながら、近年の最先端 LLM は自然言語の抽象的な指示でもその具体的実現方法を含めて的確に推論できている。利用者に細かい知識は不要である。
話を元に戻し、今後の本システムの開発方針について述べる。基本的には画像入力をサポートする既存の LLM サービスを活用したアプローチを検討しようと考えている。まず、 4o 以外のモデルを評価し、その後 LLM サービスの API 料金とのバランスを検討する。そして、もしも実用に耐えるようならば、サービスとして一般公開していきたいと考えている。その際は読者の方も是非試して貰えれば幸いである。
以上。