Thêm Firebase vào Ứng dụng iOS hỗ trợ TFLite của bạn

1. Khái quát chung

Bàn thắng

Firebase ML cho phép bạn triển khai mô hình của mình qua mạng. Điều này cho phép bạn giữ kích thước ứng dụng nhỏ và chỉ tải xuống mô hình ML khi cần, thử nghiệm nhiều mô hình hoặc cập nhật mô hình ML của bạn mà không cần phải xuất bản lại toàn bộ ứng dụng.

Trong lớp học lập trình này, bạn sẽ chuyển đổi một ứng dụng iOS sử dụng mô hình TFLite tĩnh thành một ứng dụng sử dụng mô hình được phân phối động từ Firebase. Bạn sẽ học cách:

  1. Triển khai các mô hình TFLite cho Firebase ML và truy cập chúng từ ứng dụng của bạn
  2. Ghi lại các số liệu liên quan đến mô hình bằng Analytics
  3. Chọn model nào được tải thông qua Remote Config
  4. Thử nghiệm A/B các mô hình khác nhau

Điều kiện tiên quyết

Trước khi bắt đầu lớp học lập trình này, hãy đảm bảo bạn đã cài đặt:

  • Xcode 11 (hoặc cao hơn)
  • CocoaPods 1.9.1 (hoặc cao hơn)

2. Tạo dự án bảng điều khiển Firebase

Thêm Firebase vào dự án

  1. Chuyển đến bảng điều khiển Firebase .
  2. Chọn Tạo dự án mới và đặt tên cho dự án của bạn là "Firebase ML iOS Codelab".

3. Lấy dự án mẫu

Tải xuống mã

Bắt đầu bằng cách sao chép dự án mẫu và chạy pod update trong thư mục dự án:

git clone https://github.com/FirebaseExtended/codelab-digitclassifier-ios.git
cd codelab-digitclassifier-ios
pod install --repo-update

Nếu chưa cài đặt git, bạn cũng có thể tải xuống dự án mẫu từ trang GitHub hoặc bằng cách nhấp vào liên kết này . Sau khi bạn đã tải xuống dự án, hãy chạy nó trong Xcode và thử nghiệm với bộ phân loại chữ số để hiểu cách nó hoạt động.

Thiết lập căn cứ hỏa lực

Làm theo tài liệu để tạo dự án Firebase mới. Khi bạn đã có dự án của mình, hãy tải xuống tệp GoogleService-Info.plist của dự án từ bảng điều khiển Firebase và kéo nó vào thư mục gốc của dự án Xcode.

f06cb08d48de7e10.png

Thêm Firebase vào Podfile của bạn và chạy pod install.

pod 'FirebaseMLModelDownloader', '9.3.0-beta'

Trong phương thức didFinishLaunchingWithOptions của AppDelegate , hãy nhập Firebase ở đầu tệp

import FirebaseCore

Và thêm cuộc gọi để định cấu hình Firebase.

FirebaseApp.configure()

Chạy lại dự án để đảm bảo ứng dụng được định cấu hình chính xác và không gặp sự cố khi khởi chạy.

4. Triển khai mô hình lên Firebase ML

Việc triển khai mô hình lên Firebase ML rất hữu ích vì hai lý do chính:

  1. Chúng tôi có thể giữ kích thước cài đặt ứng dụng ở mức nhỏ và chỉ tải xuống mô hình nếu cần
  2. Mô hình có thể được cập nhật thường xuyên và có chu kỳ phát hành khác với toàn bộ ứng dụng

Trước khi có thể thay thế mô hình tĩnh trong ứng dụng của mình bằng mô hình được tải xuống động từ Firebase, chúng tôi cần triển khai mô hình đó lên Firebase ML. Mô hình này có thể được triển khai thông qua bảng điều khiển hoặc theo chương trình bằng cách sử dụng SDK quản trị Firebase. Ở bước này chúng ta sẽ triển khai thông qua console.

Để đơn giản hóa mọi thứ, chúng tôi sẽ sử dụng mô hình TensorFlow Lite đã có trong ứng dụng của chúng tôi. Đầu tiên, hãy mở Firebase và nhấp vào Machine Learning trong bảng điều hướng bên trái. Sau đó điều hướng đến "Tùy chỉnh" và nhấp vào nút "Thêm mô hình".

Khi được nhắc, hãy đặt tên mô tả cho mô hình như mnist_v1 rồi tải tệp lên từ thư mục dự án lớp học lập trình.

3c3c50e6ef12b3b.png

5. Tải xuống mô hình từ Firebase ML

Việc chọn thời điểm tải mô hình từ xa từ Firebase xuống ứng dụng của bạn có thể khó khăn vì các mô hình TFLite có thể phát triển tương đối lớn. Lý tưởng nhất là chúng tôi muốn tránh tải mô hình ngay lập tức khi ứng dụng khởi chạy, vì nếu mô hình của chúng tôi chỉ được sử dụng cho một tính năng và người dùng không bao giờ sử dụng tính năng đó thì chúng tôi sẽ tải xuống một lượng dữ liệu đáng kể mà không có lý do. Chúng ta cũng có thể đặt các tùy chọn tải xuống như chỉ tìm nạp các kiểu máy khi kết nối với wifi. Nếu bạn muốn đảm bảo rằng mô hình có sẵn ngay cả khi không có kết nối mạng, bạn cũng nên gói mô hình đó như một phần của ứng dụng làm bản sao lưu.

Để đơn giản, chúng tôi sẽ xóa mô hình đi kèm mặc định và luôn tải mô hình xuống từ Firebase khi ứng dụng khởi động. Bằng cách này, khi chạy nhận dạng chữ số, bạn có thể chắc chắn rằng suy luận đang chạy với mô hình được cung cấp từ Firebase.

Ở đầu ModelLoader.swift , hãy nhập mô-đun Firebase.

import FirebaseCore
import FirebaseMLModelDownloader

Sau đó thực hiện phương pháp sau.

static func downloadModel(named name: String,
                          completion: @escaping (CustomModel?, DownloadError?) -> Void) {
  guard FirebaseApp.app() != nil else {
    completion(nil, .firebaseNotInitialized)
    return
  }
  guard success == nil && failure == nil else {
    completion(nil, .downloadInProgress)
    return
  }
  let conditions = ModelDownloadConditions(allowsCellularAccess: false)
  ModelDownloader.modelDownloader().getModel(name: name, downloadType: .localModelUpdateInBackground, conditions: conditions) { result in
          switch (result) {
          case .success(let customModel):
                  // Download complete.
                  // The CustomModel object contains the local path of the model file,
                  // which you can use to instantiate a TensorFlow Lite classifier.
                  return completion(customModel, nil)
          case .failure(let error):
              // Download was unsuccessful. Notify error message.
            completion(nil, .downloadFailed(underlyingError: error))
          }
  }
}

Trong viewDidLoad của ViewController.swift , hãy thay thế lệnh gọi khởi tạo DigitClassifier bằng phương thức tải xuống mô hình mới của chúng tôi.

    // Download the model from Firebase
    print("Fetching model...")
    ModelLoader.downloadModel(named: "mnist_v1") { (customModel, error) in
      guard let customModel = customModel else {
        if let error = error {
          print(error)
        }
        return
      }

      print("Model download complete")
      
      // Initialize a DigitClassifier instance
      DigitClassifier.newInstance(modelPath: customModel.path) { result in
      switch result {
        case let .success(classifier):
          self.classifier = classifier
        case .error(_):
          self.resultLabel.text = "Failed to initialize."
        }
      }
    }

Chạy lại ứng dụng của bạn. Sau vài giây, bạn sẽ thấy nhật ký Xcode cho biết mô hình từ xa đã được tải xuống thành công. Hãy thử vẽ một chữ số và xác nhận hành vi của ứng dụng không thay đổi.

6. Theo dõi phản hồi và chuyển đổi của người dùng để đo độ chính xác của mô hình

Chúng tôi sẽ đo lường độ chính xác của mô hình bằng cách theo dõi phản hồi của người dùng về các dự đoán của mô hình. Nếu người dùng nhấp vào "có", điều đó sẽ cho biết dự đoán đó là chính xác.

Chúng tôi có thể ghi lại sự kiện Analytics để theo dõi độ chính xác của mô hình của mình. Trước tiên, chúng ta phải thêm Analytics vào Podfile trước khi có thể sử dụng nó trong dự án:

pod 'FirebaseAnalytics'

Sau đó, trong ViewController.swift nhập Firebase ở đầu tệp

import FirebaseAnalytics

Và thêm dòng mã sau vào phương thức correctButtonPressed .

Analytics.logEvent("correct_inference", parameters: nil)

Chạy lại ứng dụng và vẽ một chữ số. Nhấn nút "Có" một vài lần để gửi phản hồi rằng suy luận đó là chính xác.

Phân tích gỡ lỗi

Nói chung, các sự kiện do ứng dụng của bạn ghi lại sẽ được nhóm lại với nhau trong khoảng thời gian khoảng một giờ và được tải lên cùng nhau. Cách tiếp cận này giúp tiết kiệm pin trên thiết bị của người dùng cuối và giảm mức sử dụng dữ liệu mạng. Tuy nhiên, với mục đích xác thực việc triển khai phân tích của bạn (và để xem phân tích của bạn trong báo cáo DebugView), bạn có thể bật chế độ Gỡ lỗi trên thiết bị phát triển của mình để tải lên các sự kiện với độ trễ tối thiểu.

Để bật chế độ Gỡ lỗi Analytics trên thiết bị phát triển của bạn, hãy chỉ định đối số dòng lệnh sau trong Xcode:

-FIRDebugEnabled

Chạy lại ứng dụng và vẽ một chữ số. Nhấn nút "Có" một vài lần để gửi phản hồi rằng suy luận đó là chính xác. Giờ đây, bạn có thể xem các sự kiện nhật ký gần như theo thời gian thực thông qua chế độ xem gỡ lỗi trong bảng điều khiển Firebase. Nhấp vào Analytics > DebugView từ thanh điều hướng bên trái.

5276199a086721fd.png

7. Theo dõi thời gian suy luận với Firebase Performance

Khi thử nghiệm mô hình của bạn, số liệu hiệu suất được thực hiện trên các thiết bị phát triển không đủ để nắm bắt cách thức hoạt động của mô hình trong tay người dùng vì rất khó để biết người dùng phần cứng nào sẽ chạy ứng dụng của bạn trên đó. May mắn thay, bạn có thể đo lường hiệu suất mô hình của mình trên thiết bị của người dùng bằng Hiệu suất Firebase để có được bức tranh rõ hơn về hiệu suất mô hình của bạn.

Để đo thời gian cần thiết để chạy suy luận, trước tiên hãy nhập Firebase trong DigitClassifier.swift:

import FirebasePerformance

Sau đó bắt đầu theo dõi hiệu suất trong phương pháp phân loại và dừng theo dõi khi quá trình suy luận hoàn tất. Đảm bảo bạn thêm các dòng mã sau vào trong phần đóng DispatchQueue.global.async chứ không phải ngay bên dưới phần khai báo phương thức.

let inferenceTrace = Performance.startTrace(name: "tflite inference")
defer {
  inferenceTrace?.stop()
}

Nếu tò mò, bạn có thể bật ghi nhật ký gỡ lỗi thông qua hướng dẫn tại đây để xác nhận dấu vết hiệu suất của bạn đang được ghi lại. Sau một thời gian, dấu vết hiệu suất cũng sẽ hiển thị trong Bảng điều khiển Firebase.

8. Triển khai mô hình thứ hai cho Firebase ML

Khi đưa ra phiên bản mới cho mô hình của bạn, chẳng hạn như phiên bản có kiến ​​trúc mô hình tốt hơn hoặc phiên bản được đào tạo trên tập dữ liệu lớn hơn hoặc cập nhật, chúng tôi có thể muốn thay thế mô hình hiện tại bằng phiên bản mới. Tuy nhiên, một mô hình hoạt động tốt trong quá trình thử nghiệm không nhất thiết phải hoạt động tốt như vậy trong quá trình sản xuất. Do đó, hãy thực hiện thử nghiệm A/B trong quá trình sản xuất để so sánh mô hình ban đầu của chúng tôi và mô hình mới.

Kích hoạt API quản lý mô hình Firebase

Trong bước này, chúng tôi sẽ kích hoạt API quản lý mô hình Firebase để triển khai phiên bản mới của mô hình TensorFlow Lite bằng mã Python.

Tạo một nhóm để lưu trữ các mô hình ML của bạn

Trong Bảng điều khiển Firebase của bạn, đi tới Bộ nhớ và nhấp vào Bắt đầu. fbbea78f0eb3dc9f.png

Thực hiện theo đoạn hội thoại để thiết lập nhóm của bạn.

19517c0d6d2aa14d.png

Kích hoạt API ML Firebase

Truy cập trang API Firebase ML trên Google Cloud Console và nhấp vào Bật.

2414fd5cced6c984.png Chọn ứng dụng Phân loại chữ số khi được hỏi.

Bây giờ, chúng tôi sẽ đào tạo phiên bản mới của mô hình bằng cách sử dụng tập dữ liệu lớn hơn và sau đó chúng tôi sẽ triển khai nó theo chương trình trực tiếp từ sổ tay đào tạo bằng SDK quản trị Firebase.

Tải xuống khóa riêng cho tài khoản dịch vụ

Trước khi có thể sử dụng SDK quản trị Firebase, chúng tôi cần tạo tài khoản dịch vụ. Mở bảng Tài khoản dịch vụ của bảng điều khiển Firebase bằng cách nhấp vào liên kết này và nhấp vào nút để tạo tài khoản dịch vụ mới cho SDK quản trị Firebase. Khi được nhắc, hãy nhấp vào nút Tạo khóa riêng mới. Chúng tôi sẽ sử dụng khóa tài khoản dịch vụ để xác thực các yêu cầu của chúng tôi từ sổ ghi chép colab.

c3b95de1e5508516.png

Bây giờ chúng ta có thể đào tạo và triển khai mô hình mới.

  1. Mở sổ tay colab này và tạo một bản sao của nó trong Drive của riêng bạn.
  2. Chạy ô đầu tiên "Huấn luyện mô hình TensorFlow Lite cải tiến" bằng cách nhấp vào nút phát ở bên trái ô đó. Quá trình này sẽ đào tạo một mô hình mới và có thể mất một chút thời gian.
  3. Chạy ô thứ hai sẽ tạo ra lời nhắc tải tệp lên. Tải tệp json bạn đã tải xuống từ Bảng điều khiển Firebase lên khi tạo tài khoản dịch vụ của mình.

71e847c6a85423b3.png

  1. Chạy hai ô cuối cùng.

Sau khi chạy sổ tay colab, bạn sẽ thấy mô hình thứ hai trong bảng điều khiển Firebase. Đảm bảo mô hình thứ hai được đặt tên là mnist_v2 .

c316683bb4d75d57.png

9. Chọn model qua Remote Config

Bây giờ chúng ta có hai mô hình riêng biệt, chúng ta sẽ thêm một tham số để chọn mô hình nào sẽ tải xuống khi chạy. Giá trị của tham số mà máy khách nhận được sẽ xác định máy khách sẽ tải xuống mô hình nào. Đầu tiên, mở bảng điều khiển Firebase và nhấp vào nút Cấu hình từ xa trong menu điều hướng bên trái. Sau đó, nhấp vào nút "Thêm tham số".

Đặt tên cho tham số mới model_name và đặt cho nó giá trị mặc định là mnist_v1 . Nhấp vào Xuất bản Thay đổi để áp dụng các bản cập nhật. Bằng cách đặt tên của mô hình vào tham số cấu hình từ xa, chúng ta có thể kiểm tra nhiều mô hình mà không cần thêm tham số mới cho mọi mô hình mà chúng ta muốn kiểm tra.

Sau khi thêm tham số, bạn sẽ thấy nó trong Bảng điều khiển:

699b3fd32acce887.png

Trong mã của chúng tôi, chúng tôi sẽ cần thêm kiểm tra khi tải mô hình từ xa. Khi nhận được tham số từ Cấu hình từ xa, chúng tôi sẽ tìm nạp mô hình từ xa có tên tương ứng; nếu không chúng tôi sẽ cố tải mnist_v1 . Trước khi có thể sử dụng Remote Config, chúng ta phải thêm nó vào dự án của mình bằng cách chỉ định nó làm phần phụ thuộc trong Podfile:

pod 'FirebaseRemoteConfig'

Chạy pod install và mở lại dự án Xcode. Trong ModelLoader.swift , hãy triển khai phương thức fetchParameterizedModel .

static func fetchParameterizedModel(completion: @escaping (CustomModel?, DownloadError?) -> Void) {
  RemoteConfig.remoteConfig().fetchAndActivate { (status, error) in
    DispatchQueue.main.async {
      if let error = error {
        let compositeError = DownloadError.downloadFailed(underlyingError: error)
        completion(nil, compositeError)
        return
      }

      let modelName: String
      if let name = RemoteConfig.remoteConfig().configValue(forKey: "model_name").stringValue {
        modelName = name
      } else {
        let defaultName = "mnist_v1"
        print("Unable to fetch model name from config, falling back to default \(defaultName)")
        modelName = defaultName
      }
      downloadModel(named: modelName, completion: completion)
    }
  }
}

Cuối cùng, trong ViewController.swift , thay thế lệnh gọi downloadModel bằng phương thức mới mà chúng ta vừa triển khai.

// Download the model from Firebase
print("Fetching model...")
ModelLoader.fetchParameterizedModel { (customModel, error) in
  guard let customModel = customModel else {
    if let error = error {
      print(error)
    }
    return
  }

  print("Model download complete")
  
  // Initialize a DigitClassifier instance
  DigitClassifier.newInstance(modelPath: customModel.path) { result in
  switch result {
    case let .success(classifier):
      self.classifier = classifier
    case .error(_):
      self.resultLabel.text = "Failed to initialize."
    }
  }
}

Chạy lại ứng dụng và đảm bảo ứng dụng vẫn tải mô hình chính xác.

10. A/B Test hai mô hình

Cuối cùng, chúng ta có thể sử dụng hành vi Thử nghiệm A/B tích hợp của Firebase để xem mô hình nào trong hai mô hình của chúng ta hoạt động tốt hơn. Chuyển đến Analytics -> Sự kiện trong bảng điều khiển Firebase. Nếu sự kiện correct_inference đang hiển thị, hãy đánh dấu sự kiện đó là "Sự kiện chuyển đổi", nếu không, bạn có thể truy cập Analytics -> Sự kiện chuyển đổi và nhấp vào "Tạo sự kiện chuyển đổi mới" và đặt correct_inference.

Bây giờ, hãy chuyển đến "Cấu hình từ xa trong bảng điều khiển Firebase, chọn nút "Thử nghiệm A/B" từ menu tùy chọn khác trên thông số "model_name" mà chúng tôi vừa thêm.

fad5ea36969d2aeb.png

Trong menu tiếp theo, chấp nhận tên mặc định.

d7c006669ace6e40.png

Chọn ứng dụng của bạn trong menu thả xuống và thay đổi tiêu chí nhắm mục tiêu thành 50% số người dùng đang hoạt động.

6246dd7c660b53fb.png

Nếu trước đó bạn có thể đặt sự kiện correct_inference làm lượt chuyển đổi, hãy sử dụng sự kiện này làm chỉ số chính để theo dõi. Ngược lại, nếu không muốn đợi sự kiện hiển thị trong Analytics, bạn có thể thêm correct_inference theo cách thủ công.

1ac9c94fb3159271.png

Cuối cùng, trên màn hình Biến thể, đặt biến thể nhóm điều khiển của bạn để sử dụng mnist_v1 và nhóm Biến thể A của bạn để sử dụng mnist_v2 .

e4510434f8da31b6.png

Nhấp vào nút Xem lại ở góc dưới bên phải.

Xin chúc mừng, bạn đã tạo thành công thử nghiệm A/B cho hai mô hình riêng biệt của mình! Thử nghiệm A/B hiện đang ở trạng thái nháp và có thể bắt đầu bất kỳ lúc nào bằng cách nhấp vào nút "Bắt đầu thử nghiệm".

Để có cái nhìn sâu hơn về thử nghiệm A/B, hãy xem tài liệu về Thử nghiệm A/B .

11. Kết luận

Trong lớp học lập trình này, bạn đã tìm hiểu cách thay thế nội dung tflite được đóng gói tĩnh trong ứng dụng của mình bằng mô hình TFLite được tải động từ Firebase. Để tìm hiểu thêm về TFLite và Firebase, hãy xem các mẫu TFLite khác và hướng dẫn bắt đầu Firebase.

Có một câu hỏi?

Báo cáo vấn đề