লিগ্যাসি কাস্টম মডেল API থেকে স্থানান্তর করুন৷

Firebase/MLModelInterpreter লাইব্রেরির সংস্করণ 0.20.0 একটি নতুন getLatestModelFilePath() পদ্ধতি প্রবর্তন করে, যা কাস্টম মডেলের ডিভাইসে অবস্থান পায়। আপনি এই পদ্ধতিটি সরাসরি একটি টেনসরফ্লো লাইট Interpreter অবজেক্ট ইনস্ট্যান্ট করতে ব্যবহার করতে পারেন, যা আপনি ফায়ারবেসের ModelInterpreter র‍্যাপারের পরিবর্তে ব্যবহার করতে পারেন।

এগিয়ে যাওয়া, এটি পছন্দের পদ্ধতি। যেহেতু টেনসরফ্লো লাইট ইন্টারপ্রেটার সংস্করণটি আর ফায়ারবেস লাইব্রেরি সংস্করণের সাথে মিলিত নয়, আপনি যখন চান তখন টেনসরফ্লো লাইটের নতুন সংস্করণে আপগ্রেড করার জন্য আপনার কাছে আরও নমনীয়তা রয়েছে বা আরও সহজে কাস্টম টেনসরফ্লো লাইট বিল্ডগুলি ব্যবহার করতে পারবেন।

এই পৃষ্ঠাটি দেখায় কিভাবে আপনি ModelInterpreter ব্যবহার করে TensorFlow Lite Interpreter স্থানান্তর করতে পারেন।

1. প্রকল্প নির্ভরতা আপডেট করুন

Firebase/MLModelInterpreter লাইব্রেরি (বা নতুন) এবং TensorFlow Lite লাইব্রেরির সংস্করণ 0.20.0 অন্তর্ভুক্ত করতে আপনার প্রকল্পের Podfile আপডেট করুন:

আগে

সুইফট

pod 'Firebase/MLModelInterpreter', '0.19.0'

উদ্দেশ্য গ

pod 'Firebase/MLModelInterpreter', '0.19.0'

পরে

সুইফট

pod 'Firebase/MLModelInterpreter', '~> 0.20.0'
pod 'TensorFlowLiteSwift'

উদ্দেশ্য গ

pod 'Firebase/MLModelInterpreter', '~> 0.20.0'
pod 'TensorFlowLiteObjC'

2. ফায়ারবেস মডেল ইন্টারপ্রেটারের পরিবর্তে একটি টেনসরফ্লো লাইট ইন্টারপ্রেটার তৈরি করুন

একটি Firebase ModelInterpreter তৈরি করার পরিবর্তে, getLatestModelFilePath() দিয়ে ডিভাইসে মডেলের অবস্থান পান এবং একটি টেনসরফ্লো লাইট Interpreter তৈরি করতে এটি ব্যবহার করুন।

আগে

সুইফট

let remoteModel = CustomRemoteModel(
    name: "your_remote_model"  // The name you assigned in the Firebase console.
)
interpreter = ModelInterpreter.modelInterpreter(remoteModel: remoteModel)

উদ্দেশ্য গ

// Initialize using the name you assigned in the Firebase console.
FIRCustomRemoteModel *remoteModel =
        [[FIRCustomRemoteModel alloc] initWithName:@"your_remote_model"];
interpreter = [FIRModelInterpreter modelInterpreterForRemoteModel:remoteModel];

পরে

সুইফট

let remoteModel = CustomRemoteModel(
    name: "your_remote_model"  // The name you assigned in the Firebase console.
)
ModelManager.modelManager().getLatestModelFilePath(remoteModel) { (remoteModelPath, error) in
    guard error == nil, let remoteModelPath = remoteModelPath else { return }
    do {
        interpreter = try Interpreter(modelPath: remoteModelPath)
    } catch {
        // Error?
    }
}

উদ্দেশ্য গ

FIRCustomRemoteModel *remoteModel =
        [[FIRCustomRemoteModel alloc] initWithName:@"your_remote_model"];
[[FIRModelManager modelManager] getLatestModelFilePath:remoteModel
                                            completion:^(NSString * _Nullable filePath,
                                                         NSError * _Nullable error) {
    if (error != nil || filePath == nil) { return; }

    NSError *tfError = nil;
    interpreter = [[TFLInterpreter alloc] initWithModelPath:filePath error:&tfError];
}];

3. ইনপুট এবং আউটপুট প্রস্তুতি কোড আপডেট করুন

ModelInterpreter এর সাথে, আপনি যখন এটি চালান তখন আপনি একটি ModelInputOutputOptions অবজেক্ট ইন্টারপ্রেটারকে পাস করে মডেলের ইনপুট এবং আউটপুট আকারগুলি নির্দিষ্ট করেন৷

TensorFlow Lite ইন্টারপ্রেটারের জন্য, আপনি মডেলের ইনপুট এবং আউটপুটের জন্য স্থান বরাদ্দ করতে allocateTensors() কল করুন, তারপর আপনার ইনপুট ডেটা ইনপুট টেনসরগুলিতে অনুলিপি করুন।

উদাহরণস্বরূপ, যদি আপনার মডেলের একটি ইনপুট আকার থাকে [1 224 224 3] float মান এবং একটি আউটপুট আকার [1 1000] float মানগুলির, তাহলে এই পরিবর্তনগুলি করুন:

আগে

সুইফট

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)")
}

let inputs = ModelInputs()
do {
    let inputData = Data()
    // Then populate with input data.

    try inputs.addInput(inputData)
} catch let error {
    print("Failed to add input: \(error)")
}

interpreter.run(inputs: inputs, options: ioOptions) { outputs, error in
    guard error == nil, let outputs = outputs else { return }
    // Process outputs
    // ...
}

উদ্দেশ্য গ

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; }

FIRModelInputs *inputs = [[FIRModelInputs alloc] init];
NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0];
// Then populate with input data.

[inputs addInput:inputData error:&error];
if (error != nil) { return; }

[interpreter runWithInputs:inputs
                   options:ioOptions
                completion:^(FIRModelOutputs * _Nullable outputs,
                             NSError * _Nullable error) {
  if (error != nil || outputs == nil) {
    return;
  }
  // Process outputs
  // ...
}];

পরে

সুইফট

do {
    try interpreter.allocateTensors()

    let inputData = Data()
    // Then populate with input data.

    try interpreter.copy(inputData, toInputAt: 0)

    try interpreter.invoke()
} catch let err {
    print(err.localizedDescription)
}

উদ্দেশ্য গ

NSError *error = nil;

[interpreter allocateTensorsWithError:&error];
if (error != nil) { return; }

TFLTensor *input = [interpreter inputTensorAtIndex:0 error:&error];
if (error != nil) { return; }

NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0];
// Then populate with input data.

[input copyData:inputData error:&error];
if (error != nil) { return; }

[interpreter invokeWithError:&error];
if (error != nil) { return; }

4. আউটপুট হ্যান্ডলিং কোড আপডেট করুন

অবশেষে, ModelOutputs অবজেক্টের output() পদ্ধতিতে মডেলের আউটপুট পাওয়ার পরিবর্তে, ইন্টারপ্রেটার থেকে আউটপুট টেনসর নিন এবং এর ডেটা আপনার ব্যবহারের ক্ষেত্রে সুবিধাজনক যে কোনও কাঠামোতে রূপান্তর করুন।

উদাহরণস্বরূপ, আপনি যদি শ্রেণীবিভাগ করছেন, আপনি নিম্নলিখিত মত পরিবর্তন করতে পারেন:

আগে

সুইফট

let output = try? outputs.output(index: 0) as? [[NSNumber]]
let probabilities = output?[0]

guard let labelPath = Bundle.main.path(
    forResource: "custom_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)")
    }
}

উদ্দেশ্য গ

// Get first and only output of inference with a batch size of 1
NSError *error;
NSArray *probabilites = [outputs outputAtIndex:0 error:&error][0];
if (error != nil) { return; }

NSString *labelPath = [NSBundle.mainBundle pathForResource:@"retrained_labels"
                                                    ofType:@"txt"];
NSString *fileContents = [NSString stringWithContentsOfFile:labelPath
                                                   encoding:NSUTF8StringEncoding
                                                      error:&error];
if (error != 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);
}

পরে

সুইফট

do {
    // After calling interpreter.invoke():
    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: "custom_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])")
    }
} catch let err {
    print(err.localizedDescription)
}

উদ্দেশ্য গ

NSError *error = nil;

TFLTensor *output = [interpreter outputTensorAtIndex:0 error:&error];
if (error != nil) { return; }

NSData *outputData = [output dataWithError:&error];
if (error != nil) { return; }

Float32 probabilities[outputData.length / 4];
[outputData getBytes:&probabilities length:outputData.length];

NSString *labelPath = [NSBundle.mainBundle pathForResource:@"custom_labels"
                                                    ofType:@"txt"];
NSString *fileContents = [NSString stringWithContentsOfFile:labelPath
                                                   encoding:NSUTF8StringEncoding
                                                      error:&error];
if (error != nil || fileContents == nil) { return; }

NSArray<NSString *> *labels = [fileContents componentsSeparatedByString:@"\n"];
for (int i = 0; i < labels.count; i++) {
    NSLog(@"%@: %f", labels[i], probabilities[i]);
}