Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ko/lite/android/tutorials/text_classification.md
25118 views

Android๋ฅผ ์ด์šฉํ•œ ํ…์ŠคํŠธ ๋ถ„๋ฅ˜

์ด ํŠœํ† ๋ฆฌ์–ผ์€ TensorFlow Lite๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์—ฐ์–ด ํ…์ŠคํŠธ๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋Š” Android ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์—ฌ๋Ÿฌ๋ถ„์—๊ฒŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์‹ค์ œ Android ๊ธฐ๊ธฐ๋ฅผ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์ง€๋งŒ ๊ธฐ๊ธฐ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ๋„ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ TensorFlow Lite๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…์ŠคํŠธ๋ฅผ ๊ธ์ •(positive) ๋˜๋Š” ๋ถ€์ •(negative)์œผ๋กœ ๋ถ„๋ฅ˜ํ•˜๊ณ , ์ž์—ฐ์–ด(NL)๋ฅผ ์œ„ํ•œ ์ž‘์—… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์กด ํ”„๋กœ์ ํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ค‘์ด๋ผ๋ฉด ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ฐธ์กฐ ๋˜๋Š” ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํ…์ŠคํŠธ ๋ถ„๋ฅ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ง€์นจ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์—…๋ฐ์ดํŠธ ๋ฐ ์ˆ˜์ •์„ ์ฐธ์กฐํ•˜์„ธ์š”.

ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ๊ฐœ์š”

ํ…์ŠคํŠธ ๋ถ„๋ฅ˜๋Š” ์ผ๋ จ์˜ ์‚ฌ์ „ ์ •์˜๋œ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ๊ฐœ๋ฐฉํ˜• ํ…์ŠคํŠธ์— ํ• ๋‹นํ•˜๋Š” ๋จธ์‹ ๋Ÿฌ๋‹ ์ž‘์—…์ž…๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ๋ชจ๋ธ์€ ๋‹จ์–ด ๋˜๋Š” ๊ตฌ์ ˆ์ด ์ˆ˜๋™์œผ๋กœ ๋ถ„๋ฅ˜๋œ ์ž์—ฐ์–ด ํ…์ŠคํŠธ ๋ง๋ญ‰์น˜์—์„œ ํ›ˆ๋ จ๋ฉ๋‹ˆ๋‹ค.

ํ›ˆ๋ จ๋œ ๋ชจ๋ธ์€ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ  ๋ถ„๋ฅ˜๋ฅผ ์œ„ํ•ด ํ›ˆ๋ จ๋œ ์•Œ๋ ค์ง„ ํด๋ž˜์Šค์˜ ์ง‘ํ•ฉ์— ๋”ฐ๋ผ ํ…์ŠคํŠธ๋ฅผ ๋ฒ”์ฃผํ™”ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์˜ˆ์ œ์˜ ๋ชจ๋ธ์€ ํ…์ŠคํŠธ์˜ (์ฝ”๋“œ)์กฐ๊ฐ์„ ๋ฐ›์•„๋“ค์ด๊ณ  ํ…์ŠคํŠธ์˜ ๊ฐ์„ฑ์ด ๊ธ์ •(positive)์ธ์ง€ ๋ถ€์ •(negative)์ธ์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ํ…์ŠคํŠธ (์ฝ”๋“œ)์กฐ๊ฐ์˜ ๊ฒฝ์šฐ, ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ๋ชจ๋ธ์€ ๊ธ์ •(positive) ๋˜๋Š” ๋ถ€์ •(negative)์œผ๋กœ ํ…์ŠคํŠธ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ถ„๋ฅ˜๋˜์—ˆ๋Š”์ง€ ์‹ ๋ขฐ๋„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

์ด ํŠœํ† ๋ฆฌ์–ผ์˜ ๋ชจ๋ธ์ด ๋งŒ๋“ค์–ด์ง„ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ์ •๋ณด๋Š” TensorFlow Lite Model Maker๋ฅผ ์ด์šฉํ•œ ํ…์ŠคํŠธ ๋ถ„๋ฅ˜๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ชจ๋ธ ๋ฐ ๋ฐ์ดํ„ฐ์„ธํŠธ

์ด ํŠœํ† ๋ฆฌ์–ผ์€ SST-2(Stanford Sentiment Treebank) ๋ฐ์ดํ„ฐ์„ธํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ํ›ˆ๋ จ๋œ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. SST-2์—๋Š” ๊ฐ ๋ฆฌ๋ทฐ๊ฐ€ ๊ธ์ •(positive) ๋˜๋Š” ๋ถ€์ •(negative)์œผ๋กœ ๋ฒ”์ฃผํ™”๋œ ํ›ˆ๋ จ์„ ์œ„ํ•œ 67,349๊ฐœ์˜ ์˜ํ™” ๋ฆฌ๋ทฐ์™€ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ 872๊ฐœ์˜ ์˜ํ™” ๋ฆฌ๋ทฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์•ฑ์— ์‚ฌ์šฉ๋œ ๋ชจ๋ธ์€ TensorFlow Lite Model Maker ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด ํ›ˆ๋ จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌ์ „ ํ›ˆ๋ จ๋œ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • Average Word Vector (NLClassifier) - ์ž‘์—… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ NLClassifier๋Š” ์ž…๋ ฅ ํ…์ŠคํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒ”์ฃผ๋กœ ๋ถ„๋ฅ˜ํ•˜๋ฉฐ ๋Œ€๋ถ€๋ถ„์˜ ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ๋ชจ๋ธ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • MobileBERT (BertNLClassifier) - ์ž‘์—… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ BertNLClassifier๋Š” NLClassifier์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ, ์ฒ ์ž ์™ธ Wordpiece๋ฐ Sentencepiece ํ† ํฐํ™”๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ๋งž์ถฐ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.

์„ค์น˜ ๋ฐ ์˜ˆ์ œ ์•ฑ ์‹คํ–‰

ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค์น˜ํ•˜๋ ค๋ฉด GitHub์—์„œ ์˜ˆ์ œ ์•ฑ์„ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  Android Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ์š”๊ตฌ ์‚ฌํ•ญ

  • Android Studio ๋ฒ„์ „ 2021.1.1(Bumblebee) ์ด์ƒ

  • Android SDK ๋ฒ„์ „ 31 ์ด์ƒ

  • ๊ฐœ๋ฐœ์ž ๋ชจ๋“œ๊ฐ€ ํ™œ์„ฑํ™”๋œ ์ƒํƒœ๋กœ ์ตœ์†Œ OS ๋ฒ„์ „์˜ SDK 21(Android 7.0 - Nougat)๊ฐ€ ์„ค์น˜๋œ Android ๊ธฐ๊ธฐ ๋˜๋Š” Android Emulator.

์˜ˆ์ œ ์ฝ”๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ

์˜ˆ์ œ ์ฝ”๋“œ์˜ ๋กœ์ปฌ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 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/text_classification/android
         

ํ”„๋กœ์ ํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ์‹คํ–‰ํ•˜๊ธฐ

๋‹ค์šด๋กœ๋“œํ•œ ์˜ˆ์ œ ์ฝ”๋“œ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•œ ํ›„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๋นŒ๋“œํ•˜๋ ค๋ฉด:

  1. Android Studio๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  2. Android ์ŠคํŠœ๋””์˜ค์—์„œ **File(ํŒŒ์ผ) > New(์ƒˆ๋กœ ๋งŒ๋“ค๊ธฐ) > Import Project(ํ”„๋กœ์ ํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ)**๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  3. build.gradle ํŒŒ์ผ(.../examples/lite/examples/text_classification/android/build.gradle)์ด ํฌํ•จ๋œ ์˜ˆ์ œ ์ฝ”๋“œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™ํ•˜์—ฌ ํ•ด๋‹น ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  4. Android Studio์—์„œ Gradle ๋™๊ธฐํ™”๋ฅผ ์š”์ฒญํ•˜๋ฉด OK(ํ™•์ธ)๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  5. Android ๊ธฐ๊ธฐ๊ฐ€ ์ปดํ“จํ„ฐ์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ  ๊ฐœ๋ฐœ์ž ๋ชจ๋“œ๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋…น์ƒ‰ Run ํ™”์‚ดํ‘œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

์˜ฌ๋ฐ”๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์„ ํƒํ•˜๋ฉด Android Studio์—์„œ ์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์„ธ์Šค๋Š” ์ปดํ“จํ„ฐ ์†๋„์™€ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์— Android Studio๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋ช‡ ๋ถ„์ด ์†Œ์š”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด Android Studio๊ฐ€ ๋นŒ๋“œ ์ถœ๋ ฅ ์ƒํƒœ ํŒจ๋„์— BUILD SUCCESSFUL ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด:

  1. Android Studio์—์„œ **Run(์‹คํ–‰) > Run(์‹คํ–‰)โ€ฆ**์„ ์„ ํƒํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  2. ์—ฐ๊ฒฐ๋œ Android ๊ธฐ๊ธฐ(๋˜๋Š” ์—๋ฎฌ๋ ˆ์ดํ„ฐ)๋ฅผ ์„ ํƒํ•˜์—ฌ ์•ฑ์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‚ฌ์šฉํ•˜๊ธฐ

Android์˜ ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ์˜ˆ์ œ ์•ฑ{: .attempt-right width="250px"}

Android Studio์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•œ ํ›„, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์—ฐ๊ฒฐ๋œ ๊ธฐ๊ธฐ ๋˜๋Š” ๊ธฐ๊ธฐ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์ž๋™์œผ๋กœ ์—ด๋ฆฝ๋‹ˆ๋‹ค.

ํ…์ŠคํŠธ ๋ถ„๋ฅ˜์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. ํ…์ŠคํŠธ ์ƒ์ž์˜ ํ…์ŠคํŠธ (์ฝ”๋“œ) ์กฐ๊ฐ์„ ์ž…๋ ฅํ•˜์„ธ์š”.

  2. Delegate(๋Œ€๋ฆฌ์ž) ๋“œ๋กญ๋‹ค์šด์—์„œCPU ๋˜๋Š” NNAPI๋ฅผ ์„ ํƒํ•˜์„ธ์š”.

  3. AverageWordVec ๋˜๋Š” MobileBERT๋ฅผ ์„ ํƒํ•˜์—ฌ ๋ชจ๋ธ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

  4. **Classify(๋ถ„๋ฅ˜)**๋ฅผ ์„ ํƒํ•˜์„ธ์š”.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ธ์ •(positive) ์ ์ˆ˜์™€ ๋ถ€์ •(negative) ์ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋‘ ์ ์ˆ˜๋Š” ํ•ฉ๊ณ„๊ฐ€ 1์ด ๋˜๋ฉฐ ์ž…๋ ฅ ํ…์ŠคํŠธ์˜ ๊ฐ์ •์ด ๊ธ์ •(positive) ๋˜๋Š” ๋ถ€์ •(negative)์ธ์ง€ ๊ฐ€๋Šฅ์„ฑ์„ ์ธก์ •ํ•ฉ๋‹ˆ๋‹ค. ๋†’์€ ์ˆซ์ž๋Š” ์‹ ๋ขฐ๋„ ์ˆ˜์ค€์ด ๋†’๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์ž‘๋™ํ•˜๋Š” ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ๊ธฐ๋Šฅ์„ ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ๋•์…˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋” ์ž˜ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ์„น์…˜์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

์˜ˆ์žฌ ์•ฑ ์ž‘๋™ ๋ฐฉ๋ฒ• {:#how_it_works}

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ž์—ฐ์–ด(NL)๋ฅผ ์œ„ํ•œ ์ž‘์—… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ๋ชจ๋ธ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. Average Word Vector์™€ MobileBERT ๋‘ ๋ชจ๋ธ์€ TensorFlow Lite Model Maker๋ฅผ ์‚ฌ์šฉํ•ด ํ›ˆ๋ จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ NNAPI ๋Œ€๋ฆฌ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ์˜ต์…˜์„ ํ†ตํ•ด ๊ธฐ๋ณธ์œผ๋กœ CPU์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํŒŒ์ผ๊ณผ ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” ์ด ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ ์ฃผ์š” ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

  • TextClassificationHelper.kt - ํ…์ŠคํŠธ ๋ถ„๋ฅ˜์ž๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ๋ชจ๋ธ ๋ฐ ๋Œ€๋ฆฌ์ž ์„ ํƒ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • MainActivity.kt - TextClassificationHelper ๋ฐ ResultsAdapter ํ˜ธ์ถœ์„ ํฌํ•จํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

  • ResultsAdapter.kt - ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ํฌ๋งทํ•ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ • {:#modify_applications}

๋‹ค์Œ ์„น์…˜์€ ์˜ˆ์ œ ์•ฑ์— ํ‘œ์‹œ๋œ ๋ชจ๋ธ์„ ์‹คํ–‰ํ•˜๋„๋ก ์ž์‹ ์˜ Android ์•ฑ์„ ์ˆ˜์ •ํ•˜๋Š” ์ฃผ์š” ๋‹จ๊ณ„๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ง€์นจ์€ ์˜ˆ์ œ ์•ฑ์„ ์ฐธ์กฐ ํฌ์ธํŠธ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž์‹ ์˜ ์•ฑ์— ํ•„์š”ํ•œ ํŠน์ • ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์˜ˆ์ œ ์•ฑ๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Android ํ”„๋กœ์ ํŠธ ์—ด๊ธฐ ๋˜๋Š” ๋งŒ๋“ค๊ธฐ

๋‚˜๋จธ์ง€ ์ง€์นจ์„ ๋”ฐ๋ฅด๋ ค๋ฉด Android Studio์˜ Android ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์ง€์นจ์„ ๋”ฐ๋ผ ๊ธฐ์กด์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ์„ธ์š”.

๊ธฐ์กด Android ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ ์—ด๊ธฐ

  • Android Studio์—์„œ *File(ํŒŒ์ผ) > Open(์—ด๊ธฐ)*๋ฅผ ์„ ํƒํ•˜๊ณ  ๊ธฐ์กด ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ Android ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ

Android Studio๋ฅผ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ์ •๋ณด๋Š” Android Studio ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

ํ”„๋กœ์ ํŠธ ์ข…์†์„ฑ ์ถ”๊ฐ€

์ž์‹ ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ TensorFlow Lite ๋จธ์‹  ๋Ÿฌ๋‹ ๋ชจ๋ธ์„ ์‹คํ–‰ํ•˜๊ณ  ๋ฌธ์ž์—ด๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ ์ค‘์ธ ๋ชจ๋ธ์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ…์„œ ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ธฐ๋Šฅ์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ํŠน์ • ํ”„๋กœ์ ํŠธ ์ข…์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์ง€์นจ์€ ํ•„์š”ํ•œ ํ”„๋กœ์ ํŠธ ๋ฐ ๋ชจ๋“ˆ ์ข…์†์„ฑ์„ ์ž์‹ ์˜ Android ์•ฑ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“ˆ ์ข…์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด:

  1. TensorFlow Lite๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“ˆ์—์„œ ๋ชจ๋“ˆ์˜ build.gradle ํŒŒ์ผ์„ ๋‹ค์Œ ์ข…์†์„ฑ์„ ํฌํ•จํ•˜๋„๋ก ์—…๋ฐ์ดํŠธํ•˜์„ธ์š”.

    ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ, ์ข…์†์„ฑ์€ app/build.gradle์— ์žˆ์Šต๋‹ˆ๋‹ค.

    dependencies { ... implementation 'org.tensorflow:tensorflow-lite-task-text:0.4.0' }

    ํ”„๋กœ์ ํŠธ๋Š” ํ…์ŠคํŠธ ์ž‘์—… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(tensorflow-lite-task-text)๋ฅผ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ์ด ์•ฑ์„ ๊ทธ๋ž˜ํ”ฝ ์ฒ˜๋ฆฌ ์žฅ์น˜(GPU)๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ์ˆ˜์ •ํ•˜๋ ค๋ฉด, GPU ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(tensorflow-lite-gpu-delegate-plugin)๋Š” GPU์—์„œ ์•ฑ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ”„๋ผ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋Œ€๋ฆฌ์ž(tensorflow-lite-gpu)๋Š” ํ˜ธํ™˜์„ฑ ๋ชฉ๋ก์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. GPU์—์„œ ์ด ์•ฑ์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์ด ํŠœํ† ๋ฆฌ์–ผ ๋ฒ”์œ„๋ฅผ ๋„˜์–ด์„ญ๋‹ˆ๋‹ค.

  2. Android Studio์—์„œ **File(ํŒŒ์ผ) > Sync Project with Gradle Files(ํ”„๋กœ์ ํŠธ๋ฅผ Gradle ํŒŒ์ผ๊ณผ ๋™๊ธฐํ™”)**๋ฅผ ์„ ํƒํ•˜์—ฌ ํ”„๋กœ์ ํŠธ ์ข…์†์„ฑ์„ ๋™๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

ML ๋ชจ๋ธ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ {:#initialize_models}

Android ์•ฑ์—์„œ, ๋ชจ๋ธ๋กœ ์˜ˆ์ธก์„ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด TensorFlow Lite ๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ์„ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

TensorFlow Lite ๋ชจ๋ธ์€ *.tflite ํŒŒ์ผ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋ธ ํŒŒ์ผ์€ ์˜ˆ์ธก ๋…ผ๋ฆฌ๊ฐ€ ํฌํ•จ๋˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ์˜ˆ์ธก ํด๋ž˜์Šค ์ด๋ฆ„๊ณผ ๊ฐ™์€ ์˜ˆ์ธก ๊ฒฐ๊ณผ๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ, ๋ชจ๋ธ ํŒŒ์ผ์€ ์ฝ”๋“œ ์˜ˆ์ œ์™€ ๊ฐ™์ด ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ์˜ src/main/assets ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

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

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

์ฐธ๊ณ : ์˜ˆ์ œ ์•ฑ์€ [download_model.gradle](https://github.com/tensorflow/examples/blob/master/lite/examples/text_classification/android/app/download_model.gradle) ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ• ์‹œ Average Word Vector์™€ MobileBERT ๋ชจ๋ธ์„ ๋‹ค์šด๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ๋ฒ•์€ ํ”„๋กœ๋•์…˜ ์•ฑ์— ํ•„์š”ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŽธ์˜์™€ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ์ด ์˜ˆ์ œ์—์„œ๋Š” ๋ชจ๋ธ์— ๋Œ€ํ•œ ์„ค์ •์„ ์ •์˜ํ•˜๋Š” ์ปดํŒจ๋‹ˆ์–ธ ๊ฐ์ฒด๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

์•ฑ์—์„œ ๋ชจ๋ธ์„ ์ดˆ๊ธฐํ™”ํ•˜๋ ค๋ฉด:

  1. ๋™๋ฐ˜ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋ชจ๋ธ์— ๋Œ€ํ•œ ์„ค์ •์„ ์ •์˜ํ•˜์„ธ์š”. ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ด ๊ฐ์ฒด๋Š” TextClassificationHelper.kt์— ์žˆ์Šต๋‹ˆ๋‹ค.

    companion object { const val DELEGATE_CPU = 0 const val DELEGATE_NNAPI = 1 const val WORD_VEC = "wordvec.tflite" const val MOBILEBERT = "mobilebert.tflite" }
  2. ๋ถ„๋ฅ˜์ž ๊ฐ์ฒด๋ฅผ ๊ตฌ์ถ•ํ•ด ๋ชจ๋ธ์— ๋Œ€ํ•œ ์„ค์ •์„ ๋งŒ๋“ค๊ณ  BertNLClassifier ๋˜๋Š” NLClassifier๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ TensorFlow Lite ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ, ์ด๊ฒƒ์€ TextClassificationHelper.kt์˜ initClassifier ํ•จ์ˆ˜์— ์žˆ์Šต๋‹ˆ๋‹ค.

    fun initClassifier() { ... if( currentModel == MOBILEBERT ) { ... bertClassifier = BertNLClassifier.createFromFileAndOptions( context, MOBILEBERT, options) } else if (currentModel == WORD_VEC) { ... nlClassifier = NLClassifier.createFromFileAndOptions( context, WORD_VEC, options) } }

    ์ฐธ๊ณ : ํ…์ŠคํŠธ ๋ถ„๋ฅ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๋•์…˜ ์•ฑ์€ BertNLClassifier ๋˜๋Š” NLClassifier๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค(๋‘ ๊ฐ€์ง€ ๋ชจ๋‘๋Š” ์•„๋‹˜).

ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ์‚ฌ์šฉ(์„ ํƒ ์‚ฌํ•ญ) {:#hardware_acceleration}

์•ฑ์—์„œ TensorFlow Lite ๋ชจ๋ธ์„ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋ธ์˜ ์˜ˆ์ธก ๊ณ„์‚ฐ ์†๋„๋ฅผ ๋†’์ด๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. TensorFlow Lite ๋Œ€๋ฆฌ์ž๋Š” GPU(๊ทธ๋ž˜ํ”ฝ ์ฒ˜๋ฆฌ ์žฅ์น˜) ๋˜๋Š” TPU(ํ…์„œ ์ฒ˜๋ฆฌ ์žฅ์น˜)์™€ ๊ฐ™์€ ๋ชจ๋ฐ”์ผ ์žฅ์น˜์˜ ํŠน์ˆ˜ ์ฒ˜๋ฆฌ ํ•˜๋“œ์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋จธ์‹  ๋Ÿฌ๋‹ ๋ชจ๋ธ์˜ ์‹คํ–‰์„ ๊ฐ€์†ํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค.

์•ฑ์—์„œ ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ์‚ฌ์šฉํ•˜๊ธฐ

  1. ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉํ•  ๋Œ€๋ฆฌ์ž๋ฅผ ์ •์˜ํ•˜์„ธ์š”. ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ, ์ด ๋ณ€์ˆ˜๋Š” TextClassificationHelper.kt์˜ ์ดˆ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค.

    var currentDelegate: Int = 0
  2. ๋Œ€๋ฆฌ์ž ์„ ํƒ์ž๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ, ๋Œ€๋ฆฌ์ž ์„ ํƒ์ž๋Š” TextClassificationHelper.kt์˜ initClassifier ํ•จ์ˆ˜์— ์žˆ์Šต๋‹ˆ๋‹ค.

    val baseOptionsBuilder = BaseOptions.builder() when (currentDelegate) { DELEGATE_CPU -> { // Default } DELEGATE_NNAPI -> { baseOptionsBuilder.useNnapi() } }

์ฐธ๊ณ : ์ด ์•ฑ์„ ์ˆ˜์ •ํ•˜์—ฌ GPU ๋Œ€๋ฆฌ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์€ ๋ถ„๋ฅ˜์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ™์€ ์Šค๋ ˆ๋“œ์—์„œ ์ƒ์„ฑ๋œ ๋ถ„๋ฅ˜์ž๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ด ํŠœํ† ๋ฆฌ์–ผ์˜ ๋ฒ”์œ„์—์„œ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค.

TensorFlow Lite ๋ชจ๋ธ ์‹คํ–‰์— ๋Œ€๋ฆฌ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋˜์ง€๋งŒ ํ•„์ˆ˜๋Š” ์•„๋‹™๋‹ˆ๋‹ค. TensorFlow Lite์—์„œ ๋Œ€๋ฆฌ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ TensorFlow Lite ๋Œ€๋ฆฌ์ž๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ชจ๋ธ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ์ค€๋น„ํ•˜๊ธฐ

Android ์•ฑ์—์„œ ์ฝ”๋“œ๋Š” ๋กœ์šฐ ํ…์ŠคํŠธ์™€ ๊ฐ™์€ ๊ธฐ์กด ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋ธ์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ…์„œ ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ํ•ด์„์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ชจ๋ธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋ธ๋กœ ์ „๋‹ฌ๋˜๋Š” ํ…์„œ์˜ ๋ฐ์ดํ„ฐ์—๋Š” ๋ชจ๋ธ ํ›ˆ๋ จ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ ํ˜•์‹๊ณผ ์ผ์น˜ํ•˜๋Š” ํŠน์ • ์ฐจ์› ๋˜๋Š” ํ˜•์ƒ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ์•ฑ์€ ์ž…๋ ฅ์œผ๋กœ ๋ฌธ์ž์—ด์„ ๋ฐ›์•„๋“ค์ด๊ณ  ๋ชจ๋ธ์€ ์˜์–ด ๋ง๋ญ‰์น˜์—์„œ ์ „์ ์œผ๋กœ ํ›ˆ๋ จ๋ฉ๋‹ˆ๋‹ค. ํŠน์ˆ˜ ๋ฌธ์ž์™€ ๋น„์˜์–ด ๋‹จ์–ด๋Š” ์ถ”๋ก  ์ค‘ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

๋ชจ๋ธ์— ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ œ๊ณตํ•˜๊ธฐ

  1. initClassifier ํ•จ์ˆ˜๊ฐ€ ML ๋ชจ๋ธ ์ดˆ๊ธฐํ™” ๋ฐ ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ์‚ฌ์šฉ ์„น์…˜์—์„œ ์„ค๋ช…๋œ ๋Œ€๋กœ ๋Œ€๋ฆฌ์ž์™€ ๋ชจ๋ธ์— ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

  2. init ๋ธ”๋ก์„ ์‚ฌ์šฉํ•ด initClassifier ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ, init์€ TextClassificationHelper.kt์— ์žˆ์Šต๋‹ˆ๋‹ค.

    init { initClassifier() }

์˜ˆ์ธก ์‹คํ–‰ํ•˜๊ธฐ

Android ์•ฑ์—์„œ, BertNLClassifier ๋˜๋Š” NLClassifier ๊ฐ์ฒด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ชจ๋ธ์— ์ž…๋ ฅ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๊ธฐ ์‹œ์ž‘ํ•˜์—ฌ "๊ธ์ •(positive)" ๋˜๋Š” "๋ถ€์ •(negative)"์œผ๋กœ ๋ชจ๋ธ์„ ๋ฒ”์ฃผํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ธก ์‹คํ–‰ํ•˜๊ธฐ

  1. ์„ ํƒ๋œ ๋ถ„๋ฅ˜์ž (currentModel)์„ ์‚ฌ์šฉํ•˜๊ณ  ์ž…๋ ฅ ํ…์ŠคํŠธ๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฐ ์‹œ๊ฐ„(inferenceTime)์„ ์ธก์ •ํ•˜๋Š” classify ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ์„ธ์š”. ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ, classify ํ•จ์ˆ˜๋Š” TextClassificationHelper.kt์— ์žˆ์Šต๋‹ˆ๋‹ค.

    fun classify(text: String) { executor = ScheduledThreadPoolExecutor(1) executor.execute { val results: List<Category> // inferenceTime is the amount of time, in milliseconds, that it takes to // classify the input text. var inferenceTime = SystemClock.uptimeMillis() // Use the appropriate classifier based on the selected model if(currentModel == MOBILEBERT) { results = bertClassifier.classify(text) } else { results = nlClassifier.classify(text) } inferenceTime = SystemClock.uptimeMillis() - inferenceTime listener.onResult(results, inferenceTime) } }
  2. classify์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌ์Šค๋„ˆ ๊ฐ์ฒด๋กœ ์ „๋‹ฌํ•˜์„ธ์š”.

    fun classify(text: String) { ... listener.onResult(results, inferenceTime) }

๋ชจ๋ธ ์ถœ๋ ฅ ์ฒ˜๋ฆฌํ•˜๊ธฐ

ํ…์ŠคํŠธ ์ค„์„ ์ž…๋ ฅํ•˜๋ฉด, ๋ชจ๋ธ์€ '๊ธ์ •(positive)'๊ณผ '๋ถ€์ •(negative)' ๋ฒ”์ฃผ๋กœ 0๊ณผ 1 ์‚ฌ์ด์—์„œ ๋ถ€๋™์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ์˜ˆ์ธก ์ ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋ธ์—์„œ ์˜ˆ์ธก ๊ฒฐ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด:

  1. ๋ฆฌ์Šค๋„ˆ ๊ฐ์ฒด์•  ๋Œ€ํ•œ onResult ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์ถœ๋ ฅ์„ ์ฒ˜๋ฆฌํ•˜์„ธ์š”. ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฆฌ์Šค๋„ˆ ๊ฐ์ฒด๋Š” MainActivity.kt์— ์žˆ์Šต๋‹ˆ๋‹ค

    private val listener = object : TextClassificationHelper.TextResultsListener { override fun onResult(results: List<Category>, inferenceTime: Long) { runOnUiThread { activityMainBinding.bottomSheetLayout.inferenceTimeVal.text = String.format("%d ms", inferenceTime) adapter.resultsList = results.sortedByDescending { it.score } adapter.notifyDataSetChanged() } } ... }
  2. ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด onError ํ•จ์ˆ˜๋ฅผ ๋ฆฌ์Šค๋„ˆ ๊ฐ์ฒด์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    private val listener = object : TextClassificationHelper.TextResultsListener { ... override fun onError(error: String) { Toast.makeText(this@MainActivity, error, Toast.LENGTH_SHORT).show() } }

๋ชจ๋ธ์ด ์ผ๋ จ์˜ ์˜ˆ์ธก ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ ๋…ผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์˜ˆ์ธก์— ๋”ฐ๋ผ ์กฐ์น˜๋ฅผ ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์˜ˆ์ธก ์ ์ˆ˜๋ฅผ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‹จ๊ณ„