สร้างเว็บแคมอัจฉริยะด้วย JavaScript ด้วยโมเดลแมชชีนเลิร์นนิงที่ฝึกไว้แล้วล่วงหน้าของ TensorFlow.js

1. ก่อนเริ่มต้น

ปัจจุบัน แมชชีนเลิร์นนิงถือเป็นคำยอดนิยม ดูเหมือนว่าแอปพลิเคชันจะมีขีดจำกัด และดูเหมือนว่าจะมีโอกาสได้ใช้งานเกือบทุกอุตสาหกรรมในอนาคตอันใกล้ หากคุณเป็นวิศวกรหรือนักออกแบบ ส่วนหน้า หรือระบบแบ็กเอนด์และคุ้นเคยกับ JavaScript โค้ด Lab นี้เขียนขึ้นเพื่อช่วยคุณเริ่มต้นเพิ่มแมชชีนเลิร์นนิงในชุดทักษะ

ข้อกำหนดเบื้องต้น

Codelab นี้เขียนขึ้นสำหรับวิศวกรที่มีประสบการณ์ซึ่งคุ้นเคยกับ JavaScript อยู่แล้ว

สิ่งที่คุณจะสร้าง

ใน Codelab นี้ คุณจะ

  • สร้างหน้าเว็บที่ใช้แมชชีนเลิร์นนิงในเว็บเบราว์เซอร์โดยตรงผ่าน TensorFlow.js เพื่อจัดประเภทและตรวจหาออบเจ็กต์ทั่วไป (เช่น การสร้างหน้าเว็บพร้อมกันมากกว่า 1 รายการพร้อมกัน) จากสตรีมแบบสดทางเว็บแคม
  • ชาร์จเว็บแคมปกติของคุณให้เต็มพิกัดเพื่อระบุวัตถุและรับพิกัดของกล่องขอบเขตสำหรับวัตถุแต่ละชิ้นที่พบ
  • ไฮไลต์วัตถุที่พบในสตรีมวิดีโอดังที่แสดงด้านล่าง

8f9bad6e49e646b.png

ลองนึกภาพดูว่าคุณสามารถตรวจจับได้ว่ามีคนอยู่ในวิดีโอหรือไม่ จากนั้นคุณสามารถนับจำนวนผู้คนในช่วงเวลาหนึ่งๆ เพื่อประมาณความพลุกพล่านของพื้นที่หนึ่งๆ ในแต่ละวัน หรือส่งการแจ้งเตือนให้ตัวเองเมื่อตรวจพบสุนัขในห้องบ้านของคุณในขณะที่คุณไม่อยู่ หากทำได้ คุณก็น่าจะพร้อมสร้างกล้อง Google Nest ในเวอร์ชันของคุณเองซึ่งสามารถแจ้งเตือนคุณเมื่อกล้องพบผู้บุกรุก (ทุกประเภท) โดยใช้ฮาร์ดแวร์ที่คุณกำหนดเอง เยี่ยมไปเลย ทำได้ยากใช่ไหม ไม่ใช่ มาเริ่มแฮ็กกันเลย...

สิ่งที่คุณจะได้เรียนรู้

  • วิธีโหลดโมเดล TensorFlow.js ที่ฝึกล่วงหน้า
  • วิธีดึงข้อมูลจากสตรีมแบบสดจากเว็บแคมและวาดภาพลงในแคนวาส
  • วิธีจัดประเภทเฟรมรูปภาพเพื่อค้นหากรอบล้อมรอบของวัตถุใดก็ตามที่โมเดลได้รับการฝึกให้จดจำ
  • วิธีใช้ข้อมูลที่ส่งคืนจากโมเดลเพื่อไฮไลต์ออบเจ็กต์ที่พบ

Codelab นี้จะมุ่งเน้นไปที่วิธีเริ่มต้นใช้งานโมเดลที่ฝึกล่วงหน้าของ TensorFlow.js จะไม่มีการอธิบายแนวคิดและโค้ดบล็อกที่ไม่เกี่ยวข้องกับ TensorFlow.js และแมชชีนเลิร์นนิง เพียงแค่คัดลอกและวางโค้ดนี้ก็เรียบร้อยแล้ว

2. TensorFlow.js คืออะไร

1aee0ede85885520.png

TensorFlow.js เป็นไลบรารีแมชชีนเลิร์นนิงโอเพนซอร์สที่เรียกใช้ JavaScript ได้ทุกที่ API ดังกล่าวอิงตามไลบรารี TensorFlow เดิมที่เขียนด้วย Python และมีเป้าหมายที่จะสร้างประสบการณ์สำหรับนักพัฒนาซอฟต์แวร์และชุด API ใหม่สำหรับระบบนิเวศของ JavaScript

ใช้ได้ที่ไหนบ้าง

เนื่องจาก JavaScript สามารถถ่ายโอนได้ จึงช่วยให้คุณเขียนในภาษาเดียวและดำเนินการแมชชีนเลิร์นนิงในแพลตฟอร์มทั้งหมดต่อไปนี้ได้อย่างง่ายดาย

  • ฝั่งไคลเอ็นต์ในเว็บเบราว์เซอร์ที่ใช้ JavaScript แบบวานิลลา
  • ฝั่งเซิร์ฟเวอร์และอุปกรณ์ IoT อย่าง Raspberry Pi ที่ใช้ Node.js
  • แอปบนเดสก์ท็อปที่ใช้ Electron
  • แอปที่มาพร้อมเครื่องที่ใช้ React Native

TensorFlow.js ยังสนับสนุนแบ็กเอนด์หลายชุดภายในแต่ละสภาพแวดล้อมเหล่านี้ (สภาพแวดล้อมจริงที่ใช้ฮาร์ดแวร์ซึ่งสามารถทำงานภายในได้ เช่น CPU หรือ WebGL เป็นต้น "แบ็กเอนด์" ในบริบทนี้ไม่ได้หมายถึงสภาพแวดล้อมฝั่งเซิร์ฟเวอร์ ตัวอย่างเช่น แบ็กเอนด์สำหรับการดำเนินการอาจเป็นฝั่งไคลเอ็นต์ใน WebGL) เพื่อรองรับความเข้ากันได้และทำให้ทุกอย่างทำงานได้อย่างรวดเร็ว ปัจจุบัน TensorFlow.js รองรับ

  • การดำเนินการของ WebGL บนการ์ดแสดงผลของอุปกรณ์ (GPU) - นี่เป็นวิธีที่เร็วที่สุดในการใช้งานโมเดลที่มีขนาดใหญ่ขึ้น (มีขนาดใหญ่กว่า 3 MB) ด้วยการเร่งความเร็ว GPU
  • การดำเนินการ Web Assembly (WASM) บน CPU เพื่อปรับปรุงประสิทธิภาพของ CPU ในอุปกรณ์ต่างๆ เช่น โทรศัพท์มือถือรุ่นเก่า วิธีนี้เหมาะกับโมเดลขนาดเล็ก (มีขนาดเล็กกว่า 3 MB) ซึ่งทำงานบน CPU ด้วย WASM ได้เร็วกว่า WebGL เนื่องจากค่าใช้จ่ายในการอัปโหลดเนื้อหาไปยังโปรเซสเซอร์กราฟิก
  • การดำเนินการของ CPU - ตัวเลือกสำรองต้องไม่มีสภาพแวดล้อมอื่นๆ พร้อมใช้งาน นี่คือรายการที่ช้าที่สุดใน 3 อันดับ แต่เราพร้อมช่วยเหลือคุณเสมอ

หมายเหตุ: คุณเลือกที่จะบังคับใช้หนึ่งในแบ็กเอนด์เหล่านี้ได้หากทราบว่าจะใช้อุปกรณ์ใด หรือจะให้ TensorFlow.js ตัดสินใจแทนก็ได้หากไม่ระบุ

พลังพิเศษฝั่งไคลเอ็นต์

การเรียกใช้ TensorFlow.js ในเว็บเบราว์เซอร์บนเครื่องไคลเอ็นต์อาจก่อให้เกิดประโยชน์มากมายที่ควรค่าแก่การพิจารณา

ความเป็นส่วนตัว

คุณจะฝึกและแยกประเภทข้อมูลในเครื่องไคลเอ็นต์ได้โดยไม่ต้องส่งข้อมูลไปยังเว็บเซิร์ฟเวอร์ของบุคคลที่สาม บางครั้งระบบอาจกำหนดให้ต้องปฏิบัติตามข้อกำหนดเพื่อปฏิบัติตามกฎหมายท้องถิ่น เช่น GDPR หรือเมื่อประมวลผลข้อมูลที่ผู้ใช้อาจต้องการเก็บไว้ในเครื่องและไม่ส่งไปยังบุคคลที่สาม

ความเร็ว

เนื่องจากคุณไม่ต้องส่งข้อมูลไปยังเซิร์ฟเวอร์ระยะไกล การอนุมาน (การแยกประเภทข้อมูล) จึงทำงานเร็วขึ้น ยิ่งไปกว่านั้น คุณยังเข้าถึงเซ็นเซอร์ของอุปกรณ์ได้โดยตรง เช่น กล้อง, ไมโครโฟน, GPS, ตัวตรวจวัดความเร่ง และอื่นๆ หากผู้ใช้ให้สิทธิ์เข้าถึงแก่คุณ

การเข้าถึงและการปรับขนาด

เพียงคลิกเดียว ทุกคนในโลกก็สามารถคลิกลิงก์ที่คุณส่งไป เปิดหน้าเว็บในเบราว์เซอร์ของตน และใช้สิ่งที่คุณสร้างขึ้นมาได้ ไม่ต้องมีการตั้งค่า Linux ฝั่งเซิร์ฟเวอร์ที่ซับซ้อนด้วยไดรเวอร์ CUDA และอื่นๆ อีกมากมายเพื่อใช้ระบบแมชชีนเลิร์นนิงเพียงอย่างเดียว

ค่าใช้จ่าย

หากไม่มีเซิร์ฟเวอร์ สิ่งเดียวที่คุณต้องเสียค่าใช้จ่ายคือ CDN เพื่อโฮสต์ไฟล์ HTML, CSS, JS และไฟล์โมเดล ค่าใช้จ่ายของ CDN ถูกกว่าการเก็บเซิร์ฟเวอร์ (โดยอาจมีการ์ดแสดงผลต่ออยู่) ที่ทำงานตลอด 24 ชั่วโมงอย่างมาก

ฟีเจอร์ฝั่งเซิร์ฟเวอร์

การใช้ประโยชน์จากการติดตั้งใช้งาน Node.js ของ TensorFlow.js จะเป็นการเปิดใช้ฟีเจอร์ต่อไปนี้

การรองรับ CUDA อย่างเต็มรูปแบบ

สำหรับฝั่งเซิร์ฟเวอร์ สำหรับการเร่งการแสดงผลการ์ดกราฟิก คุณต้องติดตั้งไดรเวอร์ NVIDIA CUDA เพื่อให้ TensorFlow ทำงานกับการ์ดแสดงผล (ต่างจากเบราว์เซอร์ที่ใช้ WebGL ไม่ต้องติดตั้ง) อย่างไรก็ตาม ด้วยการสนับสนุน CUDA เต็มรูปแบบ คุณจะสามารถใช้ประโยชน์จากความสามารถระดับต่ำกว่าของการ์ดแสดงผลได้อย่างเต็มที่ ทำให้การฝึกใช้เวลาและการอนุมานรวดเร็วขึ้นได้ ประสิทธิภาพการทำงานจะเทียบเท่ากับการติดตั้งใช้งาน Python TensorFlow เนื่องจากทั้งคู่ใช้แบ็กเอนด์ C++ เดียวกัน

ขนาดรุ่น

สำหรับโมเดลล้ำสมัยจากการวิจัย คุณอาจทำงานกับโมเดลขนาดใหญ่มากซึ่งอาจมีขนาดกิกะไบต์ โมเดลเหล่านี้ไม่สามารถทำงานในเว็บเบราว์เซอร์ได้ในขณะนี้ เนื่องจากมีข้อจำกัดในการใช้หน่วยความจำต่อแท็บของเบราว์เซอร์ หากต้องการใช้งานโมเดลที่มีขนาดใหญ่ขึ้น คุณสามารถใช้ Node.js บนเซิร์ฟเวอร์ของคุณเองที่มีข้อมูลจำเพาะของฮาร์ดแวร์ที่คุณจำเป็นต้องใช้เพื่อเรียกใช้โมเดลดังกล่าวอย่างมีประสิทธิภาพ

IOT

Node.js ได้รับการสนับสนุนบนคอมพิวเตอร์บอร์ดเดี่ยวที่ได้รับความนิยมอย่าง Raspberry Pi ซึ่งก็หมายความว่าคุณสามารถเรียกใช้โมเดล TensorFlow.js บนอุปกรณ์ดังกล่าวได้เช่นกัน

ความเร็ว

Node.js เขียนขึ้นด้วย JavaScript ซึ่งหมายความว่าจะได้รับประโยชน์จากการรวบรวมข้อมูลในเวลาเท่านั้น ซึ่งหมายความว่าคุณอาจเห็นประสิทธิภาพเพิ่มขึ้นเมื่อใช้ Node.js เนื่องจาก Node.js จะได้รับการเพิ่มประสิทธิภาพขณะรันไทม์ โดยเฉพาะสำหรับการประมวลผลล่วงหน้าที่คุณอาจกำลังทำอยู่ ดูตัวอย่างที่ยอดเยี่ยมได้ในกรณีศึกษานี้ ซึ่งแสดงให้เห็นว่า Hugging Face ใช้ Node.js ในการเพิ่มประสิทธิภาพ 2 เท่าสำหรับโมเดลการประมวลผลภาษาธรรมชาติอย่างไร

ตอนนี้คุณเข้าใจข้อมูลพื้นฐานของ TensorFlow.js ซึ่งทำงานได้รวมถึงข้อดีบางประการแล้ว มาเริ่มทำสิ่งที่เป็นประโยชน์ด้วยกันเลย

3. โมเดลก่อนการฝึก

TensorFlow.js มีโมเดลแมชชีนเลิร์นนิง (ML) ก่อนการฝึกที่หลากหลาย โมเดลเหล่านี้ได้รับการฝึกโดยทีม TensorFlow.js และรวมเข้าไว้ในคลาสที่ใช้งานง่าย และเป็นวิธีที่ยอดเยี่ยมในการใช้แมชชีนเลิร์นนิงตั้งแต่ก้าวแรก แทนที่จะสร้างและฝึกโมเดลให้แก้ปัญหา คุณสามารถนำเข้าโมเดลที่ฝึกไว้แล้วล่วงหน้าเป็นจุดเริ่มต้นได้

คุณจะพบรายการโมเดลที่ฝึกล่วงหน้าที่ใช้งานง่ายมากขึ้นเรื่อยๆ ในหน้าโมเดลสำหรับ JavaScript ของ Tensorflow.js นอกจากนี้ยังมีที่อื่นๆ ที่คุณสามารถรับโมเดล TensorFlow ที่แปลงแล้วซึ่งทำงานใน TensorFlow.js ได้ ซึ่งรวมถึง TensorFlow Hub

ทำไมฉันจึงควรใช้โมเดลก่อนการฝึก

การเริ่มต้นด้วยโมเดลที่ฝึกล่วงหน้ายอดนิยมหากรูปแบบดังกล่าวเหมาะกับกรณีการใช้งานที่คุณต้องการ เช่น

  1. โดยไม่จำเป็นต้องรวบรวมข้อมูลการฝึกด้วยตนเอง การเตรียมข้อมูลในรูปแบบที่ถูกต้องและติดป้ายกำกับเพื่อให้ระบบแมชชีนเลิร์นนิงนำไปใช้ในการเรียนรู้ได้ อาจใช้เวลามากและมีค่าใช้จ่ายสูง
  2. ความสามารถในการสร้างต้นแบบแนวคิดอย่างรวดเร็วโดยใช้เวลาและเวลาที่ลดลง
    ไม่มีข้อได้เปรียบในการ "พลิกโฉมวงล้อ" ในเมื่อโมเดลก่อนการฝึกอาจจะดีพอที่จะทำในสิ่งที่คุณต้องการ ซึ่งจะทำให้คุณจดจ่อกับการใช้ความรู้ที่ได้รับจากโมเดลเพื่อนำไอเดียสร้างสรรค์ของคุณไปใช้ได้
  3. การใช้งานวิจัยที่ทันสมัย โมเดลก่อนการฝึกมักจะอิงตามการวิจัยยอดนิยมเพื่อให้คุณได้สัมผัสกับโมเดลเหล่านั้น พร้อมกับเข้าใจประสิทธิภาพของโมเดลในชีวิตจริงไปด้วย
  4. ใช้งานง่ายและมีเอกสารประกอบที่ครอบคลุม เนื่องจากความนิยมของรุ่นดังกล่าว
  5. ถ่ายทอดความสามารถ ในการเรียนรู้ โมเดลก่อนการฝึกบางโมเดลมีความสามารถในการเรียนรู้การโอน ซึ่งเป็นวิธีการถ่ายโอนข้อมูลที่เรียนรู้จากงานด้านแมชชีนเลิร์นนิงงานหนึ่งไปยังอีกตัวอย่างหนึ่งที่คล้ายกัน เช่น โมเดลที่ได้รับการฝึกให้จดจำแมวตั้งแต่แรกอาจฝึกให้จดจำสุนัขได้ หากคุณให้ข้อมูลการฝึกใหม่ ซึ่งจะรวดเร็วขึ้น เนื่องจากคุณจะไม่เริ่มต้นด้วยแคนวาสเปล่า โมเดลนี้สามารถใช้สิ่งที่เรียนรู้มาแล้วเพื่อให้จดจำแมวเพื่อให้จดจำสิ่งใหม่ๆ ได้ ทำให้สุนัขมีตากับหูด้วยเช่นกัน ดังนั้นหากโมเดลรู้วิธีค้นหาฟีเจอร์เหล่านั้นแล้ว เราก็มาถึงครึ่งทางแล้ว ฝึกโมเดลอีกครั้งโดยใช้ข้อมูลของคุณเองให้เร็วขึ้นมาก

COCO-SSD คืออะไร

COCO-SSD คือชื่อของโมเดล ML สำหรับตรวจจับออบเจ็กต์ก่อนการฝึกที่คุณจะใช้ระหว่าง Codelab นี้ ซึ่งมีจุดประสงค์เพื่อแปลและระบุออบเจ็กต์หลายรายการในอิมเมจเดียว กล่าวคือ Google จะแจ้งให้คุณทราบกรอบของวัตถุที่ได้รับการฝึกให้ค้นหาเพื่อระบุตำแหน่งของวัตถุนั้นในรูปภาพหนึ่งๆ ที่คุณนำเสนอต่อวัตถุ ตัวอย่างดังแสดงในรูปภาพด้านล่าง

760e5f87c335dd9e.png

หากมีสุนัขมากกว่า 1 ตัวในรูปภาพด้านบน คุณจะได้รับพิกัดของกรอบล้อมรอบ 2 กรอบ ซึ่งอธิบายถึงตำแหน่งของสุนัขแต่ละตัว COCO-SSD ได้รับการฝึกล่วงหน้าให้จดจำวัตถุทั่วไปในชีวิตประจำวัน 90 รายการ เช่น คน รถยนต์ แมว ฯลฯ

ชื่อนั้นมาจากไหน

ชื่ออาจฟังดูแปลกแต่มาจากตัวย่อ 2 คำ ได้แก่

  • COCO: หมายถึงข้อเท็จจริงที่ได้รับการฝึกด้วยชุดข้อมูล COCO (Common Objects in Context) ซึ่งพร้อมให้ทุกคนดาวน์โหลดและใช้เมื่อฝึกโมเดลของตนเองได้โดยไม่มีค่าใช้จ่าย ชุดข้อมูลมีรูปภาพที่ติดป้ายกำกับกว่า 200,000 รูปซึ่งใช้เรียนรู้ได้
  • Solid (Single Shot MultiBox Detection): หมายถึงส่วนหนึ่งของสถาปัตยกรรมโมเดลที่ใช้ในการติดตั้งใช้งานโมเดล คุณไม่จำเป็นต้องทำความเข้าใจเกี่ยวกับเรื่องนี้สำหรับ Codelab แต่หากอยากทราบ คุณก็ดูข้อมูลเพิ่มเติมเกี่ยวกับ SSD ได้ที่นี่

4. ตั้งค่า

สิ่งที่คุณต้องมี

มาเขียนโค้ดกัน

เทมเพลตแบบ Boilerplate ที่จะเริ่มต้นนั้นสร้างขึ้นสำหรับ Glitch.com หรือ Codepen.io คุณสามารถโคลนเทมเพลตใดเทมเพลตหนึ่งเป็นสถานะฐานสำหรับห้องทดลองโค้ดนี้ได้ด้วยการคลิกเพียงครั้งเดียว

ใน Glitch ให้คลิกปุ่มรีมิกซ์นี้เพื่อแยกและสร้างชุดไฟล์ใหม่ที่แก้ไขได้

หรือคลิก fork ที่ด้านขวาล่างของหน้าจอบน Codepen

โครงสร้างง่ายๆ นี้จะมีไฟล์ต่อไปนี้ให้คุณ

  • หน้า HTML (index.html)
  • สไตล์ชีต (style.css)
  • ไฟล์สำหรับเขียนโค้ด JavaScript (script.js)

เพื่อความสะดวก จึงมีการนำเข้าเพิ่มเข้ามาในไฟล์ HTML สำหรับไลบรารี TensorFlow.js ซึ่งมีลักษณะดังนี้

index.html

<!-- Import TensorFlow.js library -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>

ทางเลือก: ใช้โปรแกรมแก้ไขเว็บที่ต้องการหรือทำงานในเครื่อง

หากคุณต้องการดาวน์โหลดโค้ดและทำงานภายในเครื่อง หรือในตัวแก้ไขออนไลน์อื่นๆ ก็เพียงแค่สร้างไฟล์ 3 ไฟล์ที่มีชื่อข้างต้นในไดเรกทอรีเดียวกัน แล้วคัดลอกและวางโค้ดจากต้นแบบ Glitch ลงในแต่ละไฟล์

5. สร้างโครงกระดูก HTML

ต้นแบบทั้งหมดจำเป็นต้องมีโครงสร้าง HTML พื้นฐานบางส่วน คุณจะใช้ข้อมูลนี้เพื่อแสดงผลเอาต์พุตของโมเดลแมชชีนเลิร์นนิงในภายหลัง มาเริ่มตั้งค่ากันเลย

  • ชื่อสำหรับหน้านี้
  • ข้อความอธิบายบางส่วน
  • ปุ่มสำหรับเปิดใช้เว็บแคม
  • แท็กวิดีโอในการแสดงผลสตรีมจากเว็บแคม

หากต้องการตั้งค่าคุณลักษณะเหล่านี้ ให้เปิดindex.html และวางโค้ดที่มีอยู่ด้วยข้อมูลต่อไปนี้:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Multiple object detection using pre trained model in TensorFlow.js</title>
    <meta charset="utf-8">
    <!-- Import the webpage's stylesheet -->
    <link rel="stylesheet" href="style.css">
  </head>  
  <body>
    <h1>Multiple object detection using pre trained model in TensorFlow.js</h1>

    <p>Wait for the model to load before clicking the button to enable the webcam - at which point it will become visible to use.</p>
    
    <section id="demos" class="invisible">

      <p>Hold some objects up close to your webcam to get a real-time classification! When ready click "enable webcam" below and accept access to the webcam when the browser asks (check the top left of your window)</p>
      
      <div id="liveView" class="camView">
        <button id="webcamButton">Enable Webcam</button>
        <video id="webcam" autoplay muted width="640" height="480"></video>
      </div>
    </section>

    <!-- Import TensorFlow.js library -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>
    <!-- Load the coco-ssd model to use to recognize things in images -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"></script>
    
    <!-- Import the page's JavaScript to do some stuff -->
    <script src="script.js" defer></script>
  </body>
</html>

ทำความเข้าใจโค้ด

สังเกตสิ่งสำคัญที่คุณเพิ่มดังนี้

  • คุณเพิ่มแท็ก <h1> และแท็ก <p> บางแท็กสำหรับส่วนหัว รวมถึงข้อมูลบางอย่างเกี่ยวกับวิธีใช้หน้าดังกล่าว ไม่มีอะไรพิเศษ

คุณยังเพิ่มแท็กส่วนที่แสดงถึงพื้นที่สาธิตดังนี้

index.html

    <section id="demos" class="invisible">

      <p>Hold some objects up close to your webcam to get a real-time classification! When ready click "enable webcam" below and accept access to the webcam when the browser asks (check the top left of your window)</p>
      
      <div id="liveView" class="webcam">
        <button id="webcamButton">Enable Webcam</button>
        <video id="webcam" autoplay width="640" height="480"></video>
      </div>
    </section>
  • ในขั้นต้น คุณจะกำหนดคลาสเป็น "ไม่ปรากฏ" ให้กับ section นี้ ทั้งนี้เพื่อให้คุณสามารถแสดงภาพเมื่อผู้ใช้เห็นเมื่อโมเดลพร้อมใช้งาน และคุณสามารถคลิกปุ่มเปิดใช้เว็บแคมได้อย่างปลอดภัย
  • คุณเพิ่มปุ่มเปิดใช้เว็บแคมเพื่อจัดรูปแบบใน CSS
  • คุณยังเพิ่มแท็กวิดีโอที่จะใช้สตรีมอินพุตเว็บแคมด้วย คุณจะตั้งค่านี้ในโค้ด JavaScript ของคุณในไม่ช้า

หากคุณดูตัวอย่างเอาต์พุตในขณะนี้ โค้ดควรมีลักษณะดังนี้

b1bfb8c3de68845c.png

6. เพิ่มสไตล์

ค่าเริ่มต้นขององค์ประกอบ

ก่อนอื่น มาเพิ่มสไตล์สำหรับองค์ประกอบ HTML ที่เราเพิ่งเพิ่มเพื่อให้แน่ใจว่าจะแสดงอย่างถูกต้อง ดังนี้

style.css

body {
  font-family: helvetica, arial, sans-serif;
  margin: 2em;
  color: #3D3D3D;
}

h1 {
  font-style: italic;
  color: #FF6F00;
}

video {
  display: block;
}

section {
  opacity: 1;
  transition: opacity 500ms ease-in-out;
}

ถัดไป ให้เพิ่มคลาส CSS ที่มีประโยชน์เพื่อช่วยเกี่ยวกับสถานะต่างๆ ของอินเทอร์เฟซผู้ใช้ เช่น เมื่อเราต้องการซ่อนปุ่ม หรือทำให้พื้นที่สาธิตไม่พร้อมใช้งานหากโมเดลยังไม่พร้อม

style.css

.removed {
  display: none;
}

.invisible {
  opacity: 0.2;
}

.camView {
  position: relative;
  float: left;
  width: calc(100% - 20px);
  margin: 10px;
  cursor: pointer;
}

.camView p {
  position: absolute;
  padding: 5px;
  background-color: rgba(255, 111, 0, 0.85);
  color: #FFF;
  border: 1px dashed rgba(255, 255, 255, 0.7);
  z-index: 2;
  font-size: 12px;
}

.highlighter {
  background: rgba(0, 255, 0, 0.25);
  border: 1px dashed #fff;
  z-index: 1;
  position: absolute;
}

เยี่ยม! เท่านี้ก็เรียบร้อย หากคุณเขียนทับรูปแบบด้วยโค้ด 2 ชิ้นด้านบนได้สำเร็จ พรีวิวสดควรมีลักษณะดังนี้

336899a78cf80fcb.png

โปรดสังเกตว่าข้อความในพื้นที่สาธิตและปุ่มจะใช้งานไม่ได้ เนื่องจาก HTML โดยค่าเริ่มต้นมีคลาสเป็น "invisible" ใช้แล้ว คุณจะใช้ JavaScript เพื่อนำคลาสนี้ออกเมื่อโมเดลพร้อมใช้งาน

7. สร้างโครงสร้าง JavaScript

การปรับแต่งองค์ประกอบ DOM หลัก

อย่างแรก ให้ตรวจสอบว่าคุณสามารถเข้าถึงส่วนสำคัญของหน้าเว็บซึ่งคุณจะต้องจัดการหรือเข้าถึงในภายหลังในโค้ดของเรา:

script.js

const video = document.getElementById('webcam');
const liveView = document.getElementById('liveView');
const demosSection = document.getElementById('demos');
const enableWebcamButton = document.getElementById('webcamButton');

ตรวจสอบการรองรับเว็บแคม

ตอนนี้คุณเพิ่มฟังก์ชันความช่วยเหลือพิเศษเพื่อตรวจสอบว่าเบราว์เซอร์ที่ใช้รองรับการเข้าถึงสตรีมจากเว็บแคมผ่าน getUserMedia หรือไม่ โดยทำดังนี้

script.js

// Check if webcam access is supported.
function getUserMediaSupported() {
  return !!(navigator.mediaDevices &&
    navigator.mediaDevices.getUserMedia);
}

// If webcam supported, add event listener to button for when user
// wants to activate it to call enableCam function which we will 
// define in the next step.
if (getUserMediaSupported()) {
  enableWebcamButton.addEventListener('click', enableCam);
} else {
  console.warn('getUserMedia() is not supported by your browser');
}

// Placeholder function for next step. Paste over this in the next step.
function enableCam(event) {
}

กำลังดึงข้อมูลสตรีมจากเว็บแคม

ถัดไป กรอกโค้ดสำหรับฟังก์ชัน enableCam ที่ว่างเปล่าก่อนหน้านี้ซึ่งเราได้ให้นิยามไว้ข้างต้นโดยคัดลอกและวางโค้ดด้านล่าง:

script.js

// Enable the live webcam view and start classification.
function enableCam(event) {
  // Only continue if the COCO-SSD has finished loading.
  if (!model) {
    return;
  }
  
  // Hide the button once clicked.
  event.target.classList.add('removed');  
  
  // getUsermedia parameters to force video but not audio.
  const constraints = {
    video: true
  };

  // Activate the webcam stream.
  navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
    video.srcObject = stream;
    video.addEventListener('loadeddata', predictWebcam);
  });
}

สุดท้าย ให้เพิ่มรหัสชั่วคราวเพื่อทดสอบว่าเว็บแคมทำงานหรือไม่

โค้ดด้านล่างจะสมมติว่าโมเดลของคุณโหลดขึ้นมาและเปิดใช้งานปุ่มกล้องถ่ายรูป เพื่อให้คุณสามารถคลิกได้ คุณจะแทนที่โค้ดนี้ทั้งหมดในขั้นตอนถัดไป ดังนั้นโปรดเตรียมพร้อมที่จะลบโค้ดอีกครั้งในอีกสักครู่:

script.js

// Placeholder function for next step.
function predictWebcam() {
}

// Pretend model has loaded so we can try out the webcam code.
var model = true;
demosSection.classList.remove('invisible');

เยี่ยม! หากคุณเรียกใช้โค้ดและคลิกที่ปุ่มตามเดิมแล้ว คุณจะเห็นโค้ดดังนี้

95442d7227216528.jpeg

8. การใช้โมเดลแมชชีนเลิร์นนิง

กำลังโหลดโมเดล

ตอนนี้คุณพร้อมที่จะโหลดโมเดล COCO-SSD แล้ว

เมื่อการดำเนินการเริ่มต้นเสร็จสิ้นแล้ว ให้เปิดใช้พื้นที่การสาธิตและปุ่มในหน้าเว็บของคุณ (วางโค้ดนี้บนโค้ดชั่วคราวที่คุณเพิ่มในตอนท้ายของขั้นตอนสุดท้าย):

script.js

// Store the resulting model in the global scope of our app.
var model = undefined;

// Before we can use COCO-SSD class we must wait for it to finish
// loading. Machine Learning models can be large and take a moment 
// to get everything needed to run.
// Note: cocoSsd is an external object loaded from our index.html
// script tag import so ignore any warning in Glitch.
cocoSsd.load().then(function (loadedModel) {
  model = loadedModel;
  // Show demo section now model is ready to use.
  demosSection.classList.remove('invisible');
});

เมื่อเพิ่มโค้ดด้านบนและรีเฟรชภาพสดแล้ว คุณจะสังเกตเห็นว่า 2-3 วินาทีหลังจากที่หน้าเว็บโหลดแล้ว (ขึ้นอยู่กับความเร็วเครือข่าย) ปุ่มเปิดใช้เว็บแคมจะแสดงตัวเองโดยอัตโนมัติเมื่อโมเดลพร้อมใช้งาน อย่างไรก็ตาม คุณได้วางเหนือฟังก์ชัน predictWebcam แล้ว คราวนี้ก็ถึงเวลากำหนดสิ่งนี้อย่างครบถ้วน เนื่องจากโค้ดของเราไม่สามารถดำเนินการใดๆ ได้ในขณะนี้

ก้าวต่อไป

การแยกประเภทเฟรมจากเว็บแคม

เรียกใช้โค้ดด้านล่างเพื่ออนุญาตให้แอปจับเฟรมจากสตรีมเว็บแคมอย่างต่อเนื่องเมื่อเบราว์เซอร์พร้อมใช้งาน และส่งไปยังโมเดลเพื่อจัดประเภท

จากนั้นโมเดลจะแยกวิเคราะห์ผลลัพธ์และวาดแท็ก <p> ที่พิกัดที่ย้อนกลับ และกำหนดข้อความให้เป็นป้ายกำกับของออบเจ็กต์ หากมีระดับความเชื่อมั่นเกินระดับหนึ่ง

script.js

var children = [];

function predictWebcam() {
  // Now let's start classifying a frame in the stream.
  model.detect(video).then(function (predictions) {
    // Remove any highlighting we did previous frame.
    for (let i = 0; i < children.length; i++) {
      liveView.removeChild(children[i]);
    }
    children.splice(0);
    
    // Now lets loop through predictions and draw them to the live view if
    // they have a high confidence score.
    for (let n = 0; n < predictions.length; n++) {
      // If we are over 66% sure we are sure we classified it right, draw it!
      if (predictions[n].score > 0.66) {
        const p = document.createElement('p');
        p.innerText = predictions[n].class  + ' - with ' 
            + Math.round(parseFloat(predictions[n].score) * 100) 
            + '% confidence.';
        p.style = 'margin-left: ' + predictions[n].bbox[0] + 'px; margin-top: '
            + (predictions[n].bbox[1] - 10) + 'px; width: ' 
            + (predictions[n].bbox[2] - 10) + 'px; top: 0; left: 0;';

        const highlighter = document.createElement('div');
        highlighter.setAttribute('class', 'highlighter');
        highlighter.style = 'left: ' + predictions[n].bbox[0] + 'px; top: '
            + predictions[n].bbox[1] + 'px; width: ' 
            + predictions[n].bbox[2] + 'px; height: '
            + predictions[n].bbox[3] + 'px;';

        liveView.appendChild(highlighter);
        liveView.appendChild(p);
        children.push(highlighter);
        children.push(p);
      }
    }
    
    // Call this function again to keep predicting when the browser is ready.
    window.requestAnimationFrame(predictWebcam);
  });
}

การเรียกที่สำคัญจริงๆ ในโค้ดใหม่นี้คือ model.detect()

โมเดลที่สร้างไว้ล่วงหน้าทั้งหมดของ TensorFlow.js มีฟังก์ชันแบบนี้ (ชื่ออาจเปลี่ยนไปตามโมเดลอื่น ดังนั้นโปรดดูรายละเอียดในเอกสาร) ซึ่งจะทำการอนุมานแมชชีนเลิร์นนิงจริงๆ

การอนุมานเป็นเพียงการดำเนินการเพื่อนำอินพุตบางส่วนและเรียกใช้ผ่านโมเดลแมชชีนเลิร์นนิง (ซึ่งส่วนใหญ่เป็นการดำเนินการทางคณิตศาสตร์) แล้วให้ผลลัพธ์บางอย่าง ด้วยโมเดลที่สร้างไว้ล่วงหน้า TensorFlow.js เราแสดงผลการคาดการณ์ในรูปแบบของออบเจ็กต์ JSON เพื่อให้ใช้งานได้ง่าย

ดูรายละเอียดทั้งหมดของฟังก์ชันการคาดการณ์นี้ในเอกสารประกอบของ GitHub สำหรับโมเดล COCO-SSD ที่นี่ ฟังก์ชันนี้มีการลงแรงมากมายในเบื้องหลัง โดยสามารถรับ "รูปภาพอย่าง" ได้ เป็นพารามิเตอร์ เช่น รูปภาพ วิดีโอ ผืนผ้าใบ และอื่นๆ การใช้รูปแบบที่สร้างไว้ล่วงหน้าสามารถช่วยคุณประหยัดแรงและเวลาได้มาก เนื่องจากคุณไม่จำเป็นต้องเขียนโค้ดนี้ด้วยตนเองและสามารถเรียกใช้ได้ "ทันที"

การเรียกใช้โค้ดนี้จะทำให้คุณได้รูปภาพที่มีลักษณะดังนี้

8f9bad6e49e646b.png

สุดท้าย ต่อไปนี้เป็นตัวอย่างของโค้ดที่ตรวจพบออบเจ็กต์หลายรายการพร้อมกัน

a2c73a72cf976b22.jpeg

ไชโย คุณคงนึกภาพออกว่าการสร้างอุปกรณ์อย่างเช่น Nest Cam โดยใช้โทรศัพท์เครื่องเก่าเพื่อแจ้งเตือนคุณเมื่อเห็นสุนัขบนโซฟาหรือแมวของคุณอยู่บนโซฟานั้นอาจดูง่ายเพียงใด หากคุณมีปัญหาเกี่ยวกับโค้ด ให้ตรวจสอบเวอร์ชันสุดท้ายที่ใช้งานได้ที่นี่เพื่อดูว่าคุณคัดลอกบางอย่างไม่ถูกต้องหรือไม่

9. ขอแสดงความยินดี

ยินดีด้วย คุณใช้งาน TensorFlow.js และแมชชีนเลิร์นนิงในเว็บเบราว์เซอร์ขั้นแรกเรียบร้อยแล้ว ตอนนี้ก็ถึงเวลาที่คุณจะต้องนำจุดเริ่มต้นเล็กๆ เหล่านี้มาเปลี่ยนเป็นสิ่งที่สร้างสรรค์ คุณจะทำอะไรบ้าง

สรุป

ใน Codelab นี้ เราจะดำเนินการดังนี้

  • เรียนรู้ประโยชน์ของการใช้ TensorFlow.js เหนือ TensorFlow รูปแบบอื่นๆ
  • เรียนรู้สถานการณ์ที่คุณอาจอยากเริ่มต้นด้วยโมเดลแมชชีนเลิร์นนิงที่ฝึกไว้แล้วล่วงหน้า
  • สร้างหน้าเว็บที่ใช้งานได้อย่างสมบูรณ์ซึ่งแยกประเภทออบเจ็กต์ได้แบบเรียลไทม์โดยใช้เว็บแคม ซึ่งรวมถึงรายการต่อไปนี้
  • การสร้างโครงสร้าง HTML สำหรับเนื้อหา
  • การกำหนดรูปแบบสำหรับองค์ประกอบและคลาส HTML
  • การตั้งค่าโครงข่าย JavaScript เพื่อโต้ตอบกับ HTML และตรวจหาเว็บแคม
  • กำลังโหลดโมเดล TensorFlow.js ที่ฝึกล่วงหน้า
  • ใช้โมเดลที่โหลดเพื่อทำการจัดหมวดหมู่สตรีมเว็บแคมอย่างต่อเนื่องและวาดกรอบล้อมรอบวัตถุในรูปภาพ

ขั้นตอนถัดไป

แชร์สิ่งที่คุณทำกับเรา คุณสามารถขยายสิ่งที่คุณสร้างขึ้นสำหรับ Codelab นี้ไปยังกรณีการใช้งานที่สร้างสรรค์อื่นๆ ได้อย่างง่ายดายเช่นกัน เราขอแนะนำให้คุณคิดนอกกรอบและแฮ็กไปเรื่อยๆ หลังจากที่คุณเรียนรู้จบ

(คุณอาจเพิ่มเลเยอร์ฝั่งเซิร์ฟเวอร์แบบง่ายเพื่อส่งการแจ้งเตือนไปยังอุปกรณ์อื่นเมื่อเห็นออบเจ็กต์ที่คุณต้องการโดยใช้ WebSocket นี่จะเป็นวิธีที่ยอดเยี่ยมในการรีไซเคิลสมาร์ทโฟนเก่าและนำมาตั้งวัตถุประสงค์ใหม่ ทุกอย่างเป็นไปได้)

  • แท็กเราบนโซเชียลมีเดียโดยใช้แฮชแท็ก #MadeWithTFJS เพื่อลุ้นให้โปรเจ็กต์ของคุณปรากฏบนบล็อก TensorFlow หรือแม้กระทั่งจัดแสดงผลงานในกิจกรรม TensorFlow ในอนาคต

Codelab ของ TensorFlow.js เพิ่มเติมที่ช่วยให้ข้อมูลเจาะลึกยิ่งขึ้น

เว็บไซต์ที่น่าสนใจ