מענה על שאלות עם אנדרואיד

אפליקציה לדוגמה לתשובות לשאלות באנדרואיד

מדריך זה מראה לך כיצד לבנות יישום אנדרואיד באמצעות TensorFlow Lite כדי לספק תשובות לשאלות המובנות בטקסט בשפה טבעית. היישום לדוגמה משתמש במשיב השאלות של BERT ( BertQuestionAnswerer ) API בתוך ספריית המשימות לשפה טבעית (NL) כדי לאפשר מודלים של למידה חישובית למענה לשאלות. האפליקציה מיועדת למכשיר אנדרואיד פיזי אך יכולה לרוץ גם על אמולטור מכשיר.

אם אתה מעדכן פרויקט קיים, אתה יכול להשתמש ביישום לדוגמה כהפניה או כתבנית. להנחיות כיצד להוסיף מענה לשאלות ליישום קיים, עיין בעדכון ושינוי היישום שלך .

סקירת מענה לשאלות

מענה לשאלות הוא משימת למידת מכונה של מענה על שאלות המוצגות בשפה טבעית. מודל מענה לשאלות מאומן מקבל קטע טקסט ושאלה כקלט, ומנסה לענות על השאלה על סמך פרשנותו למידע בתוך הקטע.

מודל תשובות לשאלות מאומן על מערך תשובות לשאלות, המורכב ממערך נתונים של הבנת הנקרא יחד עם צמדי שאלות ותשובות המבוססים על מקטעים שונים של טקסט.

למידע נוסף על האופן שבו המודלים במדריך זה נוצרים, עיין במדריך לשאלת BERT עם TensorFlow Lite Model Maker .

מודלים ומערך נתונים

האפליקציה לדוגמה משתמשת במודל Mobile BERT Q&A ( mobilebert ), שהוא גרסה קלה ומהירה יותר של BERT (ייצוגי קודן דו-כיווני מרובוטריקים). למידע נוסף על mobilebert , עיין במאמר המחקר של MobileBERT: a Compact Task-Agnostic BERT for Resource-Limited Devices .

מודל ה- mobilebert הוכשר באמצעות מערך הנתונים של Stanford Question Answering Dataset ( SQuAD ), מערך נתונים של הבנת הנקרא המורכב ממאמרים מויקיפדיה וקבוצה של צמדי שאלות ותשובות לכל מאמר.

הגדר והפעל את האפליקציה לדוגמה

כדי להגדיר את אפליקציית המענה לשאלות, הורד את האפליקציה לדוגמה מ- GitHub והפעל אותה באמצעות Android Studio .

דרישות מערכת

  • Android Studio גרסה 2021.1.1 (Bumblebee) ומעלה.
  • Android SDK גרסה 31 ומעלה
  • מכשיר אנדרואיד עם גרסת מערכת הפעלה מינימלית של SDK 21 (אנדרואיד 7.0 - נוגט) עם מצב מפתחים מופעל, או אמולטור אנדרואיד.

קבל את הקוד לדוגמה

צור עותק מקומי של הקוד לדוגמה. תשתמש בקוד זה כדי ליצור פרויקט ב-Android Studio ולהפעיל את היישום לדוגמה.

כדי לשכפל ולהגדיר את הקוד לדוגמה:

  1. שכפל את מאגר git
    git clone https://github.com/tensorflow/examples.git
    
  2. לחלופין, הגדר את מופע ה-git שלך לשימוש בקופה דלילה, כך שיהיו לך רק את הקבצים עבור אפליקציית המענה לדוגמה:
    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/bert_qa/android
    

ייבוא ​​והפעל את הפרויקט

צור פרוייקט מהקוד לדוגמה שהורד, בנה את הפרוייקט ולאחר מכן הפעל אותו.

כדי לייבא ולבנות את פרויקט הקוד לדוגמה:

  1. הפעל את Android Studio .
  2. מ-Android Studio, בחר קובץ > חדש > ייבוא ​​פרויקט .
  3. נווט אל ספריית הקוד לדוגמה המכילה את הקובץ build.gradle ( .../examples/lite/examples/bert_qa/android/build.gradle ) ובחר את הספרייה הזו.
  4. אם Android Studio מבקש סינכרון Gradle, בחר אישור.
  5. ודא שמכשיר האנדרואיד שלך מחובר למחשב שלך ומצב מפתח מופעל. לחץ על חץ Run הירוק.

אם תבחר את הספרייה הנכונה, Android Studio יוצר פרויקט חדש ובונה אותו. תהליך זה עשוי להימשך מספר דקות, בהתאם למהירות המחשב שלך ואם השתמשת ב-Android Studio עבור פרויקטים אחרים. כאשר הבנייה מסתיימת, ה-Android Studio מציג הודעת BUILD SUCCESSFUL בחלונית סטטוס Build Output .

להפעלת הפרויקט:

  1. מ-Android Studio, הפעל את הפרויקט על ידי בחירה בהפעלה > הפעלה... .
  2. בחר מכשיר אנדרואיד (או אמולטור) מחובר כדי לבדוק את האפליקציה.

שימוש באפליקציה

לאחר הפעלת הפרויקט ב-Android Studio, האפליקציה נפתחת אוטומטית במכשיר המחובר או באמולטור המכשיר.

כדי להשתמש באפליקציית דוגמה למשיב שאלות:

  1. בחר נושא מרשימת הנושאים.
  2. בחר שאלה מוצעת או הזן שאלה משלך בתיבת הטקסט.
  3. החלף את החץ הכתום כדי להפעיל את המודל.

האפליקציה מנסה לזהות את התשובה לשאלה מתוך טקסט הקטע. אם המודל מזהה תשובה בתוך הקטע, האפליקציה מדגישה את טווח הטקסט הרלוונטי עבור המשתמש.

כעת יש לך יישום עונה לשאלות מתפקד. השתמש בסעיפים הבאים כדי להבין טוב יותר כיצד היישום לדוגמה פועל, וכיצד ליישם תכונות מענה לשאלות ביישומי הייצור שלך:

כיצד פועלת האפליקציה לדוגמה

היישום משתמש ב- BertQuestionAnswerer API בתוך חבילת Task library for natural language (NL) . מודל MobileBERT הוכשר באמצעות TensorFlow Lite Model Maker . האפליקציה פועלת על CPU כברירת מחדל, עם אפשרות להאצת חומרה באמצעות נציג ה-GPU או NNAPI.

הקבצים והספריות הבאים מכילים את הקוד החיוני עבור יישום זה:

  • BertQaHelper.kt - מאתחל את משיב השאלה ומטפל בבחירת הדגם והנציג.
  • QaFragment.kt - מטפל ומעצב את התוצאות.
  • MainActivity.kt - מספק את ההיגיון הארגוני של האפליקציה.

שנה את האפליקציה שלך

הסעיפים הבאים מסבירים את השלבים העיקריים לשינוי אפליקציית Android משלך כדי להפעיל את הדגם המוצג באפליקציה לדוגמה. הוראות אלה משתמשות באפליקציה לדוגמה כנקודת התייחסות. השינויים הספציפיים הדרושים לאפליקציה שלך עשויים להשתנות מהאפליקציה לדוגמה.

פתח או צור פרויקט אנדרואיד

אתה צריך פרויקט פיתוח אנדרואיד ב-Android Studio כדי לבצע יחד עם שאר ההוראות האלה. עקוב אחר ההוראות שלהלן כדי לפתוח פרויקט קיים או ליצור פרויקט חדש.

כדי לפתוח פרויקט פיתוח אנדרואיד קיים:

  • ב-Android Studio, בחר קובץ > פתח ובחר פרויקט קיים.

כדי ליצור פרויקט פיתוח בסיסי של אנדרואיד:

למידע נוסף על השימוש ב-Android Studio, עיין בתיעוד של Android Studio .

הוסף תלות בפרויקט

באפליקציה משלך, הוסף תלות ספציפית בפרויקט כדי להפעיל מודלים של למידה חישובית של TensorFlow Lite וגישה לפונקציות שירות. פונקציות אלה ממירות נתונים כגון מחרוזות לפורמט נתוני טנסור שניתן לעבד על ידי המודל. ההוראות הבאות מסבירות כיצד להוסיף את התלות הנדרשת בפרויקט ובמודול לפרויקט אפליקציית Android משלך.

כדי להוסיף תלות במודול:

  1. במודול המשתמש ב-TensorFlow Lite, עדכן את קובץ build.gradle של המודול כך שיכלול את התלות הבאה.

    ביישום לדוגמה, התלות ממוקמות ב- 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'
    }
    

    הפרויקט חייב לכלול את ספריית המשימות Text ( tensorflow-lite-task-text ).

    אם ברצונך לשנות את האפליקציה הזו כך שתפעל על יחידת עיבוד גרפית (GPU), ספריית ה-GPU ( tensorflow-lite-gpu-delegate-plugin ) מספקת את התשתית להפעלת האפליקציה על GPU, ו-Delegate ( tensorflow-lite-gpu ) מספק את רשימת התאימות.

  2. ב-Android Studio, סנכרן את התלות בפרויקט על ידי בחירה: קובץ > סנכרן פרויקט עם קבצי Gradle .

אתחל את דגמי ה-ML

באפליקציית האנדרואיד שלך, עליך לאתחל את מודל הלמידה המכונה TensorFlow Lite עם פרמטרים לפני הפעלת תחזיות עם המודל.

דגם TensorFlow Lite מאוחסן כקובץ *.tflite . קובץ המודל מכיל את היגיון החיזוי ובדרך כלל כולל מטא נתונים לגבי אופן פירוש תוצאות החיזוי. בדרך כלל, קבצי המודל מאוחסנים בספריית src/main/assets של פרויקט הפיתוח שלך, כמו בדוגמה של הקוד:

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

מטעמי נוחות וקריאות קוד, הדוגמה מצהירה על אובייקט נלווה המגדיר את ההגדרות עבור המודל.

כדי לאתחל את הדגם באפליקציה שלך:

  1. צור אובייקט נלווה כדי להגדיר את ההגדרות עבור המודל. ביישום לדוגמה, אובייקט זה ממוקם ב- 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. צור את ההגדרות עבור המודל על ידי בניית אובייקט BertQaHelper , ובניית אובייקט TensorFlow Lite עם bertQuestionAnswerer .

    ביישום לדוגמה, זה ממוקם בפונקציה setupBertQuestionAnswerer() בתוך 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)
            }
        }
        ...
        }
    

אפשר האצת חומרה (אופציונלי)

בעת אתחול מודל TensorFlow Lite באפליקציה שלך, עליך לשקול להשתמש בתכונות האצת חומרה כדי להאיץ את חישובי הניבוי של המודל. נציגי TensorFlow Lite הם מודולי תוכנה המאיצים את הביצוע של מודלים של למידת מכונה באמצעות חומרת עיבוד מיוחדת במכשיר נייד, כגון יחידות עיבוד גרפיות (GPU) או יחידות עיבוד טנזור (TPUs).

כדי להפעיל האצת חומרה באפליקציה שלך:

  1. צור משתנה כדי להגדיר את הנציג שבו האפליקציה תשתמש. ביישום לדוגמה, משתנה זה ממוקם מוקדם ב- BertQaHelper.kt :

    var currentDelegate: Int = 0
    
  2. צור בורר נציגים. ביישום לדוגמה, בורר הנציגים ממוקם בפונקציה setupBertQuestionAnswerer בתוך 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()
        }
    }
    

מומלץ להשתמש בנציגים להפעלת דגמי TensorFlow Lite, אך לא חובה. למידע נוסף על שימוש בנציגים עם TensorFlow Lite, ראה TensorFlow Lite Delegates .

הכן נתונים עבור המודל

באפליקציית Android שלך, הקוד שלך מספק נתונים למודל לצורך פרשנות על ידי הפיכת נתונים קיימים כגון טקסט גולמי לפורמט נתוני Tensor שניתן לעבד על ידי המודל שלך. הטנסור שאתה מעביר למודל חייב להיות בעל ממדים או צורה ספציפיים התואמים את פורמט הנתונים המשמש לאימון המודל. אפליקציית תשובות לשאלות זו מקבלת מחרוזות כקלט הן לקטע הטקסט והן לשאלה. הדגם אינו מזהה תווים מיוחדים ומילים שאינן באנגלית.

כדי לספק נתוני טקסט מעבר למודל:

  1. השתמש באובייקט LoadDataSetClient כדי לטעון את נתוני טקסט הקטע לאפליקציה. ביישום לדוגמה, זה ממוקם ב- 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. השתמש באובייקט DatasetFragment כדי לרשום את הכותרות עבור כל קטע טקסט והתחל את מסך השאלות והתשובה של TFL . ביישום לדוגמה, זה ממוקם ב- 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. השתמש בפונקציה onCreateViewHolder בתוך אובייקט DatasetAdapter כדי להציג את הכותרות עבור כל קטע טקסט. ביישום לדוגמה, זה ממוקם ב- DatasetAdapter.kt :

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

כדי לספק שאלות משתמשים למודל:

  1. השתמש באובייקט QaAdapter כדי לספק את השאלה למודל. ביישום לדוגמה, זה ממוקם ב- 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
          }
      }
      ...
    }
    

הפעל תחזיות

באפליקציית Android שלך, לאחר שאתחול אובייקט BertQuestionAnswerer , תוכל להתחיל להזין שאלות בצורה של טקסט בשפה טבעית למודל. המודל מנסה לזהות את התשובה בתוך קטע הטקסט.

כדי להפעיל תחזיות:

  1. צור פונקציית answer , שמריצה את המודל ומודד את הזמן שלוקח לזיהוי התשובה ( inferenceTime ). ביישום לדוגמה, פונקציית answer ממוקמת ב- 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. העבירו את התוצאות answer לאובייקט המאזין.

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

ידית פלט דגם

לאחר הזנת שאלה, המודל מספק לכל היותר חמש תשובות אפשריות בתוך הקטע.

כדי לקבל את התוצאות מהמודל:

  1. צור פונקציה onResult עבור אובייקט המאזין כדי לטפל בפלט. ביישום לדוגמה, אובייקט המאזין ממוקם ב- BertQaHelper.kt

    interface AnswererListener {
        fun onError(error: String)
        fun onResults(
            results: List<QaAnswer>?,
            inferenceTime: Long
        )
    }
    
  2. הדגש קטעים מהקטע על סמך התוצאות. ביישום לדוגמה, זה ממוקם ב- 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
        )
    }
    

לאחר שהמודל החזיר קבוצה של תוצאות, היישום שלך יכול לפעול על פי התחזיות האלה על ידי הצגת התוצאה למשתמש שלך או הפעלת היגיון נוסף.

הצעדים הבאים