Firebase/MLModelInterpreter
kitaplığının 0.20.0 sürümünde yeni bir
getLatestModelFilePath()
yöntemi kullanılır ve bu yöntem, cihazındaki konumu alır.
modeller. TensorFlow Lite'ı doğrudan örneklendirmek için bu yöntemi kullanabilirsiniz.
Firebase'in ModelInterpreter
yerine kullanabileceğiniz Interpreter
nesnesi
sarmalayıcıdır.
Bundan sonra tercih edilen yaklaşım budur. TensorFlow Lite çevirmen sürümü artık Firebase kitaplığı sürümüyle ilişkili değildir, TensorFlow Lite'ın yeni sürümlerine geçmek için daha fazla esnekliğe sahip olmak daha kolay kullanabilirsiniz.
Bu sayfada, ModelInterpreter
uygulamasından
TensorFlow Lite Interpreter
.
1. Proje bağımlılıklarını güncelleme
Projenizin Podfile dosyasını şunu içerecek şekilde güncelleyin:
Firebase/MLModelInterpreter
kitaplığı (veya daha yeni) ve TensorFlow Lite
kitaplık:
Önce
Swift
pod 'Firebase/MLModelInterpreter', '0.19.0'
Objective-C
pod 'Firebase/MLModelInterpreter', '0.19.0'
Sonra
Swift
pod 'Firebase/MLModelInterpreter', '~> 0.20.0'
pod 'TensorFlowLiteSwift'
Objective-C
pod 'Firebase/MLModelInterpreter', '~> 0.20.0'
pod 'TensorFlowLiteObjC'
2. Firebase ModelTranslateer yerine TensorFlow Lite yorumlayıcısı oluşturma
Firebase ModelInterpreter
oluşturmak yerine modelin konumunu şurada alın:
getLatestModelFilePath()
ile ilişkilendirip TensorFlow Lite oluşturmak için
Interpreter
.
Önce
Swift
let remoteModel = CustomRemoteModel(
name: "your_remote_model" // The name you assigned in the Firebase console.
)
interpreter = ModelInterpreter.modelInterpreter(remoteModel: remoteModel)
Objective-C
// Initialize using the name you assigned in the Firebase console.
FIRCustomRemoteModel *remoteModel =
[[FIRCustomRemoteModel alloc] initWithName:@"your_remote_model"];
interpreter = [FIRModelInterpreter modelInterpreterForRemoteModel:remoteModel];
Sonra
Swift
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?
}
}
Objective-C
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. Giriş ve çıkış hazırlama kodunu güncelleme
ModelInterpreter
ile modelin giriş ve çıkış şekillerini belirtirsiniz
kullandığınızda, çeviriciye ModelInputOutputOptions
nesnesini iletmek
somut olarak ortaya koyar.
TensorFlow Lite yorumlayıcısı için allocateTensors()
çağırarak
modelin giriş ve çıkışı için alan ayırın, ardından giriş verilerinizi
giriş tensörleridir.
Örneğin, modelinizin giriş şekli [1 224 224 3] float
ise
ve [1 1000] float
değerinde bir çıktı şekli elde ediyorsanız şu değişiklikleri yapın:
Önce
Swift
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
// ...
}
Objective-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; }
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
// ...
}];
Sonra
Swift
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)
}
Objective-C
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. Çıkış işleme kodunu güncelleyin
Son olarak, ModelOutputs
nesnesiyle modelin çıkışını almak yerine
output()
yöntemini kullanıyorsanız yorumlayıcıdan çıkış tensörünü alın ve
verileri kullanım alanınız için uygun olan herhangi bir yapıya ekleyebilirsiniz.
Örneğin sınıflandırma yapıyorsanız: takip etmek için:
Önce
Swift
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)")
}
}
Objective-C
// 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);
}
Sonra
Swift
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)
}
Objective-C
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]);
}