If you want a simple, efficient and flexible way to integrate TensorFlow into your Flutter application, don’t miss the new plugin tflite_FLUTTER that we introduced today. The plugin was developed by Amish Garg, an intern at Google’s Summer of Code(GSoC), in his Medium article titled “Text Categorization using TensorFlow Lite in Flutter”.
The core features of the Tflite_FLUTTER plugin are:
- It provides Dart APIS that are similar to TFLite Java and Swift apis, so the flexibility is exactly the same on those platforms
- Dart: FFI is tied directly to the TensorFlow Lite C API, so it is more efficient than other platform integration approaches.
- You don’t have to write platform-specific code.
- Support for acceleration via NNAPI, using GPU Delegate on Android and Metal Delegate on iOS.
In this article, we will use Tflite_flutter to build a text classification Flutter application to take you through the Tflite_flutter plugin, starting with creating a new Flutter project, text_Classification_app.
Initial Configuration
Linux and Mac users
Copy install.sh to the root directory of your application, and then run sh install.sh in the root directory, in this case, text_Classification_app /.
Windows users
Copy the install.bat file to the application root directory and run the batch file install.bat in the root directory, which is text_Classification_app/in this example.
It automatically downloads the latest binary resource from Release Assets and places it in the specified directory.
Click on the README file for more information about the initial configuration.
To get the plugin
Add tflite_flutter to pubspec.yaml: ^
(details).
Download the model
To run the TensorFlow training model on mobile, we need to use the.tflite format. If you need to know how to convert TensorFlow trained models to.tflite format, please refer to the official guide.
Here we are going to use a pre-trained text classification model from the official TensorFlow site, which can be downloaded here.
The pre-trained model can predict whether the emotion of the current paragraph is positive or negative. It is trained based on the Large Movie Review Dataset V1.0 from Mass et al. The dataset consists of positive or negative labels based on IMDB movie reviews. Click here for more information.
Copy the text_classification. Tflite and text_Classification_vocab. TXT files to the text_Classification_app /assets/ directory.
Add assets/ to the pubspec.yaml file.
assets:
- assets/
Copy the code
Now we’re ready to start writing code. 🚀
Implementation classifier
pretreatment
As mentioned in the text classification model page. You can use the model to classify paragraphs by following these steps:
- The paragraph text is segmented and then converted into a set of term ids using a predefined word collection;
- Enter the generated set of term ids into the TensorFlow Lite model;
- Get the probability that the current paragraph is positive or negative from the output of the model.
We first write a method to partition the raw string using text_classification_vocab.txt as a word collection.
Create a new file classifier.dart under the lib/ folder.
So I’m going to load the text_classiFICation_vocab.txt into the dictionary.
import 'package:flutter/services.dart';
class Classifier {
final _vocabFile = 'text_classification_vocab.txt';
Map<String.int> _dict;
Classifier() {
_loadDictionary();
}
void _loadDictionary() async {
final vocab = await rootBundle.loadString('assets/$_vocabFile');
var dict = <String.int> {};final vocabList = vocab.split('\n');
for (var i = 0; i < vocabList.length; i++) {
var entry = vocabList[i].trim().split(' ');
dict[entry[0]] = int.parse(entry[1]);
}
_dict = dict;
print('Dictionary loaded successfully'); }}Copy the code
Loading the dictionary
Now let’s write a function to partition the raw string.
import 'package:flutter/services.dart';
class Classifier {
final _vocabFile = 'text_classification_vocab.txt';
// Maximum length of a single sentence
final int _sentenceLen = 256;
final String start = '<START>';
final String pad = '<PAD>';
final String unk = '<UNKNOWN>';
Map<String.int> _dict;
List<List<double>> tokenizeInputText(String text) {
// Use Spaces for word segmentation
final toks = text.split(' ');
// Create a list whose length is equal to _sentenceLen and fill it with the corresponding dictionary value of
var vec = List<double>.filled(_sentenceLen, _dict[pad].toDouble());
var index = 0;
if (_dict.containsKey(start)) {
vec[index++] = _dict[start].toDouble();
}
// For each word in the sentence, find the corresponding index value in the dict
for (var tok in toks) {
if (index > _sentenceLen) {
break;
}
vec[index++] = _dict.containsKey(tok)
? _dict[tok].toDouble()
: _dict[unk].toDouble();
}
// Use our interpreter to input the shape we need for our tensor.
return[vec]; }}Copy the code
Analysis was performed using TFLite_FLUTTER
This is the main part of this article, where we discuss the purpose of the tflite_FLUTTER plugin.
Analysis here refers to the process of using the TensorFlow Lite model on the device based on input data. To use the TensorFlow Lite model for analysis, you need to run it through the interpreter to learn more.
Create the interpreter and load the model
Tflite_flutter provides a way to create an interpreter directly from a resource.
static Future<Interpreter> fromAsset(String assetName, {InterpreterOptions options})
Copy the code
Since our model is in assets/, we need to use the above method to create the parser. For instructions for InterpreterOptions, please refer here.
import 'package:flutter/services.dart';
/ / introduce tflite_flutter
import 'package:tflite_flutter/tflite_flutter.dart';
class Classifier {
// The model file name
final _modelFile = 'text_classification.tflite';
// TensorFlow Lite interpreter object
Interpreter _interpreter;
Classifier() {
// Load the model after the classifier is initialized
_loadModel();
}
void _loadModel() async {
// Create the Interpreter using interpreter.fromasset
_interpreter = await Interpreter.fromAsset(_modelFile);
print('Interpreter loaded successfully'); }}Copy the code
Create the code for the interpreter
Tflite_flutter also provides factory constructors to create interpreters if you don’t want to put models in assets/.
Let’s start analyzing!
Now start the analysis with the following method:
void run(Object input, Object output);
Copy the code
Note that the methods here are the same as in the Java API.
Object Input and Object Output have to be lists that have the same dimension as input Tensor and output Tensor.
To view the dimensions of input tensors and output tensors, you can use the following code:
_interpreter.allocateTensors();
// Print the input tensor list
print(_interpreter.getInputTensors());
// Prints the output tensor list
print(_interpreter.getOutputTensors());
Copy the code
In this example, the output of the Text_classification model is as follows:
InputTensorList:
[Tensor{_tensor: Pointer<TfLiteTensor>: address=0xbffcf280, name: embedding_input, type: TfLiteType.float32, shape: [1, 256], data: 1024]
OutputTensorList:
[Tensor{_tensor: Pointer<TfLiteTensor>: address=0xbffcf140, name: dense_1/Softmax, type: TfLiteType.float32, shape: [1, 2], data: 8]
Copy the code
Now, we implement a classification method that returns 1 for positive and 0 for negative.
int classify(String rawText) {
// tokenizeInputText returns List
> of shape [1, 256]
List<List<double>> input = tokenizeInputText(rawText);
// output of the [1,2] shape
var output = List<double> (2).reshape([1.2]);
// The run method runs the analysis and stores the output value
_interpreter.run(input, output);
var result = 0;
// If the value of the first element in the output is greater than that of the second, the sentence is negative
if ((output[0] [0] as double) > (output[0] [1] as double)) {
result = 0;
} else {
result = 1;
}
return result;
}
Copy the code
Code for analysis
The extension ListShape on List of tflite_FLUTTER defines some extensions to use:
// Matrix deform the supplied list, taking the total number of elements as the input parameter // keeping it equal
List(400).0
/ / return the List < dynamic >
List reshape(List<int> shape)
// Return the list shape
List<int> get shape
// Returns the number of elements of any shape in the list
int get computeNumElements
Copy the code
The final classifier.dart should look like this:
import 'package:flutter/services.dart';
/ / introduce tflite_flutter
import 'package:tflite_flutter/tflite_flutter.dart';
class Classifier {
// The model file name
final _modelFile = 'text_classification.tflite';
final _vocabFile = 'text_classification_vocab.txt';
// The maximum length of the statement
final int _sentenceLen = 256;
final String start = '<START>';
final String pad = '<PAD>';
final String unk = '<UNKNOWN>';
Map<String.int> _dict;
// TensorFlow Lite interpreter object
Interpreter _interpreter;
Classifier() {
// Load the model when the classifier is initialized
_loadModel();
_loadDictionary();
}
void _loadModel() async {
// Create a parser with intepreter.fromasset
_interpreter = await Interpreter.fromAsset(_modelFile);
print('Interpreter loaded successfully');
}
void _loadDictionary() async {
final vocab = await rootBundle.loadString('assets/$_vocabFile');
var dict = <String.int> {};final vocabList = vocab.split('\n');
for (var i = 0; i < vocabList.length; i++) {
var entry = vocabList[i].trim().split(' ');
dict[entry[0]] = int.parse(entry[1]);
}
_dict = dict;
print('Dictionary loaded successfully');
}
int classify(String rawText) {
// tokenizeInputText returns List
> of shape [1, 256]
List<List<double>> input = tokenizeInputText(rawText);
// Output the matrix of shape [1, 2]
var output = List<double> (2).reshape([1.2]);
// The run method runs the analysis and stores the results in output.
_interpreter.run(input, output);
var result = 0;
If the output of the first element is larger than the output of the second, the current statement is negative
if ((output[0] [0] as double) > (output[0] [1] as double)) {
result = 0;
} else {
result = 1;
}
return result;
}
List<List<double>> tokenizeInputText(String text) {
// use Spaces to break words
final toks = text.split(' ');
// Create a list whose length is equal to _sentenceLen and fill it with the dictionary value corresponding to
var vec = List<double>.filled(_sentenceLen, _dict[pad].toDouble());
var index = 0;
if (_dict.containsKey(start)) {
vec[index++] = _dict[start].toDouble();
}
// For each word in the sentence, find the corresponding index value in the dict
for (var tok in toks) {
if (index > _sentenceLen) {
break;
}
vec[index++] = _dict.containsKey(tok)
? _dict[tok].toDouble()
: _dict[unk].toDouble();
}
// Use our interpreter to input the shape we need for our tensor.
return[vec]; }}Copy the code
Now that you can code the UI to your liking, the classifier is simple to use.
// Create the Classifier object
Classifer _classifier = Classifier();
// Call the classify method with the target statement as an argument
_classifier.classify("I liked the movie");
// Return 1 (active)
_classifier.classify("I didn't liked the movie");
// Return 0 (negative)
Copy the code
See the full code here: Text Classification Example app with UI
Example application of text classification
For more information about the Tflite_flutter_plugin, visit GitHub repo: am15h/ tflite_Flutter_plugin.
Answering questions
Q:tflite_flutter
和 Tflite v1.0.5
What are the differences?
Tflite V1.0.5 focuses on advanced features for application-specific scenarios, such as image classification, object detection, and so on. The new Tflite_FLUTTER offers the same features and flexibility as the Java API, and can be used in any TFlite model. It also supports delegates.
Because dart: FFI (DART ↔️ (FFI) ↔️ C) is used, tFLite_FLUTTER is very fast (with low latency). Tflite uses platform integration (Dart ↔️ platform-channel ↔️ (Java/Swift) ↔️ JNI ↔️ C).
Q: How do I create an image classification application using Tflite_FLUTTER? Is there anything likeTensorFlow Lite Android Support LibraryDependency packages?
Update (07/01/2020) : The TFLite Flutter Helper development library has been released.
The TensorFlow Lite Flutter Helper Library provides an easy-to-use architecture for handling and controlling the inputs and outputs of TFLite models. Its API design and documentation are the same as the TensorFlow Lite Android Support Library. See here for more information.
This is the end of this article. Your feedback on tflite_FLUTTER is welcome. Please report any bugs or feature requirements here.
Thank you for your attention.
Michael Thomsen.
Thank you
- Translation: Yuan, Gu Chuang subtitle group
- Review: Xinlei, Lynn Wang, Alex, CFUG Community.
This article is published on the TensorFlow online discussion forum, 101.dev and the Flutter Chinese documentation, as well as the Flutter community online.