落ちたからアプリ作る⑤:Layout Parserを使った画像セグメンテーションの検証と反省

システム開発

はじめに

※本記事の一部コンテンツ(文章・画像)はAIの支援を受けて作成しています。

情報処理安全確保支援士の午前Ⅰに落ちた私。試験対策とAIを活用した開発の勉強を両立させようと始めた試験対策アプリ開発の5回目の記事です。

アプリ開発に先立ちデータの準備を自動化しようとしています。具体的には過去問PDFをツールで処理してDB化してしまおうという試みです。以前の検証ではOCRで過去問を6~7割ほどテキスト化できることがわかりましたが、誤読も多く、それなら画像のまま表示させれば良いのではと、今度は試験問題の画像を自動で「設問ごと」に分割しようとしています。

前回はOpenCVを使ったルールベースでのセグメンテーションを検証しました。

今回は、「Layout Parser」を使った機械学習ベースでのセグメンテーションの検証を行いました。検証実施にはGoogleColabを利用しました。その検証結果などの記録をまとめています。

検証の背景と目的

  • 対象は情報処理安全確保支援士午前Ⅰの過去問題PDFを画像化したもの。
  • 設問・図・解説などが混在しているため、画像分割(セグメンテーション)が必要。
  • 以前、OpenCVを用いたルールベースの方法である程度の成果が出たが、より高精度な分割の可能性を探るべく、Layout Parserを検討。
  • OpenCVのルールベースでは画像に何が描かれているか?を、「これは設問部、これは選択肢部」というように画像上の意味合いまでは解析してくれないので、機械学習のライブラリでセグメンテーションしてみる

Layout Parserとは?

Layout Parserは、文書画像やPDFのレイアウト構造を自動的に検出・解析するPythonライブラリで、論文や帳票、試験問題のように構造を持った文書に対して有効です。

コアとなる仕組みには、Facebook Researchが開発した物体検出ライブラリ「Detectron2」が使われており、学習済みの物体検出モデル(例えば、テキストブロック・図表・見出しなど)を使って、文書画像内の各構造要素の位置と種類を認識することができます。

また、Layout Parserは視覚的なレイアウト検出だけでなく、Google Vision APIなどのOCRエンジンと組み合わせることで、検出された領域ごとにテキスト抽出を行う構成も可能です。そのため、セグメンテーションから文字認識、構造的な情報の取得まで一貫した処理パイプラインが構築できるのが特長です。

なお、OpenCVがしきい値や構造の特徴を明示的に指定する「ルールベース」な処理であるのに対し、Layout Parserは学習データに基づく「機械学習ベース」のアプローチである点が大きな違いです。

今回の検証では、事前学習済みのDetectron2モデルを使い、試験問題画像に対してレイアウトの自動検出がどこまで使えるのかを評価しました。

結果:精度は期待ほどではなかった

検証に利用したNotebookはこちらです。アップロードした画像に対して、PubLayNetというドキュメントレイアウト分析のための史上最大のデータセットで事前学習したモデルを使用してセグメンテーションを実施する内容です。

検証に利用したGoogle ColabのNotebookから一部抜粋して掲載します(通常のpython環境では動作しません、詳細は検証に利用したNotebookを参照してください)

import layoutparser as lp
import cv2
import os
from google.colab import files

# アップロードはColabでの書き方。
uploaded = files.upload()
# イメージファイルをアップロードしてOpenCVで読み込んでます。 
img_path = os.path.join("/content/", list(uploaded.keys())[0])
img = cv2.imread(img_path)

# Detectron2で準備されているPubLayNetのモデルの読込と設定です。
# extra_configはモデルへの調整事項。信頼度0.3以上のものを利用、という指定をしてい"る。
model = lp.Detectron2LayoutModel('lp://PubLayNet/faster_rcnn_R_50_FPN_3x/config', extra_config=["MODEL.ROI_HEADS.SCORE_THRESH_TEST", 0.3])

# 事前学習済みモデルを使ってレイアウトを解析
layout = model.detect(image)

実装はモデルをロードして、解析する、というシンプルなもの。結果は残念ながら以下の通り。事前学習している内容と、試験画像ではレイアウトが異なるのでうまくいかないようです。他のモデルも試してみましたが、うまくいきそうなモデルも無くOpenCVほど簡単にはできなさそうです。

  • 事前学習済みモデルでは試験問題画像に対しては精度が低かった。
  • 特に設問や図の区別が曖昧で、ルールベースのOpenCVの方がむしろマシな印象。
出典:令和5年度 秋期試験 情報処理安全確保支援士 午前Ⅰ 問1~2 枠で囲っている箇所がレイアウトのブロックとして検知された箇所です。

パラメータ調整と限界

各種しきい値やスケーリングのパラメータをChatGPTに相談しながら調整しましたが、明確な改善には至りませんでした。そもそもDetectron2の設定ファイル自体がかなり難解で、理解するのに苦労しました。

どうやら私には画像認識とか機械学習の基礎知識が足りておらず、理解しながら進めるにはかなりの学習時間が必要そう。ChatGPTに必要な知識をまとめてもらいましたが、まとめてもらってもさっぱりわかりません(記事の補足として最後にまとめを載せておきます)

ただGoogle Geminiにも機械学習に関する質問で回答してもらったのですが画像認識は機械学習の勉強のとっかかりには最適らしいです。ですのでこの辺りの知識も今後の課題としたいと思います。今回はアプリケーション作成のための検証作業なので・・・・先送りです!

AIプログラミング学習におすすめの題材(Geminiの回答抜粋)

  • 画像認識・画像生成:
    • 具体的な内容: 犬と猫の画像を判別する、手書き数字を認識する、あるいは既存の画像から新しい画像を生成する(例:GANsやDiffusion Models)など。
    • おすすめポイント: 視覚的に結果が分かりやすく、実装の楽しさを感じやすい分野です。データセットも豊富で、初心者でも取り組みやすいでしょう。深層学習の基礎であるCNN(畳み込みニューラルネットワーク)を学ぶのに最適です。

今後の課題と当面の方針

検証はいったんここまでとして、Layout-Parserはボツ、データ作成はOpenCVで進めることにしました。

モデルに試験問題のレイアウトを学習させればもっと精度があがるのではと思ってChatGPTに聞いてみました。可能です、とのことですが、この作業は難易度高そうで時間もかかりそう。OpenCVである程度進めれそうなことはわかっているので、この案についても今後の課題としてアプリケーション作成と並行で作業することにしました。

ChatGPTにまとめてももらった再学習についての作業内容は記事の補足として最後に載せておきます。

検証時のトラブル(ハルシネーション)

検証をサクッと終わらせようと、ColabのNotebookに必要なソースをChatGPTに生成してもらいました。実行したところエラーが発生。ChatGPTにかかれば一瞬で解決するやろ、と思いChatGPTに質問。

エラーの原因はこれです!解決方法はこうです!とズバリ回答してくれるのですが、修正しても解決せず。

ChatGPTによるトラブルシューティング

最初に出たエラーは以下のようなもの。Detectron2がインストールされていないみたいだから、pipコマンドでインストールするように、という指示でした。言われた通りのコマンドを記述して修正してみましたが、似たようなエラーが延々と出続けることに。

・エラーの内容

AttributeError: module layoutparser has no attribute Detectron2LayoutModel

・ChatGPTによる修正

!pip install -q "layoutparser[layoutmodels]"

オフィシャルNotebookの存在に気づく

延々とこまごまとした修正を指示されましたが、一向に解決せず。Detectron2が依存しているPyTorchとCUDAのバージョンが違うだとか、そもそもPythonの新しいバージョンに対応していないので、Colabでは動作しないだとか。

最終的にはLayout-ParserやめてYOLOというライブラリで検証するか、DockerでPython3.9の環境を作って検証するしかないですね、という提案。やりたいことから微妙にずれ出しました。

ChatGPTの実際の回答(回答内容は誤りです)

さっさとLayoutParserやDetectron2の公式サイトで真偽を確認すればよかったのですが、ChatGPTを信頼しきっていた私は仕方なくDockerファイルの準備をし始めました。当然ChatGPTに生成してもらい、docker buildしましたがやっぱり動きません。。。。YOLOのコードも生成してもらって実行してみましたが、こちらもエラー。エラーの内容確認してみると、同じようにライブラリのバージョンがいけないとLayout-Parserの時と同じような言い訳をえんえんとするようになりました。

ここまで来てようやく、公式サイト確認してみるか・・・となった私。その判断がいまいち遅かったです。

公式みたら、ちゃんとColab用のNotebookが存在してました。ChatGPTに言われた依存ライブラリのバージョンの複雑な話は1件だけで、すんなり動きました。

以下が実際に動作したもの)修正。Layout-Parser公式のNotebookのもの。ChatGPTの回答とはまるで違いますね。

pip install 'git+https://github.com/facebookresearch/detectron2.git@v0.4#egg=detectron2'
pip install layoutparser[ocr]

ChatGPTへの依存を反省

そもそもChatGPTのチャット画面自体に「ChatGPT の回答は必ずしも正しいとは限りません。重要な情報は確認するようにしてください。」と書いてあるんですよね。知ってましたけど、

公式サイトの英語を読む vs ChatGPTに日本語チャットで聞く

であれば、やっぱり面倒くさい気持ちが出てついついChatGPTに聞いてしまってました。

生成系AIの回答はやはり、毎回疑ってかかる必要がありそうです。生成系AIがこういった虚偽の情報を自信満々に回答してくれる現象をハルシネーションと言うらしいです。

おわりに

今回の検証は、技術的な知見だけでなく、開発における姿勢や情報収集の重要性も再確認する機会となりました。引き続き、試験対策アプリの完成に向けて試行錯誤を続けていきます。

補足(ChatGPTによる解説)

Detectron2の設定ファイルの理解に必要なもの

試験問題の設問を自動で分割しようと、Detectron2を触ってみたものの——設定ファイルのコメントを読んでも、正直ピンとこない。

そこでズバリChatGPTに聞いてみました。「この設定ファイルを理解するには何の知識が必要ですか?機械学習の知識?それともセグメンテーションの理解不足?」で、答えが返ってきました。やはり想像通り基礎知識が不足しているようです。

理解に必要な3つの要素

Detectron2の設定ファイル(YAML)を理解するには、主に以下の3つの知識が絡んできます。

  1. 機械学習の基礎知識
    • 学習率(learning rate)
    • エポック・イテレーション
    • 損失関数や最適化手法(SGD, Adamなど)
    → これがわからないと、SOLVER.BASE_LRMAX_ITER の意味がつかみにくいです。
  2. セグメンテーションや物体検出の知識
    • アンカーボックス(anchor box)
    • RPN(Region Proposal Network)
    • RoIAlign、FPNなどの構成要素
    • 検出スコア(SCORE_THRESH_TEST
    → これがないと、MODEL.ROI_HEADS.* あたりの設定が意味不明になります。
  3. Detectron2特有の構成・記法
    • ネストされた階層的な設定形式(例:MODEL.BACKBONE.NAME
    • Pythonの辞書構造的なYAML構文
    → これに慣れていないと、どこに何が書いてあるのか見失いやすいです。

結論:設定ファイルがわからないのは当然

Detectron2は、「研究にも耐えうる高機能モデル」を扱うためのライブラリです。そのぶん、初心者には設定が複雑なのも当然。

大事なのは、「全部理解しようとしない」こと。まずは以下だけ押さえておけば、設問分割や簡単な物体検出には十分です:

  • MODEL.WEIGHTS:学習済みモデルの指定
  • MODEL.ROI_HEADS.SCORE_THRESH_TEST:検出のしきい値(精度に影響)
  • MODEL.ROI_HEADS.NUM_CLASSES:クラス数(PubLayNetなら5)
  • SOLVER.BASE_LR:学習率(再学習時のみ)

必要に応じて、少しずつ学んでいけばOK。まずは動かして、少しずつ意味を補っていくのが現実的です。

Detectron2は自前で学習できるの?

Detectron2に事前に用意されたモデルではうまくレイアウトを検出できませんでした。そこで正解の試験画像をモデルに学習させれば、精度が上がってうまく検出できるのでは?と考えChatGPTに聞いてみました。

答えは「Yes」です。Detectron2は、事前学習済みモデルをベースにした再学習(ファインチューニング)が可能です。
つまり、「試験問題の設問領域」だけに特化したモデルに自分で育てることもできる
ようです。

必要なサンプル数はどれくらい?

転移学習を前提にした場合(PubLayNetなどからの再学習):

画像数アノテーション数所要時間の目安
30~50枚約100~200個約2~3時間で準備可能

※ 1枚の画像に設問が3〜5個あれば、アノテーション数は意外とすぐ稼げます。

アノテーション作業に必要なもの

ツール例:

  • Label Studio
  • makesense.ai
  • VGG Image Annotator (VIA)

やること:

  1. 画像を読み込む
  2. 「問1」「問2」などの設問領域を矩形で囲む
  3. question などのラベルを付ける
  4. COCO形式などでエクスポートする

Detectron2で学習するまでの流れ

  1. 事前学習済みモデルの選定(例:PubLayNetベースのFaster R-CNN)
  2. COCO形式でのデータ準備
  3. 設定ファイル(YAML)の調整
  4. train_net.py を使って学習
  5. 学習済みモデルを保存 → 推論へ活用

自前で学習すべきか、事前モデルで工夫すべきか?

選択肢適しているケース
事前モデルを流用(PubLayNet)図表・段落中心のレイアウトなら対応可能。精度はそこそこ
自前で学習(Detectron2 + 転移学習)設問の境界が独特/画像が教科書やPDFとは異なる構成の場合はこちらが有効

結論:自前学習はできる、でも工数と相談しよう

Detectron2は強力だが手間もかかるツールです。
自前の設問データを用意し、ファインチューニングで専用モデルを作れば、精度は格段に向上します。ただし、最低でも数時間の準備作業(アノテーション含む)は必要です。

タイトルとURLをコピーしました