اگر برنامه شما از مدلهای سفارشی TensorFlow Lite استفاده میکند، میتوانید از Firebase ML برای استقرار مدلهای خود استفاده کنید. با استقرار مدلها با Firebase، میتوانید حجم دانلود اولیه برنامه خود را کاهش دهید و مدلهای ML برنامه خود را بدون انتشار نسخه جدیدی از برنامه خود بهروزرسانی کنید. و با Remote Config و A/B Testing ، میتوانید به صورت پویا مدلهای مختلف را به مجموعههای مختلف کاربران ارائه دهید.
پیش نیازها
- کتابخانه
MLModelDownloader
فقط برای Swift در دسترس است. - TensorFlow Lite فقط روی دستگاههایی که iOS 9 و جدیدتر استفاده میکنند اجرا میشود.
مدل های TensorFlow Lite
مدل های TensorFlow Lite مدل های ML هستند که برای اجرا در دستگاه های تلفن همراه بهینه شده اند. برای دریافت مدل TensorFlow Lite:
- از یک مدل از پیش ساخته شده مانند یکی از مدلهای رسمی TensorFlow Lite استفاده کنید.
- یک مدل TensorFlow، مدل Keras یا تابع بتن را به TensorFlow Lite تبدیل کنید.
قبل از شروع
برای استفاده از TensorFlowLite با Firebase، باید از CocoaPods استفاده کنید زیرا TensorFlowLite در حال حاضر از نصب با Swift Package Manager پشتیبانی نمیکند. راهنمای نصب CocoaPods را برای دستورالعملهای نحوه نصب MLModelDownloader
ببینید.
پس از نصب، Firebase و TensorFlowLite را وارد کنید تا از آنها استفاده کنید.
سویفت
import FirebaseMLModelDownloader
import TensorFlowLite
1. مدل خود را مستقر کنید
مدلهای TensorFlow سفارشی خود را با استفاده از کنسول Firebase یا Firebase Admin Python و Node.js SDK اجرا کنید. به استقرار و مدیریت مدلهای سفارشی مراجعه کنید.
پس از اینکه یک مدل سفارشی را به پروژه Firebase خود اضافه کردید، میتوانید با استفاده از نامی که مشخص کردهاید به مدل در برنامههای خود ارجاع دهید. در هر زمان، میتوانید یک مدل جدید TensorFlow Lite را اجرا کنید و با فراخوانی getModel()
مدل جدید را در دستگاههای کاربران دانلود کنید (به زیر مراجعه کنید).
2. مدل را در دستگاه دانلود کنید و یک مفسر TensorFlow Lite را مقداردهی اولیه کنید
برای استفاده از مدل TensorFlow Lite در برنامه خود، ابتدا از Firebase ML SDK برای دانلود آخرین نسخه مدل در دستگاه استفاده کنید. برای شروع دانلود مدل، متد getModel()
دانلود کننده مدل را فراخوانی کنید، نامی را که به مدل اختصاص داده اید هنگام آپلود کردن، مشخص کنید که آیا می خواهید همیشه آخرین مدل را دانلود کنید، و شرایطی که می خواهید اجازه دانلود را بدهید.
شما می توانید از بین سه رفتار دانلود انتخاب کنید:
نوع دانلود | توضیحات |
---|---|
localModel | مدل محلی را از دستگاه دریافت کنید. اگر هیچ مدل محلی در دسترس نباشد، مانند latestModel عمل می کند. اگر علاقه ای به بررسی به روز رسانی مدل ندارید از این نوع دانلود استفاده کنید. برای مثال، شما از Remote Config برای بازیابی نام مدل ها استفاده می کنید و همیشه مدل ها را با نام های جدید آپلود می کنید (توصیه می شود). |
localModelUpdateInBackground | مدل محلی را از دستگاه دریافت کنید و به روز رسانی مدل را در پس زمینه شروع کنید. اگر هیچ مدل محلی در دسترس نباشد، مانند latestModel عمل می کند. |
latestModel | آخرین مدل را دریافت کنید. اگر مدل محلی آخرین نسخه باشد، مدل محلی را برمی گرداند. در غیر این صورت آخرین مدل را دانلود کنید. این رفتار تا زمانی که آخرین نسخه دانلود نشود مسدود می شود (توصیه نمی شود). از این رفتار فقط در مواردی استفاده کنید که به صراحت به آخرین نسخه نیاز دارید. |
باید عملکردهای مربوط به مدل را غیرفعال کنید - برای مثال، خاکستری کردن یا پنهان کردن بخشی از رابط کاربری خود - تا زمانی که تأیید کنید مدل دانلود شده است.
سویفت
let conditions = ModelDownloadConditions(allowsCellularAccess: false)
ModelDownloader.modelDownloader()
.getModel(name: "your_model",
downloadType: .localModelUpdateInBackground,
conditions: conditions) { result in
switch (result) {
case .success(let customModel):
do {
// Download complete. Depending on your app, you could enable the ML
// feature, or switch from the local model to the remote model, etc.
// The CustomModel object contains the local path of the model file,
// which you can use to instantiate a TensorFlow Lite interpreter.
let interpreter = try Interpreter(modelPath: customModel.path)
} catch {
// Error. Bad model file?
}
case .failure(let error):
// Download was unsuccessful. Don't enable ML features.
print(error)
}
}
بسیاری از برنامهها وظیفه دانلود را در کد اولیه خود شروع میکنند، اما شما میتوانید این کار را در هر زمانی قبل از نیاز به استفاده از مدل انجام دهید.
3. استنتاج بر روی داده های ورودی انجام دهید
اشکال ورودی و خروجی مدل خود را دریافت کنید
مفسر مدل TensorFlow Lite به عنوان ورودی می گیرد و یک یا چند آرایه چند بعدی را به عنوان خروجی تولید می کند. این آرایه ها حاوی مقادیر byte
، int
، long
یا float
هستند. قبل از اینکه بتوانید داده ها را به یک مدل منتقل کنید یا از نتیجه آن استفاده کنید، باید تعداد و ابعاد ("شکل") آرایه هایی که مدل شما استفاده می کند را بدانید.
اگر مدل را خودتان ساخته اید، یا اگر فرمت ورودی و خروجی مدل مستند است، ممکن است از قبل این اطلاعات را داشته باشید. اگر شکل و نوع داده ورودی و خروجی مدل خود را نمی دانید، می توانید از مفسر TensorFlow Lite برای بررسی مدل خود استفاده کنید. به عنوان مثال:
پایتون
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="your_model.tflite") interpreter.allocate_tensors() # Print input shape and type inputs = interpreter.get_input_details() print('{} input(s):'.format(len(inputs))) for i in range(0, len(inputs)): print('{} {}'.format(inputs[i]['shape'], inputs[i]['dtype'])) # Print output shape and type outputs = interpreter.get_output_details() print('\n{} output(s):'.format(len(outputs))) for i in range(0, len(outputs)): print('{} {}'.format(outputs[i]['shape'], outputs[i]['dtype']))
خروجی نمونه:
1 input(s): [ 1 224 224 3] <class 'numpy.float32'> 1 output(s): [1 1000] <class 'numpy.float32'>
مترجم را اجرا کنید
پس از اینکه فرمت ورودی و خروجی مدل خود را تعیین کردید، داده های ورودی خود را دریافت کنید و هر گونه تغییری را که برای به دست آوردن ورودی با شکل مناسب برای مدل شما ضروری است، روی داده ها انجام دهید. به عنوان مثال، اگر مدل شما تصاویر را پردازش می کند و مدل شما دارای ابعاد ورودی [1, 224, 224, 3]
مقادیر ممیز شناور است، ممکن است لازم باشد مقادیر رنگ تصویر را به یک محدوده ممیز شناور تغییر دهید، مانند مثال زیر. :
سویفت
let image: CGImage = // Your input image
guard let context = CGContext(
data: nil,
width: image.width, height: image.height,
bitsPerComponent: 8, bytesPerRow: image.width * 4,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue
) else {
return false
}
context.draw(image, in: CGRect(x: 0, y: 0, width: image.width, height: image.height))
guard let imageData = context.data else { return false }
var inputData = Data()
for row in 0 ..< 224 {
for col in 0 ..< 224 {
let offset = 4 * (row * context.width + col)
// (Ignore offset 0, the unused alpha channel)
let red = imageData.load(fromByteOffset: offset+1, as: UInt8.self)
let green = imageData.load(fromByteOffset: offset+2, as: UInt8.self)
let blue = imageData.load(fromByteOffset: offset+3, as: UInt8.self)
// Normalize channel values to [0.0, 1.0]. This requirement varies
// by model. For example, some models might require values to be
// normalized to the range [-1.0, 1.0] instead, and others might
// require fixed-point values or the original bytes.
var normalizedRed = Float32(red) / 255.0
var normalizedGreen = Float32(green) / 255.0
var normalizedBlue = Float32(blue) / 255.0
// Append normalized values to Data object in RGB order.
let elementSize = MemoryLayout.size(ofValue: normalizedRed)
var bytes = [UInt8](repeating: 0, count: elementSize)
memcpy(&bytes, &normalizedRed, elementSize)
inputData.append(&bytes, count: elementSize)
memcpy(&bytes, &normalizedGreen, elementSize)
inputData.append(&bytes, count: elementSize)
memcpy(&ammp;bytes, &normalizedBlue, elementSize)
inputData.append(&bytes, count: elementSize)
}
}
سپس، ورودی NSData
خود را در مفسر کپی کنید و آن را اجرا کنید:
سویفت
try interpreter.allocateTensors()
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()
با فراخوانی متد output(at:)
می توانید خروجی مدل را دریافت کنید. نحوه استفاده از خروجی به مدلی که استفاده می کنید بستگی دارد.
به عنوان مثال، اگر در حال انجام طبقه بندی هستید، در مرحله بعدی، ممکن است نمایه های نتیجه را به برچسب هایی که نشان می دهند نگاشت کنید:
سویفت
let output = try interpreter.output(at: 0)
let probabilities =
UnsafeMutableBufferPointer<Float32>.allocate(capacity: 1000)
output.data.copyBytes(to: probabilities)
guard let labelPath = Bundle.main.path(forResource: "retrained_labels", ofType: "txt") else { return }
let fileContents = try? String(contentsOfFile: labelPath)
guard let labels = fileContents?.components(separatedBy: "\n") else { return }
for i in labels.indices {
print("\(labels[i]): \(probabilities[i])")
}
ضمیمه: امنیت مدل
صرف نظر از اینکه چگونه مدلهای TensorFlow Lite خود را در دسترس Firebase ML قرار میدهید، Firebase ML آنها را در قالب استاندارد پروتوباف سریالی در حافظه محلی ذخیره میکند.
در تئوری، این بدان معنی است که هر کسی می تواند مدل شما را کپی کند. با این حال، در عمل، بیشتر مدلها به قدری برنامههای کاربردی خاص هستند و بهوسیله بهینهسازیها مبهم هستند که خطر آن مشابه خطر جداسازی و استفاده مجدد کد شما توسط رقبا است. با این وجود، قبل از استفاده از یک مدل سفارشی در برنامه خود، باید از این خطر آگاه باشید.