আপনার অ্যাপ কাস্টম 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-এ কনভার্ট করুন।
শুরু করার আগে
Firebase-এর সাথে TensorFlowLite ব্যবহার করতে, আপনাকে অবশ্যই CocoaPods ব্যবহার করতে হবে, কারণ TensorFlowLite
বর্তমানে Swift Package Manager-এর সাথে ইনস্টল করা যায় না। MLModelDownloader ইনস্টল করার
নির্দেশাবলীর জন্য
CocoaPods ইনস্টলেশন গাইড দেখুন।
ইনস্টল করা হয়ে গেলে, সেগুলি ব্যবহার করার জন্য Firebase ও TensorFlowLite ইমপোর্ট করুন।
Swift
import FirebaseMLModelDownloader
import TensorFlowLite
১. আপনার মডেল ডেপ্লয় করা
Firebase কনসোল বা Firebase Admin Python এবং Node.js SDK ব্যবহার করে আপনার কাস্টম TensorFlow মডেল ডিপ্লয় করুন। কাস্টম মডেল ডেপ্লয় ও ম্যানেজ করা দেখুন।
Firebase প্রোজেক্টে কাস্টম মডেল যোগ করার পরে, আপনি যে নাম নির্দিষ্ট করেছেন সেটি ব্যবহার করে অ্যাপে মডেলের
রেফারেন্স দিতে পারবেন। আপনি যেকোনও সময়, নতুন TensorFlow Lite মডেল ডেপ্লয় করতে
পারেন এবং getModel() কল করে (নিচে দেখুন)
ব্যবহারকারীর ডিভাইসে নতুন মডেল ডাউনলোড করতে পারেন।
২. ডিভাইসে মডেল ডাউনলোড করুন এবং TensorFlow Lite ইন্টারপ্রেটার ইনিশিয়ালাইজ করুন
আপনার অ্যাপে TensorFlow Lite মডেল ব্যবহার করতে, প্রথমে Firebase ML SDK ব্যবহার করে ডিভাইসে মডেলের লেটেস্ট ভার্সন ডাউনলোড করুন।মডেল ডাউনলোড শুরু করতে, মডেল ডাউনলোডার getModel() মেথডকে কল করুন,
আপনি আপলোড করার সময় মডেলটিকে যে নাম অ্যাসাইন করেছিলেন সেটি উল্লেখ করুন, আপনি
সর্বদা লেটেস্ট মডেল ডাউনলোড করতে চান কিনা এবং আপনি যে শর্তের অধীনে
ডাউনলোড করার অনুমতি দিতে চান।
আপনি তিনটি ডাউনলোড আচরণ থেকে বেছে নিতে পারবেন:
| ডাউনলোডের ধরন | বিবরণ |
|---|---|
localModel
|
ডিভাইস থেকে লোকাল মডেল পান।
কোনও লোকাল মডেল উপলভ্য না থাকলে, এটি
latestModel-এর মতো আচরণ করে। মডেল আপডেট চেক করার
ব্যাপারে আগ্রহী না হলে এই
ডাউনলোড করার ধরন ব্যবহার করুন। যেমন,
আপনি মডেলের নাম রিট্রিভ করতে
রিমোট কনফিগারেশন ব্যবহার করছেন এবং আপনি সবসময়
নতুন নামে মডেল আপলোড করেন (সাজেস্ট করা)। |
localModelUpdateInBackground
|
ডিভাইস থেকে লোকাল মডেল পান এবং
ব্যাকগ্রাউন্ডে মডেল আপডেট করা শুরু করুন।
কোনও লোকাল মডেল উপলভ্য না থাকলে, এটি
latestModel-এর মতো আচরণ করে। |
latestModel
|
লেটেস্ট মডেল পান। লোকাল মডেলটি লেটেস্ট ভার্সন হলে, লোকাল মডেলটি রিটার্ন করে। অন্যথায়, লেটেস্ট মডেল ডাউনলোড করুন। লেটেস্ট ভার্সন ডাউনলোড না করা পর্যন্ত এই আচরণ ব্লক করা হবে (সাজেস্ট করা হয় না)। আপনি যদি স্পষ্টভাবে লেটেস্ট ভার্সন চান, শুধুমাত্র সেইসব ক্ষেত্রে এই আচরণ ব্যবহার করুন। |
মডেল ডাউনলোড করা হয়েছে বলে নিশ্চিত না হওয়া পর্যন্ত, মডেল-সম্পর্কিত ফাংশনালিটি বন্ধ করে দিন—যেমন, আপনার UI-এর অংশ গ্রে-আউট বা লুকিয়ে দিন।
Swift
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)
}
}
অনেক অ্যাপ তাদের ইনিশিয়ালাইজেশন কোডে ডাউনলোড টাস্ক শুরু করে, কিন্তু মডেল ব্যবহার করার প্রয়োজন হওয়ার আগে আপনি যেকোনও সময় এটি করতে পারেন।
৩. ইনপুট ডেটা থেকে ফলাফল অনুমান করা
আপনার মডেলের ইনপুট ও আউটপুট শেপ পাওয়া
TensorFlow Lite মডেল ইন্টারপ্রেটার ইনপুট হিসেবে নেয় এবং আউটপুট হিসেবে
এক বা একাধিক মাল্টিডাইমেনশনাল অ্যারে তৈরি করে। এইসব অ্যারেতে
byte, int, long অথবা float
ভ্যালু থাকে। কোনও মডেলে ডেটা পাস করা বা তার ফলাফল ব্যবহার করার আগে, আপনাকে অবশ্যই
মডেলের ব্যবহার করা অ্যারের সংখ্যা ও ডাইমেনশন ("শেপ") জানতে হবে।
আপনি নিজে মডেল তৈরি করে থাকলে অথবা মডেলের ইনপুট ও আউটপুট ফরম্যাট ডকুমেন্টেড থাকলে, আপনার কাছে হয়ত আগেই এই তথ্য আছে। আপনার মডেলের ইনপুট ও আউটপুটের আকার ও ডেটা টাইপ না জানলে, আপনার মডেল পরীক্ষা করে দেখতে TensorFlow Lite ইন্টারপ্রেটার ব্যবহার করতে পারবেন। যেমন:
Python
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] ফ্লোটিং-পয়েন্ট ভ্যালু হয়, তাহলে আপনাকে হয়ত নিম্নলিখিত উদাহরণের মতো
ছবির কালার ভ্যালুকে ফ্লোটিং-পয়েন্ট রেঞ্জে স্কেল করতে হবে:
Swift
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 ইন্টারপ্রেটারে কপি করে রান করান:
Swift
try interpreter.allocateTensors()
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()
ইন্টারপ্রেটারের output(at:) মেথড কল করে আপনি মডেলের আউটপুট পেতে পারেন।
আপনি কীভাবে আউটপুট ব্যবহার করবেন তা নির্ভর করে আপনি কোন মডেল ব্যবহার করছেন তার উপর।
যেমন, আপনি যদি শ্রেণীবিভাগ করছেন, তাহলে পরবর্তী ধাপ হিসেবে, আপনি ফলাফলের ইন্ডেক্সকে সেই লেবেলের সাথে ম্যাপ করতে পারেন যেগুলি সেগুলিকে প্রতিনিধিত্ব করে:
Swift
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 সেগুলি লোকাল স্টোরেজে স্ট্যান্ডার্ড সিরিয়ালাইজড প্রোটোবাফ ফর্ম্যাটে সেভ করে।
তত্ত্বগতভাবে, এর অর্থ হল যে কেউ আপনার মডেল কপি করতে পারবেন। তবে, বাস্তবে, বেশিরভাগ মডেলই এত বেশি অ্যাপ্লিকেশন-নির্দিষ্ট এবং অপ্টিমাইজেশনের মাধ্যমে অস্পষ্ট করা হয় যে ঝুঁকিটি আপনার কোড ডিসঅ্যাসেম্বল করা এবং পুনরায় ব্যবহার করার ক্ষেত্রে প্রতিযোগীদের ঝুঁকির মতোই। তবে, আপনার অ্যাপে কাস্টম মডেল ব্যবহার করার আগে এই ঝুঁকি সম্পর্কে সচেতন থাকা উচিত।