Journal

Acoustic Anomaly Detection: ตรวจจับเสียงแตกกระจก เสียงร้อง YAMNet TensorFlow บน Raspberry Pi

Acoustic Anomaly Detection: Glass Break and Scream Detection with YAMNet TensorFlow on Raspberry Pi

12 พฤษภาคม 2569 · 1 นาที

Acoustic Anomaly Detection: หูของบ้านที่ไม่เคยหลับ

กล้อง CCTV ตรวจจับการบุกรุกได้เมื่อเห็นคน แต่เสียง แตกกระจก เกิดก่อนที่บุคคลจะปรากฏในกล้อง และเสียง ร้องขอความช่วยเหลือ เกิดในมุมที่กล้องมองไม่เห็น Acoustic Detection ปิดช่องว่างนี้ด้วยการฟังตลอด 24 ชั่วโมง

YAMNet: Google Audio Classification Model

YAMNet (Yet Another Mobile Network) เป็น audio classification model ของ Google ที่ฝึกด้วย AudioSet dataset (2 ล้าน video, 521 classes) รองรับการตรวจจับ: - Glass breaking (เสียงแตกกระจก) - Screaming (เสียงร้อง) - Smoke alarm / CO alarm - Gunshot - Dog barking - Siren รัน YAMNet TFLite บน Raspberry Pi 5 ด้วย ~180MB RAM, ~15% CPU

Hardware Setup

Microphone Array แนะนำ: - ReSpeaker 4-Mic Array สำหรับ Raspberry Pi (~1,200 บาท): 4 microphones พร้อม DOA (Direction of Arrival) estimation - หรือ USB omnidirectional mic ราคา ~300–600 บาท สำหรับ single-room monitoring การวาง microphone: - ห้องนั่งเล่น: ติดเพดาน ตรงกลางห้อง - หน้าประตูทางเข้า: ตรวจจับเสียงทุบประตูหรือแกะกุญแจ - ห้องนอนผู้สูงอายุ: ตรวจจับ fall sound + scream

Implementation: YAMNet บน Raspberry Pi

python import numpy as np import sounddevice as sd import tensorflow as tf  # Load YAMNet TFLite model interpreter = tf.lite.Interpreter('yamnet.tflite') interpreter.allocate_tensors() input_details = interpreter.get_input_details() output_details = interpreter.get_output_details()  TARGET_CLASSES = {     9: ('glass_break', 0.7),      # Glass, shatter     40: ('scream', 0.65),          # Screaming     312: ('smoke_alarm', 0.8),     # Smoke detector     427: ('gunshot', 0.85),        # Gunshot }  def classify_audio(audio_chunk):     waveform = audio_chunk.flatten().astype(np.float32)     waveform = waveform / np.max(np.abs(waveform) + 1e-6)     interpreter.set_tensor(input_details[0]['index'], [waveform])     interpreter.invoke()     scores = interpreter.get_tensor(output_details[0]['index'])[0]     for class_id, (class_name, threshold) in TARGET_CLASSES.items():         if scores[class_id] > threshold:             return class_name, scores[class_id]     return None, 0  def audio_callback(indata, frames, time, status):     audio_chunk = indata[:, 0]     event, confidence = classify_audio(audio_chunk)     if event:         publish_to_mqtt(event, confidence)  with sd.InputStream(samplerate=16000, channels=1,                     blocksize=15600, callback=audio_callback):     sd.sleep(int(1e9))  # run forever

False Positive Reduction

YAMNet มี false positive สูงกับเสียงบางชนิด ใช้กลยุทธ์:

  1. Confirmation Window: event ต้องเกิดขึ้น 2 ครั้งใน 3 วินาที 2. Context Suppression: ถ้า TV เปิดอยู่ (ดูจาก media player state ใน HA) ลด threshold ลงหรือ ignore เสียงบางชนิด 3. Direction Estimation (ถ้าใช้ 4-mic array): เสียงจากทิศที่มีกำแพงนอก (ไม่ใช่ทิศห้องน้ำ) ให้ priority สูงกว่า 4. Nighttime Sensitivity Boost: ระหว่าง 22:00–07:00 ลด confirmation threshold เป็น 1 ครั้ง

Home Assistant Integration

yaml automation:   - alias: "Glass Break Alert"     trigger:       - platform: mqtt         topic: "acoustic/event"         payload: "glass_break"     action:       - service: alarm_control_panel.alarm_trigger         target:           entity_id: alarm_control_panel.home_alarm       - service: notify.line_family         data:           message: "🔔 ตรวจพบเสียงแตกกระจก! กรุณาตรวจสอบทันที"           data:             photo: "/api/frigate/notifications/front_door/thumbnail.jpg"

Privacy: ไม่บันทึกเสียง

ระบบประมวลผล audio stream แบบ real-time ไม่บันทึกเสียงพูดหรือ audio file ใดๆ ลงดิสก์ บันทึกเฉพาะ event label, timestamp, confidence score เท่านั้น ทำให้ไม่มีความเสี่ยงด้าน privacy จาก audio recording

ต้นทุนรวม

| รายการ | ราคา (THB) | |--------|------------| | Raspberry Pi 5 4GB | 2,200 | | ReSpeaker 4-Mic Array | 1,200 | | USB power + enclosure | 400 | | YAMNet TFLite model | ฟรี (Apache 2.0) | | รวม | 3,800 |

คำถามที่พบบ่อย

ระบบนี้จะ false positive กับเสียง TV หรือเสียงเด็กเล่นไหม?
Context suppression ช่วยได้มาก ถ้า Home Assistant รู้ว่า TV เปิดอยู่ จะเพิ่ม threshold สำหรับเสียงที่อาจ false positive สำหรับเสียงเด็กเล่น confirmation window 2 ครั้งใน 3 วินาทีช่วยกรอง isolated false alarm ออก
YAMNet สามารถตรวจจับเสียงภาษาไทยได้ไหม?
YAMNet ตรวจจับ acoustic characteristics ไม่ใช่ภาษา ดังนั้น scream ภาษาไทยมี frequency content เดียวกับ scream ภาษาอื่น ตรวจจับได้เท่ากัน แต่ถ้าต้องการ speech recognition ต้องใช้ model อื่น เช่น Whisper
ระยะทำการของ microphone ครอบคลุมกี่ตร.ม.?
ReSpeaker 4-Mic Array ครอบคลุมได้ประมาณ 5–8 เมตร ในห้องที่มีเฟอร์นิเจอร์ดูดซับเสียง สำหรับบ้าน 2 ชั้น ควรติดตั้ง 1 unit ต่อชั้น หรือ 1 unit ต่อ zone หลัก