こんにちは、皆さん。
今日は七夕ですね。七夕とか盆踊りとかクリスマスとかって、なんとなく音的なイメージもある気がします。しかも、音楽や効果音など、複数カテゴリの音が合成されて一つの印象を作っているようにも感じます。
さて、今日は YAMNet の TFLite モデルを使い、環境音データセット ESC-50 をどのくらいタグ付けできるか検証します。
今回検証する内容
YAMNet は、AudioSet の 521 種類の音響イベントを予測する音声タグ付けモデルです。今回は TensorFlow Hub で公開されている TFLite 版を Python から実行し、ESC-50 の 50 カテゴリと照合しました。
確認したい点は次のとおりです。
- YAMNet TFLite を Python から再現可能に実行できるか
- YAMNet の 521 ラベルを ESC-50 の 50 カテゴリへ対応させると、正解カテゴリが上位に入るか
- 細かいカテゴリより、5 つの大分類では安定するか
- 5 秒音声 2,000 本を処理する時間はどの程度か
完全なコードと再現可能な環境は、kiarina/labs の yamnet-esc50-audio-tagging lab で公開しています。
検証環境を準備する
実行には、次のツールと数百 MB 程度の空き容量が必要です。
次のコマンドで対象の lab だけを取得して実行できます。
git clone --depth 1 --filter=blob:none --sparse \
https://github.com/kiarina/labs.git
cd labs
git sparse-checkout set .gitignore .mise/tasks Makefile mise.toml \
2026/07/07/yamnet-esc50-audio-tagging
mise -C 2026/07/07/yamnet-esc50-audio-tagging run
初回は YAMNet TFLite、class map、ESC-50 archive を取得します。2 回目以降はダウンロード済みファイルの SHA-256 を確認して再利用します。
短い動作確認だけなら、lab ディレクトリで次を実行できます。
uv run python main.py --folds 1 --limit-per-class 1
モデルとデータセット
モデルは TensorFlow Hub の YAMNet TFLite 版を使いました。
model: https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1?lite-format=tflite
model SHA-256: 10c95ea3eb9a7bb4cb8bddf6feb023250381008177ac162ce169694d05c317de
class map revision: 5c597f85268743140854f0e670f2175e8668553a
class map SHA-256: cdf24d193e196d9e95912a2667051ae203e92a2ba09449218ccb40ef787c6df2
input: 1-D float32 waveform, 16 kHz mono
output: frame scores [frames, 521]
音声は FFmpeg で 16 kHz mono float32 PCM に変換し、TFLite モデルへ入力します。出力される frame scores は clip 単位で平均しました。
入力には ESC-50 の全 2,000 本を使います。ESC-50 は 5 秒の環境音を 50 クラスに分けたデータセットです。さらに、50 クラスは次の 5 つの大分類にまとまっています。
- animals
- natural soundscapes and water
- human non-speech
- interior and domestic
- exterior and urban
dataset revision は 33c8ce9eb2cf0b1c2f8bcf322eb349b6be34dbb6 に固定しました。ESC-50 全体は CC BY-NC なので、全 50 クラスを使う今回の検証も非商用条件に従う必要があります。
評価方法
YAMNet と ESC-50 はラベル体系が一致しません。そこで、ESC-50 の各カテゴリに対応しそうな YAMNet ラベルを手作業で割り当てました。
例は次のとおりです。
| ESC-50 category | 対応させた YAMNet label |
|---|---|
dog |
Dog, Bark
|
cat |
Cat, Meow, Purr
|
keyboard_typing |
Typing, Computer keyboard
|
chainsaw |
Chainsaw |
washing_machine |
Mechanisms, Water, Environmental noise
|
各音声について、対応する YAMNet ラベルの最大 score を ESC-50 category score としました。その score が最も高いカテゴリを予測結果とし、次を集計します。
- fine accuracy@1: 正解カテゴリが 1 位か
- fine accuracy@3: 正解カテゴリが上位 3 件に入るか
- fine accuracy@5: 正解カテゴリが上位 5 件に入るか
- coarse accuracy@1: 予測カテゴリの大分類が正解と同じか
学習や cross-validation は行いません。事前学習済みモデルを固定し、全 2,000 本を 1 回ずつ推論した観測結果です。
実行結果
Mac Studio でウォームアップなしに 1 回実行した結果は、次のとおりでした。
| 対象 | count | fine@1 | fine@3 | fine@5 | coarse@1 |
|---|---|---|---|---|---|
| all categories | 2,000 | 60.45% | 79.15% | 85.45% | 78.70% |
| direct label mapping categories | 1,600 | 68.94% | 85.00% | 90.50% | 83.00% |
direct label mapping categories は、ESC-50 category と YAMNet label が比較的直接対応していると判断した 40 カテゴリだけを集計したものです。dog、cat、rain、keyboard_typing、chainsaw などは含め、insects、drinking_sipping、can_opening、washing_machine などは除いています。
処理時間は次のとおりです。
2000 clips elapsed: 57.985 s
seconds per clip: 0.029 s
この時間には 2,000 ファイルの FFmpeg decode、TFLite 推論、frame score の平均、ESC-50 category score の計算が含まれます。モデルやデータの download は含みません。
カテゴリ別に見る
細分類でよく当たったカテゴリは次のとおりです。
| category | fine@1 | fine@3 | coarse@1 |
|---|---|---|---|
church_bells |
100.0% | 100.0% | 100.0% |
dog |
97.5% | 97.5% | 97.5% |
keyboard_typing |
97.5% | 97.5% | 97.5% |
train |
95.0% | 100.0% | 97.5% |
frog |
92.5% | 95.0% | 97.5% |
一方、難しかったカテゴリは次のとおりです。
| category | fine@1 | fine@3 | coarse@1 |
|---|---|---|---|
drinking_sipping |
0.0% | 2.5% | 20.0% |
hen |
0.0% | 92.5% | 92.5% |
mouse_click |
2.5% | 37.5% | 82.5% |
can_opening |
5.0% | 20.0% | 57.5% |
washing_machine |
5.0% | 25.0% | 12.5% |
hen は fine@1 では 0% ですが、fine@3 と coarse@1 は 92.5% です。多くは rooster と混同されました。細かい名前は外しても、音としては近い候補に入っている例です。
主な混同は次のとおりです。
| actual | predicted | count |
|---|---|---|
hen |
rooster |
35 |
snoring |
breathing |
28 |
pouring_water |
water_drops |
27 |
mouse_click |
keyboard_typing |
22 |
siren |
clock_alarm |
20 |
大分類別の accuracy は次のとおりです。
| coarse category | correct / count | coarse@1 |
|---|---|---|
| animals | 369 / 400 | 92.25% |
| exterior and urban | 349 / 400 | 87.25% |
| human non-speech | 293 / 400 | 73.25% |
| natural soundscapes and water | 284 / 400 | 71.00% |
| interior and domestic | 279 / 400 | 69.75% |
結果を考える
まず、YAMNet TFLite は Python から問題なく実行できました。5 秒音声 2,000 本を 1 分弱で処理できたので、軽いタグ付け処理としては扱いやすい印象です。
結果は、細かい 50 カテゴリを一発で当てる用途では強くありません。全体の fine@1 は 60.45% です。ただし、正解が上位 5 件に入る割合は 85.45%、直接対応しやすいカテゴリでは 90.50% でした。人に見せる候補を出す、後段の分類器へ渡す、音声検索の初期ラベルを付ける、といった使い方なら現実的に見えます。
大分類では 78.70% まで上がりました。特に animals と exterior and urban は安定しています。一方で、interior and domestic は低めでした。生活音は click、water、mechanisms のような広いラベルに寄りやすく、細かいカテゴリへ分けるには情報が足りない場面がありそうです。
注意点もあります。今回の評価は、YAMNet の 521 ラベルを ESC-50 の 50 カテゴリへ手作業で写像しています。対応表にない近いラベルを YAMNet が強く出した場合、音の理解としては自然でも、評価上は不正解になります。逆に、広いラベルが偶然 category score を押し上げることもあります。
また、ESC-50 の公式リポジトリには、元音源へクラス依存の前処理が施されたことによる情報漏洩の可能性が記載されています。今回の数値は、モデル性能の絶対評価ではなく、この固定した条件での観測結果として読むのがよさそうです。
検証環境は次のとおりです。
- machine: Mac Studio
- chip: Apple M4 Max
- OS: macOS 26.5.1、arm64
- Python: 3.12.11
- NumPy: 2.5.1
- ai-edge-litert: 2.1.6
- aggregation: mean
試してみた感想
YAMNet は、CLAP のように「音同士の意味的な近さ」を見るモデルとは少し違い、いま鳴っている音に直接ラベルを付ける道具としてわかりやすいです。精度表だけを見ると 60% 台に見えますが、上位候補まで含めるとかなり使い道があります。
特に hen → rooster、snoring → breathing、pouring_water → water_drops のような間違いは、人間から見ても近い音です。アプリ側で「候補」として扱うなら、失敗というより、粗い音の理解としては悪くない結果に見えました。
一方で、washing_machine や drinking_sipping のような生活音は難しそうです。複数の音が混ざるカテゴリや、YAMNet 側にぴったりのラベルがないカテゴリでは、対応表の作り方に強く左右されます。
それでも、複数のカテゴリが合成されて一つの印象を作り出している音を、上位候補としてほどいて見られるのは面白いところです。YAMNet 単体で完璧を狙うより、軽い音声タグ付けの入口として使うのが良さそうでした。