さんや商事
猿とAI+人間の奮闘記

ヒヨドリで配管を通す

さんや
さんや
ヒヨドリで配管を通す
#YOLO #ヒヨドリ #物体検知 #可観測性 #南房総

移住して二年目の初夏のことです。

畑にはブルーベリーの木があります。移住一年目は、何もしないでも実がたわわになりました。剪定の知識も防鳥の備えもないまま、ただ枝が紫色に埋まって、毎朝もいで食べていました。豊作でした。だから二年目も、当然そうなるものだと思っていました。

ステンレスの台の上に、大小六つのボウルやザルに山盛りになった大量の収穫済みブルーベリー
一年目の収穫。何もしなくても、これだけ採れた

ところが、その年はいつまで経っても実が完熟しません。色づき始めてもいい時期に、まだ青い。おかしいなと思いながら待っていました。気がついたら、実がほとんど残っていませんでした。

最初は原因の見当がつきませんでした。病害か、天候か、土か、木の樹勢か。候補がいくつもあって、どれも決め手に欠ける。しばらく畑に立って、ブルーベリーの木をただ見ていました。すると、ヒヨドリが来ました。一羽ではありません。次々に来て、青いうちから実をついばんで、また飛んでいく。それを何度も繰り返している。

律速はそこでした。天候でも病害でもなく、鳥が実を持っていく速さが、収穫までのプロセス全体を決めていた。観察するまで、私はそれを病気だと思い込んでいたのです。一年目に豊作だったのは、たまたまこの個体群に見つかっていなかっただけかもしれません。

その年のブルーベリーはほぼ全滅でした。翌年から防鳥ネットを張りました。

山並みを背景に、緑色の防鳥ネットですっぽり覆われたブルーベリーの木。骨組みの支柱で立体的に張られている
翌年から張った防鳥ネット。物理的に遮断すれば、そこで終わる

ネットを張ってからは、ヒヨドリは実に届きません。物理的に遮断してしまえば、そこで終わりです。敵を見て、効くところに対策を一点だけ打つ。畑ではそれで片がつきました。

この「まず律速を見つける」という順序を、私はこのあと、まったく別の場所でもう一度なぞることになります。


サルを検知するシステムを作り始めたとき、最初にぶつかったのは、サルが来ないことでした。

正確に言うと、サルが来ないこと自体は問題ではありません。問題は、サルが来ないせいで、作ったシステムが動いているのかどうかが、観測できないことでした。

組んだのは、カメラが何かを捉えたら判定して、判定が出たら手元に通知が飛ぶ、という一本の流れです。配管のようなものだと思ってください。入口から入れたものが出口から出てくるか。その経路が通っているかを確かめたい。ところが入口に流すべきサルが、月に一度来るかどうかなのです。

来ないあいだ、何も起きません。通知も来ません。これは経路が通っていて、ただ入力がないだけなのか。それとも経路のどこかで切れていて、サルが来ても通知は出ないのか。区別がつきません。入力がゼロのままでは、システムが正常なのか故障なのか、切り分けようがない。

しかも、深夜帯にだけは反応がありました。誤検知です。夜になると、本来は何もないはずのフレームに、システムが発火する。サルでも他の動物でもないものに反応して、けれど肝心のサルは一度も捉えない。動かしているのに、生きているのか死んでいるのか判定できない。この、可観測性のない状態が、しばらく続きました。

ここで考えたのは、配管の検証と、入力が来るか来ないかを、分離することでした。サルという低頻度の入力で経路を試すから、いつまでも確かめられない。だったら、確実に来るもので入口を埋めればいい。入力を定常にしてしまえば、観測したいのは経路の生死だけになります。

毎日、必ず来るもの。心当たりは一つでした。ヒヨドリです。

ブルーベリーを全滅させた、あの鳥です。あれは確実に来ます。来ない日はない。サルの代わりにヒヨドリで配管を通せば、入力の有無という変数が落ちて、経路が生きているかどうかだけが残る。皮肉な話で、二年前に畑を荒らした相手が、今度はシステムのテスト入力として役に立つことになりました。


とはいえ、ヒヨドリに切り替えてすぐ通った、という話ではありません。

最初に使っていたのは YOLOv8 です。画像から物体を見つける、汎用の検出モデル。汎用なので人や車も見つける。鳥も当然見つけられるはずでした。ところが回してみると鳥はほとんど拾えず、代わりに妙なものばかり引っかかりました。ベンチ。ボート。象。畑にベンチも象もありません。

モデルは、検出するたびに「これは鳥だ」という確信度を一緒に出してきます。その確信度が一定の線を超えたものだけを採用する、という線が引いてある。閾値です。鳥が拾えないなら閾値が高すぎるのだろうと考えて、その線をだいぶ下まで下げました。それでも鳥は出てきません。閾値をいじっても、出ないものは出ない。感度の問題ではない、ということだけがわかりました。

数値をいじるのをやめて、システムが実際に何を見て「ベンチだ」「ボートだ」と発火しているのか、その画像を全部保存して、一枚ずつ目で見ることにしました。畑でヒヨドリを見つけたときと同じです。律速がわからないなら、まず現物を見る。

見てわかりました。「ベンチ」と判定されていたのは、小屋の屋根の水平なエッジでした。横一直線の構造を、モデルが低い確信度でベンチの背と読んでいた。夜中の「人」は、赤外線照明に光ったクモの糸や、レンズ近傍を横切る虫でした。鳥がいないのではなく、画角に鳥が来る場所が入っていなかったのです。閾値の高低の問題ではありませんでした。何を視野に入れているか、の問題でした。誤検知の中身が、ぜんぶ画角由来のアーティファクトだった。

カメラの向きを調整して、屋根の水平エッジが主たる被写体にならないようにし、ブルーベリーの木と、その先の草地が入るようにしました。それでもベンチや人の誤検知が消えたわけではありません。誤検知の分布が入れ替わっただけで、件数が落ちたわけではない。ただ、向きを変えてしばらくした頃、初めて鳥が映りました。低木のそばに二羽。判定が出て、通知が、手元に飛びました。

経路は生きていました。


確かめたかったのは、それだけです。サルを検知できたわけではありません。この時点で、サルはまだ一度も映っていません。わかったのは、入口に何かが来れば、判定されて、出口の通知まで一本で通る、ということだけです。

それでも、これは小さなことではありませんでした。サルを待ち続けていたら、経路が通っているのかどうかすら、いつまでも未確定だったはずです。低頻度の入力では何も検証できない。確実に来るもので入力を定常化して、先に経路だけを通しておく。サルはそのあとでいい。

ブルーベリーのときと同じでした。実がならない原因を、観察するまで私は病害だと思っていた。サルが拾えない原因を、画像を見るまで私は閾値だと思っていた。どちらも、現物を見るまでは律速でない場所をいじっていたのです。ヒヨドリには、見たあとでネットという解がありました。サルに対して、ネットに当たる解が何なのかは、まだわかっていません。