จดจำดอกไม้ด้วย TensorFlow Lite บน iOS

1. บทนำ

657431be3173fa86.png

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

Codelab นี้ใช้ TensorFlow Lite เพื่อเรียกใช้โมเดลการจดจำรูปภาพในอุปกรณ์ iOS

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

  • วิธีเพิ่มประสิทธิภาพโมเดลโดยใช้ตัวแปลง TFLite
  • วิธีเรียกใช้ในแอป iOS ที่สร้างไว้ล่วงหน้าโดยใช้ล่าม TFLite

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

แอปกล้องง่ายๆ ที่เรียกใช้โปรแกรมจดจำรูปภาพ TensorFlow เพื่อระบุดอกไม้

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

หากคุณทำ Codelab นี้ในฮาร์ดแวร์ของคุณเอง โปรดตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งสิ่งต่อไปนี้แล้ว:

  • Xcode 10 ขึ้นไป
  • CocoaPods 1.8.0 ขึ้นไป

c45ecd122998622e.png

ใบอนุญาต: ใช้งานฟรี

2. ฝึกระบบจดจำดอกไม้โดยใช้ Colab

Codelab นี้จะใช้ Colaboratory และ Xcode

เปิด Colab ที่ใช้เครื่องสร้างโมเดล TensorFlow Lite เพื่อฝึกตัวแยกประเภทให้จดจำดอกไม้โดยใช้การเรียนรู้การโอนและส่งออกโมเดล TFLite เพื่อใช้ในแอปบนอุปกรณ์เคลื่อนที่

3. ตั้งค่าไดเรกทอรีที่ใช้งานอยู่

โคลนที่เก็บ Git

คำสั่งต่อไปนี้จะโคลนที่เก็บ Git ที่มีไฟล์ที่จำเป็นสำหรับ Codelab นี้

git clone https://github.com/tensorflow/examples.git

ตอนนี้ cd ในรูทของโปรเจ็กต์ Xcode ของโคลนที่คุณเพิ่งสร้าง นี่คือตรงที่คุณจะทำงานที่เหลือของ Codelab นี้

cd examples/lite/examples/image_classification/ios

4. ตั้งค่าแอป iOS

ทรัพยากร Dependency ของการติดตั้ง

ใช้ CocoaPods ติดตั้งทรัพยากร Dependency ของแอป iOS (รวมถึง TensorFlow Lite) เมื่อคำสั่งติดตั้งเสร็จสิ้น ให้เปิด ImageClassification.xcworkspace เพื่อเปิดโปรเจ็กต์ใน Xcode

pod install --repo-update
open ImageClassification.xcworkspace

5. ทดสอบเรียกใช้แอป

ในการใช้กล้อง แอปจะต้องทำงานบนอุปกรณ์จริง เนื่องจาก iOS Simulator ไม่มีสิทธิ์เข้าถึงกล้องของ Mac หากต้องการสร้างแอปในอุปกรณ์ iOS คุณต้องลงทะเบียนในโปรแกรมนักพัฒนาซอฟต์แวร์ Apple หรือมีสิทธิ์เข้าถึงอุปกรณ์ที่ผู้อื่นจัดสรรไว้ให้คุณ

หากคุณต้องการเรียกใช้ Codelab นี้ในเครื่องมือจำลอง คุณจะต้องคัดลอกภาพจาก Safari ในตัวจำลองเพื่อคัดลอกรูปภาพไปยัง Pasteboard ขั้นตอนการประมวลผลรูปภาพในเครื่องมือจำลองมีดังนี้

  1. สร้างแอปให้บรรลุเป้าหมายเครื่องจำลองที่คุณต้องการ
  2. ในเครื่องมือจำลอง iOS ให้กด Cmd+Shift+H เพื่อย่อแอป
  3. แตะ Safari ที่ด้านล่างของหน้าจอหลักและค้นหารูปภาพ
  4. ในผลการค้นหาของ Google รูปภาพ ให้แตะผลการค้นหาและกดรูปภาพค้างไว้ ในกล่องโต้ตอบที่ปรากฏขึ้น ให้เลือก "คัดลอก"
  5. กลับไปที่แอป TFL Classify รูปภาพที่คัดลอกควรแสดงโดยอัตโนมัติพร้อมกับผลการอนุมาน หากไม่คัดลอก ให้ตรวจสอบว่าคุณได้คัดลอกข้อมูลรูปภาพเองแล้ว ไม่ใช่ URL ของรูปภาพ

ทดสอบบิลด์และติดตั้งแอป

ก่อนที่จะทำการเปลี่ยนแปลงใดๆ กับแอป โปรดลองใช้เวอร์ชันที่มาพร้อมกับที่เก็บก่อน เลือกอุปกรณ์ iOS จากเมนูแบบเลื่อนลงที่ด้านบนซ้าย

275753d3a77a0df3.png

จากนั้นกด Cmd+R หรือกดปุ่มเล่น f96cf117245c0fa6.png ใน Xcode เพื่อสร้างแอปในอุปกรณ์ของคุณ แอปควรเปิดโดยอัตโนมัติเมื่อติดตั้งลงในอุปกรณ์แล้ว

แอปเวอร์ชันนี้ใช้ MobileNet มาตรฐาน ซึ่งฝึกล่วงหน้าในหมวดหมู่ ImageNet จำนวน 1, 000 หมวดหมู่ ซึ่งควรมีหน้าตาเช่นนี้

d11436f0bb5a75db.jpeg

6. เรียกใช้แอปที่กำหนดเอง

การตั้งค่าแอปเริ่มต้นจะจัดประเภทรูปภาพเป็นหนึ่งในคลาส ImageNet ที่มี 1, 000 คลาส โดยใช้ MobileNet มาตรฐาน

ตอนนี้เรามาแก้ไขแอปกันเพื่อให้แอปใช้โมเดลที่ฝึกไปแล้วของเราสำหรับหมวดหมู่รูปภาพที่กำหนดเองตามการฝึกอบรมใน Colab

7. แปลงแอปเพื่อเรียกใช้โมเดล

เพิ่มไฟล์โมเดลลงในโปรเจ็กต์

ทรัพยากรโมเดลของโปรเจ็กต์อยู่ใน ImageClassification > Model ในตัวนำทางโปรเจ็กต์ Xcode หากต้องการแทนที่ ให้ลบไฟล์ 2 ไฟล์ที่มีอยู่ในกลุ่ม Model ก่อน เมื่อมีข้อความแจ้ง ให้เลือก "ย้ายไปที่ถังขยะ"

cf2f7fefb2e5075f.png

จากนั้นลากไฟล์ model.tflite และ labels.txt ที่คุณดาวน์โหลดจาก Colab ไปยังกลุ่มโมเดล เมื่อได้รับข้อความแจ้ง ให้ตรวจสอบว่าได้เลือกทั้ง Copy items if needed และ Add to targets แล้ว

281d7eb72635bb5f.png

แก้ไขโค้ดของแอป

เพื่อให้แอปใช้งานได้ เราจำเป็นต้องอัปเดตเส้นทางของตรรกะการโหลดโมเดลให้ชี้ไปยังโมเดลใหม่ที่เพิ่มเข้ามา

เปิด ModelDataHandler.swift (เส้นทางตัวนำทาง Xcode: ImageClassification -> ModelDataHandler -> ModelDataHandler.swift) แล้วเปลี่ยนบรรทัดที่ 36 เป็น

// before
static let modelInfo: FileInfo = (name: "mobilenet_quant_v1_224", extension: "tflite")

// after
static let modelInfo: FileInfo = (name: "model", extension: "tflite")

ตรวจสอบว่าได้บันทึกการเปลี่ยนแปลงทั้งหมดแล้ว

8. เรียกใช้แอปที่กำหนดเอง

กด Cmd+B หรือกดปุ่มเล่น f96cf117245c0fa6.png ใน Xcode เพื่อสร้างแอปในอุปกรณ์ของคุณ เมื่อแอปเปิดขึ้นแล้ว แอปควรมีลักษณะเช่นนี้

c45ecd122998622e.png

คุณสามารถกดปุ่มเปิด/ปิดและปุ่มเพิ่มระดับเสียงค้างไว้เพื่อถ่ายภาพหน้าจอ

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

หรือให้เพื่อนถ่ายรูปคุณและค้นหาว่าคุณเป็น Tensor Flower ชนิดใด\\uf339 \\uf33b \\uf337!

9. หลักการทำงาน

ตอนนี้เมื่อคุณเรียกใช้แอปแล้ว เรามาดูโค้ดเฉพาะของ TensorFlow Lite

TensorFlowLiteSwift

แอปนี้ใช้ไลบรารี TensorFlowLite Swift ผ่าน CocoaPods ไลบรารี Swift เป็น Wrapper แบบบางเหนือ TFLite C API ซึ่งเป็น Wrapper ของไลบรารี TFLite C++

บรรทัดต่อไปนี้ในไฟล์ Podfile ของโมดูลจะดึงข้อมูลที่เก็บข้อกำหนดของ CocoaPods ทั่วโลกเวอร์ชันล่าสุดเข้าสู่โปรเจ็กต์

Podfile

target 'ImageClassification' do
  use_frameworks!

  # Pods for ImageClassification
   pod 'TensorFlowLiteSwift'
end

การใช้ TensorFlow Lite Swift API

โค้ดที่โต้ตอบกับ TensorFlow Lite มีอยู่ใน ModelDataHandler.swift

ตั้งค่า

บล็อกแรกที่สนใจคือข้อมูลเบื้องต้นสำหรับ ModelDataHandler:

ModelDataHandler.swift

/// A failable initializer for `ModelDataHandler`. A new instance is created if the model and
/// labels files are successfully loaded from the app's main bundle. Default `threadCount` is 1.
init?(modelFileInfo: FileInfo, labelsFileInfo: FileInfo, threadCount: Int = 1) {
  let modelFilename = modelFileInfo.name

  // Construct the path to the model file.
  guard let modelPath = Bundle.main.path(
    forResource: modelFilename,
    ofType: modelFileInfo.extension
  ) else {
    print("Failed to load the model file with name: \(modelFilename).")
    return nil
  }

  // Specify the options for the `Interpreter`.
  self.threadCount = threadCount
  var options = InterpreterOptions()
  options.threadCount = threadCount
  do {
    // Create the `Interpreter`.
    interpreter = try Interpreter(modelPath: modelPath, options: options)
    // Allocate memory for the model's input `Tensor`s.
    try interpreter.allocateTensors()
  } catch let error {
    print("Failed to create the interpreter with error: \(error.localizedDescription)")
    return nil
  }
  // Load the classes listed in the labels file.
  loadLabels(fileInfo: labelsFileInfo)
}

โดยมีข้อมูลอีก 2-3 บรรทัดที่ควรกล่าวถึงรายละเอียดเพิ่มเติม

บรรทัดต่อไปนี้จะสร้างอินเทอร์พรีเตอร์ TFLite

ModelDataHandler.swift

interpreter = try Interpreter(modelPath: modelPath, options: options)

อินเทอร์พรีเตอร์มีหน้าที่ส่งผ่านอินพุตข้อมูลดิบผ่านกราฟ TensorFlow เราส่งผ่านเส้นทางอินเทอร์พรีเตอร์ไปยังโมเดลของเราในดิสก์ จากนั้นอินเตอร์พรีเตอร์จะโหลดเป็น FlatBufferModel

บรรทัดสุดท้ายจะโหลดรายการป้ายกำกับ:

loadLabels(fileInfo: labelsFileInfo)

ซึ่งทำได้โดยการโหลดสตริงจากไฟล์ข้อความลงในหน่วยความจำ

เรียกใช้โมเดล

บล็อกที่ 2 ที่สนใจคือเมธอด runModel ระบบจะใช้ CVPixelBuffer เป็นอินพุต เรียกใช้ล่าม และส่งกลับข้อความที่จะพิมพ์ในแอป

ModelDataHandler.swift

try interpreter.copy(rgbData, toInputAt: 0)
// ...
try interpreter.invoke()
// ...
outputTensor = try interpreter.output(at: 0)

10. ขั้นต่อไปคืออะไร

โปรดดูข้อมูลเพิ่มเติมที่ลิงก์ต่อไปนี้