ใน ep นี้เราจะเรียนรู้การสร้าง App ที่มีความสามารถ Image Classification แบบ Multi-class Classification จำแนกรูปภาพ ด้วย TensorFlow Lite โดยใช้โมเดลที่เราแปลงเตรียมไว้แล้วใน ep ก่อน ซึ่งเป็นโมเดล Convolutional Neural Network จำแนกหมาแมว สำหรับรันบนมือถือ Android ด้วยภาษา Kotlin
Image Classification บนมือถือ Android
เราสามารถพัฒนา App บนมือถือ ให้มีความสามารถด้าน AI / Machine Learning มีฟังก์ชันจำแนกรูปภาพ Image Classification ได้ดังตัวอย่างด้านล่าง
ในเคสนี้ เพื่อให้โค้ดไม่ซับซ้อน เข้าใจง่าย เราจะใช้รูปภาพที่อยู่ใน Resource Bundle ของตัว App เอง ไม่ได้ใช้กล้องมือถือ หรือรูปจาก User
TensorFlow Lite on Android Code Example
นอกจาก build.gradle
โค้ดตัวอย่างจะประกอบด้วย 2 ไฟล์ คือ Classifier.kt
เป็น Utility Class และ ImageClassifierActivity.kt
เป็น UI (Android View)
build.gradle
ใน Build Script เราจะกำหนดค่าสำหรับ dependencies
ไปยัง org.tensorflow:tensorflow-lite:0.0.0-nightly
และ กำหนด aaptOptions
ให้ไม่ต้องบีบอัดไฟล์ FlatBuffer นามสกุล tflite
, lite
ซึ่งเก็บโมเดล TensorFlow Lite
android {
...
aaptOptions {
noCompress "tflite"
noCompress "lite"
}
}
dependencies {
implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly'
}
Classifier.kt
ประกาศฟังก์ชัน loadModelFile
โหลดไฟล์ FlatBuffer นามสกุล .tflite (โมเดล TensorFlow Lite)
private fun loadModelFile(assetManager: AssetManager, modelPath: String): MappedByteBuffer {
val fileDescriptor = assetManager.openFd(modelPath)
val inputStream = FileInputStream(fileDescriptor.fileDescriptor)
return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength)
}
ประกาศฟังก์ชัน loadLabelList
โหลด Label
private fun loadLabelList(assetManager: AssetManager, labelPath: String): List<String> {
return assetManager.open(labelPath).bufferedReader().useLines { it.toList() }
}
ประกาศฟังก์ชัน recognizeImage
ย่อรูปให้อยู่ในขนาดที่โมเดลกำหนด และรัน Intepreter แล้ว return result ไปแสดงบนหน้าจอ
fun recognizeImage(bitmap: Bitmap): List<Recognition> {
val scaledBitmap = Bitmap.createScaledBitmap(bitmap, INPUT_SIZE, INPUT_SIZE, false)
interpreter.run(byteBuffer, result)
return getSortedResult(result)
}
ประกาศ init
Block ที่จะเรียกฟังก์ชันด้านบน เพื่อโหลดข้อมูล กำหนดค่าเริ่มต้นระบบ
init {
val options = Interpreter.Options()
options.setNumThreads(5)
options.setUseNNAPI(true)
interpreter = Interpreter(loadModelFile(assetManager, modelPath), options)
lableList = loadLabelList(assetManager, labelPath)
}
เนื่องจากในเคสนี้เราใช้ Android เราจะเรียก Neural Networks API ของ Android ด้วย options.setUseNNAPI(true)
เพื่อเพิ่มความเร็วของโมเดล Machine Learning ด้วย Neural Networks Hardware, GPU, Digital Signal Processors (DSPs), etc.
ImageClassifierActivity.kt
ประกาศตัวแปร mInputSize
เก็บค่าขนาดรูป mModelPath
ชื่อไฟล์โมเดล TensorFlow Lite และ mLabelPath
ชื่อไฟล์ Label
private val mInputSize = 224
private val mModelPath = "converted_model.tflite"
private val mLabelPath = "label.txt"
overide ฟังก์ชัน onCreate ด้วยโค้ดสำหรับ Initialize หน้าตา Layout ของ App, Classifier และ Bind Event Click/Tap สำหรับรูปต่าง ๆ
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_image_classifier)
initClassifier()
initViews()
}
เมื่อมีการคลิก หรือ Tap เกิดขึ้นกับรูป ให้นำรูปมาส่งให้ classifier
แล้วนำผลลัพธ์ที่ได้มาแสดงบน Toast
override fun onClick(view: View?) {
val bitmap = ((view as ImageView).drawable as BitmapDrawable).bitmap
val result = classifier.recognizeImage(bitmap)
runOnUiThread { Toast.makeText(this, result.get(0).title, Toast.LENGTH_SHORT).show() }
}
เรามาเริ่มกันเลยดีกว่า
Build
Compile และ Build Project
Run on Android Emulator
Deploy บน Android Emulator
Credit
- https://www.coursera.org/learn/device-based-models-tensorflow/
- https://www.tensorflow.org/lite/guide/android
- https://www.tensorflow.org/lite/models