Dengan kemajuan terkini dalam Neural Networks secara umum dan Pengenalan gambar khususnya, mungkin tampak bahwa membuat aplikasi berbasis NN untuk pengenalan gambar adalah operasi rutin sederhana. Ya, sampai batas tertentu memang benar: jika Anda bisa membayangkan aplikasi pengenalan gambar, maka kemungkinan besar seseorang telah melakukan hal serupa. Yang perlu Anda lakukan adalah Google mengulanginya dan mengulanginya.
Namun, masih ada detail kecil yang tak terhitung jumlahnya yang ... mereka tidak dapat dipecahkan, tidak. Mereka hanya mengambil terlalu banyak waktu Anda, terutama jika Anda seorang pemula. Apa yang bisa membantu adalah proyek selangkah demi selangkah, dilakukan tepat di depan Anda, mulai dari awal sampai akhir. Sebuah proyek yang tidak mengandung pernyataan "bagian ini jelas jadi mari kita lewati saja". Yah, hampir :)
Dalam tutorial ini kita akan berjalan melalui Dog Breed Identifier: kita akan membuat dan mengajarkan Neural Network, lalu kita akan porting ke Java untuk Android dan menerbitkannya di Google Play.
Bagi Anda yang ingin melihat hasil akhirnya, berikut ini tautan ke
Aplikasi NeuroDog di Google Play.
Situs web dengan robotika saya:
robotics.snowcron.com .
Situs web dengan:
Panduan Pengguna NeuroDog .
Ini adalah screenshot dari program:

Ikhtisar
Kita akan menggunakan Keras: perpustakaan Google untuk bekerja dengan Neural Networks. Ini tingkat tinggi, yang berarti bahwa kurva belajar akan curam, pasti lebih cepat daripada perpustakaan lain yang saya sadari. Buat diri Anda terbiasa dengannya: ada banyak tutorial online berkualitas tinggi.
Kami akan menggunakan CNN - Jaringan Syaraf Konvolusional. CNN (dan jaringan yang lebih maju berdasarkan mereka) adalah standar de-facto dalam pengenalan gambar. Namun, mengajar satu dengan benar dapat menjadi tugas yang berat: struktur jaringan, parameter pembelajaran (semua tingkat pembelajaran, momentum, L1 dan L2 dan seterusnya) harus disesuaikan dengan hati-hati, dan karena tugas tersebut membutuhkan banyak sumber daya komputasi, kami tidak bisa begitu saja mencoba semua kombinasi yang mungkin.
Ini adalah salah satu dari beberapa alasan mengapa dalam kebanyakan kasus kami lebih suka menggunakan pendekatan "transfer pengetahuan" untuk apa yang disebut "vanilla". Transfer Knowlege menggunakan jaringan saraf yang dilatih oleh orang lain (pikirkan Google) untuk beberapa tugas lain. Lalu kita menghapus beberapa lapisan terakhir itu, tambahkan lapisan kita sendiri ... dan itu berfungsi keajaiban.
Mungkin kedengarannya aneh: kami mengambil jaringan Google yang terlatih untuk mengenali kucing, bunga, dan furnitur, dan sekarang mengidentifikasi jenis anjing! Untuk memahami cara kerjanya, mari kita lihat cara Deep Neural Networks, termasuk yang digunakan untuk pengenalan gambar, bekerja.
Kami memberinya gambar sebagai input. Lapisan pertama jaringan menganalisis gambar untuk pola-pola sederhana, seperti "garis horizontal pendek", "lengkungan", dan sebagainya. Lapisan berikutnya mengambil pola-pola ini (dan di mana mereka berada pada gambar) dan menghasilkan pola tingkat yang lebih tinggi, seperti "bulu", "sudut mata" dll. Pada akhirnya, kami memiliki puzzle yang dapat digabungkan menjadi deskripsi seekor anjing: bulu, dua mata, kaki manusia di mulut dan sebagainya.
Sekarang, semua ini dilakukan oleh serangkaian lapisan pra-pelatihan yang kami dapatkan (dari Google atau pemain besar lainnya). Akhirnya, kami menambahkan layer kami sendiri di atasnya dan kami mengajarkannya untuk bekerja dengan pola-pola itu untuk mengenali ras anjing. Kedengarannya logis.
Sebagai rangkuman, dalam tutorial ini kita akan membuat CNN “vanilla” dan beberapa jaringan “transfer learning” dari berbagai jenis. Adapun "vanilla": Saya hanya akan menggunakannya sebagai contoh bagaimana hal itu bisa dilakukan, tetapi saya tidak akan menyempurnakannya, karena jaringan "pra-terlatih" adalah cara yang lebih mudah untuk digunakan. Keras hadir dengan beberapa jaringan pra-terlatih, saya akan memilih beberapa konfigurasi dan membandingkannya.
Karena kami ingin Jaringan Saraf Tiruan kami dapat mengenali ras anjing, kami perlu "menunjukkan" sampel gambar dari berbagai ras. Untungnya, ada
dataset besar yang dibuat untuk tugas serupa (
asli di sini ). Pada artikel ini, saya akan menggunakan
versi dari KaggleLalu saya akan port "pemenang" ke Android. Porting Keras NN ke Android relatif mudah, dan kami akan berjalan melalui semua langkah yang diperlukan.
Kemudian kami akan menerbitkannya di Google Play. Seperti yang diharapkan, Google tidak akan bekerja sama, jadi hanya sedikit trik tambahan yang diperlukan. Misalnya, Jaringan Saraf Tiruan kami melebihi ukuran yang diizinkan untuk Android APK: kami harus menggunakan bundel. Juga, Google tidak akan menampilkan aplikasi kami di hasil pencarian, kecuali kami melakukan hal-hal ajaib tertentu.
Pada akhirnya kita akan memiliki "komersial" yang berfungsi penuh (dalam tanda kutip, karena aplikasi ini gratis meskipun siap pasar) Android NN-diberdayakan.
Lingkungan pengembangan
Ada beberapa pendekatan berbeda untuk pemrograman Keras, tergantung pada OS yang Anda gunakan (Ubuntu disarankan), kartu video yang Anda miliki (atau tidak) dan sebagainya. Tidak ada yang salah dengan mengonfigurasi lingkungan pengembangan di komputer lokal Anda dan menginstal semua perpustakaan yang diperlukan dan sebagainya. Kecuali ... ada cara yang lebih mudah.
Pertama, menginstal dan mengonfigurasi beberapa alat pengembangan membutuhkan waktu dan Anda harus menghabiskan waktu lagi, ketika versi baru tersedia. Kedua, pelatihan Neural Networks membutuhkan banyak daya komputasi. Anda dapat mempercepat komputer Anda dengan menggunakan GPU ... pada saat penulisan ini, GPU teratas untuk perhitungan terkait NN menelan biaya 2.000 - 7.000 dolar. Dan mengonfigurasinya membutuhkan waktu juga.
Jadi kita akan menggunakan pendekatan yang berbeda. Lihat, Google memungkinkan orang untuk menggunakan GPU-nya secara gratis untuk perhitungan terkait NN, ia juga telah menciptakan lingkungan yang sepenuhnya terkonfigurasi; semuanya itu disebut Google Colab. Layanan ini memberi Anda akses ke Notebook Jupiter dengan Python, Keras dan banyak perpustakaan tambahan yang sudah diinstal. Yang perlu Anda lakukan adalah mendapatkan akun Google (dapatkan akun Gmail, dan Anda akan memiliki akses ke semua yang lain) dan hanya itu.
Pada saat penulisan ini, Colab dapat diakses
oleh tautan ini , tetapi dapat berubah. Hanya google up "Google Colab."
Masalah nyata dengan Colab adalah layanan WEB. Bagaimana Anda akan mengakses file ANDA dari itu? Menyimpan Neural Networks setelah pelatihan selesai, memuat data khusus untuk tugas Anda dan seterusnya?
Ada beberapa (pada saat penulisan ini - tiga) pendekatan yang berbeda; kita akan menggunakan apa yang saya percaya adalah yang terbaik: menggunakan Google Drive.
Google Drive adalah penyimpanan cloud yang berfungsi hampir seperti hard drive, dan dapat dipetakan ke Google Colab (lihat kode di bawah). Kemudian Anda bekerja dengannya seperti halnya menggunakan hard drive lokal. Jadi, misalnya, jika Anda ingin mengakses foto anjing dari Neural Network yang Anda buat di Colab, Anda harus mengunggah foto-foto itu ke Google Drive Anda, itu saja.
Membuat dan melatih NN
Di bawah, saya akan berjalan melalui kode Python, satu blok kode dari Jupiter Notebook demi satu. Anda dapat menyalin kode itu ke buku catatan Anda dan menjalankannya, karena blok dapat dieksekusi terpisah satu sama lain.
Inisialisasi
Pertama-tama, mari kita pasang Google Drive. Hanya dua baris kode. Kode itu perlu dieksekusi hanya sekali per sesi Colab (katakanlah, sekali per enam jam kerja). Jika Anda menjalankannya untuk kedua kalinya, itu akan dilewati karena drive sudah terpasang.
from google.colab import drive drive.mount('/content/drive/')
Pertama kali Anda akan diminta untuk mengkonfirmasi pemasangan - tidak ada yang rumit di sini. Ini terlihat seperti ini:
>>> Go to this URL in a browser: ... >>> Enter your authorization code: >>> ·········· >>> Mounted at /content/drive/
Bagian standar yang cantik; kemungkinan besar beberapa termasuk tidak diperlukan. Juga, karena saya akan menguji konfigurasi NN yang berbeda, Anda harus mengomentari / menghapus komentar beberapa dari mereka untuk jenis NN tertentu: misalnya, untuk menggunakan InceptionV3 tipe NN, uncomment InceptionV3, dan komentar, katakanlah, ResNet50. Atau tidak: Anda dapat menyimpannya termasuk uncommented, itu akan menggunakan lebih banyak memori, tetapi hanya itu.
import datetime as dt import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from tqdm import tqdm import cv2 import numpy as np import os import sys import random import warnings from sklearn.model_selection import train_test_split import keras from keras import backend as K from keras import regularizers from keras.models import Sequential from keras.models import Model from keras.layers import Dense, Dropout, Activation from keras.layers import Flatten, Conv2D from keras.layers import MaxPooling2D from keras.layers import BatchNormalization, Input from keras.layers import Dropout, GlobalAveragePooling2D from keras.callbacks import Callback, EarlyStopping from keras.callbacks import ReduceLROnPlateau from keras.callbacks import ModelCheckpoint import shutil from keras.applications.vgg16 import preprocess_input from keras.preprocessing import image from keras.preprocessing.image import ImageDataGenerator from keras.models import load_model from keras.applications.resnet50 import ResNet50 from keras.applications.resnet50 import preprocess_input from keras.applications.resnet50 import decode_predictions from keras.applications import inception_v3 from keras.applications.inception_v3 import InceptionV3 from keras.applications.inception_v3 import preprocess_input as inception_v3_preprocessor from keras.applications.mobilenetv2 import MobileNetV2 from keras.applications.nasnet import NASNetMobile
Di Google Drive, kita akan membuat folder untuk file kita. Baris kedua menampilkan isinya:
working_path = "/content/drive/My Drive/DeepDogBreed/data/" !ls "/content/drive/My Drive/DeepDogBreed/data" >>> all_images labels.csv models test train valid
Seperti yang Anda lihat, foto-foto anjing (yang disalin dari dataset Stanford (lihat di atas) ke Google Drive, awalnya disimpan di folder
all_images . Nanti kita akan menyalinnya ke folder
train, valid, dan
test . Kita akan menyimpan model terlatih dalam folder
model . Adapun file labels.csv, ini adalah bagian dari dataset, memetakan file gambar ke trah anjing.
Ada banyak tes yang dapat Anda jalankan untuk mengetahui apa yang Anda miliki, mari kita jalankan satu saja:
Ok, GPU terhubung. Jika tidak, temukan di pengaturan Notebook Jupiter dan hidupkan.
Sekarang kita perlu mendeklarasikan beberapa konstanta yang akan kita gunakan, seperti ukuran gambar yang harus diharapkan oleh Neural Network dan sebagainya. Perhatikan, bahwa kami menggunakan gambar 256x256, karena ini cukup besar di satu sisi dan sesuai dengan memori di sisi lain. Namun, beberapa jenis Jaringan Saraf Tiruan yang akan kita gunakan mengharapkan gambar 224x224. Untuk menangani ini, bila perlu, komentari ukuran gambar lama dan batalkan komentar pada yang baru.
Pendekatan yang sama (komentar satu - hapus komentar yang lain) berlaku untuk nama model yang kami simpan, hanya karena kami tidak ingin menimpa hasil pengujian sebelumnya ketika kami mencoba konfigurasi baru.
warnings.filterwarnings("ignore") os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' np.random.seed(7) start = dt.datetime.now() BATCH_SIZE = 16 EPOCHS = 15 TESTING_SPLIT=0.3
Memuat data
Pertama, mari kita memuat file
labels.csv dan membagi isinya ke bagian pelatihan dan validasi. Perhatikan bahwa belum ada bagian pengujian, karena saya akan sedikit curang, untuk mendapatkan lebih banyak data untuk pelatihan.
labels = pd.read_csv(working_path + 'labels.csv') print(labels.head()) train_ids, valid_ids = train_test_split(labels, test_size = TESTING_SPLIT) print(len(train_ids), 'train ids', len(valid_ids), 'validation ids') print('Total', len(labels), 'testing images') >>> id breed >>> 0 000bec180eb18c7604dcecc8fe0dba07 boston_bull >>> 1 001513dfcb2ffafc82cccf4d8bbaba97 dingo >>> 2 001cdf01b096e06d78e9e5112d419397 pekinese >>> 3 00214f311d5d2247d5dfe4fe24b2303d bluetick >>> 4 0021f9ceb3235effd7fcde7f7538ed62 golden_retriever >>> 7155 train ids 3067 validation ids >>> Total 10222 testing images
Selanjutnya, kita perlu menyalin file gambar yang sebenarnya ke folder pelatihan / validasi / pengujian, sesuai dengan array nama file yang kita lewati. Fungsi berikut menyalin file dengan nama yang diberikan ke folder yang ditentukan.
def copyFileSet(strDirFrom, strDirTo, arrFileNames): arrBreeds = np.asarray(arrFileNames['breed']) arrFileNames = np.asarray(arrFileNames['id']) if not os.path.exists(strDirTo): os.makedirs(strDirTo) for i in tqdm(range(len(arrFileNames))): strFileNameFrom = strDirFrom + arrFileNames[i] + ".jpg" strFileNameTo = strDirTo + arrBreeds[i] + "/" + arrFileNames[i] + ".jpg" if not os.path.exists(strDirTo + arrBreeds[i] + "/"): os.makedirs(strDirTo + arrBreeds[i] + "/")
Seperti yang Anda lihat, kami hanya menyalin satu file untuk setiap jenis anjing ke folder
tes . Saat kami menyalin file, kami juga membuat subfolder - satu subfolder untuk setiap jenis anjing. Gambar untuk setiap trah tertentu disalin ke dalam subfoldernya.
Alasannya adalah, Keras dapat bekerja dengan struktur direktori yang diatur dengan cara ini, memuat file gambar sesuai kebutuhan, menghemat memori. Ini akan menjadi ide yang sangat buruk untuk memuat semua 15.000 gambar ke dalam memori sekaligus.
Memanggil fungsi ini setiap kali kita menjalankan kode kita akan menjadi berlebihan: gambar sudah disalin, mengapa kita harus menyalinnya lagi. Jadi, beri komentar untuk pertambahan penggunaan pertama:
Selain itu, kami membutuhkan daftar ras anjing:
breeds = np.unique(labels['breed']) map_characters = {}
Memproses gambar
Kami akan menggunakan fitur Keras yang disebut ImageDataGenerators. ImageDataGenerator dapat memproses gambar, mengubah ukurannya, memutar, dan sebagainya. Itu juga dapat mengambil fungsi
pemrosesan yang melakukan manipulasi gambar khusus.
def preprocess(img): img = cv2.resize(img, (IMAGE_SIZE, IMAGE_SIZE), interpolation = cv2.INTER_AREA)
Perhatikan baris berikut:
Kita dapat melakukan normalisasi (menyesuaikan rentang 0-255 saluran gambar ke 0-1) di ImageDataGenerator itu sendiri. Jadi mengapa kita perlu preprosesor? Sebagai contoh, saya telah menyediakan fungsi
blur (dikomentari): yaitu manipulasi gambar khusus. Anda dapat menggunakan apa saja dari mengasah ke HDR di sini.
Kami akan menggunakan dua ImageDataGenerators yang berbeda, satu untuk pelatihan dan satu untuk validasi. Perbedaannya adalah, kita perlu rotasi dan zoom untuk pelatihan, untuk membuat gambar lebih "beragam", tetapi kita tidak membutuhkannya untuk validasi (tidak dalam tugas ini).
train_datagen = ImageDataGenerator( preprocessing_function=preprocess,
Menciptakan jaringan saraf
Seperti yang disebutkan di atas, kita akan membuat beberapa jenis Neural Networks. Setiap kali kami menggunakan fungsi yang berbeda, pustaka yang berbeda termasuk dan dalam beberapa kasus, ukuran gambar yang berbeda. Jadi untuk beralih dari satu jenis Neural Network ke yang lain, Anda perlu komentar / batalkan komentar terkait kode.
Pertama, mari kita buat CNN "vanilla". Ini berkinerja buruk, karena saya belum mengoptimalkannya, tetapi setidaknya itu memberikan kerangka kerja yang dapat Anda gunakan untuk membuat jaringan Anda sendiri (umumnya, itu adalah ide yang buruk, karena ada jaringan pra-terlatih yang tersedia).
def createModelVanilla(): model = Sequential()
Saat kami membuat Neural Network menggunakan
transfer learning , prosedurnya berubah:
def createModelMobileNetV2():
Membuat jenis NN pra-terlatih lainnya sangat mirip:
def createModelResNet50(): base_model = ResNet50(weights='imagenet', include_top=False, pooling='avg', input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3)) x = base_model.output x = Dense(512)(x) x = Activation('relu')(x) x = Dropout(0.5)(x) predictions = Dense(NUM_CLASSES, activation='softmax')(x) model = Model(inputs=base_model.input, outputs=predictions)
Attn: pemenang! NN ini menunjukkan hasil terbaik:
def createModelInceptionV3():
Satu lagi:
def createModelNASNetMobile():
Berbagai jenis NN digunakan dalam situasi yang berbeda. Selain masalah presisi, ukuran masalah (NN seluler 5 kali lebih kecil dari Inception satu) dan kecepatan (jika kita memerlukan analisis waktu nyata dari aliran video, kita mungkin harus mengorbankan presisi).
Pelatihan jaringan saraf
Pertama-tama, kami sedang
bereksperimen , jadi kami harus dapat menghapus NN yang telah kami simpan sebelumnya, tetapi tidak perlu lagi. Fungsi berikut menghapus NN jika file ada:
Cara kami membuat dan menghapus NN sangat mudah. Pertama, kami hapus. Sekarang, jika Anda tidak ingin
menghapus panggilan, ingat saja bahwa Jupiter Notebook memiliki fungsi "jalankan pemilihan" - pilih saja yang Anda butuhkan, dan jalankan.
Kemudian kita membuat NN jika file-nya tidak ada atau
memuatnya jika file itu ada: tentu saja, kita tidak bisa memanggil "delete" dan kemudian mengharapkan NN ada, jadi untuk menggunakan jaringan yang disimpan sebelumnya, jangan panggil
delete .
Dengan kata lain, kita dapat membuat NN baru atau menggunakan yang sudah ada, tergantung pada apa yang kita coba sekarang. Skenario sederhana: kami telah melatih NN, lalu pergi berlibur. Google mengeluarkan kami, jadi kami perlu memuat ulang NN: beri komentar pada bagian "hapus" dan batalkan komentar pada bagian "muat".
deleteSavedNet(working_path + strModelFileName)
Pos pemeriksaan sangat penting ketika mengajar NN. Anda dapat membuat berbagai fungsi untuk dipanggil di akhir setiap periode pelatihan, misalnya, Anda dapat menyimpan NN
jika jika menunjukkan hasil yang lebih baik daripada yang terakhir disimpan.
checkpoint = ModelCheckpoint(working_path + strModelFileName, monitor='val_acc', verbose=1, save_best_only=True, mode='auto', save_weights_only=False) callbacks_list = [ checkpoint ]
Akhirnya, kami akan mengajarkan NN kami menggunakan set pelatihan:
Berikut adalah grafik akurasi dan kehilangan untuk pemenang NN:


Seperti yang Anda lihat, Jaringan belajar dengan baik.
Menguji Jaringan Saraf Tiruan
Setelah fase pelatihan selesai, kita perlu melakukan pengujian; untuk melakukannya, NN disajikan dengan gambar yang tidak pernah dilihatnya. Ingat, kami telah menyisihkan satu gambar untuk masing-masing spesies anjing.
Mengekspor NN ke Jawa
Pertama, kita perlu memuat NN. Alasannya, mengekspor adalah blok kode yang terpisah, jadi kami cenderung menjalankannya secara terpisah, tanpa melatih ulang NN. Ketika Anda menggunakan kode saya, Anda tidak terlalu peduli, tetapi jika Anda melakukan pengembangan sendiri, Anda akan mencoba untuk tidak melatih kembali jaringan yang
sama satu demi satu.
Untuk alasan yang sama - ini entah bagaimana blok kode yang terpisah - kami menggunakan tambahan termasuk di sini. Tidak ada yang menghalangi kita untuk menaikkannya, tentu saja:
from keras.models import Model from keras.models import load_model from keras.layers import * import os import sys import tensorflow as tf
Sedikit pengujian, hanya untuk memastikan kami telah memuat semuanya dengan benar:
img = image.load_img(working_path + "test/affenpinscher.jpg")

Selanjutnya, kita perlu mendapatkan nama lapisan input dan output jaringan kita (kecuali kita menggunakan parameter "nama" saat membuat jaringan, yang tidak kita lakukan).
model.summary() >>> Layer (type) >>> ====================== >>> input_7 (InputLayer) >>> ______________________ >>> conv2d_283 (Conv2D) >>> ______________________ >>> ... >>> dense_14 (Dense) >>> ====================== >>> Total params: 22,913,432 >>> Trainable params: 1,110,648 >>> Non-trainable params: 21,802,784
Kita akan menggunakan nama lapisan input dan output nanti, ketika mengimpor NN di aplikasi Android Java.
Kami juga dapat menggunakan kode berikut untuk mendapatkan info ini:
def print_graph_nodes(filename): g = tf.GraphDef() g.ParseFromString(open(filename, 'rb').read()) print() print(filename) print("=======================INPUT===================") print([n for n in g.node if n.name.find('input') != -1]) print("=======================OUTPUT==================") print([n for n in g.node if n.name.find('output') != -1]) print("===================KERAS_LEARNING==============") print([n for n in g.node if n.name.find('keras_learning_phase') != -1]) print("===============================================") print()
Namun, pendekatan pertama lebih disukai.
Fungsi berikut mengekspor Keras Neural Network ke format
pb , yang akan kita gunakan di Android.
def keras_to_tensorflow(keras_model, output_dir, model_name,out_prefix="output_", log_tensorboard=True): if os.path.exists(output_dir) == False: os.mkdir(output_dir) out_nodes = [] for i in range(len(keras_model.outputs)): out_nodes.append(out_prefix + str(i + 1)) tf.identity(keras_model.output[i], out_prefix + str(i + 1)) sess = K.get_session() from tensorflow.python.framework import graph_util from tensorflow.python.framework graph_io init_graph = sess.graph.as_graph_def() main_graph = graph_util.convert_variables_to_constants( sess, init_graph, out_nodes) graph_io.write_graph(main_graph, output_dir, name=model_name, as_text=False) if log_tensorboard: from tensorflow.python.tools import import_pb_to_tensorboard import_pb_to_tensorboard.import_to_tensorboard( os.path.join(output_dir, model_name), output_dir)
Mari kita gunakan fungsi-fungsi ini untuk membuat ekspor NN:
model = load_model(working_path + strModelFileName) keras_to_tensorflow(model, output_dir=working_path + strModelFileName, model_name=working_path + "models/dogs.pb") print_graph_nodes(working_path + "models/dogs.pb")
Baris terakhir mencetak struktur NN kami.
Membuat Aplikasi Android yang diberdayakan NN
Mengekspor NN ke aplikasi Android. diformalkan dengan baik dan tidak menimbulkan kesulitan. Ada, seperti biasa, lebih dari satu cara melakukannya; kita akan menggunakan yang paling populer (setidaknya, saat ini).
Pertama-tama, gunakan Android Studio untuk membuat proyek baru. Kami akan memotong sudut sedikit, jadi itu hanya akan berisi satu aktivitas.

Seperti yang Anda lihat, kami telah menambahkan folder "aset" dan menyalin file Neural Network kami di sana.
File gradle
Ada beberapa perubahan yang perlu kita lakukan untuk mengatur file. Pertama-tama, kita harus mengimpor perpustakaan
tensorflow-android . Ini digunakan untuk menangani Tensorflow (dan Keras, sesuai) dari Jawa:

Sebagai detail "sulit ditemukan" tambahan, catat versi:
versionCode dan
versionName . Saat Anda mengerjakan aplikasi, Anda perlu mengunggah versi baru ke Google Play. Tanpa memperbarui versi (seperti 1 -> 2 -> 3 ...) Anda tidak akan dapat melakukannya.
Terwujud
Pertama-tama, aplikasi kami. akan menjadi "berat" - Jaringan 100 Mb Neural mudah masuk ke memori ponsel modern, tetapi membuka contoh terpisah setiap kali pengguna "berbagi" gambar dari Facebook jelas bukan ide yang baik.
Jadi kami akan memastikan hanya ada satu instance dari aplikasi kami:
<activity android:name=".MainActivity" android:launchMode="singleTask">
Dengan menambahkan
android: launchMode = "singleTask" ke MainActivity, kami memberi tahu Android untuk membuka aplikasi yang sudah ada, alih-alih meluncurkan instance lain.
Maka kami memastikan aplikasi kami. muncul di daftar aplikasi yang mampu menangani gambar
bersama :
<intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter>
Terakhir, kita perlu meminta fitur dan izin, sehingga aplikasi dapat mengakses fungsionalitas sistem yang diperlukan:
<uses-feature android:name="android.hardware.camera" android:required="true" /> <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />
Jika Anda terbiasa dengan pemrograman Android, bagian ini seharusnya tidak menimbulkan pertanyaan.
Tata Letak Aplikasi.
Kami akan membuat dua tata letak, satu untuk Potret dan satu untuk mode Lansekap. Berikut adalah
tata letak Portrait .
Apa yang kita miliki di sini: tampilan besar untuk menampilkan gambar, daftar iklan yang agak mengganggu (ditampilkan ketika tombol "tulang" ditekan), tombol "Bantuan", tombol untuk memuat gambar dari File / Galeri dan dari Kamera, dan akhirnya, tombol (awalnya disembunyikan) "Proses".

Dalam aktivitas itu sendiri kita akan mengimplementasikan beberapa logika yang menunjukkan / menyembunyikan dan mengaktifkan / menonaktifkan tombol tergantung pada keadaan aplikasi.
Kegiatan utama
Aktivitas ini memperluas Aktivitas Android standar:
public class MainActivity extends Activity
Mari kita lihat kode yang bertanggung jawab untuk operasi NN.
Pertama-tama, NN menerima Bitmap. Awalnya ini adalah Bitmap besar dari file atau Kamera (m_bitmap), kemudian kami mengubahnya menjadi Bitmap 256x256 standar (m_bitmapForNn). Kami juga menjaga dimensi gambar (256) dalam konstan:
static Bitmap m_bitmap = null; static Bitmap m_bitmapForNn = null; private int m_nImageSize = 256;
Kita perlu memberi tahu NN apa nama untuk layer input dan output; jika Anda melihat daftar di atas, Anda akan menemukan bahwa namanya (dalam kasus kami! kasus Anda dapat berbeda!):
private String INPUT_NAME = "input_7_1"; private String OUTPUT_NAME = "output_1";
Kemudian kita mendeklarasikan variabel untuk menahan objek TensofFlow. Kami juga menyimpan jalur ke file NN di aset:
private TensorFlowInferenceInterface tf;
private String MODEL_PATH =
"file: ///android_asset/dogs.pb";
Trah anjing, untuk menyajikan kepada pengguna informasi yang bermakna, alih-alih indeks dalam array:
private String[] m_arrBreedsArray;
Awalnya, kami memuat Bitmap. Namun, NN sendiri mengharapkan susunan nilai RGB, dan outputnya adalah susunan probabilitas gambar yang disajikan sebagai jenis tertentu. Jadi kita perlu menambahkan dua array lagi (perhatikan bahwa 120 adalah jumlah breed dalam dataset pelatihan kami):
private float[] m_arrPrediction = new float[120]; private float[] m_arrInput = null;
Memuat perpustakaan inferensi tensorflow
static { System.loadLibrary("tensorflow_inference"); }
Karena operasi NN adalah operasi yang panjang, kita perlu melakukannya di utas terpisah, jika tidak ada peluang bagus untuk memukul aplikasi "sistem". tidak menanggapi "peringatan, belum lagi merusak pengalaman pengguna.
class PredictionTask extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); }
Di onCreate () dari MainActivity, kita perlu menambahkan onClickListener untuk tombol "Proses": m_btn_process.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { processImage(); } });
Apa yang processImage () lakukan hanyalah memanggil utas yang kami lihat di atas: private void processImage() { try { enableControls(false);
Detail tambahan
Kami tidak akan membahas kode terkait UI dalam tutorial ini, karena sepele dan jelas bukan bagian dari tugas "porting NN". Namun, ada beberapa hal yang harus diklarifikasi.Ketika kami menerapkan aplikasi kami. dari meluncurkan beberapa contoh, kami telah mencegah, pada saat yang sama, aliran normal pada kontrol: jika Anda berbagi gambar dari Facebook, dan kemudian membagikan yang lain, aplikasi tidak akan dimulai ulang. Ini berarti bahwa cara "tradisional" dalam menangani data bersama dengan menangkapnya di onCreate tidak cukup dalam kasus kami, karena onCreate tidak disebut dalam skenario yang baru kami buat.Berikut adalah cara untuk menangani situasi:1. Di onCreate of MainActivity, panggil fungsi onSharedIntent: protected void onCreate( Bundle savedInstanceState) { super.onCreate(savedInstanceState); .... onSharedIntent(); ....
Juga, tambahkan handler untuk onNewIntent: @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); onSharedIntent(); }
Fungsi onSharedIntent sendiri: private void onSharedIntent() { Intent receivedIntent = getIntent(); String receivedAction = receivedIntent.getAction(); String receivedType = receivedIntent.getType(); if (receivedAction.equals(Intent.ACTION_SEND)) {
Sekarang kita dapat menangani gambar bersama dari onCreate (jika aplikasi baru saja dimulai) atau dari onNewIntent jika sebuah instance ditemukan dalam memori.Semoga beruntung Jika Anda suka artikel ini, silakan “suka” di jejaring sosial, juga ada tombol sosial di situs itu sendiri.