Android ile soruları yanıtlama

Android'de soru yanıtlama örnek uygulaması

Bu eğitimde, doğal dil metninde yapılandırılmış sorulara yanıtlar sağlamak için TensorFlow Lite kullanarak nasıl bir Android uygulaması oluşturulacağı gösterilmektedir. Örnek uygulama, Soru yanıtlama makine öğrenimi modellerini etkinleştirmek için doğal dil (NL) için Görev kitaplığı içindeki BERT soru yanıtlayıcı ( BertQuestionAnswerer ) API'sini kullanır. Uygulama fiziksel bir Android cihazı için tasarlanmıştır ancak aynı zamanda bir cihaz emülatöründe de çalışabilir.

Mevcut bir projeyi güncelliyorsanız örnek uygulamayı referans veya şablon olarak kullanabilirsiniz. Mevcut bir uygulamaya soru yanıtlamanın nasıl ekleneceğine ilişkin talimatlar için Uygulamanızı güncelleme ve değiştirme konusuna bakın.

Soru yanıtlamaya genel bakış

Soru cevaplama, doğal dilde sorulan soruları cevaplamaya yönelik makine öğrenimi görevidir. Eğitimli bir soru cevaplama modeli, girdi olarak bir metin pasajı ve soruyu alır ve pasaj içindeki bilgilerin kendi yorumuna dayanarak soruyu cevaplamaya çalışır.

Soru yanıtlama modeli, okuduğunu anlama veri kümesinin yanı sıra farklı metin bölümlerine dayalı soru-cevap çiftlerinden oluşan bir soru yanıtlama veri kümesi üzerinde eğitilir.

Bu eğitimdeki modellerin nasıl oluşturulduğu hakkında daha fazla bilgi için TensorFlow Lite Model Oluşturucu ile BERT Soru Cevap eğitimine bakın.

Modeller ve veri kümesi

Örnek uygulama, BERT'in (Transformers'tan Çift Yönlü Kodlayıcı Gösterimleri) daha hafif ve daha hızlı bir versiyonu olan Mobil BERT Soru-Cevap ( mobilebert ) modelini kullanır. mobilebert hakkında daha fazla bilgi için MobileBERT: Kaynak Sınırlı Cihazlar için Kompakt Görevden Bağımsız BERT araştırma makalesine bakın.

mobilebert modeli, Wikipedia'daki makalelerden ve her makale için bir dizi soru-cevap çiftinden oluşan bir okuduğunu anlama veri seti olan Stanford Soru Yanıtlama Veri Seti ( SQuAD ) veri seti kullanılarak eğitildi.

Örnek uygulamayı kurun ve çalıştırın

Soru yanıtlama uygulamasını kurmak için örnek uygulamayı GitHub'dan indirin ve Android Studio'yu kullanarak çalıştırın.

Sistem gereksinimleri

  • Android Studio sürüm 2021.1.1 (Bumblebee) veya üzeri.
  • Android SDK sürüm 31 veya üzeri
  • Geliştirici modunun etkin olduğu minimum işletim sistemi sürümü SDK 21'e (Android 7.0 - Nougat) veya bir Android Emulator'a sahip Android cihazı.

Örnek kodu alın

Örnek kodun yerel bir kopyasını oluşturun. Android Studio'da proje oluşturup örnek uygulamayı çalıştırmak için bu kodu kullanacaksınız.

Örnek kodu klonlamak ve ayarlamak için:

  1. Git deposu
    git clone https://github.com/tensorflow/examples.git
    
    klonlayın
  2. İsteğe bağlı olarak git örneğinizi seyrek ödeme kullanacak şekilde yapılandırın, böylece yalnızca soru yanıtlayan örnek uygulamaya ait dosyalara sahip olursunuz:
    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/bert_qa/android
    

Projeyi içe aktarın ve çalıştırın

İndirilen örnek koddan bir proje oluşturun, projeyi derleyin ve ardından çalıştırın.

Örnek kod projesini içe aktarmak ve oluşturmak için:

  1. Android Studio'yu başlatın.
  2. Android Studio'dan Dosya > Yeni > Projeyi İçe Aktar'ı seçin.
  3. build.gradle dosyasını içeren örnek kod dizinine gidin ( .../examples/lite/examples/bert_qa/android/build.gradle ) ve bu dizini seçin.
  4. Android Studio Gradle Sync isterse Tamam'ı seçin.
  5. Android cihazınızın bilgisayarınıza bağlı olduğundan ve geliştirici modunun etkinleştirildiğinden emin olun. Yeşil Run okunu tıklayın.

Doğru dizini seçerseniz Android Studio yeni bir proje oluşturur ve onu derler. Bu işlem, bilgisayarınızın hızına ve Android Studio'yu başka projeler için kullanıp kullanmadığınıza bağlı olarak birkaç dakika sürebilir. Derleme tamamlandığında Android Studio, Derleme Çıktısı durum panelinde OLUŞTURMA BUILD SUCCESSFUL mesajını görüntüler.

Projeyi çalıştırmak için:

  1. Android Studio'dan Run > Run…' ı seçerek projeyi çalıştırın.
  2. Uygulamayı test etmek için bağlı bir Android cihazını (veya emülatörünü) seçin.

Uygulamayı kullanma

Projeyi Android Studio'da çalıştırdıktan sonra uygulama bağlı cihazda veya cihaz emülatöründe otomatik olarak açılır.

Soru cevaplayıcı örnek uygulamasını kullanmak için:

  1. Konu listesinden bir konu seçin.
  2. Önerilen bir soruyu seçin veya metin kutusuna kendi sorunuzu girin.
  3. Modeli çalıştırmak için turuncu oku değiştirin.

Uygulama, sorunun cevabını pasaj metninden belirlemeye çalışır. Model pasaj içinde bir cevap tespit ederse uygulama kullanıcı için ilgili metin aralığını vurgular.

Artık işleyen bir soru cevaplama uygulamanız var. Örnek uygulamanın nasıl çalıştığını ve soru yanıtlama özelliklerinin üretim uygulamalarınıza nasıl uygulanacağını daha iyi anlamak için aşağıdaki bölümleri kullanın:

Örnek uygulama nasıl çalışır?

Uygulama , doğal dil (NL) paketi için Görev kitaplığı içindeki BertQuestionAnswerer API'sini kullanır. MobileBERT modeli TensorFlow Lite Model Maker kullanılarak eğitildi. Uygulama, GPU veya NNAPI temsilcisini kullanarak donanım hızlandırma seçeneğiyle birlikte varsayılan olarak CPU üzerinde çalışır.

Aşağıdaki dosyalar ve dizinler bu uygulama için önemli kodu içerir:

Uygulamanızı değiştirin

Aşağıdaki bölümlerde, örnek uygulamada gösterilen modeli çalıştıracak şekilde kendi Android uygulamanızı değiştirmeye yönelik temel adımlar açıklanmaktadır. Bu talimatlar örnek uygulamayı referans noktası olarak kullanır. Kendi uygulamanız için gereken belirli değişiklikler örnek uygulamadan farklı olabilir.

Bir Android projesi açın veya oluşturun

Bu talimatların geri kalanıyla birlikte takip etmek için Android Studio'da bir Android geliştirme projesine ihtiyacınız var. Mevcut bir projeyi açmak veya yeni bir proje oluşturmak için aşağıdaki talimatları izleyin.

Mevcut bir Android geliştirme projesini açmak için:

  • Android Studio'da Dosya > Aç'ı seçin ve mevcut bir projeyi seçin.

Temel bir Android geliştirme projesi oluşturmak için:

Android Studio'yu kullanma hakkında daha fazla bilgi için Android Studio belgelerine bakın.

Proje bağımlılıkları ekleyin

TensorFlow Lite makine öğrenimi modellerini çalıştırmak ve yardımcı program işlevlerine erişmek için kendi uygulamanıza belirli proje bağımlılıkları ekleyin. Bu işlevler, dizeler gibi verileri, model tarafından işlenebilecek bir tensör veri biçimine dönüştürür. Aşağıdaki talimatlar, gerekli proje ve modül bağımlılıklarını kendi Android uygulama projenize nasıl ekleyeceğinizi açıklamaktadır.

Modül bağımlılıkları eklemek için:

  1. TensorFlow Lite kullanan modülde, modülün build.gradle dosyasını aşağıdaki bağımlılıkları içerecek şekilde güncelleyin.

    Örnek uygulamada bağımlılıklar app/build.gradle konumunda bulunur:

    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'
    }
    

    Projenin Metin görev kitaplığını ( tensorflow-lite-task-text ) içermesi gerekir.

    Bu uygulamayı bir grafik işlem biriminde (GPU) çalışacak şekilde değiştirmek istiyorsanız GPU kitaplığı ( tensorflow-lite-gpu-delegate-plugin ) uygulamayı GPU'da çalıştırmak için altyapıyı sağlar ve Delege ( tensorflow-lite-gpu ) uyumluluk listesini sağlar.

  2. Android Studio'da, şunu seçerek proje bağımlılıklarını senkronize edin: File > Sync Project with Gradle Files .

ML modellerini başlatın

Android uygulamanızda, tahminleri modelle çalıştırmadan önce TensorFlow Lite makine öğrenimi modelini parametrelerle başlatmanız gerekir.

TensorFlow Lite modeli *.tflite dosyası olarak saklanır. Model dosyası tahmin mantığını içerir ve genellikle tahmin sonuçlarının nasıl yorumlanacağına ilişkin meta verileri içerir. Tipik olarak model dosyaları, kod örneğinde olduğu gibi geliştirme projenizin src/main/assets dizininde saklanır:

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

Kolaylık ve kod okunabilirliği için örnek, modelin ayarlarını tanımlayan bir tamamlayıcı nesneyi bildirir.

Modeli uygulamanızda başlatmak için:

  1. Modelin ayarlarını tanımlamak için tamamlayıcı bir nesne oluşturun. Örnek uygulamada bu nesne BertQaHelper.kt'de bulunur:

    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. Bir BertQaHelper nesnesi oluşturarak modelin ayarlarını oluşturun ve bertQuestionAnswerer ile bir TensorFlow Lite nesnesi oluşturun.

    Örnek uygulamada bu, BertQaHelper.kt içindeki setupBertQuestionAnswerer() işlevinde bulunur:

    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)
            }
        }
        ...
        }
    

Donanım hızlandırmayı etkinleştirin (isteğe bağlı)

Uygulamanızda bir TensorFlow Lite modelini başlatırken, modelin tahmin hesaplamalarını hızlandırmak için donanım hızlandırma özelliklerini kullanmayı düşünmelisiniz. TensorFlow Lite delegeleri , grafik işleme birimi (GPU'lar) veya tensör işleme birimleri (TPU'lar) gibi bir mobil cihazda özel işleme donanımını kullanarak makine öğrenimi modellerinin yürütülmesini hızlandıran yazılım modülleridir.

Uygulamanızda donanım hızlandırmayı etkinleştirmek için:

  1. Uygulamanın kullanacağı temsilciyi tanımlamak için bir değişken oluşturun. Örnek uygulamada, bu değişken BertQaHelper.kt dosyasının başında yer almaktadır:

    var currentDelegate: Int = 0
    
  2. Bir temsilci seçici oluşturun. Örnek uygulamada, temsilci seçici BertQaHelper.kt içindeki setupBertQuestionAnswerer işlevinde bulunur:

    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()
        }
    }
    

TensorFlow Lite modellerini çalıştırmak için delegelerin kullanılması önerilir ancak zorunlu değildir. Temsilcileri TensorFlow Lite ile kullanma hakkında daha fazla bilgi için bkz. TensorFlow Lite Temsilcileri .

Model için veri hazırlama

Android uygulamanızda kodunuz, ham metin gibi mevcut verileri modeliniz tarafından işlenebilecek bir Tensor veri formatına dönüştürerek yorumlanmak üzere modele veri sağlar. Bir modele ilettiğiniz Tensörün, modeli eğitmek için kullanılan veri formatıyla eşleşen belirli boyutlara veya şekle sahip olması gerekir. Bu soru yanıtlama uygulaması, dizeleri hem metin pasajı hem de soru için girdi olarak kabul eder. Model, özel karakterleri ve İngilizce olmayan kelimeleri tanımıyor.

Modele pasaj metni verileri sağlamak için:

  1. Pasaj metni verilerini uygulamaya yüklemek için LoadDataSetClient nesnesini kullanın. Örnek uygulamada bu, LoadDataSetClient.kt'de bulunur.

    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. Her metin pasajının başlıklarını listelemek için DatasetFragment nesnesini kullanın ve TFL Soru ve Cevap ekranını başlatın. Örnek uygulamada bu DatasetFragment.kt konumunda bulunur:

    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. Her metin pasajının başlıklarını sunmak için DatasetAdapter nesnesi içindeki onCreateViewHolder işlevini kullanın. Örnek uygulamada bu DatasetAdapter.kt konumunda bulunur:

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

Modele kullanıcı soruları sağlamak için:

  1. Soruyu modele sağlamak için QaAdapter nesnesini kullanın. Örnek uygulamada bu, QaAdapter.kt'de bulunur:

    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
          }
      }
      ...
    }
    

Tahminleri çalıştır

Android uygulamanızda, bir BertQuestionAnswerer nesnesini başlattığınızda, soruları doğal dil metni biçiminde modele girmeye başlayabilirsiniz. Model, metin pasajındaki cevabı tanımlamaya çalışır.

Tahminleri çalıştırmak için:

  1. Modeli çalıştıran ve yanıtı tanımlamak için geçen süreyi ölçen bir answer işlevi oluşturun ( inferenceTime ). Örnek uygulamada answer işlevi BertQaHelper.kt'de bulunmaktadır:

    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. answer sonuçlarını dinleyici nesnesine iletin.

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

Model çıktısını işle

Bir soru girdikten sonra model, pasaj içinde en fazla beş olası cevap sunar.

Modelden sonuçları almak için:

  1. Dinleyici nesnesinin çıktıyı işlemesi için bir onResult işlevi oluşturun. Örnek uygulamada dinleyici nesnesi BertQaHelper.kt'de bulunmaktadır.

    interface AnswererListener {
        fun onError(error: String)
        fun onResults(
            results: List<QaAnswer>?,
            inferenceTime: Long
        )
    }
    
  2. Sonuçlara göre pasajın bölümlerini vurgulayın. Örnek uygulamada bu, QaFragment.kt'de bulunur:

    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
        )
    }
    

Model bir dizi sonuç döndürdüğünde uygulamanız, sonucu kullanıcıya sunarak veya ek mantık yürüterek bu tahminlere göre hareket edebilir.

Sonraki adımlar