0% loading

気遣い

Computer Vision YOLOv8 React Native Deep Learning Disaster Tech

これはモバイルAIアプリだ——課題のためでも、ハッカソンのためでもなく、IDCamp 2025 Developer Challenge: Small Apps for Big Preparedness という大会に参加するため、イードの長期休暇の間にただスクロールし続けるよりはマシなことをしようと始めたもの。


災害報道からいつも抜け落ちていることがある。死者数、瓦礫の写真、被害額——そういったものは目に入る。でも現場で最も根本的なボトルネックについて語られることは、ほとんどない:優先順位付けだ。救援チームが現地に到着する。被災した建物が何百棟もある。完全に崩壊しているのはどれか?まだ居住できるのはどれか?物資支援が最も急がれるのはどれか?今の作業は手作業だ——建物から建物へと歩き、目で確認し、紙やスプレッドシートにメモする。

緊急事態において、遅さは代償を伴う。時に、取り返しのつかないほどの代償を。

Kizukai——インドネシア語でkepedulian、「気遣い」を意味する——はアルファが出した答えだ。アイデアはシンプルだ:写真 → AIが損傷レベルを評価 → 報告書が自動入力される。救援スタッフが建物の写真を撮り、AIがその損傷をDS0(無被害)からDS4(全壊)のスケールで分類し、データが直接優先順位付けシステムへと流れ込む。建物一棟あたり何十分もかかっていた作業が、数秒になる。

紙の上では、アイデアはきれいだ。実装は、また別の話だった。


最初の試みは、振り返ってみると、あまり現実的ではない自信から始まった。

アルファはMobileNetV3Smallをバックボーンに選んだ。理にかなっていた——軽量なアーキテクチャ、モバイル推論向けの設計、エッジコンピューティングアプリで広く使われている。データセットはRoboflowから取得した:Hurricane、Tornado、Earthquakeの災害画像コレクションで、ラベルも整っていた。学習が走った。Lossが下がった。検証メトリクスは良さそうに見えた。

学習データの外にある画像で推論を試みるまでは。

MobileNetV3 Results

結果は悪かった。「ファインチューニングが必要」という意味での悪さではなく——このモデルが自信満々に、ほぼすべてのテスト画像を誤判定するという意味での悪さだ。これはアンダーフィットではない。モデルが慎重すぎるのではない。これは教科書通りのオーバーフィット——モデルは答えを暗記したが、概念を学んでいなかった。学習データを丸ごと頭に入れているのに、それ以外のものには全く対応できない。

深く調べると、問題はキャパシティの問題だった。MobileNetV3Smallは、そもそもこの課題には力が足りなかった。建物の損傷検出は繊細な仕事だ——壁のひび、構造的な変形、一部が崩落した屋根——これらすべてに、MobileNetV3が捉えられるよりもはるかに豊かな特徴表現が必要だ。アーキテクチャが問題に対して小さすぎた。


新しい戦略:グローバルにより幅広いバリエーションを得るため、異なるソースから3つのデータセットを組み合わせる。

  1. TornadoNet Dataset — HuggingFace
  2. All Hurricane / Tornado / Earthquake — Roboflow
  3. Building Damage Assessment — Roboflow

最初のデータセット——約3,000枚——はほぼすべてアメリカ式の住宅だった。インドネシアではない。2番目と3番目のデータセットを追加することで、より明確な構造的損傷とより幅広い建物タイプの画像が加わり、モデルが欠いていたバリエーションが補えると期待した。

シンプルに聞こえる:ダウンロードして、マージして、学習させる。しかしファイルを一つずつ開いた瞬間、現実は違った。データセットAのラベルはdestroyeddamagedminor-damage。データセットBはDS1DS2DS3。データセットCはまた別の数値体系を使っていた。これはそのままconcatできない。標準化なしに強引に組み合わせたら、モデルは間違ったことを学習してしまう——同じ概念に対して3つの異なる言葉、同じ言葉に対して3つの異なる概念。Garbage in, garbage out.

解決策は一つ——最初からラベリングをやり直し、すべてのクラスをDS0からDS4の一貫した標準に再マッピングする。

アルファはLabel Studioをインストールした——それまで一度も触ったことのないアノテーションソフトウェアだ。最初の数日間はワークフローを理解するだけで費やした:データセットのインポート方法、新しいクラスの定義方法、YOLOフォーマットへのエクスポート方法。その後、ラベリングが始まった。一枚ずつ。何千もの画像。バウンディングボックスを描いて、クラスを割り当てて、次へ。繰り返す。

このプロセスに華やかさは一切ない。座って、クリックして、描いて、次へ。しかしこれがすべての基盤だ——モデルはそれが与えられたデータと同じレベルにしかなれない。最初からデータが間違っていたら、どんなアーキテクチャも救えない。


データセットの準備が整った。次は、より本格的なアーキテクチャへ移行する時だ:YOLOv8。精度だけの問題ではない——YOLOv8は最初から物体検出のために設計されており、画像を分類するだけでなく、バウンディングボックスを通じてオブジェクトをローカライズする。損傷がどこにあるかを知る必要がある建物損傷評価に、まさに適したアーキテクチャだ。

学習が始まった。最初の数分間は何も問題なかった。そしてコンソールが埋まり始めた:

ignoring corrupt image/label: cannot identify image file 'train/images/sample_0847.npy'
ignoring corrupt image/label: cannot identify image file 'train/images/aug_frame_112.npy'
ignoring corrupt image/label: cannot identify image file 'train/images/img_0293.jpg'

何十行も。すべて赤色。

調査した。3つのデータセットをマージする過程で、いくつかの**.npy**ファイル——NumPyバイナリ配列フォーマット——が/imagesフォルダの中に紛れ込んでいた。これらは画像ではない。バイナリフォーマットにシリアライズされたデータ配列だ。しかしそのファイル名のせいで、何千もの.jpgファイルの中に目立たず埋もれていた。YOLOv8はそれらを画像ファイルとして開こうとして、当然失敗した。さらに、いくつかの.jpgファイルは0バイトだった——最初のダウンロード段階でこっそり失敗していたものだ。

アルファは手動でのクリーンアップを覚悟した。学習をゼロから再起動しなければならないかもしれないと諦めながら。

しかし学習は止まらなかった。

走り続けた。エラーはログに記録され、そしてYOLOv8は破損したファイルをすべてスキップして、健全なデータセットの残りで学習を続けた。クラッシュなし。途中でのアボートなし。このシステムにはアルファが知らなかったフォールトトレランスが組み込まれていた——不完全なデータの中でも生き残れるほど頑丈で、スキップしたすべてのものをログに正直に書き残すほど誠実だった。

学習が完了した後の最終結果は?

mAP: 0.72。

YOLOv8 Results

0.72は確かな数字だ。完璧ではない——完璧な建物損傷検出モデルなど存在しない——しかし現場での補助ツールのバックボーンとして、十分に一貫していて十分に信頼できる。そしてここからの教訓は、数字だけに留まらない:よく設計されたシステムは汚いデータの中でも生き残れる。現実世界で機能するモデルを得るために、100%清潔なデータセットは必要ない。


.ptモデルをTFLiteにエクスポートした——モバイル推論向けに最適化されたフォーマットだ。最終サイズ:42MB。アプリに直接組み込めるほど軽量で、推論のたびに外部サーバーへの接続を必要としない——インターネット接続がしばしば最初の犠牲になる被災地では、これは決定的に重要だ。

React Nativeへの統合が最後の章となった。それまでのすべてのプロセスとは、まったく違う感触だった。データエンジニアリングの段階があらゆるデバッグに満ちた疲弊する作業だったとすれば、この段階はどのプログラマーにも覚えのあるモードだ:バイブコーディング。必要なMCPを繋いで、AIにプロンプトを投げて、生成を待ちながらFacebookをスクロールする。

UIはMaterial Design 3の上に構築した——ユーザーに親しみやすさと安心感を与えるデザインシステムだ。緊急事態の中で、プレッシャーの下で、もしかしたらこうしたツールを初めて手にする人が使うアプリにとって、この2つは決定的に重要だ。色、タイポグラフィ、コンポーネント——すべてが既に実績のあるシステムに従っている。

Kizukaiの最終的なワークフローはシンプルだ:

  • 写真 — 救援スタッフが被災した建物を撮影する
  • AI検出 — TFLiteモデルがデバイス上で直接動作し、損傷レベルDS0〜DS4を分類する
  • フォーム自動入力 — 検出結果が報告書のフィールドに自動的に入力される
  • 報告書送信 — データが物資の優先順位付けシステムに流れ込む

Kizukaiが現場で軸力を計算できる構造エンジニアの代わりになれないことは明らかだ。mAP 0.72は正直な数字だ——誤差の余地があり、災害対応の文脈では、誤りには現実の結果が伴う。これは補助ツールであり、最終的な判断を下すものではない。

しかしパイプラインは本物だ。写真から構造化された報告書まで、推論にインターネット接続を必要とせず、高いプレッシャーの下でも操作できるUIを持って。

そしてすべての背後には、mAPのスコアよりもずっと重要な教訓がある:退屈なデータエンジニアリングの作業は、AIプロジェクトのサイドタスクではない——それこそがプロジェクトそのものだ。Label Studioで何日も一つずつバウンディングボックスを描き、なぜ.npyファイルが画像フォルダに紛れ込んだのかを追い、誤ったクラスのラベルを一つずつ検証する——それがモデルが機能するかどうかを決める。

気遣いは、先に面倒な作業をいとわないところから始まる。

データのレベルにまで降りて。

それがKizukaiだ。

Logo

© 2026 Raditya Alfarisi

Github LinkedIn Instagram Kaggle Chess.com