概要
機械学習初心者がSegment Anything Model (SAM)をGISで応用的に使いたかったのでその概要や使い方をメモしておく。
SAMを使うと,ラスターがベクターにできる……?!
Segment Anything Modelとは
Meta社が開発した,画像中の物体を分類するモデル。
公式ウェブサイトはキャッチ―で分かりやすいのだけれど,下記arXivの論文を確認してみることにする。全部読もうかと思ったけど,とりあえずイントロを読めば良さそうなのでイントロだけ。
Segment Anything論文の解説
Introduction 1
背景~ゴール
- 大規模言語モデルはすごいよね。zero-shotとかfew-shotで,訓練に使った以上の汎化性能が発揮されてるよね。こういうのを基礎モデル(foundation model)と呼ぶよ。
- zero-shotでは,追加訓練なしで結果が出力される
- few-shotでは,わずかな追加指示(プロンプト/prompt engineering)で結果が出力される
- コンピューター・ヴィジョンでも,自然言語ほどではないけれども,基礎モデルが研究されているよ。テキストと画像に関するモデルが有名だね。
- zero-shotで画像からテキストを生成したり,テキストから画像を生成したりするよ。
- でも,コンピューター・ビジョンには,この様な問題設定を超えるものもあるし,訓練に使えるデータが少ないよ。
- この研究では,画像のセグメンテーション(image segmentation)に関する基礎モデルを開発することがゴールだよ。
- 指示可能なモデル(promptable model)を作るよ
- タスクを使った幅広いデータに基づく,訓練済みモデルを作るよ
- 高い汎化性能を持つよ
キークエスチョン
3つの要素:タスク(task),モデル(model),データ(data),が,この研究の成功を左右するので,次のようなキークエスチョンを定めたよ
- zero-shotを可能とするtaskは何か
- それに対応するmodelは何か
- このtaskやmodelを可能とするdataは何か
taskについて
これまでの基礎モデルに倣って,指示可能なセグメンテーションタスク(promptable segmentation task)を提案するよ。次の画像の様に。
画像の位置や文字での指示が可能だよ。
modelについて
- 指示可能なセグメンテーションタスク(promptable segmentation task)のために,モデルの要件も定まるよ。
- フレキシブルな指示(flexible prompt)への対応
- リアルタイム・インタラクティブな処理
- あいまいさ(ambiguity-aware)への対応
- 驚くべきことに(!),シンプルなデザインでこれらの要件が満たされるよ2。画像の様に。これをSAM(Segment Anything Model)と呼ぶよ。
- 画像のエンコーダーとプロンプトのエンコーダーを分けることで,計算コストが有利で,リアルタイム・インタラクティブな予測が可能だよ。
Data engineについて
普通はインターネットからデータを集めるけど,マスクのデータが入手できるケースは少ないから,data engineというアプローチをとるよ。モデルと同時にデータセットを開発したよ3。
- assisted-manual: 古典的なやり方と同様,人(annotator)がマスクに注釈を付ける作業をSAMがアシストする
- semi-automatic: SAMに一部のオブジェクトについての指示を与えることでマスクを自動生成し,残りのオブジェクトについて人(annotator)が残りのオブジェクトを担当する
- fully automatic: 格子点を指示として与え,SAMにマスクを生成させる。
Datasetについて
データセット(SA-1B)は,1100万の画像と10億以上のマスクが含まれるよ。
既存のデータと比べると400倍くらいのサイズがあるよ。
Responsible AIについて
差別を助長しない,公平性を持ったAIを作るよ
Experimentsについて
- 23の新たなデータセットを使ってSAMを評価したよ。
- 画像中の1点を指示することによるマスクの生成については,手作業による分類と比べてごくわずかに劣る程度だったよ
- プロンプトエンジニアリングに基づく様々な下流タスク(エッジ検出,オブジェクト生成提案,インスタンスセグメンテーション,テキストに基づくマスクの探索的な予測)について,定性的・定量的に一貫した結果を示したよ
Releaseについて
データセットSA-1BとモデルSAMについて,研究目的で公表するよ。
Segment anything論文で書いていないこと
Checkpoint
機械学習だと当然の用語なのか……?
学習中のモデルのスナップショットのことをcheckpointと呼ぶらしい。
Segment Anything Modelでは,backbone(ニューラルネットワークにおける,序盤から中盤までの層全体を指すらしい)が異なるいくつかの学習済みモデル(vit_b
(Base),vit_l
(Large),vit_h
(Huge))が提供されている。正確性とパフォーマンスのトレードオフで,どれを選択するか決定する。デフォルトはvit_h
だが,vit_l
のバランスが良いらしい。
- vit_h
: 正確だが時間がかかる
- vit_l
: 2つのモデルの中間
- vit_b
: 高速だがやや不正確
GISでSAM:Geo-SAM
QGISプラグインになっているようなので,導入してみた。環境はWindows 11 + QGIS 3.32
導入手順
公式(https://geo-sam.readthedocs.io/en/latest/Installation.html)と同じだが,メモに残しておく。
-
OSGeo4Wshellを開いて,以下を入力
pip3 install torch torchvision pip3 install torchgeo pip3 install segment-anything
-
プラグインzipをダウンロード(https://github.com/coolzhao/Geo-SAM/releases/tag/v1.1.1)
-
プラグインをQGISプラグインのパス(
%APPDATA%\QGIS\QGIS3\profiles\default\python\plugins
)に展開。ただし,フォルダ名がGeo-SAM
になるように注意(そのまま展開するとGeo-SAN-1.1.1
とかになるので) -
QGISでプラグインを有効化
これで,簡単に使える。
使用法
公式の通りなので省略
GISでSAM:segment-geospatial
適当なtifの全体についてマスクを生成したかった。
ざっと見てGeo-SAMでの方法が分からなかったが,pythonのsegment-geospatialパッケージを使うと簡単にできることがわかった。
導入手順
こちらもほぼ公式と同じだが
- 適当なpython環境に
segment-geospatial
をインストールpip install segment-geospatial
- 同じく,GDALをインストール。ただし,私のpython環境では
pip
ではうまく行かず,アーカイブ(https://www.lfd.uci.edu/~gohlke/pythonlibs/)から適当な.whl
ファイル(たとえばGDAL-3.4.3-cp310-cp310-win_amd64.whl
)をダウンロードしてくる必要があった。pip install GDAL-3.4.3-cp310-cp310-win_amd64.whl
- SAMのcheckpoint (https://github.com/facebookresearch/segment-anything#model-checkpoints)をダウンロードする。
使用法
下記のpythonコードで,適当な画像(ここでは1286 x 697の衛星画像,解像度1.2mくらい)についてマスクを生成できる。
ただし,python実行環境にSAMチェックポイントsam_vit_l_0b3195.pth
を格納している。
from samgeo import SamGeo, tms_to_geotiff
bbox = [-122.2659, 37.8682, -122.2521, 37.8741]
image = "satellite.tif"
tms_to_geotiff(output = image, bbox = bbox, zoom = 17, source = "Satellite", overwrite = True)
sam = SamGeo(model_type = "vit_l", checkpoint_dir=".", sam_kwargs = None)
sam.generate(image, output="masks.tif", foreground=True, unique=True)
sam.tiff_to_vector("masks.tif", "masks.gpkg")
マスクして,QGISにインポートすると,こんな感じ
精度はともかく,tiffからベクトルが生成できることはわかった。