Menjawab pertanyaan dengan Android

Contoh aplikasi menjawab pertanyaan di Android

Tutorial ini menunjukkan cara membuat aplikasi Android menggunakan TensorFlow Lite untuk memberikan jawaban atas pertanyaan terstruktur dalam teks bahasa alami. Contoh aplikasi menggunakan API penjawab pertanyaan BERT ( BertQuestionAnswerer ) dalam pustaka Tugas untuk bahasa alami (NL) untuk mengaktifkan model pembelajaran mesin penjawab pertanyaan. Aplikasi ini dirancang untuk perangkat Android fisik tetapi juga dapat dijalankan pada emulator perangkat.

Jika Anda memperbarui proyek yang sudah ada, Anda dapat menggunakan contoh aplikasi sebagai referensi atau templat. Untuk instruksi tentang cara menambahkan jawaban pertanyaan ke aplikasi yang sudah ada, lihat Memperbarui dan memodifikasi aplikasi Anda .

Ikhtisar menjawab pertanyaan

Menjawab pertanyaan adalah tugas pembelajaran mesin untuk menjawab pertanyaan yang diajukan dalam bahasa alami. Model penjawab pertanyaan yang terlatih menerima bagian teks dan pertanyaan sebagai masukan, dan mencoba menjawab pertanyaan berdasarkan interpretasinya terhadap informasi di dalam bagian tersebut.

Model penjawab pertanyaan dilatih pada kumpulan data penjawab pertanyaan, yang terdiri dari kumpulan data pemahaman bacaan beserta pasangan pertanyaan-jawaban berdasarkan segmen teks yang berbeda.

Untuk informasi selengkapnya tentang cara pembuatan model dalam tutorial ini, lihat tutorial BERT Question Answer dengan TensorFlow Lite Model Maker .

Model dan kumpulan data

Contoh aplikasi menggunakan model Mobile BERT Q&A ( mobilebert ), yang merupakan versi BERT (BiDirectional Encoder Representations from Transformers) yang lebih ringan dan lebih cepat. Untuk informasi lebih lanjut tentang mobilebert , lihat MobileBERT: makalah penelitian BERT Task-Agnostic Ringkas untuk Perangkat Terbatas Sumber Daya .

Model mobilebert dilatih menggunakan dataset Stanford Question Answering Dataset ( SQuAD ), yaitu kumpulan data pemahaman bacaan yang terdiri dari artikel dari Wikipedia dan kumpulan pasangan tanya jawab untuk setiap artikel.

Siapkan dan jalankan aplikasi contoh

Untuk menyiapkan aplikasi penjawab pertanyaan, unduh aplikasi contoh dari GitHub dan jalankan menggunakan Android Studio .

Persyaratan sistem

  • Android Studio versi 2021.1.1 (Bumblebee) atau lebih tinggi.
  • Android SDK versi 31 atau lebih tinggi
  • Perangkat Android dengan versi OS minimum SDK 21 (Android 7.0 - Nougat) dengan mode pengembang diaktifkan, atau Android Emulator.

Dapatkan kode contoh

Buat salinan lokal dari kode contoh. Anda akan menggunakan kode ini untuk membuat proyek di Android Studio dan menjalankan aplikasi contoh.

Untuk mengkloning dan mengatur kode contoh:

  1. Kloning repositori git
    git clone https://github.com/tensorflow/examples.git
    
  2. Secara opsional, konfigurasikan instance git Anda untuk menggunakan checkout jarang, sehingga Anda hanya memiliki file untuk aplikasi contoh jawaban pertanyaan:
    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/bert_qa/android
    

Impor dan jalankan proyek

Buat proyek dari kode contoh yang diunduh, buat proyek, lalu jalankan.

Untuk mengimpor dan membuat proyek kode contoh:

  1. Mulai Android Studio .
  2. Dari Android Studio, pilih File > New > Import Project .
  3. Navigasikan ke direktori kode contoh yang berisi file build.gradle ( .../examples/lite/examples/bert_qa/android/build.gradle ) dan pilih direktori tersebut.
  4. Jika Android Studio meminta Sinkronisasi Gradle, pilih OK.
  5. Pastikan perangkat Android Anda terhubung ke komputer dan mode pengembang diaktifkan. Klik panah Run yang berwarna hijau.

Jika Anda memilih direktori yang benar, Android Studio akan membuat proyek baru dan membangunnya. Proses ini dapat memakan waktu beberapa menit, bergantung pada kecepatan komputer Anda dan apakah Anda pernah menggunakan Android Studio untuk proyek lain. Saat build selesai, Android Studio menampilkan pesan BUILD SUCCESSFUL di panel status Build Output .

Untuk menjalankan proyek:

  1. Dari Android Studio, jalankan proyek dengan memilih Run > Run… .
  2. Pilih perangkat Android yang terpasang (atau emulator) untuk menguji aplikasi.

Menggunakan aplikasi

Setelah menjalankan proyek di Android Studio, aplikasi otomatis terbuka di perangkat atau emulator perangkat yang terhubung.

Untuk menggunakan aplikasi contoh penjawab pertanyaan:

  1. Pilih topik dari daftar mata pelajaran.
  2. Pilih pertanyaan yang disarankan atau masukkan pertanyaan Anda sendiri di kotak teks.
  3. Alihkan panah oranye untuk menjalankan model.

Aplikasi ini mencoba mengidentifikasi jawaban atas pertanyaan dari teks bagian. Jika model mendeteksi jawaban dalam bagian tersebut, aplikasi akan menyoroti rentang teks yang relevan bagi pengguna.

Anda sekarang memiliki aplikasi penjawab pertanyaan yang berfungsi. Gunakan bagian berikut untuk lebih memahami cara kerja aplikasi contoh, dan cara mengimplementasikan fitur menjawab pertanyaan di aplikasi produksi Anda:

Cara kerja aplikasi contoh

Aplikasi ini menggunakan API BertQuestionAnswerer dalam paket Task Library for Natural Language (NL) . Model MobileBERT dilatih menggunakan TensorFlow Lite Model Maker . Aplikasi berjalan pada CPU secara default, dengan opsi akselerasi perangkat keras menggunakan delegasi GPU atau NNAPI.

File dan direktori berikut berisi kode penting untuk aplikasi ini:

Ubah aplikasi Anda

Bagian berikut menjelaskan langkah-langkah utama untuk memodifikasi aplikasi Android Anda untuk menjalankan model yang ditunjukkan dalam contoh aplikasi. Petunjuk ini menggunakan aplikasi contoh sebagai titik referensi. Perubahan spesifik yang diperlukan untuk aplikasi Anda mungkin berbeda dari aplikasi contoh.

Buka atau buat proyek Android

Anda memerlukan proyek pengembangan Android di Android Studio untuk mengikuti petunjuk selanjutnya. Ikuti petunjuk di bawah ini untuk membuka proyek yang sudah ada atau membuat proyek baru.

Untuk membuka proyek pengembangan Android yang sudah ada:

  • Di Android Studio, pilih File > Buka dan pilih proyek yang sudah ada.

Untuk membuat proyek pengembangan Android dasar:

Untuk informasi selengkapnya tentang penggunaan Android Studio, lihat dokumentasi Android Studio .

Tambahkan dependensi proyek

Di aplikasi Anda sendiri, tambahkan dependensi proyek tertentu untuk menjalankan model machine learning TensorFlow Lite dan mengakses fungsi utilitas. Fungsi-fungsi ini mengubah data seperti string menjadi format data tensor yang dapat diproses oleh model. Petunjuk berikut menjelaskan cara menambahkan dependensi proyek dan modul yang diperlukan ke proyek aplikasi Android Anda sendiri.

Untuk menambahkan dependensi modul:

  1. Pada modul yang menggunakan TensorFlow Lite, perbarui file build.gradle modul untuk menyertakan dependensi berikut.

    Dalam contoh aplikasi, dependensi terletak di app/build.gradle :

    dependencies {
      ...
      // Import tensorflow library
      implementation 'org.tensorflow:tensorflow-lite-task-text:0.3.0'
    
      // Import the GPU delegate plugin Library for GPU inference
      implementation 'org.tensorflow:tensorflow-lite-gpu-delegate-plugin:0.4.0'
      implementation 'org.tensorflow:tensorflow-lite-gpu:2.9.0'
    }
    

    Proyek harus menyertakan pustaka tugas Teks ( tensorflow-lite-task-text ).

    Jika Anda ingin memodifikasi aplikasi ini agar berjalan pada unit pemrosesan grafis (GPU), pustaka GPU ( tensorflow-lite-gpu-delegate-plugin ) menyediakan infrastruktur untuk menjalankan aplikasi pada GPU, dan Delegate ( tensorflow-lite-gpu ) menyediakan daftar kompatibilitas.

  2. Di Android Studio, sinkronkan dependensi proyek dengan memilih: File > Sync Project with Gradle Files .

Inisialisasi model ML

Di aplikasi Android, Anda harus menginisialisasi model machine learning TensorFlow Lite dengan parameter sebelum menjalankan prediksi dengan model tersebut.

Model TensorFlow Lite disimpan sebagai file *.tflite . File model berisi logika prediksi dan biasanya menyertakan metadata tentang cara menafsirkan hasil prediksi. Biasanya, file model disimpan di direktori src/main/assets proyek pengembangan Anda, seperti pada contoh kode:

  • <project>/src/main/assets/mobilebert_qa.tflite

Untuk kenyamanan dan keterbacaan kode, contoh mendeklarasikan objek pendamping yang menentukan pengaturan model.

Untuk menginisialisasi model di aplikasi Anda:

  1. Buat objek pendamping untuk menentukan pengaturan model. Dalam contoh aplikasi, objek ini terletak di BertQaHelper.kt :

    companion object {
        private const val BERT_QA_MODEL = "mobilebert.tflite"
        private const val TAG = "BertQaHelper"
        const val DELEGATE_CPU = 0
        const val DELEGATE_GPU = 1
        const val DELEGATE_NNAPI = 2
    }
    
  2. Buat pengaturan untuk model dengan membuat objek BertQaHelper , dan membuat objek TensorFlow Lite dengan bertQuestionAnswerer .

    Dalam contoh aplikasi, ini terletak di fungsi setupBertQuestionAnswerer() dalam BertQaHelper.kt :

    class BertQaHelper(
        ...
    ) {
        ...
        init {
            setupBertQuestionAnswerer()
        }
    
        fun clearBertQuestionAnswerer() {
            bertQuestionAnswerer = null
        }
    
        private fun setupBertQuestionAnswerer() {
            val baseOptionsBuilder = BaseOptions.builder().setNumThreads(numThreads)
            ...
            val options = BertQuestionAnswererOptions.builder()
                .setBaseOptions(baseOptionsBuilder.build())
                .build()
    
            try {
                bertQuestionAnswerer =
                    BertQuestionAnswerer.createFromFileAndOptions(context, BERT_QA_MODEL, options)
            } catch (e: IllegalStateException) {
                answererListener
                    ?.onError("Bert Question Answerer failed to initialize. See error logs for details")
                Log.e(TAG, "TFLite failed to load model with error: " + e.message)
            }
        }
        ...
        }
    

Aktifkan akselerasi perangkat keras (opsional)

Saat menginisialisasi model TensorFlow Lite di aplikasi Anda, Anda harus mempertimbangkan penggunaan fitur akselerasi hardware untuk mempercepat penghitungan prediksi model. Delegasi TensorFlow Lite adalah modul perangkat lunak yang mempercepat eksekusi model pembelajaran mesin menggunakan perangkat keras pemrosesan khusus pada perangkat seluler, seperti unit pemrosesan grafis (GPU) atau unit pemrosesan tensor (TPU).

Untuk mengaktifkan akselerasi perangkat keras di aplikasi Anda:

  1. Buat variabel untuk menentukan delegasi yang akan digunakan aplikasi. Dalam contoh aplikasi, variabel ini terletak di awal BertQaHelper.kt :

    var currentDelegate: Int = 0
    
  2. Buat pemilih delegasi. Dalam contoh aplikasi, pemilih delegasi terletak di fungsi setupBertQuestionAnswerer dalam BertQaHelper.kt :

    when (currentDelegate) {
        DELEGATE_CPU -> {
            // Default
        }
        DELEGATE_GPU -> {
            if (CompatibilityList().isDelegateSupportedOnThisDevice) {
                baseOptionsBuilder.useGpu()
            } else {
                answererListener?.onError("GPU is not supported on this device")
            }
        }
        DELEGATE_NNAPI -> {
            baseOptionsBuilder.useNnapi()
        }
    }
    

Disarankan untuk menggunakan delegasi untuk menjalankan model TensorFlow Lite, tetapi tidak wajib. Untuk informasi selengkapnya tentang penggunaan delegasi dengan TensorFlow Lite, lihat Delegasi TensorFlow Lite .

Siapkan data untuk model

Di aplikasi Android, kode Anda menyediakan data ke model untuk diinterpretasikan dengan mengubah data yang ada seperti teks mentah menjadi format data Tensor yang dapat diproses oleh model Anda. Tensor yang Anda teruskan ke model harus memiliki dimensi atau bentuk tertentu yang cocok dengan format data yang digunakan untuk melatih model. Aplikasi penjawab pertanyaan ini menerima string sebagai masukan untuk bagian teks dan pertanyaan. Model tidak mengenali karakter khusus dan kata-kata non-Inggris.

Untuk menyediakan data teks bagian ke model:

  1. Gunakan objek LoadDataSetClient untuk memuat data teks bagian ke aplikasi. Dalam contoh aplikasi, ini terletak di LoadDataSetClient.kt

    fun loadJson(): DataSet? {
        var dataSet: DataSet? = null
        try {
            val inputStream: InputStream = context.assets.open(JSON_DIR)
            val bufferReader = inputStream.bufferedReader()
            val stringJson: String = bufferReader.use { it.readText() }
            val datasetType = object : TypeToken<DataSet>() {}.type
            dataSet = Gson().fromJson(stringJson, datasetType)
        } catch (e: IOException) {
            Log.e(TAG, e.message.toString())
        }
        return dataSet
    }
    
  2. Gunakan objek DatasetFragment untuk mencantumkan judul setiap bagian teks dan memulai layar Tanya Jawab TFL . Dalam contoh aplikasi, ini terletak di DatasetFragment.kt :

    class DatasetFragment : Fragment() {
        ...
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            val client = LoadDataSetClient(requireActivity())
            client.loadJson()?.let {
                titles = it.getTitles()
            }
            ...
        }
       ...
    }
    
  3. Gunakan fungsi onCreateViewHolder dalam objek DatasetAdapter untuk menyajikan judul setiap bagian teks. Dalam contoh aplikasi, ini terletak di DatasetAdapter.kt :

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val binding = ItemDatasetBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return ViewHolder(binding)
    }
    

Untuk memberikan pertanyaan pengguna kepada model:

  1. Gunakan objek QaAdapter untuk memberikan pertanyaan kepada model. Dalam contoh aplikasi, ini terletak di QaAdapter.kt :

    class QaAdapter(private val question: List<String>, private val select: (Int) -> Unit) :
      RecyclerView.Adapter<QaAdapter.ViewHolder>() {
    
      inner class ViewHolder(private val binding: ItemQuestionBinding) :
          RecyclerView.ViewHolder(binding.root) {
          init {
              binding.tvQuestionSuggestion.setOnClickListener {
                  select.invoke(adapterPosition)
              }
          }
    
          fun bind(question: String) {
              binding.tvQuestionSuggestion.text = question
          }
      }
      ...
    }
    

Jalankan prediksi

Di aplikasi Android Anda, setelah menginisialisasi objek BertQuestionAnswerer , Anda bisa mulai memasukkan pertanyaan dalam bentuk teks bahasa alami ke model. Model ini mencoba mengidentifikasi jawaban dalam bagian teks.

Untuk menjalankan prediksi:

  1. Buat fungsi answer , yang menjalankan model dan mengukur waktu yang dibutuhkan untuk mengidentifikasi jawabannya ( inferenceTime ). Pada contoh aplikasi, fungsi answer terletak di BertQaHelper.kt :

    fun answer(contextOfQuestion: String, question: String) {
        if (bertQuestionAnswerer == null) {
            setupBertQuestionAnswerer()
        }
    
        var inferenceTime = SystemClock.uptimeMillis()
    
        val answers = bertQuestionAnswerer?.answer(contextOfQuestion, question)
        inferenceTime = SystemClock.uptimeMillis() - inferenceTime
        answererListener?.onResults(answers, inferenceTime)
    }
    
  2. Berikan hasil dari answer ke objek pendengar.

    interface AnswererListener {
        fun onError(error: String)
        fun onResults(
            results: List<QaAnswer>?,
            inferenceTime: Long
        )
    }
    

Menangani keluaran model

Setelah Anda memasukkan pertanyaan, model memberikan maksimal lima kemungkinan jawaban dalam bagian tersebut.

Untuk mendapatkan hasil dari model:

  1. Buat fungsi onResult untuk objek pendengar guna menangani output. Dalam contoh aplikasi, objek pendengar terletak di BertQaHelper.kt

    interface AnswererListener {
        fun onError(error: String)
        fun onResults(
            results: List<QaAnswer>?,
            inferenceTime: Long
        )
    }
    
  2. Sorot bagian dari bagian tersebut berdasarkan hasil. Dalam contoh aplikasi, ini terletak di QaFragment.kt :

    override fun onResults(results: List<QaAnswer>?, inferenceTime: Long) {
        results?.first()?.let {
            highlightAnswer(it.text)
        }
    
        fragmentQaBinding.tvInferenceTime.text = String.format(
            requireActivity().getString(R.string.bottom_view_inference_time),
            inferenceTime
        )
    }
    

Setelah model mengembalikan serangkaian hasil, aplikasi Anda dapat bertindak berdasarkan prediksi tersebut dengan menyajikan hasilnya kepada pengguna atau menjalankan logika tambahan.

Langkah selanjutnya