از API مدل سفارشی قدیمی مهاجرت کنید

نسخه ۲۲.۰.۲ کتابخانه firebase-ml-model-interpreter یک متد جدید getLatestModelFile() معرفی می‌کند که موقعیت مکانی مدل‌های سفارشی را روی دستگاه دریافت می‌کند. می‌توانید از این متد برای نمونه‌سازی مستقیم یک شیء TensorFlow Lite Interpreter استفاده کنید که می‌توانید به جای پوشش FirebaseModelInterpreter از آن استفاده کنید.

از این به بعد، این رویکرد ترجیح داده می‌شود. از آنجا که نسخه مفسر TensorFlow Lite دیگر با نسخه کتابخانه Firebase همراه نیست، شما انعطاف‌پذیری بیشتری برای ارتقا به نسخه‌های جدید TensorFlow Lite در صورت تمایل یا استفاده آسان‌تر از نسخه‌های سفارشی TensorFlow Lite خواهید داشت.

این صفحه نشان می‌دهد که چگونه می‌توانید از استفاده از FirebaseModelInterpreter به TensorFlow Lite Interpreter مهاجرت کنید.

۱. وابستگی‌های پروژه را به‌روزرسانی کنید

وابستگی‌های پروژه خود را به‌روزرسانی کنید تا نسخه ۲۲.۰.۲ کتابخانه firebase-ml-model-interpreter (یا جدیدتر) و کتابخانه tensorflow-lite شامل شود:

قبل از

implementation("com.google.firebase:firebase-ml-model-interpreter:22.0.1")

بعد از

implementation("com.google.firebase:firebase-ml-model-interpreter:22.0.2")
implementation("org.tensorflow:tensorflow-lite:2.0.0")

۲. به جای FirebaseModelInterpreter، یک مفسر TensorFlow Lite ایجاد کنید.

به جای ایجاد یک FirebaseModelInterpreter ، مکان مدل روی دستگاه را با getLatestModelFile() دریافت کنید و از آن برای ایجاد یک TensorFlow Lite Interpreter استفاده کنید.

قبل از

Kotlin

val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()
val options = FirebaseModelInterpreterOptions.Builder(remoteModel).build()
val interpreter = FirebaseModelInterpreter.getInstance(options)

Java

FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();
FirebaseModelInterpreterOptions options =
        new FirebaseModelInterpreterOptions.Builder(remoteModel).build();
FirebaseModelInterpreter interpreter = FirebaseModelInterpreter.getInstance(options);

بعد از

Kotlin

val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
    .addOnCompleteListener { task ->
        val modelFile = task.getResult()
        if (modelFile != null) {
            // Instantiate an org.tensorflow.lite.Interpreter object.
            interpreter = Interpreter(modelFile)
        }
    }

Java

FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnCompleteListener(new OnCompleteListener<File>() {
            @Override
            public void onComplete(@NonNull Task<File> task) {
                File modelFile = task.getResult();
                if (modelFile != null) {
                    // Instantiate an org.tensorflow.lite.Interpreter object.
                    Interpreter interpreter = new Interpreter(modelFile);
                }
            }
        });

۳. کد آماده‌سازی ورودی و خروجی را به‌روزرسانی کنید

با استفاده از FirebaseModelInterpreter ، شما با ارسال یک شیء FirebaseModelInputOutputOptions به مفسر هنگام اجرای آن، شکل‌های ورودی و خروجی مدل را مشخص می‌کنید.

برای مفسر TensorFlow Lite، شما به جای آن، اشیاء ByteBuffer را با اندازه مناسب برای ورودی و خروجی مدل خود اختصاص می‌دهید.

برای مثال، اگر مدل شما شکل ورودی با مقادیر float [1 224 224 3] و شکل خروجی با مقادیر float [1 1000] دارد، این تغییرات را اعمال کنید:

قبل از

Kotlin

val inputOutputOptions = FirebaseModelInputOutputOptions.Builder()
    .setInputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 224, 224, 3))
    .setOutputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 1000))
    .build()

val input = ByteBuffer.allocateDirect(224*224*3*4).order(ByteOrder.nativeOrder())
// Then populate with input data.

val inputs = FirebaseModelInputs.Builder()
    .add(input)
    .build()

interpreter.run(inputs, inputOutputOptions)
    .addOnSuccessListener { outputs ->
        // ...
    }
    .addOnFailureListener {
        // Task failed with an exception.
        // ...
    }

Java

FirebaseModelInputOutputOptions inputOutputOptions =
        new FirebaseModelInputOutputOptions.Builder()
                .setInputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 224, 224, 3})
                .setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 1000})
                .build();

float[][][][] input = new float[1][224][224][3];
// Then populate with input data.

FirebaseModelInputs inputs = new FirebaseModelInputs.Builder()
        .add(input)
        .build();

interpreter.run(inputs, inputOutputOptions)
        .addOnSuccessListener(
                new OnSuccessListener<FirebaseModelOutputs>() {
                    @Override
                    public void onSuccess(FirebaseModelOutputs result) {
                        // ...
                    }
                })
        .addOnFailureListener(
                new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        // Task failed with an exception
                        // ...
                    }
                });

بعد از

Kotlin

val inBufferSize = 1 * 224 * 224 * 3 * java.lang.Float.SIZE / java.lang.Byte.SIZE
val inputBuffer = ByteBuffer.allocateDirect(inBufferSize).order(ByteOrder.nativeOrder())
// Then populate with input data.

val outBufferSize = 1 * 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE
val outputBuffer = ByteBuffer.allocateDirect(outBufferSize).order(ByteOrder.nativeOrder())

interpreter.run(inputBuffer, outputBuffer)

Java

int inBufferSize = 1 * 224 * 224 * 3 * java.lang.Float.SIZE / java.lang.Byte.SIZE;
ByteBuffer inputBuffer =
        ByteBuffer.allocateDirect(inBufferSize).order(ByteOrder.nativeOrder());
// Then populate with input data.

int outBufferSize = 1 * 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE;
ByteBuffer outputBuffer =
        ByteBuffer.allocateDirect(outBufferSize).order(ByteOrder.nativeOrder());

interpreter.run(inputBuffer, outputBuffer);

۴. کد مدیریت خروجی را به‌روزرسانی کنید

در نهایت، به جای دریافت خروجی مدل با متد getOutput() از شیء FirebaseModelOutputs ، خروجی ByteBuffer را به هر ساختاری که برای مورد استفاده شما مناسب است تبدیل کنید.

برای مثال، اگر در حال طبقه‌بندی هستید، ممکن است تغییراتی مانند موارد زیر ایجاد کنید:

قبل از

Kotlin

val output = result.getOutput(0)
val probabilities = output[0]
try {
    val reader = BufferedReader(InputStreamReader(assets.open("custom_labels.txt")))
    for (probability in probabilities) {
        val label: String = reader.readLine()
        println("$label: $probability")
    }
} catch (e: IOException) {
    // File not found?
}

Java

float[][] output = result.getOutput(0);
float[] probabilities = output[0];
try {
    BufferedReader reader = new BufferedReader(
          new InputStreamReader(getAssets().open("custom_labels.txt")));
    for (float probability : probabilities) {
        String label = reader.readLine();
        Log.i(TAG, String.format("%s: %1.4f", label, probability));
    }
} catch (IOException e) {
    // File not found?
}

بعد از

Kotlin

modelOutput.rewind()
val probabilities = modelOutput.asFloatBuffer()
try {
    val reader = BufferedReader(
            InputStreamReader(assets.open("custom_labels.txt")))
    for (i in probabilities.capacity()) {
        val label: String = reader.readLine()
        val probability = probabilities.get(i)
        println("$label: $probability")
    }
} catch (e: IOException) {
    // File not found?
}

Java

modelOutput.rewind();
FloatBuffer probabilities = modelOutput.asFloatBuffer();
try {
    BufferedReader reader = new BufferedReader(
            new InputStreamReader(getAssets().open("custom_labels.txt")));
    for (int i = 0; i < probabilities.capacity(); i++) {
        String label = reader.readLine();
        float probability = probabilities.get(i);
        Log.i(TAG, String.format("%s: %1.4f", label, probability));
    }
} catch (IOException e) {
    // File not found?
}