মোবাইল অ্যাপ্লিকেশন ডেভেলপাররা সাধারণত টাইপ করা অবজেক্ট যেমন বিটম্যাপ বা প্রিমিটিভ যেমন ইন্টিজারের সাথে ইন্টারঅ্যাক্ট করে। তবে, LiterRT ইন্টারপ্রেটার API যা অন-ডিভাইস মেশিন লার্নিং মডেল চালায় তা ByteBuffer আকারে টেনসর ব্যবহার করে, যা ডিবাগ এবং ম্যানিপুলেট করা কঠিন হতে পারে। LiterRT অ্যান্ড্রয়েড সাপোর্ট লাইব্রেরিটি LiterRT মডেলের ইনপুট এবং আউটপুট প্রক্রিয়াকরণে সহায়তা করার জন্য এবং LiterRT ইন্টারপ্রেটার ব্যবহার করা সহজ করার জন্য ডিজাইন করা হয়েছে।
শুরু করা
গ্রেডল নির্ভরতা এবং অন্যান্য সেটিংস আমদানি করুন
.tflite মডেল ফাইলটি অ্যান্ড্রয়েড মডিউলের সম্পদ ডিরেক্টরিতে অনুলিপি করুন যেখানে মডেলটি চালানো হবে। ফাইলটি সংকুচিত করা উচিত নয় তা নির্দিষ্ট করুন এবং মডিউলের build.gradle ফাইলে LiteRT লাইব্রেরি যুক্ত করুন:
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 'com.google.ai.edge.litert:litert-gpu:0.0.0-nightly-SNAPSHOT'
implementation 'com.google.ai.edge.litert:litert-support:0.0.0-nightly-SNAPSHOT'
}
সাপোর্ট লাইব্রেরির বিভিন্ন সংস্করণের জন্য MavenCentral-এ হোস্ট করা LiterRT সাপোর্ট লাইব্রেরি AAR অন্বেষণ করুন।
মৌলিক চিত্র ম্যানিপুলেশন এবং রূপান্তর
LiterRT সাপোর্ট লাইব্রেরিতে ছবি ম্যানিপুলেশনের মৌলিক পদ্ধতি যেমন ক্রপ এবং রিসাইজ করার একটি স্যুট রয়েছে। এটি ব্যবহার করার জন্য, একটি ImagePreprocessor তৈরি করুন এবং প্রয়োজনীয় ক্রিয়াকলাপ যোগ করুন। LiterRT ইন্টারপ্রেটার দ্বারা প্রয়োজনীয় টেনসর ফর্ম্যাটে ছবিটি রূপান্তর করতে, ইনপুট হিসাবে ব্যবহারের জন্য একটি 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 LiteRT interpreter needs.
TensorImage tensorImage = new TensorImage(DataType.UINT8);
// Analysis code for every frame
// Preprocess the image
tensorImage.load(bitmap);
tensorImage = imageProcessor.process(tensorImage);
একটি টেনসরের DataType মেটাডেটা এক্সট্র্যাক্টর লাইব্রেরির পাশাপাশি অন্যান্য মডেল তথ্যের মাধ্যমে পড়া যেতে পারে।
মৌলিক অডিও ডেটা প্রক্রিয়াকরণ
LiterRT সাপোর্ট লাইব্রেরি কিছু মৌলিক অডিও ডেটা প্রক্রিয়াকরণ পদ্ধতি মোড়ানো একটি 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 কোয়ান্টাইজড মডেলের জন্য, প্রতিটি বিভাগের জন্য 0 (সম্ভবত কম) থেকে 1 (সম্ভবত সবচেয়ে বেশি) পর্যন্ত সম্ভাব্যতা পেতে ডেভেলপারকে প্রতিটি আউটপুট মানকে 255 দিয়ে ভাগ করতে হবে।
ঐচ্ছিক: লেবেলে ফলাফল ম্যাপ করা
ডেভেলপাররা ঐচ্ছিকভাবে ফলাফলগুলিকে লেবেলে ম্যাপ করতে পারেন। প্রথমে, লেবেলযুক্ত টেক্সট ফাইলটি মডিউলের সম্পদ ডিরেক্টরিতে কপি করুন। এরপর, নিম্নলিখিত কোড ব্যবহার করে লেবেল ফাইলটি লোড করুন:
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();
}
বর্তমান ব্যবহারের ক্ষেত্রে কভারেজ
LiterRT সাপোর্ট লাইব্রেরির বর্তমান সংস্করণে অন্তর্ভুক্ত রয়েছে:
- tflite মডেলের ইনপুট এবং আউটপুট হিসেবে সাধারণ ডেটা টাইপ (float, uint8, ছবি, অডিও এবং এই বস্তুর অ্যারে)।
- মৌলিক চিত্র ক্রিয়াকলাপ (ছবি ক্রপ করুন, আকার পরিবর্তন করুন এবং ঘোরান)।
- স্বাভাবিকীকরণ এবং পরিমাণ নির্ধারণ
- ফাইল ইউটিলিটি
ভবিষ্যতের সংস্করণগুলি টেক্সট-সম্পর্কিত অ্যাপ্লিকেশনগুলির জন্য সমর্থন উন্নত করবে।
ইমেজপ্রসেসর আর্কিটেকচার
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 ইনপুট টেনসরের পরিমাণ নির্ধারণ করতে অথবা আউটপুট টেনসরের পরিমাণ নির্ধারণ করতে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, একটি কোয়ান্টাইজড আউটপুট TensorBuffer প্রক্রিয়াকরণ করার সময়, ডেভেলপার DequantizeOp ব্যবহার করে ফলাফলকে 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);
একটি টেনসরের কোয়ান্টাইজেশন প্যারামিটারগুলি মেটাডেটা এক্সট্র্যাক্টর লাইব্রেরির মাধ্যমে পড়া যেতে পারে।