עזרה להגן על שונית המחסום הגדולה עם TensorFlow על Kaggle הצטרפו אתגר

עבד נתוני קלט ופלט עם ספריית התמיכה של TensorFlow Lite

מפתחי יישומים ניידים בדרך כלל מקיימים אינטראקציה עם אובייקטים מוקלדים כגון מפות סיביות או פרימיטיביות כגון מספרים שלמים. עם זאת, ה-API של המתורגמן של TensorFlow Lite המריץ את מודל למידת המכונה במכשיר משתמש בטנזורים בצורה של ByteBuffer, שעלולים להיות קשים לניפוי באגים ולתמרן. ספריית תמיכת אנדרואיד TensorFlow לייט נועדה תהליך עזרת הקלט והפלט של מודלים לייט TensorFlow, ולהפוך את לייט TensorFlow מתורגמן קל יותר לשימוש.

מתחילים

ייבא תלות Gradle והגדרות אחרות

העתק את .tflite קובץ המודל לספריית הנכסים של מודול אנדרואיד שבו המודל תופעל. ציין כי הקובץ אינו יכול להיות דחוס, ולהוסיף את הספרייה לייט TensorFlow אל של מודול build.gradle הקובץ:

android {
    // Other settings

    // Specify tflite file should not be compressed for the app apk
    aaptOptions {
        noCompress "tflite"
    }

}

dependencies {
    // Other dependencies

    // Import tflite dependencies
    implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly-SNAPSHOT'
    // The GPU delegate library is optional. Depend on it as needed.
    implementation 'org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly-SNAPSHOT'
    implementation 'org.tensorflow:tensorflow-lite-support:0.0.0-nightly-SNAPSHOT'
}

חקור את AAR הספריה תמיכה לייט TensorFlow אירחה בבית MavenCentral עבור גרסאות שונות של הספרייה תמיכה.

מניפולציה והמרת תמונה בסיסית

ספריית התמיכה של TensorFlow Lite כוללת חבילה של שיטות מניפולציה בסיסיות של תמונות כגון חיתוך ושינוי גודל. כדי להשתמש בו, ליצור ImagePreprocessor ולהוסיף את הפעולות הנדרשות. כדי להמיר את התמונה לפורמט מותח נדרש על ידי המתורגמן לייט TensorFlow, ליצור TensorImage לשמש כקלט:

import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.image.ImageProcessor;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.image.ops.ResizeOp;

// Initialization code
// Create an ImageProcessor with all ops required. For more ops, please
// refer to the ImageProcessor Architecture section in this README.
ImageProcessor imageProcessor =
    new ImageProcessor.Builder()
        .add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR))
        .build();

// Create a TensorImage object. This creates the tensor of the corresponding
// tensor type (uint8 in this case) that the TensorFlow Lite interpreter needs.
TensorImage tensorImage = new TensorImage(DataType.UINT8);

// Analysis code for every frame
// Preprocess the image
tensorImage.load(bitmap);
tensorImage = imageProcessor.process(tensorImage);

DataType של מותח ניתן לקרוא דרך הספרייה exractor metadata וכן מידע מודל אחר.

עיבוד נתוני אודיו בסיסי

ספריית תמיכת לייט TensorFlow גם מגדירה TensorAudio בכיתת גלישה כמה נתונים בסיסיים אודיו עיבוד שיטות. זה בעיקר בשימוש יחד עם AudioRecord לוכד דגימות אודיו במאגר טבעת.

import android.media.AudioRecord;
import org.tensorflow.lite.support.audio.TensorAudio;

// Create an `AudioRecord` instance.
AudioRecord record = AudioRecord(...)

// Create a `TensorAudio` object from Android AudioFormat.
TensorAudio tensorAudio = new TensorAudio(record.getFormat(), size)

// Load all audio samples available in the AudioRecord without blocking.
tensorAudio.load(record)

// Get the `TensorBuffer` for inference.
TensorBuffer buffer = tensorAudio.getTensorBuffer()

צור אובייקטי פלט והפעל את המודל

לפני הפעלת המודל, עלינו ליצור את אובייקטי המיכל שיאחסנו את התוצאה:

import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;

// Create a container for the result and specify that this is a quantized model.
// Hence, the 'DataType' is defined as UINT8 (8-bit unsigned integer)
TensorBuffer probabilityBuffer =
    TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);

טעינת הדגם והפעלת הסקת מסקנות:

import java.nio.MappedByteBuffer;
import org.tensorflow.lite.InterpreterFactory;
import org.tensorflow.lite.InterpreterApi;

// Initialise the model
try{
    MappedByteBuffer tfliteModel
        = FileUtil.loadMappedFile(activity,
            "mobilenet_v1_1.0_224_quant.tflite");
    InterpreterApi tflite = new InterpreterFactory().create(
        tfliteModel, new InterpreterApi.Options());
} catch (IOException e){
    Log.e("tfliteSupport", "Error reading model", e);
}

// Running inference
if(null != tflite) {
    tflite.run(tImage.getBuffer(), probabilityBuffer.getBuffer());
}

גישה לתוצאה

מפתחים יכולים לגשת פלט ישירות דרך probabilityBuffer.getFloatArray() . אם המודל מייצר פלט כמותי, זכור להמיר את התוצאה. עבור המודל המקוונטי של MobileNet, המפתח צריך לחלק כל ערך פלט ב-255 כדי לקבל את ההסתברות הנעה בין 0 (הכי פחות סביר) ל-1 (סביר ביותר) עבור כל קטגוריה.

אופציונלי: מיפוי תוצאות לתוויות

מפתחים יכולים גם למפות את התוצאות לתוויות. ראשית, העתק את קובץ הטקסט המכיל תוויות לספריית הנכסים של המודול. לאחר מכן, טען את קובץ התווית באמצעות הקוד הבא:

import org.tensorflow.lite.support.common.FileUtil;

final String ASSOCIATED_AXIS_LABELS = "labels.txt";
List<String> associatedAxisLabels = null;

try {
    associatedAxisLabels = FileUtil.loadLabels(this, ASSOCIATED_AXIS_LABELS);
} catch (IOException e) {
    Log.e("tfliteSupport", "Error reading label file", e);
}

הקטע הבא מדגים כיצד לשייך את ההסתברויות עם תוויות קטגוריות:

import java.util.Map;
import org.tensorflow.lite.support.common.TensorProcessor;
import org.tensorflow.lite.support.common.ops.NormalizeOp;
import org.tensorflow.lite.support.label.TensorLabel;

// Post-processor which dequantize the result
TensorProcessor probabilityProcessor =
    new TensorProcessor.Builder().add(new NormalizeOp(0, 255)).build();

if (null != associatedAxisLabels) {
    // Map of labels and their corresponding probability
    TensorLabel labels = new TensorLabel(associatedAxisLabels,
        probabilityProcessor.process(probabilityBuffer));

    // Create a map to access the result based on label
    Map<String, Float> floatMap = labels.getMapWithFloatValue();
}

כיסוי שימוש נוכחי

הגרסה הנוכחית של ספריית התמיכה של TensorFlow Lite מכסה:

  • סוגי נתונים נפוצים (float, uint8, תמונות, אודיו ומערך של אובייקטים אלה) ככניסות ויציאות של דגמי tflite.
  • פעולות תמונה בסיסיות (חיתוך תמונה, שינוי גודל וסיבוב).
  • נורמליזציה וקונטיזציה
  • שימושי קבצים

גרסאות עתידיות ישפרו את התמיכה ביישומים הקשורים לטקסט.

ארכיטקטורת ImageProcessor

העיצוב של ImageProcessor איפשר פעולות מניפולציה התמונה תוגדר מראש ומותאמים במהלך תהליך הבניה. ImageProcessor תומך כיום שלוש פעולות עיבוד מקדימות בסיסיות, כמתואר שלוש ההערות בקטע הקוד הבא:

import org.tensorflow.lite.support.common.ops.NormalizeOp;
import org.tensorflow.lite.support.common.ops.QuantizeOp;
import org.tensorflow.lite.support.image.ops.ResizeOp;
import org.tensorflow.lite.support.image.ops.ResizeWithCropOrPadOp;
import org.tensorflow.lite.support.image.ops.Rot90Op;

int width = bitmap.getWidth();
int height = bitmap.getHeight();

int size = height > width ? width : height;

ImageProcessor imageProcessor =
    new ImageProcessor.Builder()
        // Center crop the image to the largest square possible
        .add(new ResizeWithCropOrPadOp(size, size))
        // Resize using Bilinear or Nearest neighbour
        .add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR));
        // Rotation counter-clockwise in 90 degree increments
        .add(new Rot90Op(rotateDegrees / 90))
        .add(new NormalizeOp(127.5, 127.5))
        .add(new QuantizeOp(128.0, 1/128.0))
        .build();

לפרטים נוספים ראה כאן על נורמליזציה קוונטיזציה.

המטרה הסופית של הספרייה תמיכה היא לתמוך בכל tf.image טרנספורמציות. המשמעות היא שהטרנספורמציה תהיה זהה ל-TensorFlow והיישום יהיה בלתי תלוי במערכת ההפעלה.

מפתחים מוזמנים גם ליצור מעבדים מותאמים אישית. חשוב במקרים אלו להיות מיושרים עם תהליך האימון - כלומר אותו עיבוד מקדים צריך לחול גם על אימון וגם על מסקנות כדי להגביר את יכולת השחזור.

כימות

כאשר ייזום חפצים קלט או פלט כגון TensorImage או TensorBuffer עליך לציין סוגים שלהם להיות DataType.UINT8 או DataType.FLOAT32 .

TensorImage tensorImage = new TensorImage(DataType.UINT8);
TensorBuffer probabilityBuffer =
    TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);

TensorProcessor יכול לשמש לקוואנטיזציה tensors קלט או dequantize tensors פלט. לדוגמה, בעת עיבוד פלט בדיד TensorBuffer , המפתחים יכולים להשתמש DequantizeOp כדי dequantize את התוצאה הסתברות נקודה צפה בין 0 לבין 1:

import org.tensorflow.lite.support.common.TensorProcessor;

// Post-processor which dequantize the result
TensorProcessor probabilityProcessor =
    new TensorProcessor.Builder().add(new DequantizeOp(0, 1/255.0)).build();
TensorBuffer dequantizedBuffer = probabilityProcessor.process(probabilityBuffer);

הפרמטרים קוונטיזציה של מותח ניתן לקרוא דרך הספרייה metadata exractor .