আপনি একটি টেনসরফ্লো লাইট মডেলের সাথে ডিভাইসে অনুমান সম্পাদন করতে ML কিট ব্যবহার করতে পারেন।
ML Kit TensorFlow Lite মডেল ব্যবহার করতে পারে শুধুমাত্র iOS 9 এবং তার পরবর্তী ডিভাইসে চলমান ডিভাইসগুলিতে।
আপনি শুরু করার আগে
- আপনি যদি ইতিমধ্যে আপনার অ্যাপে Firebase যোগ না করে থাকেন, তাহলে শুরু করার নির্দেশিকাতে দেওয়া ধাপগুলি অনুসরণ করে তা করুন৷
- আপনার পডফাইলে এমএল কিট লাইব্রেরি অন্তর্ভুক্ত করুন:
pod 'Firebase/MLModelInterpreter', '6.25.0'
আপনি আপনার প্রোজেক্টের পড ইনস্টল বা আপডেট করার পরে, আপনার Xcode প্রোজেক্ট এর.xcworkspace
ব্যবহার করে খুলতে ভুলবেন না। - আপনার অ্যাপে, Firebase আমদানি করুন:
সুইফট
import Firebase
উদ্দেশ্য-C
@import Firebase;
- আপনি যে টেনসরফ্লো মডেলটি ব্যবহার করতে চান তা টেনসরফ্লো লাইট ফর্ম্যাটে রূপান্তর করুন। TOCO দেখুন: TensorFlow Lite অপটিমাইজিং কনভার্টার ।
হোস্ট বা আপনার মডেল বান্ডিল
আপনার অ্যাপে অনুমান করার জন্য আপনি একটি TensorFlow Lite মডেল ব্যবহার করার আগে, আপনাকে অবশ্যই মডেলটি ML Kit-এ উপলব্ধ করতে হবে। ML Kit TensorFlow Lite মডেল ব্যবহার করতে পারে যা দূরবর্তীভাবে Firebase ব্যবহার করে হোস্ট করা, অ্যাপ বাইনারি বা উভয়ের সাথে বান্ডিল করা।
Firebase-এ একটি মডেল হোস্ট করার মাধ্যমে, আপনি একটি নতুন অ্যাপ সংস্করণ প্রকাশ না করেই মডেলটি আপডেট করতে পারেন এবং আপনি ব্যবহারকারীদের বিভিন্ন সেটের কাছে গতিশীলভাবে বিভিন্ন মডেল পরিবেশন করতে Remote Config এবং A/B Testing ব্যবহার করতে পারেন।
আপনি যদি শুধুমাত্র Firebase-এর সাথে হোস্ট করে মডেলটি প্রদান করতে চান এবং এটিকে আপনার অ্যাপের সাথে বান্ডিল না করে, তাহলে আপনি আপনার অ্যাপের প্রাথমিক ডাউনলোডের আকার কমাতে পারেন। মনে রাখবেন, যদিও, মডেলটি আপনার অ্যাপের সাথে বান্ডিল না থাকলে, আপনার অ্যাপটি প্রথমবারের মতো মডেলটি ডাউনলোড না করা পর্যন্ত কোনো মডেল-সম্পর্কিত কার্যকারিতা উপলব্ধ হবে না।
আপনার অ্যাপের সাথে আপনার মডেলকে একত্রিত করে, আপনি নিশ্চিত করতে পারেন যে Firebase-হোস্টেড মডেলটি উপলব্ধ না থাকলে আপনার অ্যাপের ML বৈশিষ্ট্যগুলি এখনও কাজ করে।
Firebase-এ হোস্ট মডেল
Firebase এ আপনার TensorFlow Lite মডেল হোস্ট করতে:
- Firebase কনসোলের ML Kit বিভাগে, কাস্টম ট্যাবে ক্লিক করুন।
- কাস্টম মডেল যোগ করুন ক্লিক করুন (বা অন্য মডেল যোগ করুন )।
- একটি নাম নির্দিষ্ট করুন যা আপনার ফায়ারবেস প্রকল্পে আপনার মডেল শনাক্ত করতে ব্যবহার করা হবে, তারপর TensorFlow Lite মডেল ফাইল আপলোড করুন (সাধারণত
.tflite
বা.lite
এ শেষ হয়)।
আপনি আপনার ফায়ারবেস প্রোজেক্টে একটি কাস্টম মডেল যোগ করার পরে, আপনি আপনার নির্দিষ্ট করা নাম ব্যবহার করে আপনার অ্যাপে মডেলটি উল্লেখ করতে পারেন। যে কোনো সময়ে, আপনি একটি নতুন TensorFlow Lite মডেল আপলোড করতে পারেন এবং আপনার অ্যাপটি নতুন মডেল ডাউনলোড করবে এবং অ্যাপটি পরবর্তী রিস্টার্ট হলে এটি ব্যবহার করা শুরু করবে। আপনি মডেল আপডেট করার চেষ্টা করার জন্য আপনার অ্যাপের জন্য প্রয়োজনীয় ডিভাইসের শর্তগুলি সংজ্ঞায়িত করতে পারেন (নীচে দেখুন)।
একটি অ্যাপ সহ মডেল বান্ডিল করুন
আপনার অ্যাপের সাথে আপনার TensorFlow Lite মডেলটি বান্ডিল করতে, আপনার Xcode প্রকল্পে মডেল ফাইলটি (সাধারণত .tflite
বা .lite
এ শেষ হয়) যোগ করুন, যখন আপনি এটি করবেন তখন কপি বান্ডেল সংস্থান নির্বাচন করবেন। মডেল ফাইলটি অ্যাপ বান্ডেলে অন্তর্ভুক্ত করা হবে এবং ML কিটে উপলব্ধ হবে।
মডেল লোড করুন
আপনার অ্যাপে আপনার TensorFlow Lite মডেল ব্যবহার করতে, প্রথমে আপনার মডেল উপলব্ধ যেখানে অবস্থানের সাথে ML Kit কনফিগার করুন: দূরবর্তীভাবে Firebase ব্যবহার করে, স্থানীয় স্টোরেজে বা উভয়ই। আপনি যদি স্থানীয় এবং দূরবর্তী উভয় মডেল নির্দিষ্ট করেন, তাহলে আপনি দূরবর্তী মডেলটি ব্যবহার করতে পারেন যদি এটি উপলব্ধ থাকে, এবং যদি দূরবর্তী মডেল উপলব্ধ না হয় তবে স্থানীয়ভাবে-সঞ্চিত মডেলটিতে ফিরে যেতে পারেন।
একটি Firebase-হোস্টেড মডেল কনফিগার করুন
আপনি যদি Firebase-এর সাথে আপনার মডেল হোস্ট করেন, তাহলে একটি CustomRemoteModel
অবজেক্ট তৈরি করুন, আপনি মডেলটিকে প্রকাশ করার সময় যে নামটি বরাদ্দ করেছেন তা উল্লেখ করে:
সুইফট
let remoteModel = CustomRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
উদ্দেশ্য-C
// Initialize using the name you assigned in the Firebase console.
FIRCustomRemoteModel *remoteModel =
[[FIRCustomRemoteModel alloc] initWithName:@"your_remote_model"];
তারপরে, আপনি যে শর্তে ডাউনলোড করার অনুমতি দিতে চান তা উল্লেখ করে মডেল ডাউনলোড টাস্ক শুরু করুন। যদি মডেলটি ডিভাইসে না থাকে, বা মডেলটির একটি নতুন সংস্করণ উপলব্ধ থাকলে, টাস্কটি অসিঙ্ক্রোনাসভাবে Firebase থেকে মডেলটি ডাউনলোড করবে:
সুইফট
let downloadConditions = ModelDownloadConditions(
allowsCellularAccess: true,
allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
remoteModel,
conditions: downloadConditions
)
উদ্দেশ্য-C
FIRModelDownloadConditions *downloadConditions =
[[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[FIRModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
অনেক অ্যাপ তাদের ইনিশিয়ালাইজেশন কোডে ডাউনলোড টাস্ক শুরু করে, কিন্তু মডেল ব্যবহার করার আগে আপনি যেকোন সময়ে তা করতে পারেন।
একটি স্থানীয় মডেল কনফিগার করুন
আপনি যদি আপনার অ্যাপের সাথে মডেলটি বান্ডিল করেন, তাহলে TensorFlow Lite মডেলের ফাইলের নাম উল্লেখ করে একটি CustomLocalModel
অবজেক্ট তৈরি করুন:
সুইফট
guard let modelPath = Bundle.main.path(
forResource: "your_model",
ofType: "tflite",
inDirectory: "your_model_directory"
) else { /* Handle error. */ }
let localModel = CustomLocalModel(modelPath: modelPath)
উদ্দেশ্য-C
NSString *modelPath = [NSBundle.mainBundle pathForResource:@"your_model"
ofType:@"tflite"
inDirectory:@"your_model_directory"];
FIRCustomLocalModel *localModel =
[[FIRCustomLocalModel alloc] initWithModelPath:modelPath];
আপনার মডেল থেকে একটি দোভাষী তৈরি করুন
আপনি আপনার মডেল উত্স কনফিগার করার পরে, তাদের মধ্যে একটি থেকে একটি ModelInterpreter
অবজেক্ট তৈরি করুন।
যদি আপনার কাছে শুধুমাত্র স্থানীয়ভাবে বান্ডিল করা মডেল থাকে, তাহলে শুধু CustomLocalModel
অবজেক্টকে modelInterpreter(localModel:)
এ পাস করুন :
সুইফট
let interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
উদ্দেশ্য-C
FIRModelInterpreter *interpreter =
[FIRModelInterpreter modelInterpreterForLocalModel:localModel];
আপনার যদি দূরবর্তীভাবে-হোস্ট করা মডেল থাকে, তাহলে আপনাকে এটি চালানোর আগে এটি ডাউনলোড করা হয়েছে কিনা তা পরীক্ষা করতে হবে। আপনি মডেল ম্যানেজারের isModelDownloaded(remoteModel:)
পদ্ধতি ব্যবহার করে মডেল ডাউনলোড টাস্কের স্থিতি পরীক্ষা করতে পারেন।
যদিও আপনাকে শুধুমাত্র দোভাষী চালানোর আগে এটি নিশ্চিত করতে হবে, যদি আপনার কাছে একটি দূরবর্তীভাবে-হোস্ট করা মডেল এবং একটি স্থানীয়ভাবে-বান্ডিল মডেল উভয়ই থাকে, তাহলে ModelInterpreter
ইনস্ট্যান্টিয়েট করার সময় এই চেকটি সম্পাদন করা বোধগম্য হতে পারে: যদি এটি হয় তবে দূরবর্তী মডেল থেকে একটি দোভাষী তৈরি করুন ডাউনলোড করা হয়েছে, এবং অন্যথায় স্থানীয় মডেল থেকে।
সুইফট
var interpreter: ModelInterpreter
if ModelManager.modelManager().isModelDownloaded(remoteModel) {
interpreter = ModelInterpreter.modelInterpreter(remoteModel: remoteModel)
} else {
interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
}
উদ্দেশ্য-C
FIRModelInterpreter *interpreter;
if ([[FIRModelManager modelManager] isModelDownloaded:remoteModel]) {
interpreter = [FIRModelInterpreter modelInterpreterForRemoteModel:remoteModel];
} else {
interpreter = [FIRModelInterpreter modelInterpreterForLocalModel:localModel];
}
যদি আপনার কাছে শুধুমাত্র একটি দূরবর্তীভাবে হোস্ট করা মডেল থাকে, তাহলে আপনার মডেল-সম্পর্কিত কার্যকারিতা অক্ষম করা উচিত-উদাহরণস্বরূপ, ধূসর-আউট বা আপনার UI-এর অংশ লুকান-যতক্ষণ না আপনি নিশ্চিত করেন যে মডেলটি ডাউনলোড করা হয়েছে।
আপনি ডিফল্ট বিজ্ঞপ্তি কেন্দ্রে পর্যবেক্ষকদের সংযুক্ত করে মডেল ডাউনলোডের অবস্থা পেতে পারেন। পর্যবেক্ষক ব্লকে self
সম্পর্কে একটি দুর্বল রেফারেন্স ব্যবহার করতে ভুলবেন না, যেহেতু ডাউনলোডে কিছু সময় লাগতে পারে, এবং ডাউনলোড শেষ হওয়ার সময় থেকে উদ্ভূত বস্তুটি মুক্ত করা যেতে পারে। যেমন:
সুইফট
NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidSucceed, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel, model.name == "your_remote_model" else { return } // The model was downloaded and is available on the device } NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidFail, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel else { return } let error = userInfo[ModelDownloadUserInfoKey.error.rawValue] // ... }
উদ্দেশ্য-C
__weak typeof(self) weakSelf = self; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidSucceedNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel]; if ([model.name isEqualToString:@"your_remote_model"]) { // The model was downloaded and is available on the device } }]; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidFailNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; NSError *error = note.userInfo[FIRModelDownloadUserInfoKeyError]; }];
মডেলের ইনপুট এবং আউটপুট উল্লেখ করুন
এর পরে, মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট ফর্ম্যাটগুলি কনফিগার করুন।
একটি টেনসরফ্লো লাইট মডেল ইনপুট হিসাবে নেয় এবং আউটপুট হিসাবে এক বা একাধিক বহুমাত্রিক অ্যারে তৈরি করে। এই অ্যারেগুলিতে হয় byte
, int
, long
, বা float
মান থাকে৷ আপনার মডেল ব্যবহার করে অ্যারেগুলির সংখ্যা এবং মাত্রা ("আকৃতি") সহ আপনাকে ML কিট কনফিগার করতে হবে৷
আপনি যদি আপনার মডেলের ইনপুট এবং আউটপুটের আকার এবং ডেটা টাইপ না জানেন, তাহলে আপনি আপনার মডেল পরিদর্শন করতে TensorFlow Lite Python ইন্টারপ্রেটার ব্যবহার করতে পারেন। যেমন:
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="my_model.tflite") interpreter.allocate_tensors() # Print input shape and type print(interpreter.get_input_details()[0]['shape']) # Example: [1 224 224 3] print(interpreter.get_input_details()[0]['dtype']) # Example: <class 'numpy.float32'> # Print output shape and type print(interpreter.get_output_details()[0]['shape']) # Example: [1 1000] print(interpreter.get_output_details()[0]['dtype']) # Example: <class 'numpy.float32'>
আপনি আপনার মডেলের ইনপুট এবং আউটপুটের বিন্যাস নির্ধারণ করার পরে, একটি ModelInputOutputOptions
অবজেক্ট তৈরি করে আপনার অ্যাপের মডেল ইন্টারপ্রেটার কনফিগার করুন৷
উদাহরণস্বরূপ, একটি ফ্লোটিং-পয়েন্ট ইমেজ ক্লাসিফিকেশন মডেল ইনপুট হিসাবে Float
মানগুলির একটি N x224x224x3 অ্যারে নিতে পারে, যা N 224x224 থ্রি-চ্যানেল (RGB) চিত্রগুলির একটি ব্যাচের প্রতিনিধিত্ব করে এবং আউটপুট হিসাবে 1000টি Float
মানগুলির একটি তালিকা তৈরি করে, প্রতিটি প্রতিনিধিত্ব করে সম্ভাব্যতা মডেলটি ভবিষ্যদ্বাণী করে এমন 1000টি বিভাগের একটির একটি সদস্য।
এই ধরনের একটি মডেলের জন্য, আপনি মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট কনফিগার করবেন যা নীচে দেখানো হয়েছে:
সুইফট
let ioOptions = ModelInputOutputOptions() do { try ioOptions.setInputFormat(index: 0, type: .float32, dimensions: [1, 224, 224, 3]) try ioOptions.setOutputFormat(index: 0, type: .float32, dimensions: [1, 1000]) } catch let error as NSError { print("Failed to set input or output format with error: \(error.localizedDescription)") }
উদ্দেশ্য-C
FIRModelInputOutputOptions *ioOptions = [[FIRModelInputOutputOptions alloc] init]; NSError *error; [ioOptions setInputFormatForIndex:0 type:FIRModelElementTypeFloat32 dimensions:@[@1, @224, @224, @3] error:&error]; if (error != nil) { return; } [ioOptions setOutputFormatForIndex:0 type:FIRModelElementTypeFloat32 dimensions:@[@1, @1000] error:&error]; if (error != nil) { return; }
ইনপুট ডেটার উপর অনুমান সম্পাদন করুন
অবশেষে, মডেল ব্যবহার করে অনুমান সম্পাদন করতে, আপনার ইনপুট ডেটা পান, আপনার মডেলের জন্য প্রয়োজনীয় হতে পারে এমন ডেটাতে যে কোনও রূপান্তর সম্পাদন করুন এবং ডেটা ধারণ করে এমন একটি Data
অবজেক্ট তৈরি করুন।
উদাহরণস্বরূপ, যদি আপনার মডেল চিত্রগুলি প্রক্রিয়া করে এবং আপনার মডেলটিতে [BATCH_SIZE, 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 } let inputs = ModelInputs() var inputData = Data() do { for row in 0 ..< 224 { for col in 0 ..< 224 { let offset = 4 * (col * context.width + row) // (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) } } try inputs.addInput(inputData) } catch let error { print("Failed to add input: \(error)") }
উদ্দেশ্য-C
CGImageRef image = // Your input image long imageWidth = CGImageGetWidth(image); long imageHeight = CGImageGetHeight(image); CGContextRef context = CGBitmapContextCreate(nil, imageWidth, imageHeight, 8, imageWidth * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst); CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image); UInt8 *imageData = CGBitmapContextGetData(context); FIRModelInputs *inputs = [[FIRModelInputs alloc] init]; NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0]; for (int row = 0; row < 224; row++) { for (int col = 0; col < 224; col++) { long offset = 4 * (col * imageWidth + row); // 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. // (Ignore offset 0, the unused alpha channel) Float32 red = imageData[offset+1] / 255.0f; Float32 green = imageData[offset+2] / 255.0f; Float32 blue = imageData[offset+3] / 255.0f; [inputData appendBytes:&red length:sizeof(red)]; [inputData appendBytes:&green length:sizeof(green)]; [inputData appendBytes:&blue length:sizeof(blue)]; } } [inputs addInput:inputData error:&error]; if (error != nil) { return nil; }
আপনি আপনার মডেল ইনপুট প্রস্তুত করার পরে (এবং আপনি নিশ্চিত করার পরে মডেলটি উপলব্ধ), ইনপুট এবং ইনপুট/আউটপুট বিকল্পগুলি আপনার মডেল ইন্টারপ্রেটারের run(inputs:options:completion:)
পদ্ধতিতে পাস করুন।
সুইফট
interpreter.run(inputs: inputs, options: ioOptions) { outputs, error in guard error == nil, let outputs = outputs else { return } // Process outputs // ... }
উদ্দেশ্য-C
[interpreter runWithInputs:inputs options:ioOptions completion:^(FIRModelOutputs * _Nullable outputs, NSError * _Nullable error) { if (error != nil || outputs == nil) { return; } // Process outputs // ... }];
যে বস্তুটি ফেরত দেওয়া হয়েছে তার output(index:)
পদ্ধতিতে কল করে আপনি আউটপুট পেতে পারেন। যেমন:
সুইফট
// Get first and only output of inference with a batch size of 1 let output = try? outputs.output(index: 0) as? [[NSNumber]] let probabilities = output??[0]
উদ্দেশ্য-C
// Get first and only output of inference with a batch size of 1 NSError *outputError; NSArray *probabilites = [outputs outputAtIndex:0 error:&outputError][0];
আপনি কীভাবে আউটপুট ব্যবহার করবেন তা নির্ভর করে আপনি যে মডেলটি ব্যবহার করছেন তার উপর।
উদাহরণ স্বরূপ, আপনি যদি শ্রেণীবিন্যাস সম্পাদন করছেন, পরবর্তী পদক্ষেপ হিসাবে, আপনি ফলাফলের সূচীগুলিকে তারা প্রতিনিধিত্ব করে এমন লেবেলে ম্যাপ করতে পারেন। ধরুন আপনার কাছে আপনার মডেলের প্রতিটি বিভাগের জন্য লেবেল স্ট্রিং সহ একটি পাঠ্য ফাইল ছিল; আপনি নিম্নলিখিত মত কিছু করে আউটপুট সম্ভাব্যতা লেবেল স্ট্রিং ম্যাপ করতে পারেন:
সুইফট
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 0 ..< labels.count { if let probability = probabilities?[i] { print("\(labels[i]): \(probability)") } }
উদ্দেশ্য-C
NSError *labelReadError = nil; NSString *labelPath = [NSBundle.mainBundle pathForResource:@"retrained_labels" ofType:@"txt"]; NSString *fileContents = [NSString stringWithContentsOfFile:labelPath encoding:NSUTF8StringEncoding error:&labelReadError]; if (labelReadError != nil || fileContents == NULL) { return; } NSArray<NSString *> *labels = [fileContents componentsSeparatedByString:@"\n"]; for (int i = 0; i < labels.count; i++) { NSString *label = labels[i]; NSNumber *probability = probabilites[i]; NSLog(@"%@: %f", label, probability.floatValue); }
পরিশিষ্ট: মডেল নিরাপত্তা
আপনি ML Kit-এ আপনার TensorFlow Lite মডেলগুলিকে যেভাবে উপলব্ধ করুন না কেন, ML Kit স্থানীয় স্টোরেজে স্ট্যান্ডার্ড সিরিয়ালাইজড প্রোটোবাফ ফর্ম্যাটে সেগুলি সঞ্চয় করে৷
তত্ত্বগতভাবে, এর মানে হল যে কেউ আপনার মডেল অনুলিপি করতে পারে। যাইহোক, বাস্তবে, বেশিরভাগ মডেলগুলি এতটাই অ্যাপ্লিকেশন-নির্দিষ্ট এবং অপ্টিমাইজেশান দ্বারা অস্পষ্ট যে ঝুঁকি প্রতিযোগীদের বিচ্ছিন্ন করা এবং আপনার কোড পুনরায় ব্যবহার করার মতোই। তবুও, আপনার অ্যাপে একটি কাস্টম মডেল ব্যবহার করার আগে আপনার এই ঝুঁকি সম্পর্কে সচেতন হওয়া উচিত।
,আপনি একটি টেনসরফ্লো লাইট মডেলের সাথে ডিভাইসে অনুমান সম্পাদন করতে ML কিট ব্যবহার করতে পারেন।
ML Kit TensorFlow Lite মডেল ব্যবহার করতে পারে শুধুমাত্র iOS 9 এবং তার পরবর্তী ডিভাইসে চলমান ডিভাইসগুলিতে।
আপনি শুরু করার আগে
- আপনি যদি ইতিমধ্যে আপনার অ্যাপে Firebase যোগ না করে থাকেন, তাহলে শুরু করার নির্দেশিকাতে দেওয়া ধাপগুলি অনুসরণ করে তা করুন৷
- আপনার পডফাইলে এমএল কিট লাইব্রেরি অন্তর্ভুক্ত করুন:
pod 'Firebase/MLModelInterpreter', '6.25.0'
আপনি আপনার প্রোজেক্টের পড ইনস্টল বা আপডেট করার পরে, আপনার Xcode প্রোজেক্ট এর.xcworkspace
ব্যবহার করে খুলতে ভুলবেন না। - আপনার অ্যাপে, Firebase আমদানি করুন:
সুইফট
import Firebase
উদ্দেশ্য-C
@import Firebase;
- আপনি যে টেনসরফ্লো মডেলটি ব্যবহার করতে চান তা টেনসরফ্লো লাইট ফর্ম্যাটে রূপান্তর করুন। TOCO দেখুন: TensorFlow Lite অপটিমাইজিং কনভার্টার ।
হোস্ট বা আপনার মডেল বান্ডিল
আপনার অ্যাপে অনুমান করার জন্য আপনি একটি TensorFlow Lite মডেল ব্যবহার করার আগে, আপনাকে অবশ্যই মডেলটি ML Kit-এ উপলব্ধ করতে হবে। ML Kit TensorFlow Lite মডেল ব্যবহার করতে পারে যা দূরবর্তীভাবে Firebase ব্যবহার করে হোস্ট করা, অ্যাপ বাইনারি বা উভয়ের সাথে বান্ডিল করা।
Firebase-এ একটি মডেল হোস্ট করার মাধ্যমে, আপনি একটি নতুন অ্যাপ সংস্করণ প্রকাশ না করেই মডেলটি আপডেট করতে পারেন এবং আপনি ব্যবহারকারীদের বিভিন্ন সেটের কাছে গতিশীলভাবে বিভিন্ন মডেল পরিবেশন করতে Remote Config এবং A/B Testing ব্যবহার করতে পারেন।
আপনি যদি শুধুমাত্র Firebase-এর সাথে হোস্ট করে মডেলটি প্রদান করতে চান এবং এটিকে আপনার অ্যাপের সাথে বান্ডিল না করে, তাহলে আপনি আপনার অ্যাপের প্রাথমিক ডাউনলোডের আকার কমাতে পারেন। মনে রাখবেন, যদিও, মডেলটি আপনার অ্যাপের সাথে বান্ডিল না থাকলে, আপনার অ্যাপটি প্রথমবারের মতো মডেলটি ডাউনলোড না করা পর্যন্ত কোনো মডেল-সম্পর্কিত কার্যকারিতা উপলব্ধ হবে না।
আপনার অ্যাপের সাথে আপনার মডেলকে একত্রিত করে, আপনি নিশ্চিত করতে পারেন যে Firebase-হোস্টেড মডেলটি উপলব্ধ না থাকলে আপনার অ্যাপের ML বৈশিষ্ট্যগুলি এখনও কাজ করে।
Firebase-এ হোস্ট মডেল
Firebase এ আপনার TensorFlow Lite মডেল হোস্ট করতে:
- Firebase কনসোলের ML Kit বিভাগে, কাস্টম ট্যাবে ক্লিক করুন।
- কাস্টম মডেল যোগ করুন ক্লিক করুন (বা অন্য মডেল যোগ করুন )।
- একটি নাম নির্দিষ্ট করুন যা আপনার ফায়ারবেস প্রকল্পে আপনার মডেল শনাক্ত করতে ব্যবহার করা হবে, তারপর TensorFlow Lite মডেল ফাইল আপলোড করুন (সাধারণত
.tflite
বা.lite
এ শেষ হয়)।
আপনি আপনার ফায়ারবেস প্রোজেক্টে একটি কাস্টম মডেল যোগ করার পরে, আপনি আপনার নির্দিষ্ট করা নাম ব্যবহার করে আপনার অ্যাপে মডেলটি উল্লেখ করতে পারেন। যে কোনো সময়ে, আপনি একটি নতুন TensorFlow Lite মডেল আপলোড করতে পারেন এবং আপনার অ্যাপটি নতুন মডেল ডাউনলোড করবে এবং অ্যাপটি পরবর্তী রিস্টার্ট হলে এটি ব্যবহার করা শুরু করবে। আপনি মডেল আপডেট করার চেষ্টা করার জন্য আপনার অ্যাপের জন্য প্রয়োজনীয় ডিভাইসের শর্তগুলি সংজ্ঞায়িত করতে পারেন (নীচে দেখুন)।
একটি অ্যাপ সহ মডেল বান্ডিল করুন
আপনার অ্যাপের সাথে আপনার TensorFlow Lite মডেলটি বান্ডিল করতে, আপনার Xcode প্রকল্পে মডেল ফাইলটি (সাধারণত .tflite
বা .lite
এ শেষ হয়) যোগ করুন, যখন আপনি এটি করবেন তখন কপি বান্ডেল সংস্থান নির্বাচন করবেন। মডেল ফাইলটি অ্যাপ বান্ডেলে অন্তর্ভুক্ত করা হবে এবং ML কিটে উপলব্ধ হবে।
মডেল লোড করুন
আপনার অ্যাপে আপনার TensorFlow Lite মডেল ব্যবহার করতে, প্রথমে আপনার মডেল উপলব্ধ যেখানে অবস্থানের সাথে ML Kit কনফিগার করুন: দূরবর্তীভাবে Firebase ব্যবহার করে, স্থানীয় স্টোরেজে বা উভয়ই। আপনি যদি স্থানীয় এবং দূরবর্তী উভয় মডেল নির্দিষ্ট করেন, তাহলে আপনি দূরবর্তী মডেলটি ব্যবহার করতে পারেন যদি এটি উপলব্ধ থাকে, এবং যদি দূরবর্তী মডেল উপলব্ধ না হয় তবে স্থানীয়ভাবে-সঞ্চিত মডেলটিতে ফিরে যেতে পারেন।
একটি Firebase-হোস্টেড মডেল কনফিগার করুন
আপনি যদি Firebase-এর সাথে আপনার মডেল হোস্ট করেন, তাহলে একটি CustomRemoteModel
অবজেক্ট তৈরি করুন, আপনি মডেলটিকে প্রকাশ করার সময় যে নামটি বরাদ্দ করেছেন তা উল্লেখ করে:
সুইফট
let remoteModel = CustomRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
উদ্দেশ্য-C
// Initialize using the name you assigned in the Firebase console.
FIRCustomRemoteModel *remoteModel =
[[FIRCustomRemoteModel alloc] initWithName:@"your_remote_model"];
তারপরে, আপনি যে শর্তে ডাউনলোড করার অনুমতি দিতে চান তা উল্লেখ করে মডেল ডাউনলোড টাস্ক শুরু করুন। যদি মডেলটি ডিভাইসে না থাকে, বা মডেলটির একটি নতুন সংস্করণ উপলব্ধ থাকলে, টাস্কটি অসিঙ্ক্রোনাসভাবে Firebase থেকে মডেলটি ডাউনলোড করবে:
সুইফট
let downloadConditions = ModelDownloadConditions(
allowsCellularAccess: true,
allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
remoteModel,
conditions: downloadConditions
)
উদ্দেশ্য-C
FIRModelDownloadConditions *downloadConditions =
[[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[FIRModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
অনেক অ্যাপ তাদের ইনিশিয়ালাইজেশন কোডে ডাউনলোড টাস্ক শুরু করে, কিন্তু মডেল ব্যবহার করার আগে আপনি যেকোন সময়ে তা করতে পারেন।
একটি স্থানীয় মডেল কনফিগার করুন
আপনি যদি আপনার অ্যাপের সাথে মডেলটি বান্ডিল করেন, তাহলে TensorFlow Lite মডেলের ফাইলের নাম উল্লেখ করে একটি CustomLocalModel
অবজেক্ট তৈরি করুন:
সুইফট
guard let modelPath = Bundle.main.path(
forResource: "your_model",
ofType: "tflite",
inDirectory: "your_model_directory"
) else { /* Handle error. */ }
let localModel = CustomLocalModel(modelPath: modelPath)
উদ্দেশ্য-C
NSString *modelPath = [NSBundle.mainBundle pathForResource:@"your_model"
ofType:@"tflite"
inDirectory:@"your_model_directory"];
FIRCustomLocalModel *localModel =
[[FIRCustomLocalModel alloc] initWithModelPath:modelPath];
আপনার মডেল থেকে একটি দোভাষী তৈরি করুন
আপনি আপনার মডেল উত্স কনফিগার করার পরে, তাদের মধ্যে একটি থেকে একটি ModelInterpreter
অবজেক্ট তৈরি করুন।
যদি আপনার কাছে শুধুমাত্র স্থানীয়ভাবে বান্ডিল করা মডেল থাকে, তাহলে শুধু CustomLocalModel
অবজেক্টকে modelInterpreter(localModel:)
এ পাস করুন :
সুইফট
let interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
উদ্দেশ্য-C
FIRModelInterpreter *interpreter =
[FIRModelInterpreter modelInterpreterForLocalModel:localModel];
আপনার যদি দূরবর্তীভাবে-হোস্ট করা মডেল থাকে, তাহলে আপনাকে এটি চালানোর আগে এটি ডাউনলোড করা হয়েছে কিনা তা পরীক্ষা করতে হবে। আপনি মডেল ম্যানেজারের isModelDownloaded(remoteModel:)
পদ্ধতি ব্যবহার করে মডেল ডাউনলোড টাস্কের স্থিতি পরীক্ষা করতে পারেন।
যদিও আপনাকে শুধুমাত্র দোভাষী চালানোর আগে এটি নিশ্চিত করতে হবে, যদি আপনার কাছে একটি দূরবর্তীভাবে-হোস্ট করা মডেল এবং একটি স্থানীয়ভাবে-বান্ডিল মডেল উভয়ই থাকে, তাহলে ModelInterpreter
ইনস্ট্যান্টিয়েট করার সময় এই চেকটি সম্পাদন করা বোধগম্য হতে পারে: যদি এটি হয় তবে দূরবর্তী মডেল থেকে একটি দোভাষী তৈরি করুন ডাউনলোড করা হয়েছে, এবং অন্যথায় স্থানীয় মডেল থেকে।
সুইফট
var interpreter: ModelInterpreter
if ModelManager.modelManager().isModelDownloaded(remoteModel) {
interpreter = ModelInterpreter.modelInterpreter(remoteModel: remoteModel)
} else {
interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
}
উদ্দেশ্য-C
FIRModelInterpreter *interpreter;
if ([[FIRModelManager modelManager] isModelDownloaded:remoteModel]) {
interpreter = [FIRModelInterpreter modelInterpreterForRemoteModel:remoteModel];
} else {
interpreter = [FIRModelInterpreter modelInterpreterForLocalModel:localModel];
}
যদি আপনার কাছে শুধুমাত্র একটি দূরবর্তীভাবে হোস্ট করা মডেল থাকে, তাহলে আপনার মডেল-সম্পর্কিত কার্যকারিতা অক্ষম করা উচিত-উদাহরণস্বরূপ, ধূসর-আউট বা আপনার UI-এর অংশ লুকান-যতক্ষণ না আপনি নিশ্চিত করেন যে মডেলটি ডাউনলোড করা হয়েছে।
আপনি ডিফল্ট বিজ্ঞপ্তি কেন্দ্রে পর্যবেক্ষকদের সংযুক্ত করে মডেল ডাউনলোডের অবস্থা পেতে পারেন। পর্যবেক্ষক ব্লকে self
সম্পর্কে একটি দুর্বল রেফারেন্স ব্যবহার করতে ভুলবেন না, যেহেতু ডাউনলোডে কিছু সময় লাগতে পারে, এবং ডাউনলোড শেষ হওয়ার সময় থেকে উদ্ভূত বস্তুটি মুক্ত করা যেতে পারে। যেমন:
সুইফট
NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidSucceed, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel, model.name == "your_remote_model" else { return } // The model was downloaded and is available on the device } NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidFail, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel else { return } let error = userInfo[ModelDownloadUserInfoKey.error.rawValue] // ... }
উদ্দেশ্য-C
__weak typeof(self) weakSelf = self; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidSucceedNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel]; if ([model.name isEqualToString:@"your_remote_model"]) { // The model was downloaded and is available on the device } }]; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidFailNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; NSError *error = note.userInfo[FIRModelDownloadUserInfoKeyError]; }];
মডেলের ইনপুট এবং আউটপুট উল্লেখ করুন
এর পরে, মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট ফর্ম্যাটগুলি কনফিগার করুন।
একটি টেনসরফ্লো লাইট মডেল ইনপুট হিসাবে নেয় এবং আউটপুট হিসাবে এক বা একাধিক বহুমাত্রিক অ্যারে তৈরি করে। এই অ্যারেগুলিতে হয় byte
, int
, long
, বা float
মান থাকে৷ আপনার মডেল ব্যবহার করে অ্যারেগুলির সংখ্যা এবং মাত্রা ("আকৃতি") সহ আপনাকে ML কিট কনফিগার করতে হবে৷
আপনি যদি আপনার মডেলের ইনপুট এবং আউটপুটের আকার এবং ডেটা টাইপ না জানেন, তাহলে আপনি আপনার মডেল পরিদর্শন করতে TensorFlow Lite Python ইন্টারপ্রেটার ব্যবহার করতে পারেন। যেমন:
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="my_model.tflite") interpreter.allocate_tensors() # Print input shape and type print(interpreter.get_input_details()[0]['shape']) # Example: [1 224 224 3] print(interpreter.get_input_details()[0]['dtype']) # Example: <class 'numpy.float32'> # Print output shape and type print(interpreter.get_output_details()[0]['shape']) # Example: [1 1000] print(interpreter.get_output_details()[0]['dtype']) # Example: <class 'numpy.float32'>
আপনি আপনার মডেলের ইনপুট এবং আউটপুটের বিন্যাস নির্ধারণ করার পরে, একটি ModelInputOutputOptions
অবজেক্ট তৈরি করে আপনার অ্যাপের মডেল ইন্টারপ্রেটার কনফিগার করুন৷
উদাহরণস্বরূপ, একটি ফ্লোটিং-পয়েন্ট ইমেজ ক্লাসিফিকেশন মডেল ইনপুট হিসাবে Float
মানগুলির একটি N x224x224x3 অ্যারে নিতে পারে, যা N 224x224 থ্রি-চ্যানেল (RGB) চিত্রগুলির একটি ব্যাচের প্রতিনিধিত্ব করে এবং আউটপুট হিসাবে 1000টি Float
মানগুলির একটি তালিকা তৈরি করে, প্রতিটি প্রতিনিধিত্ব করে মডেলটি ভবিষ্যদ্বাণী করে এমন 1000টি বিভাগের মধ্যে একটির একটি সদস্য হওয়ার সম্ভাবনা।
এই ধরনের একটি মডেলের জন্য, আপনি মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট কনফিগার করবেন যা নীচে দেখানো হয়েছে:
সুইফট
let ioOptions = ModelInputOutputOptions() do { try ioOptions.setInputFormat(index: 0, type: .float32, dimensions: [1, 224, 224, 3]) try ioOptions.setOutputFormat(index: 0, type: .float32, dimensions: [1, 1000]) } catch let error as NSError { print("Failed to set input or output format with error: \(error.localizedDescription)") }
উদ্দেশ্য-C
FIRModelInputOutputOptions *ioOptions = [[FIRModelInputOutputOptions alloc] init]; NSError *error; [ioOptions setInputFormatForIndex:0 type:FIRModelElementTypeFloat32 dimensions:@[@1, @224, @224, @3] error:&error]; if (error != nil) { return; } [ioOptions setOutputFormatForIndex:0 type:FIRModelElementTypeFloat32 dimensions:@[@1, @1000] error:&error]; if (error != nil) { return; }
ইনপুট ডেটার উপর অনুমান সম্পাদন করুন
অবশেষে, মডেল ব্যবহার করে অনুমান সম্পাদন করতে, আপনার ইনপুট ডেটা পান, আপনার মডেলের জন্য প্রয়োজনীয় হতে পারে এমন ডেটাতে যে কোনও রূপান্তর সম্পাদন করুন এবং ডেটা ধারণ করে এমন একটি Data
অবজেক্ট তৈরি করুন।
উদাহরণস্বরূপ, যদি আপনার মডেল চিত্রগুলি প্রক্রিয়া করে এবং আপনার মডেলটিতে [BATCH_SIZE, 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 } let inputs = ModelInputs() var inputData = Data() do { for row in 0 ..< 224 { for col in 0 ..< 224 { let offset = 4 * (col * context.width + row) // (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) } } try inputs.addInput(inputData) } catch let error { print("Failed to add input: \(error)") }
উদ্দেশ্য-C
CGImageRef image = // Your input image long imageWidth = CGImageGetWidth(image); long imageHeight = CGImageGetHeight(image); CGContextRef context = CGBitmapContextCreate(nil, imageWidth, imageHeight, 8, imageWidth * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst); CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image); UInt8 *imageData = CGBitmapContextGetData(context); FIRModelInputs *inputs = [[FIRModelInputs alloc] init]; NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0]; for (int row = 0; row < 224; row++) { for (int col = 0; col < 224; col++) { long offset = 4 * (col * imageWidth + row); // 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. // (Ignore offset 0, the unused alpha channel) Float32 red = imageData[offset+1] / 255.0f; Float32 green = imageData[offset+2] / 255.0f; Float32 blue = imageData[offset+3] / 255.0f; [inputData appendBytes:&red length:sizeof(red)]; [inputData appendBytes:&green length:sizeof(green)]; [inputData appendBytes:&blue length:sizeof(blue)]; } } [inputs addInput:inputData error:&error]; if (error != nil) { return nil; }
আপনি আপনার মডেল ইনপুট প্রস্তুত করার পরে (এবং আপনি নিশ্চিত করার পরে মডেলটি উপলব্ধ), ইনপুট এবং ইনপুট/আউটপুট বিকল্পগুলি আপনার মডেল ইন্টারপ্রেটারের run(inputs:options:completion:)
পদ্ধতিতে পাস করুন।
সুইফট
interpreter.run(inputs: inputs, options: ioOptions) { outputs, error in guard error == nil, let outputs = outputs else { return } // Process outputs // ... }
উদ্দেশ্য-C
[interpreter runWithInputs:inputs options:ioOptions completion:^(FIRModelOutputs * _Nullable outputs, NSError * _Nullable error) { if (error != nil || outputs == nil) { return; } // Process outputs // ... }];
যে বস্তুটি ফেরত দেওয়া হয়েছে তার output(index:)
পদ্ধতিতে কল করে আপনি আউটপুট পেতে পারেন। যেমন:
সুইফট
// Get first and only output of inference with a batch size of 1 let output = try? outputs.output(index: 0) as? [[NSNumber]] let probabilities = output??[0]
উদ্দেশ্য-C
// Get first and only output of inference with a batch size of 1 NSError *outputError; NSArray *probabilites = [outputs outputAtIndex:0 error:&outputError][0];
আপনি কীভাবে আউটপুট ব্যবহার করবেন তা নির্ভর করে আপনি যে মডেলটি ব্যবহার করছেন তার উপর।
উদাহরণ স্বরূপ, আপনি যদি শ্রেণীবিন্যাস সম্পাদন করছেন, পরবর্তী পদক্ষেপ হিসাবে, আপনি ফলাফলের সূচীগুলিকে তারা প্রতিনিধিত্ব করে এমন লেবেলে ম্যাপ করতে পারেন। ধরুন আপনার কাছে আপনার মডেলের প্রতিটি বিভাগের জন্য লেবেল স্ট্রিং সহ একটি পাঠ্য ফাইল ছিল; আপনি নিম্নলিখিত মত কিছু করে আউটপুট সম্ভাব্যতা লেবেল স্ট্রিং ম্যাপ করতে পারেন:
সুইফট
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 0 ..< labels.count { if let probability = probabilities?[i] { print("\(labels[i]): \(probability)") } }
উদ্দেশ্য-C
NSError *labelReadError = nil; NSString *labelPath = [NSBundle.mainBundle pathForResource:@"retrained_labels" ofType:@"txt"]; NSString *fileContents = [NSString stringWithContentsOfFile:labelPath encoding:NSUTF8StringEncoding error:&labelReadError]; if (labelReadError != nil || fileContents == NULL) { return; } NSArray<NSString *> *labels = [fileContents componentsSeparatedByString:@"\n"]; for (int i = 0; i < labels.count; i++) { NSString *label = labels[i]; NSNumber *probability = probabilites[i]; NSLog(@"%@: %f", label, probability.floatValue); }
পরিশিষ্ট: মডেল নিরাপত্তা
আপনি ML Kit-এ আপনার TensorFlow Lite মডেলগুলিকে যেভাবে উপলব্ধ করুন না কেন, ML Kit স্থানীয় স্টোরেজে স্ট্যান্ডার্ড সিরিয়ালাইজড প্রোটোবাফ ফর্ম্যাটে সেগুলি সঞ্চয় করে৷
তত্ত্বগতভাবে, এর মানে হল যে কেউ আপনার মডেল অনুলিপি করতে পারে। যাইহোক, বাস্তবে, বেশিরভাগ মডেলগুলি এতটাই অ্যাপ্লিকেশন-নির্দিষ্ট এবং অপ্টিমাইজেশান দ্বারা অস্পষ্ট যে ঝুঁকি প্রতিযোগীদের বিচ্ছিন্ন করা এবং আপনার কোড পুনরায় ব্যবহার করার মতোই। তবুও, আপনার অ্যাপে একটি কাস্টম মডেল ব্যবহার করার আগে আপনার এই ঝুঁকি সম্পর্কে সচেতন হওয়া উচিত।
,আপনি একটি টেনসরফ্লো লাইট মডেলের সাথে ডিভাইসে অনুমান সম্পাদন করতে ML কিট ব্যবহার করতে পারেন।
ML Kit TensorFlow Lite মডেল ব্যবহার করতে পারে শুধুমাত্র iOS 9 এবং তার পরবর্তী ডিভাইসে চলমান ডিভাইসগুলিতে।
আপনি শুরু করার আগে
- আপনি যদি ইতিমধ্যে আপনার অ্যাপে Firebase যোগ না করে থাকেন, তাহলে শুরু করার নির্দেশিকাতে দেওয়া ধাপগুলি অনুসরণ করে তা করুন৷
- আপনার পডফাইলে এমএল কিট লাইব্রেরি অন্তর্ভুক্ত করুন:
pod 'Firebase/MLModelInterpreter', '6.25.0'
আপনি আপনার প্রোজেক্টের পড ইনস্টল বা আপডেট করার পরে, আপনার Xcode প্রোজেক্ট এর.xcworkspace
ব্যবহার করে খুলতে ভুলবেন না। - আপনার অ্যাপে, Firebase আমদানি করুন:
সুইফট
import Firebase
উদ্দেশ্য-C
@import Firebase;
- আপনি যে টেনসরফ্লো মডেলটি ব্যবহার করতে চান তা টেনসরফ্লো লাইট ফর্ম্যাটে রূপান্তর করুন। TOCO দেখুন: TensorFlow Lite অপটিমাইজিং কনভার্টার ।
হোস্ট বা আপনার মডেল বান্ডিল
আপনার অ্যাপে অনুমান করার জন্য আপনি একটি TensorFlow Lite মডেল ব্যবহার করার আগে, আপনাকে অবশ্যই মডেলটি ML Kit-এ উপলব্ধ করতে হবে। ML Kit TensorFlow Lite মডেল ব্যবহার করতে পারে যা দূরবর্তীভাবে Firebase ব্যবহার করে হোস্ট করা, অ্যাপ বাইনারি বা উভয়ের সাথে বান্ডিল করা।
Firebase-এ একটি মডেল হোস্ট করার মাধ্যমে, আপনি একটি নতুন অ্যাপ সংস্করণ প্রকাশ না করেই মডেলটি আপডেট করতে পারেন এবং আপনি ব্যবহারকারীদের বিভিন্ন সেটের কাছে গতিশীলভাবে বিভিন্ন মডেল পরিবেশন করতে Remote Config এবং A/B Testing ব্যবহার করতে পারেন।
আপনি যদি শুধুমাত্র Firebase-এর সাথে হোস্ট করে মডেলটি প্রদান করতে চান এবং এটিকে আপনার অ্যাপের সাথে বান্ডিল না করে, তাহলে আপনি আপনার অ্যাপের প্রাথমিক ডাউনলোডের আকার কমাতে পারেন। মনে রাখবেন, যদিও, মডেলটি আপনার অ্যাপের সাথে বান্ডিল না থাকলে, আপনার অ্যাপটি প্রথমবারের মতো মডেলটি ডাউনলোড না করা পর্যন্ত কোনো মডেল-সম্পর্কিত কার্যকারিতা উপলব্ধ হবে না।
আপনার অ্যাপের সাথে আপনার মডেলকে একত্রিত করে, আপনি নিশ্চিত করতে পারেন যে Firebase-হোস্টেড মডেলটি উপলব্ধ না থাকলে আপনার অ্যাপের ML বৈশিষ্ট্যগুলি এখনও কাজ করে।
Firebase-এ হোস্ট মডেল
Firebase এ আপনার TensorFlow Lite মডেল হোস্ট করতে:
- Firebase কনসোলের ML Kit বিভাগে, কাস্টম ট্যাবে ক্লিক করুন।
- কাস্টম মডেল যোগ করুন ক্লিক করুন (বা অন্য মডেল যোগ করুন )।
- একটি নাম নির্দিষ্ট করুন যা আপনার ফায়ারবেস প্রকল্পে আপনার মডেল শনাক্ত করতে ব্যবহার করা হবে, তারপর TensorFlow Lite মডেল ফাইল আপলোড করুন (সাধারণত
.tflite
বা.lite
এ শেষ হয়)।
আপনি আপনার ফায়ারবেস প্রোজেক্টে একটি কাস্টম মডেল যোগ করার পরে, আপনি আপনার নির্দিষ্ট করা নাম ব্যবহার করে আপনার অ্যাপে মডেলটি উল্লেখ করতে পারেন। যে কোনো সময়ে, আপনি একটি নতুন TensorFlow Lite মডেল আপলোড করতে পারেন এবং আপনার অ্যাপটি নতুন মডেল ডাউনলোড করবে এবং অ্যাপটি পরবর্তী রিস্টার্ট হলে এটি ব্যবহার করা শুরু করবে। আপনি মডেল আপডেট করার চেষ্টা করার জন্য আপনার অ্যাপের জন্য প্রয়োজনীয় ডিভাইসের শর্তগুলি সংজ্ঞায়িত করতে পারেন (নীচে দেখুন)।
একটি অ্যাপ সহ মডেল বান্ডিল করুন
আপনার অ্যাপের সাথে আপনার TensorFlow Lite মডেলটি বান্ডিল করতে, আপনার Xcode প্রকল্পে মডেল ফাইলটি (সাধারণত .tflite
বা .lite
এ শেষ হয়) যোগ করুন, যখন আপনি এটি করবেন তখন কপি বান্ডেল সংস্থান নির্বাচন করবেন। মডেল ফাইলটি অ্যাপ বান্ডেলে অন্তর্ভুক্ত করা হবে এবং ML কিটে উপলব্ধ হবে।
মডেল লোড করুন
আপনার অ্যাপে আপনার TensorFlow Lite মডেল ব্যবহার করতে, প্রথমে আপনার মডেল উপলব্ধ যেখানে অবস্থানের সাথে ML Kit কনফিগার করুন: দূরবর্তীভাবে Firebase ব্যবহার করে, স্থানীয় স্টোরেজে বা উভয়ই। আপনি যদি স্থানীয় এবং দূরবর্তী উভয় মডেল নির্দিষ্ট করেন, তাহলে আপনি দূরবর্তী মডেলটি ব্যবহার করতে পারেন যদি এটি উপলব্ধ থাকে, এবং যদি দূরবর্তী মডেল উপলব্ধ না হয় তবে স্থানীয়ভাবে-সঞ্চিত মডেলটিতে ফিরে যেতে পারেন।
একটি Firebase-হোস্টেড মডেল কনফিগার করুন
আপনি যদি Firebase-এর সাথে আপনার মডেল হোস্ট করেন, তাহলে একটি CustomRemoteModel
অবজেক্ট তৈরি করুন, আপনি মডেলটিকে প্রকাশ করার সময় যে নামটি বরাদ্দ করেছেন তা উল্লেখ করে:
সুইফট
let remoteModel = CustomRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
উদ্দেশ্য-C
// Initialize using the name you assigned in the Firebase console.
FIRCustomRemoteModel *remoteModel =
[[FIRCustomRemoteModel alloc] initWithName:@"your_remote_model"];
তারপরে, আপনি যে শর্তে ডাউনলোড করার অনুমতি দিতে চান তা উল্লেখ করে মডেল ডাউনলোড টাস্ক শুরু করুন। যদি মডেলটি ডিভাইসে না থাকে, বা মডেলটির একটি নতুন সংস্করণ উপলব্ধ থাকলে, টাস্কটি অসিঙ্ক্রোনাসভাবে Firebase থেকে মডেলটি ডাউনলোড করবে:
সুইফট
let downloadConditions = ModelDownloadConditions(
allowsCellularAccess: true,
allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
remoteModel,
conditions: downloadConditions
)
উদ্দেশ্য-C
FIRModelDownloadConditions *downloadConditions =
[[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[FIRModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
অনেক অ্যাপ তাদের ইনিশিয়ালাইজেশন কোডে ডাউনলোড টাস্ক শুরু করে, কিন্তু মডেল ব্যবহার করার আগে আপনি যেকোন সময়ে তা করতে পারেন।
একটি স্থানীয় মডেল কনফিগার করুন
আপনি যদি আপনার অ্যাপের সাথে মডেলটি বান্ডিল করেন, তাহলে TensorFlow Lite মডেলের ফাইলের নাম উল্লেখ করে একটি CustomLocalModel
অবজেক্ট তৈরি করুন:
সুইফট
guard let modelPath = Bundle.main.path(
forResource: "your_model",
ofType: "tflite",
inDirectory: "your_model_directory"
) else { /* Handle error. */ }
let localModel = CustomLocalModel(modelPath: modelPath)
উদ্দেশ্য-C
NSString *modelPath = [NSBundle.mainBundle pathForResource:@"your_model"
ofType:@"tflite"
inDirectory:@"your_model_directory"];
FIRCustomLocalModel *localModel =
[[FIRCustomLocalModel alloc] initWithModelPath:modelPath];
আপনার মডেল থেকে একটি দোভাষী তৈরি করুন
আপনি আপনার মডেল উত্স কনফিগার করার পরে, তাদের মধ্যে একটি থেকে একটি ModelInterpreter
অবজেক্ট তৈরি করুন।
যদি আপনার কাছে শুধুমাত্র স্থানীয়ভাবে বান্ডিল করা মডেল থাকে, তাহলে শুধু CustomLocalModel
অবজেক্টকে modelInterpreter(localModel:)
এ পাস করুন :
সুইফট
let interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
উদ্দেশ্য-C
FIRModelInterpreter *interpreter =
[FIRModelInterpreter modelInterpreterForLocalModel:localModel];
আপনার যদি দূরবর্তীভাবে-হোস্ট করা মডেল থাকে, তাহলে আপনাকে এটি চালানোর আগে এটি ডাউনলোড করা হয়েছে কিনা তা পরীক্ষা করতে হবে। আপনি মডেল ম্যানেজারের isModelDownloaded(remoteModel:)
পদ্ধতি ব্যবহার করে মডেল ডাউনলোড টাস্কের স্থিতি পরীক্ষা করতে পারেন।
যদিও আপনাকে শুধুমাত্র দোভাষী চালানোর আগে এটি নিশ্চিত করতে হবে, যদি আপনার কাছে একটি দূরবর্তীভাবে-হোস্ট করা মডেল এবং একটি স্থানীয়ভাবে-বান্ডিল মডেল উভয়ই থাকে, তাহলে ModelInterpreter
ইনস্ট্যান্টিয়েট করার সময় এই চেকটি সম্পাদন করা বোধগম্য হতে পারে: যদি এটি হয় তবে দূরবর্তী মডেল থেকে একটি দোভাষী তৈরি করুন ডাউনলোড করা হয়েছে, এবং অন্যথায় স্থানীয় মডেল থেকে।
সুইফট
var interpreter: ModelInterpreter
if ModelManager.modelManager().isModelDownloaded(remoteModel) {
interpreter = ModelInterpreter.modelInterpreter(remoteModel: remoteModel)
} else {
interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
}
উদ্দেশ্য-C
FIRModelInterpreter *interpreter;
if ([[FIRModelManager modelManager] isModelDownloaded:remoteModel]) {
interpreter = [FIRModelInterpreter modelInterpreterForRemoteModel:remoteModel];
} else {
interpreter = [FIRModelInterpreter modelInterpreterForLocalModel:localModel];
}
যদি আপনার কাছে শুধুমাত্র একটি দূরবর্তীভাবে হোস্ট করা মডেল থাকে, তাহলে আপনার মডেল-সম্পর্কিত কার্যকারিতা অক্ষম করা উচিত-উদাহরণস্বরূপ, ধূসর-আউট বা আপনার UI-এর অংশ লুকান-যতক্ষণ না আপনি নিশ্চিত করেন যে মডেলটি ডাউনলোড করা হয়েছে।
আপনি ডিফল্ট বিজ্ঞপ্তি কেন্দ্রে পর্যবেক্ষকদের সংযুক্ত করে মডেল ডাউনলোডের অবস্থা পেতে পারেন। পর্যবেক্ষক ব্লকে self
সম্পর্কে একটি দুর্বল রেফারেন্স ব্যবহার করতে ভুলবেন না, যেহেতু ডাউনলোডে কিছু সময় লাগতে পারে, এবং ডাউনলোড শেষ হওয়ার সময় থেকে উদ্ভূত বস্তুটি মুক্ত করা যেতে পারে। যেমন:
সুইফট
NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidSucceed, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel, model.name == "your_remote_model" else { return } // The model was downloaded and is available on the device } NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidFail, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel else { return } let error = userInfo[ModelDownloadUserInfoKey.error.rawValue] // ... }
উদ্দেশ্য-C
__weak typeof(self) weakSelf = self; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidSucceedNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel]; if ([model.name isEqualToString:@"your_remote_model"]) { // The model was downloaded and is available on the device } }]; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidFailNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; NSError *error = note.userInfo[FIRModelDownloadUserInfoKeyError]; }];
মডেলের ইনপুট এবং আউটপুট উল্লেখ করুন
এর পরে, মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট ফর্ম্যাটগুলি কনফিগার করুন।
একটি টেনসরফ্লো লাইট মডেল ইনপুট হিসাবে নেয় এবং আউটপুট হিসাবে এক বা একাধিক বহুমাত্রিক অ্যারে তৈরি করে। এই অ্যারেগুলিতে হয় byte
, int
, long
, বা float
মান থাকে৷ আপনার মডেল ব্যবহার করে অ্যারেগুলির সংখ্যা এবং মাত্রা ("আকৃতি") সহ আপনাকে ML কিট কনফিগার করতে হবে৷
আপনি যদি আপনার মডেলের ইনপুট এবং আউটপুটের আকার এবং ডেটা টাইপ না জানেন, তাহলে আপনি আপনার মডেল পরিদর্শন করতে TensorFlow Lite Python ইন্টারপ্রেটার ব্যবহার করতে পারেন। যেমন:
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="my_model.tflite") interpreter.allocate_tensors() # Print input shape and type print(interpreter.get_input_details()[0]['shape']) # Example: [1 224 224 3] print(interpreter.get_input_details()[0]['dtype']) # Example: <class 'numpy.float32'> # Print output shape and type print(interpreter.get_output_details()[0]['shape']) # Example: [1 1000] print(interpreter.get_output_details()[0]['dtype']) # Example: <class 'numpy.float32'>
আপনি আপনার মডেলের ইনপুট এবং আউটপুটের বিন্যাস নির্ধারণ করার পরে, একটি ModelInputOutputOptions
অবজেক্ট তৈরি করে আপনার অ্যাপের মডেল ইন্টারপ্রেটার কনফিগার করুন৷
উদাহরণস্বরূপ, একটি ফ্লোটিং-পয়েন্ট ইমেজ ক্লাসিফিকেশন মডেল ইনপুট হিসাবে Float
মানগুলির একটি N x224x224x3 অ্যারে নিতে পারে, যা N 224x224 থ্রি-চ্যানেল (RGB) চিত্রগুলির একটি ব্যাচের প্রতিনিধিত্ব করে এবং আউটপুট হিসাবে 1000টি Float
মানগুলির একটি তালিকা তৈরি করে, প্রতিটি প্রতিনিধিত্ব করে মডেলটি ভবিষ্যদ্বাণী করে এমন 1000টি বিভাগের মধ্যে একটির একটি সদস্য হওয়ার সম্ভাবনা।
এই ধরনের একটি মডেলের জন্য, আপনি মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট কনফিগার করবেন যা নীচে দেখানো হয়েছে:
সুইফট
let ioOptions = ModelInputOutputOptions() do { try ioOptions.setInputFormat(index: 0, type: .float32, dimensions: [1, 224, 224, 3]) try ioOptions.setOutputFormat(index: 0, type: .float32, dimensions: [1, 1000]) } catch let error as NSError { print("Failed to set input or output format with error: \(error.localizedDescription)") }
উদ্দেশ্য-C
FIRModelInputOutputOptions *ioOptions = [[FIRModelInputOutputOptions alloc] init]; NSError *error; [ioOptions setInputFormatForIndex:0 type:FIRModelElementTypeFloat32 dimensions:@[@1, @224, @224, @3] error:&error]; if (error != nil) { return; } [ioOptions setOutputFormatForIndex:0 type:FIRModelElementTypeFloat32 dimensions:@[@1, @1000] error:&error]; if (error != nil) { return; }
ইনপুট ডেটার উপর অনুমান সম্পাদন করুন
অবশেষে, মডেল ব্যবহার করে অনুমান সম্পাদন করতে, আপনার ইনপুট ডেটা পান, আপনার মডেলের জন্য প্রয়োজনীয় হতে পারে এমন ডেটাতে যে কোনও রূপান্তর সম্পাদন করুন এবং ডেটা ধারণ করে এমন একটি Data
অবজেক্ট তৈরি করুন।
উদাহরণস্বরূপ, যদি আপনার মডেল চিত্রগুলি প্রক্রিয়া করে এবং আপনার মডেলটিতে [BATCH_SIZE, 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 } let inputs = ModelInputs() var inputData = Data() do { for row in 0 ..< 224 { for col in 0 ..< 224 { let offset = 4 * (col * context.width + row) // (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) } } try inputs.addInput(inputData) } catch let error { print("Failed to add input: \(error)") }
উদ্দেশ্য-C
CGImageRef image = // Your input image long imageWidth = CGImageGetWidth(image); long imageHeight = CGImageGetHeight(image); CGContextRef context = CGBitmapContextCreate(nil, imageWidth, imageHeight, 8, imageWidth * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst); CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image); UInt8 *imageData = CGBitmapContextGetData(context); FIRModelInputs *inputs = [[FIRModelInputs alloc] init]; NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0]; for (int row = 0; row < 224; row++) { for (int col = 0; col < 224; col++) { long offset = 4 * (col * imageWidth + row); // 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. // (Ignore offset 0, the unused alpha channel) Float32 red = imageData[offset+1] / 255.0f; Float32 green = imageData[offset+2] / 255.0f; Float32 blue = imageData[offset+3] / 255.0f; [inputData appendBytes:&red length:sizeof(red)]; [inputData appendBytes:&green length:sizeof(green)]; [inputData appendBytes:&blue length:sizeof(blue)]; } } [inputs addInput:inputData error:&error]; if (error != nil) { return nil; }
আপনি আপনার মডেল ইনপুট প্রস্তুত করার পরে (এবং আপনি নিশ্চিত করার পরে মডেলটি উপলব্ধ), ইনপুট এবং ইনপুট/আউটপুট বিকল্পগুলি আপনার মডেল ইন্টারপ্রেটারের run(inputs:options:completion:)
পদ্ধতিতে পাস করুন।
সুইফট
interpreter.run(inputs: inputs, options: ioOptions) { outputs, error in guard error == nil, let outputs = outputs else { return } // Process outputs // ... }
উদ্দেশ্য-C
[interpreter runWithInputs:inputs options:ioOptions completion:^(FIRModelOutputs * _Nullable outputs, NSError * _Nullable error) { if (error != nil || outputs == nil) { return; } // Process outputs // ... }];
যে বস্তুটি ফেরত দেওয়া হয়েছে তার output(index:)
পদ্ধতিতে কল করে আপনি আউটপুট পেতে পারেন। যেমন:
সুইফট
// Get first and only output of inference with a batch size of 1 let output = try? outputs.output(index: 0) as? [[NSNumber]] let probabilities = output??[0]
উদ্দেশ্য-C
// Get first and only output of inference with a batch size of 1 NSError *outputError; NSArray *probabilites = [outputs outputAtIndex:0 error:&outputError][0];
আপনি কীভাবে আউটপুট ব্যবহার করবেন তা নির্ভর করে আপনি যে মডেলটি ব্যবহার করছেন তার উপর।
উদাহরণ স্বরূপ, আপনি যদি শ্রেণীবিন্যাস সম্পাদন করছেন, পরবর্তী পদক্ষেপ হিসাবে, আপনি ফলাফলের সূচীগুলিকে তারা প্রতিনিধিত্ব করে এমন লেবেলে ম্যাপ করতে পারেন। ধরুন আপনার কাছে আপনার মডেলের প্রতিটি বিভাগের জন্য লেবেল স্ট্রিং সহ একটি পাঠ্য ফাইল ছিল; আপনি নিম্নলিখিত মত কিছু করে আউটপুট সম্ভাব্যতা লেবেল স্ট্রিং ম্যাপ করতে পারেন:
সুইফট
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 0 ..< labels.count { if let probability = probabilities?[i] { print("\(labels[i]): \(probability)") } }
উদ্দেশ্য-C
NSError *labelReadError = nil; NSString *labelPath = [NSBundle.mainBundle pathForResource:@"retrained_labels" ofType:@"txt"]; NSString *fileContents = [NSString stringWithContentsOfFile:labelPath encoding:NSUTF8StringEncoding error:&labelReadError]; if (labelReadError != nil || fileContents == NULL) { return; } NSArray<NSString *> *labels = [fileContents componentsSeparatedByString:@"\n"]; for (int i = 0; i < labels.count; i++) { NSString *label = labels[i]; NSNumber *probability = probabilites[i]; NSLog(@"%@: %f", label, probability.floatValue); }
পরিশিষ্ট: মডেল নিরাপত্তা
আপনি ML Kit-এ আপনার TensorFlow Lite মডেলগুলিকে যেভাবে উপলব্ধ করুন না কেন, ML Kit স্থানীয় স্টোরেজে স্ট্যান্ডার্ড সিরিয়ালাইজড প্রোটোবাফ ফর্ম্যাটে সেগুলি সঞ্চয় করে৷
তত্ত্বগতভাবে, এর মানে হল যে কেউ আপনার মডেল অনুলিপি করতে পারে। যাইহোক, বাস্তবে, বেশিরভাগ মডেলগুলি এতটাই অ্যাপ্লিকেশন-নির্দিষ্ট এবং অপ্টিমাইজেশান দ্বারা অস্পষ্ট যে ঝুঁকি প্রতিযোগীদের বিচ্ছিন্ন করা এবং আপনার কোড পুনরায় ব্যবহার করার মতোই। তবুও, আপনার অ্যাপে একটি কাস্টম মডেল ব্যবহার করার আগে আপনার এই ঝুঁকি সম্পর্কে সচেতন হওয়া উচিত।
,আপনি একটি টেনসরফ্লো লাইট মডেলের সাথে ডিভাইসে অনুমান সম্পাদন করতে ML কিট ব্যবহার করতে পারেন।
ML Kit TensorFlow Lite মডেল ব্যবহার করতে পারে শুধুমাত্র iOS 9 এবং তার পরবর্তী ডিভাইসে চলমান ডিভাইসগুলিতে।
আপনি শুরু করার আগে
- আপনি যদি ইতিমধ্যে আপনার অ্যাপে Firebase যোগ না করে থাকেন, তাহলে শুরু করার নির্দেশিকাতে দেওয়া ধাপগুলি অনুসরণ করে তা করুন৷
- আপনার পডফাইলে এমএল কিট লাইব্রেরি অন্তর্ভুক্ত করুন:
pod 'Firebase/MLModelInterpreter', '6.25.0'
আপনি আপনার প্রোজেক্টের পড ইনস্টল বা আপডেট করার পরে, আপনার Xcode প্রোজেক্ট এর.xcworkspace
ব্যবহার করে খুলতে ভুলবেন না। - আপনার অ্যাপে, Firebase আমদানি করুন:
সুইফট
import Firebase
উদ্দেশ্য-C
@import Firebase;
- আপনি যে টেনসরফ্লো মডেলটি ব্যবহার করতে চান তা টেনসরফ্লো লাইট ফর্ম্যাটে রূপান্তর করুন। TOCO দেখুন: TensorFlow Lite অপটিমাইজিং কনভার্টার ।
হোস্ট বা আপনার মডেল বান্ডিল
আপনার অ্যাপে অনুমান করার জন্য আপনি একটি TensorFlow Lite মডেল ব্যবহার করার আগে, আপনাকে অবশ্যই মডেলটি ML Kit-এ উপলব্ধ করতে হবে। ML Kit TensorFlow Lite মডেল ব্যবহার করতে পারে যা দূরবর্তীভাবে Firebase ব্যবহার করে হোস্ট করা, অ্যাপ বাইনারি বা উভয়ের সাথে বান্ডিল করা।
Firebase-এ একটি মডেল হোস্ট করার মাধ্যমে, আপনি একটি নতুন অ্যাপ সংস্করণ প্রকাশ না করেই মডেলটি আপডেট করতে পারেন এবং আপনি ব্যবহারকারীদের বিভিন্ন সেটের কাছে গতিশীলভাবে বিভিন্ন মডেল পরিবেশন করতে Remote Config এবং A/B Testing ব্যবহার করতে পারেন।
আপনি যদি শুধুমাত্র Firebase-এর সাথে হোস্ট করে মডেলটি প্রদান করতে চান এবং এটিকে আপনার অ্যাপের সাথে বান্ডিল না করে, তাহলে আপনি আপনার অ্যাপের প্রাথমিক ডাউনলোডের আকার কমাতে পারেন। মনে রাখবেন, যদিও, মডেলটি আপনার অ্যাপের সাথে বান্ডিল না থাকলে, আপনার অ্যাপটি প্রথমবারের মতো মডেলটি ডাউনলোড না করা পর্যন্ত কোনো মডেল-সম্পর্কিত কার্যকারিতা উপলব্ধ হবে না।
আপনার অ্যাপের সাথে আপনার মডেলকে একত্রিত করে, আপনি নিশ্চিত করতে পারেন যে Firebase-হোস্টেড মডেলটি উপলব্ধ না থাকলে আপনার অ্যাপের ML বৈশিষ্ট্যগুলি এখনও কাজ করে।
Firebase-এ হোস্ট মডেল
Firebase এ আপনার TensorFlow Lite মডেল হোস্ট করতে:
- Firebase কনসোলের ML Kit বিভাগে, কাস্টম ট্যাবে ক্লিক করুন।
- কাস্টম মডেল যোগ করুন ক্লিক করুন (বা অন্য মডেল যোগ করুন )।
- একটি নাম নির্দিষ্ট করুন যা আপনার ফায়ারবেস প্রকল্পে আপনার মডেল শনাক্ত করতে ব্যবহার করা হবে, তারপর TensorFlow Lite মডেল ফাইল আপলোড করুন (সাধারণত
.tflite
বা.lite
এ শেষ হয়)।
আপনি আপনার ফায়ারবেস প্রোজেক্টে একটি কাস্টম মডেল যোগ করার পরে, আপনি আপনার নির্দিষ্ট করা নাম ব্যবহার করে আপনার অ্যাপে মডেলটি উল্লেখ করতে পারেন। যে কোনো সময়ে, আপনি একটি নতুন TensorFlow Lite মডেল আপলোড করতে পারেন এবং আপনার অ্যাপটি নতুন মডেল ডাউনলোড করবে এবং অ্যাপটি পরবর্তী রিস্টার্ট হলে এটি ব্যবহার করা শুরু করবে। আপনি মডেল আপডেট করার চেষ্টা করার জন্য আপনার অ্যাপের জন্য প্রয়োজনীয় ডিভাইসের শর্তগুলি সংজ্ঞায়িত করতে পারেন (নীচে দেখুন)।
একটি অ্যাপ সহ মডেল বান্ডিল করুন
আপনার অ্যাপের সাথে আপনার TensorFlow Lite মডেলটি বান্ডিল করতে, আপনার Xcode প্রকল্পে মডেল ফাইলটি (সাধারণত .tflite
বা .lite
এ শেষ হয়) যোগ করুন, যখন আপনি এটি করবেন তখন কপি বান্ডেল সংস্থান নির্বাচন করবেন। মডেল ফাইলটি অ্যাপ বান্ডেলে অন্তর্ভুক্ত করা হবে এবং ML কিটে উপলব্ধ হবে।
মডেল লোড করুন
আপনার অ্যাপে আপনার TensorFlow Lite মডেল ব্যবহার করতে, প্রথমে আপনার মডেল উপলব্ধ যেখানে অবস্থানের সাথে ML Kit কনফিগার করুন: দূরবর্তীভাবে Firebase ব্যবহার করে, স্থানীয় স্টোরেজে বা উভয়ই। আপনি যদি স্থানীয় এবং দূরবর্তী উভয় মডেল নির্দিষ্ট করেন, তাহলে আপনি দূরবর্তী মডেলটি ব্যবহার করতে পারেন যদি এটি উপলব্ধ থাকে, এবং যদি দূরবর্তী মডেল উপলব্ধ না হয় তবে স্থানীয়ভাবে-সঞ্চিত মডেলটিতে ফিরে যেতে পারেন।
একটি Firebase-হোস্টেড মডেল কনফিগার করুন
আপনি যদি Firebase-এর সাথে আপনার মডেল হোস্ট করেন, তাহলে একটি CustomRemoteModel
অবজেক্ট তৈরি করুন, আপনি মডেলটিকে প্রকাশ করার সময় যে নামটি বরাদ্দ করেছেন তা উল্লেখ করে:
সুইফট
let remoteModel = CustomRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
উদ্দেশ্য-C
// Initialize using the name you assigned in the Firebase console.
FIRCustomRemoteModel *remoteModel =
[[FIRCustomRemoteModel alloc] initWithName:@"your_remote_model"];
তারপরে, আপনি যে শর্তে ডাউনলোড করার অনুমতি দিতে চান তা উল্লেখ করে মডেল ডাউনলোড টাস্ক শুরু করুন। যদি মডেলটি ডিভাইসে না থাকে, বা মডেলটির একটি নতুন সংস্করণ উপলব্ধ থাকলে, টাস্কটি অসিঙ্ক্রোনাসভাবে Firebase থেকে মডেলটি ডাউনলোড করবে:
সুইফট
let downloadConditions = ModelDownloadConditions(
allowsCellularAccess: true,
allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
remoteModel,
conditions: downloadConditions
)
উদ্দেশ্য-C
FIRModelDownloadConditions *downloadConditions =
[[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[FIRModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
অনেক অ্যাপ তাদের ইনিশিয়ালাইজেশন কোডে ডাউনলোড টাস্ক শুরু করে, কিন্তু মডেল ব্যবহার করার আগে আপনি যেকোন সময়ে তা করতে পারেন।
একটি স্থানীয় মডেল কনফিগার করুন
আপনি যদি আপনার অ্যাপের সাথে মডেলটি বান্ডিল করেন, তাহলে TensorFlow Lite মডেলের ফাইলের নাম উল্লেখ করে একটি CustomLocalModel
অবজেক্ট তৈরি করুন:
সুইফট
guard let modelPath = Bundle.main.path(
forResource: "your_model",
ofType: "tflite",
inDirectory: "your_model_directory"
) else { /* Handle error. */ }
let localModel = CustomLocalModel(modelPath: modelPath)
উদ্দেশ্য-C
NSString *modelPath = [NSBundle.mainBundle pathForResource:@"your_model"
ofType:@"tflite"
inDirectory:@"your_model_directory"];
FIRCustomLocalModel *localModel =
[[FIRCustomLocalModel alloc] initWithModelPath:modelPath];
আপনার মডেল থেকে একটি দোভাষী তৈরি করুন
আপনি আপনার মডেল উত্স কনফিগার করার পরে, তাদের মধ্যে একটি থেকে একটি ModelInterpreter
অবজেক্ট তৈরি করুন।
যদি আপনার কাছে শুধুমাত্র স্থানীয়ভাবে বান্ডিল করা মডেল থাকে, তাহলে শুধু CustomLocalModel
অবজেক্টকে modelInterpreter(localModel:)
এ পাস করুন :
সুইফট
let interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
উদ্দেশ্য-C
FIRModelInterpreter *interpreter =
[FIRModelInterpreter modelInterpreterForLocalModel:localModel];
আপনার যদি দূরবর্তীভাবে-হোস্ট করা মডেল থাকে, তাহলে আপনাকে এটি চালানোর আগে এটি ডাউনলোড করা হয়েছে কিনা তা পরীক্ষা করতে হবে। আপনি মডেল ম্যানেজারের isModelDownloaded(remoteModel:)
পদ্ধতি ব্যবহার করে মডেল ডাউনলোড টাস্কের স্থিতি পরীক্ষা করতে পারেন।
যদিও আপনাকে শুধুমাত্র দোভাষী চালানোর আগে এটি নিশ্চিত করতে হবে, যদি আপনার কাছে একটি দূরবর্তীভাবে-হোস্ট করা মডেল এবং একটি স্থানীয়ভাবে-বান্ডিল মডেল উভয়ই থাকে, তাহলে ModelInterpreter
ইনস্ট্যান্টিয়েট করার সময় এই চেকটি সম্পাদন করা বোধগম্য হতে পারে: যদি এটি হয় তবে দূরবর্তী মডেল থেকে একটি দোভাষী তৈরি করুন ডাউনলোড করা হয়েছে, এবং অন্যথায় স্থানীয় মডেল থেকে।
সুইফট
var interpreter: ModelInterpreter
if ModelManager.modelManager().isModelDownloaded(remoteModel) {
interpreter = ModelInterpreter.modelInterpreter(remoteModel: remoteModel)
} else {
interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
}
উদ্দেশ্য-C
FIRModelInterpreter *interpreter;
if ([[FIRModelManager modelManager] isModelDownloaded:remoteModel]) {
interpreter = [FIRModelInterpreter modelInterpreterForRemoteModel:remoteModel];
} else {
interpreter = [FIRModelInterpreter modelInterpreterForLocalModel:localModel];
}
যদি আপনার কাছে শুধুমাত্র একটি দূরবর্তীভাবে হোস্ট করা মডেল থাকে, তাহলে আপনার মডেল-সম্পর্কিত কার্যকারিতা অক্ষম করা উচিত-উদাহরণস্বরূপ, ধূসর-আউট বা আপনার UI-এর অংশ লুকান-যতক্ষণ না আপনি নিশ্চিত করেন যে মডেলটি ডাউনলোড করা হয়েছে।
আপনি ডিফল্ট বিজ্ঞপ্তি কেন্দ্রে পর্যবেক্ষকদের সংযুক্ত করে মডেল ডাউনলোডের অবস্থা পেতে পারেন। পর্যবেক্ষক ব্লকে self
সম্পর্কে একটি দুর্বল রেফারেন্স ব্যবহার করতে ভুলবেন না, যেহেতু ডাউনলোডে কিছু সময় লাগতে পারে, এবং ডাউনলোড শেষ হওয়ার সময় থেকে উদ্ভূত বস্তুটি মুক্ত করা যেতে পারে। যেমন:
সুইফট
NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidSucceed, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel, model.name == "your_remote_model" else { return } // The model was downloaded and is available on the device } NotificationCenter.default.addObserver( forName: .firebaseMLModelDownloadDidFail, object: nil, queue: nil ) { [weak self] notification in guard let strongSelf = self, let userInfo = notification.userInfo, let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel else { return } let error = userInfo[ModelDownloadUserInfoKey.error.rawValue] // ... }
উদ্দেশ্য-C
__weak typeof(self) weakSelf = self; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidSucceedNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel]; if ([model.name isEqualToString:@"your_remote_model"]) { // The model was downloaded and is available on the device } }]; [NSNotificationCenter.defaultCenter addObserverForName:FIRModelDownloadDidFailNotification object:nil queue:nil usingBlock:^(NSNotification *_Nonnull note) { if (weakSelf == nil | note.userInfo == nil) { return; } __strong typeof(self) strongSelf = weakSelf; NSError *error = note.userInfo[FIRModelDownloadUserInfoKeyError]; }];
মডেলের ইনপুট এবং আউটপুট উল্লেখ করুন
এর পরে, মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট ফর্ম্যাটগুলি কনফিগার করুন।
একটি টেনসরফ্লো লাইট মডেল ইনপুট হিসাবে নেয় এবং আউটপুট হিসাবে এক বা একাধিক বহুমাত্রিক অ্যারে তৈরি করে। এই অ্যারেগুলিতে হয় byte
, int
, long
, বা float
মান থাকে৷ আপনার মডেল ব্যবহার করে অ্যারেগুলির সংখ্যা এবং মাত্রা ("আকৃতি") সহ আপনাকে ML কিট কনফিগার করতে হবে৷
আপনি যদি আপনার মডেলের ইনপুট এবং আউটপুটের আকার এবং ডেটা টাইপ না জানেন, তাহলে আপনি আপনার মডেল পরিদর্শন করতে TensorFlow Lite Python ইন্টারপ্রেটার ব্যবহার করতে পারেন। যেমন:
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="my_model.tflite") interpreter.allocate_tensors() # Print input shape and type print(interpreter.get_input_details()[0]['shape']) # Example: [1 224 224 3] print(interpreter.get_input_details()[0]['dtype']) # Example: <class 'numpy.float32'> # Print output shape and type print(interpreter.get_output_details()[0]['shape']) # Example: [1 1000] print(interpreter.get_output_details()[0]['dtype']) # Example: <class 'numpy.float32'>
আপনি আপনার মডেলের ইনপুট এবং আউটপুটের বিন্যাস নির্ধারণ করার পরে, একটি ModelInputOutputOptions
অবজেক্ট তৈরি করে আপনার অ্যাপের মডেল ইন্টারপ্রেটার কনফিগার করুন৷
উদাহরণস্বরূপ, একটি ফ্লোটিং-পয়েন্ট ইমেজ ক্লাসিফিকেশন মডেল ইনপুট হিসাবে Float
মানগুলির একটি N x224x224x3 অ্যারে নিতে পারে, যা N 224x224 থ্রি-চ্যানেল (RGB) চিত্রগুলির একটি ব্যাচের প্রতিনিধিত্ব করে এবং আউটপুট হিসাবে 1000টি Float
মানগুলির একটি তালিকা তৈরি করে, প্রতিটি প্রতিনিধিত্ব করে মডেলটি ভবিষ্যদ্বাণী করে এমন 1000টি বিভাগের মধ্যে একটির একটি সদস্য হওয়ার সম্ভাবনা।
এই ধরনের একটি মডেলের জন্য, আপনি মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট কনফিগার করবেন যা নীচে দেখানো হয়েছে:
সুইফট
let ioOptions = ModelInputOutputOptions() do { try ioOptions.setInputFormat(index: 0, type: .float32, dimensions: [1, 224, 224, 3]) try ioOptions.setOutputFormat(index: 0, type: .float32, dimensions: [1, 1000]) } catch let error as NSError { print("Failed to set input or output format with error: \(error.localizedDescription)") }
উদ্দেশ্য-C
FIRModelInputOutputOptions *ioOptions = [[FIRModelInputOutputOptions alloc] init]; NSError *error; [ioOptions setInputFormatForIndex:0 type:FIRModelElementTypeFloat32 dimensions:@[@1, @224, @224, @3] error:&error]; if (error != nil) { return; } [ioOptions setOutputFormatForIndex:0 type:FIRModelElementTypeFloat32 dimensions:@[@1, @1000] error:&error]; if (error != nil) { return; }
ইনপুট ডেটার উপর অনুমান সম্পাদন করুন
অবশেষে, মডেল ব্যবহার করে অনুমান সম্পাদন করতে, আপনার ইনপুট ডেটা পান, আপনার মডেলের জন্য প্রয়োজনীয় হতে পারে এমন ডেটাতে যে কোনও রূপান্তর সম্পাদন করুন এবং ডেটা ধারণ করে এমন একটি Data
অবজেক্ট তৈরি করুন।
উদাহরণস্বরূপ, যদি আপনার মডেল চিত্রগুলি প্রক্রিয়া করে এবং আপনার মডেলটিতে [BATCH_SIZE, 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 } let inputs = ModelInputs() var inputData = Data() do { for row in 0 ..< 224 { for col in 0 ..< 224 { let offset = 4 * (col * context.width + row) // (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) } } try inputs.addInput(inputData) } catch let error { print("Failed to add input: \(error)") }
উদ্দেশ্য-C
CGImageRef image = // Your input image long imageWidth = CGImageGetWidth(image); long imageHeight = CGImageGetHeight(image); CGContextRef context = CGBitmapContextCreate(nil, imageWidth, imageHeight, 8, imageWidth * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst); CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image); UInt8 *imageData = CGBitmapContextGetData(context); FIRModelInputs *inputs = [[FIRModelInputs alloc] init]; NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0]; for (int row = 0; row < 224; row++) { for (int col = 0; col < 224; col++) { long offset = 4 * (col * imageWidth + row); // 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. // (Ignore offset 0, the unused alpha channel) Float32 red = imageData[offset+1] / 255.0f; Float32 green = imageData[offset+2] / 255.0f; Float32 blue = imageData[offset+3] / 255.0f; [inputData appendBytes:&red length:sizeof(red)]; [inputData appendBytes:&green length:sizeof(green)]; [inputData appendBytes:&blue length:sizeof(blue)]; } } [inputs addInput:inputData error:&error]; if (error != nil) { return nil; }
আপনি আপনার মডেল ইনপুট প্রস্তুত করার পরে (এবং আপনি নিশ্চিত করার পরে মডেলটি উপলব্ধ), ইনপুট এবং ইনপুট/আউটপুট বিকল্পগুলি আপনার মডেল ইন্টারপ্রেটারের run(inputs:options:completion:)
পদ্ধতিতে পাস করুন।
সুইফট
interpreter.run(inputs: inputs, options: ioOptions) { outputs, error in guard error == nil, let outputs = outputs else { return } // Process outputs // ... }
উদ্দেশ্য-C
[interpreter runWithInputs:inputs options:ioOptions completion:^(FIRModelOutputs * _Nullable outputs, NSError * _Nullable error) { if (error != nil || outputs == nil) { return; } // Process outputs // ... }];
যে বস্তুটি ফেরত দেওয়া হয়েছে তার output(index:)
পদ্ধতিতে কল করে আপনি আউটপুট পেতে পারেন। যেমন:
সুইফট
// Get first and only output of inference with a batch size of 1 let output = try? outputs.output(index: 0) as? [[NSNumber]] let probabilities = output??[0]
উদ্দেশ্য-C
// Get first and only output of inference with a batch size of 1 NSError *outputError; NSArray *probabilites = [outputs outputAtIndex:0 error:&outputError][0];
আপনি কীভাবে আউটপুট ব্যবহার করবেন তা নির্ভর করে আপনি যে মডেলটি ব্যবহার করছেন তার উপর।
উদাহরণ স্বরূপ, আপনি যদি শ্রেণীবিন্যাস সম্পাদন করছেন, পরবর্তী পদক্ষেপ হিসাবে, আপনি ফলাফলের সূচীগুলিকে তারা প্রতিনিধিত্ব করে এমন লেবেলে ম্যাপ করতে পারেন। ধরুন আপনার কাছে আপনার মডেলের প্রতিটি বিভাগের জন্য লেবেল স্ট্রিং সহ একটি পাঠ্য ফাইল ছিল; আপনি নিম্নলিখিত মত কিছু করে আউটপুট সম্ভাব্যতা লেবেল স্ট্রিং ম্যাপ করতে পারেন:
সুইফট
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 0 ..< labels.count { if let probability = probabilities?[i] { print("\(labels[i]): \(probability)") } }
উদ্দেশ্য-C
NSError *labelReadError = nil; NSString *labelPath = [NSBundle.mainBundle pathForResource:@"retrained_labels" ofType:@"txt"]; NSString *fileContents = [NSString stringWithContentsOfFile:labelPath encoding:NSUTF8StringEncoding error:&labelReadError]; if (labelReadError != nil || fileContents == NULL) { return; } NSArray<NSString *> *labels = [fileContents componentsSeparatedByString:@"\n"]; for (int i = 0; i < labels.count; i++) { NSString *label = labels[i]; NSNumber *probability = probabilites[i]; NSLog(@"%@: %f", label, probability.floatValue); }
পরিশিষ্ট: মডেল নিরাপত্তা
আপনি ML Kit-এ আপনার TensorFlow Lite মডেলগুলিকে যেভাবে উপলব্ধ করুন না কেন, ML Kit স্থানীয় স্টোরেজে স্ট্যান্ডার্ড সিরিয়ালাইজড প্রোটোবাফ ফর্ম্যাটে সেগুলি সঞ্চয় করে৷
তত্ত্বগতভাবে, এর মানে হল যে কেউ আপনার মডেল অনুলিপি করতে পারে। যাইহোক, বাস্তবে, বেশিরভাগ মডেলগুলি এতটাই অ্যাপ্লিকেশন-নির্দিষ্ট এবং অপ্টিমাইজেশান দ্বারা অস্পষ্ট যে ঝুঁকি প্রতিযোগীদের বিচ্ছিন্ন করা এবং আপনার কোড পুনরায় ব্যবহার করার মতোই। তবুও, আপনার অ্যাপে একটি কাস্টম মডেল ব্যবহার করার আগে আপনার এই ঝুঁকি সম্পর্কে সচেতন হওয়া উচিত।