Menentukan kematangan semangka menggunakan Keras: siklus penuh, dari ide hingga program di Google Play

Bagaimana semuanya dimulai


Semuanya dimulai dengan Apple Market - Saya menemukan bahwa mereka memiliki program untuk menentukan kematangan semangka. Programnya ... aneh. Apa yang layak, setidaknya, tawaran mengetuk semangka bukan dengan buku jari Anda, tapi ... melalui telepon! Meskipun demikian, saya ingin mengulangi pencapaian ini pada platform Android yang lebih akrab.

Pemilihan alat


Masalah kami diselesaikan dalam beberapa cara, dan jujur ​​saja, saya harus melakukan upaya yang cukup besar untuk tidak pergi dengan cara "sederhana". Yaitu, ambil transformasi Fourier, wavelet, dan editor sinyal. Namun, saya ingin mendapatkan pengalaman dengan jaringan saraf, jadi biarkan jaringan melakukan analisis data.

Keras, add-on Google untuk TensorFlow dan Theano, dipilih sebagai perpustakaan untuk membuat dan melatih jaringan saraf. Secara umum, jika Anda baru memulai dengan jaringan pembelajaran yang mendalam, Anda sebaiknya tidak menemukan alat. Di satu sisi, Keras adalah alat yang kuat yang dioptimalkan untuk kecepatan, memori dan perangkat keras (ya, itu dapat bekerja pada kartu video dan klusternya). Di sisi lain, segala sesuatu yang dapat "disembunyikan" dari pengguna disembunyikan di sana, jadi Anda tidak perlu memutar otak Anda di atas docking lapisan jaringan saraf, misalnya. Sangat nyaman

Seperti Keras, dan jaringan saraf pada umumnya, membutuhkan pengetahuan tentang Python - bahasa ini, seperti ular yang melilit ... maaf, terpendam. Singkatnya, Anda tidak boleh ikut campur dalam Pembelajaran Jauh modern tanpa Python. Untungnya, Python dapat dipelajari dalam dua minggu, dalam kasus yang ekstrim - dalam sebulan.

Anda akan memerlukan beberapa pustaka lagi untuk Python, tetapi ini adalah hal-hal sepele - maksud saya, jika Anda telah berurusan dengan Python sendiri. Ini akan membutuhkan kenalan (sangat dangkal) dengan NumPy, PyPlot dan, mungkin, dengan beberapa pustaka, dari mana kita benar-benar mengambil beberapa fungsi. Tidak sulit. Yang benar adalah.

Yah, sebagai kesimpulan, saya perhatikan bahwa kita tidak perlu kelompok kartu video yang disebutkan di atas - tugas kita biasanya diselesaikan dengan bantuan CPU komputer - perlahan, tetapi tidak terlalu lambat.

Rencana kerja


Pertama, Anda perlu membuat jaringan saraf - pada Python dan Keras, di bawah Ubuntu. Anda dapat - pada emulator Ubunta. Anda dapat - untuk Windows, tetapi waktu tambahan yang dihabiskan cukup untuk Anda mempelajari Ubuntu yang disebutkan, dan kemudian bekerja di bawahnya.

Langkah selanjutnya adalah menulis program. Saya berencana untuk melakukan ini di Jawa di bawah Android. Ini akan menjadi prototipe program, dalam arti bahwa ia akan memiliki antarmuka pengguna, tetapi belum ada jaringan saraf.

Apa artinya menulis "soothers," Anda bertanya. Tapi inilah masalahnya: tugas apa pun yang terkait dengan analisis data, cepat atau lambat bertumpu pada pencarian data - untuk melatih program kami. Sebenarnya, berapa banyak semangka yang perlu disadap dan dicicipi sehingga jaringan saraf dapat membangun model yang andal pada data ini? Seratus? Lebih?

Di sini program kami akan membantu kami: mengunggahnya ke Google Play, mendistribusikan (oke, memaksakan, memutar lengan) ke semua teman yang tidak beruntung memiliki ponsel dengan Android, dan data, aliran kecil, mulai mengalir ... dan omong-omong, di mana?

Langkah selanjutnya adalah menulis program server yang menerima data dari klien android kami. Benar, program server ini sangat sederhana, saya menyelesaikan semuanya dalam waktu sekitar dua puluh menit. Tetapi, bagaimanapun, ini adalah tahap yang terpisah.

Akhirnya, cukup data. Kami melatih jaringan saraf.

Kami port jaringan saraf di Jawa dan merilis pembaruan untuk program kami.

Untung Meski tidak. Program itu gratis. Hanya pengalaman dan gundukan boneka.

Menciptakan jaringan saraf


Bekerja dengan audio, yang, tentu saja, mengetuk semangka, adalah jaringan saraf berulang atau yang disebut jaringan evolusi satu dimensi. Terlebih lagi, dalam beberapa tahun terakhir, jaringan evolusi secara jelas memimpin, menggantikan yang berulang. Gagasan dari jaringan konvolusional adalah bahwa jendela meluncur di atas array data - grafik "intensitas suara - waktu" - dan bukannya menganalisis ratusan ribu sampel, kami hanya bekerja dengan apa yang masuk ke jendela. Lapisan berikut menggabungkan dan menganalisis hasil dari lapisan ini.

Untuk membuatnya lebih jelas, bayangkan Anda perlu menemukan burung camar di foto lanskap laut. Anda memindai gambar - "jendela" perhatian Anda bergerak di sepanjang baris dan kolom imajiner, untuk mencari tanda centang putih. Ini adalah cara kerja jaringan konvolusional 2D, sementara jaringan satu dimensi memindai sepanjang satu koordinat - pilihan terbaik jika kita berurusan dengan sinyal audio.

Saya perhatikan, bagaimanapun, bahwa tidak perlu untuk fokus pada jaringan 1D. Sebagai latihan, saya memplot suara dan menganalisis bitmap yang dihasilkan sebagai gambar - menggunakan jaringan konvolusi 2d. Yang mengejutkan saya, hasilnya tidak lebih buruk daripada ketika menganalisis data "mentah satu dimensi".

Jaringan yang digunakan memiliki struktur berikut:

model = Sequential() model.add(Conv1D(filters=32, kernel_size=512, strides=3, padding='valid', use_bias=False, input_shape=(nSampleSize, 1), name='c1d', activation='relu')) model.add(Activation('relu', input_shape=(nSampleSize, 1))) model.add(MaxPooling1D(pool_size=(2))) model.add(Conv1D(32, (3))) model.add(Activation('relu')) model.add(MaxPooling1D(pool_size=(2))) model.add(Conv1D(64, (3))) model.add(Activation('relu')) model.add(MaxPooling1D(pool_size=(2))) model.add(Flatten()) model.add(Dense(64)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(nNumOfOutputs)) #1)) model.add(Activation('sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy']) 

Jaringan ini memiliki dua nilai keluaran (ia memprediksi dua nilai): manis dan matang. Manisnya adalah 0 (tanpa pemanis), 1 (normal) dan 2 (sangat baik), dan kematangannya, 0 terlalu keras, 1 adalah yang Anda butuhkan, dan 2 terlalu matang, seperti wol kapas dengan pasir.

Nilai untuk sampel uji ditetapkan oleh orang tersebut, persis bagaimana - kita akan berbicara di bagian program untuk Android. Tugas dari jaringan saraf adalah untuk memperkirakan peringkat apa yang akan diberikan seseorang untuk semangka yang diberikan (menurut keran).

Menulis program


Saya sudah menyebutkan bahwa program harus keluar dalam dua versi. Yang pertama, pendahuluan, secara jujur ​​memperingatkan pengguna bahwa prediksinya benar-benar omong kosong. Tetapi memungkinkan pengguna untuk merekam ketukan pada semangka, menilai rasa semangka ini dan mengirimkannya ke penulis program melalui Internet. Artinya, versi pertama hanya mengumpulkan data.

Berikut adalah halaman program di Google Play, tentu saja, program ini gratis.

Apa yang dia lakukan:

1. Tekan tombol dengan mikrofon dan perekaman dimulai. Anda memiliki lima detik untuk memukul semangka tiga kali - ketukan-ketukan. Sebuah tombol dengan semangka membuat "prediksi", dan kami belum menyentuhnya.

Catatan - jika Google memiliki versi lama, maka perekaman dan prediksi digabungkan dalam tombol dengan semangka, tetapi tidak ada tombol dengan mikrofon.

gambar

2. File yang disimpan bersifat sementara dan akan ditimpa saat berikutnya Anda menekan tombol rekam. Ini memungkinkan Anda mengulangi ketukan jika seseorang berbicara bergandengan tangan (Anda tidak bisa membayangkan betapa sulitnya membuat orang lain tutup mulut selama lima detik!) Atau airnya berisik - piringnya berdering - tetangga sedang mengebor ...

Tapi sekarang semangka dipilih dan dibeli. Anda membawanya pulang, merekam suara dan memotongnya. Sekarang Anda siap untuk mengevaluasi rasanya. Pilih tab Simpan.

Pada tab ini, kita melihat dua kotak kombo untuk penilaian - kemanisan dan kematangan (kemanisan dan kematangan, pengerjaan terjemahan sedang berlangsung). Beri tanda - klik Simpan.

Perhatian! Simpan dapat diklik hanya sekali. Jadi, pertama-tama beri tanda. Dengan satu sentuhan tombol, file suara diganti namanya, dan sekarang file itu tidak akan dihapus saat berikutnya direkam.

gambar

3. Akhirnya, setelah merekam (dan, karenanya, memakan) selusin semangka, Anda kembali dari pondok, di mana Anda tidak memiliki Internet. Sekarang Internet. Buka tab Kirim dan tekan tombol. Paket (dengan selusin semangka) pergi ke server pengembang.

gambar

Menulis program server


Semuanya sederhana di sini, jadi saya lebih baik memberikan kode lengkap untuk skrip ini. Program "menangkap" file, memberi mereka nama unik dan menempatkannya di direktori yang hanya dapat diakses oleh pemilik situs.

 <?php if (is_uploaded_file($_FILES['file']['tmp_name'])) { $uploads_dir = './melonaire/'; $tmp_name = $_FILES['file']['tmp_name']; $pic_name = $_FILES['file']['name']; $filename = md5(date('Ymd H:i:s:u')); move_uploaded_file($tmp_name, $uploads_dir.$filename); } else { echo "File not uploaded successfully."; } ?> 

Pelatihan jaringan saraf


Data dibagi menjadi pelatihan dan tes, masing-masing 70 dan 30 persen. Jaringan saraf - menyatu. Namun, tidak ada kejutan di sini untuk pemula: jangan lupa untuk menormalkan data input, ini akan menghemat banyak keberanian. Sesuatu seperti itu:

 for file_name in os.listdir(path): nSweetness, nRipeness, arr_loaded = loadData(file_name) arr_data.append(arr_loaded / max(abs(arr_loaded))) # 2 stands for num. of inputs of a combo box - 1 arr_labels.append([nSweetness / 2.0, nRipeness / 2.0]) 

Porting jaringan saraf


Ada beberapa cara untuk mem-port jaringan dari lingkungan Python ke Java. Baru-baru ini, Google telah membuat proses ini lebih nyaman, jadi jika Anda membaca buku pelajaran, pastikan buku-buku itu tidak ketinggalan zaman. Begini cara saya melakukannya:

 from keras.models import Model from keras.models import load_model from keras.layers import * import os import sys import tensorflow as tf # ------------------- 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() # ------------------- def get_script_path(): return os.path.dirname(os.path.realpath(sys.argv[0])) # ------------------- 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, 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) model = load_model(get_script_path() + "/models/model.h5") #keras_to_tensorflow(model, output_dir=get_script_path() + "/models/model.h5", # model_name=get_script_path() + "/models/converted.pb") print_graph_nodes(get_script_path() + "/models/converted.pb") 

Perhatikan baris terakhir: dalam kode Java Anda harus menentukan nama input dan output jaringan. "Cetak" ini hanya mencetaknya.

Jadi, kami menempatkan file yang diterima coordted.pb ke direktori aset proyek di Android Studio, sambungkan perpustakaan tensorflowinferenceinterface (lihat di sini , atau lebih baik, di sini ), dan hanya itu.

Itu saja. Ketika saya melakukan ini untuk pertama kalinya, saya berharap itu akan sulit, tapi ... itu berhasil pada percobaan pertama.

Begini tampilannya jaringan neural dari kode Java:

  protected Void doInBackground(Void... params) { try { //Pass input into the tensorflow tf.feed(INPUT_NAME, m_arrInput, 1, // batch ? m_arrInput.length, 1); // channels ? //compute predictions tf.run(new String[]{OUTPUT_NAME}); //copy the output into the PREDICTIONS array tf.fetch(OUTPUT_NAME, m_arrPrediction); } catch (Exception e) { e.getMessage(); } return null; } 

Di sini m_arrInput adalah array dengan dua elemen yang mengandung - ya! - prediksi kami, dinormalisasi dari nol menjadi satu.

Kesimpulan


Di sini, tampaknya, orang seharusnya berterima kasih atas perhatiannya, dan menyatakan harapan bahwa itu menarik. Sebagai gantinya, saya perhatikan bahwa Google adalah versi pertama dari program ini. Yang kedua benar-benar siap, tetapi tidak cukup data. Jadi jika Anda suka semangka - silakan letakkan program di Android Anda. Semakin banyak data yang Anda kirim, semakin baik versi kedua akan berfungsi ...

Tentu saja itu akan gratis.

Semoga beruntung, dan ya: terima kasih sudah menonton. Saya harap itu menarik.

Pembaruan penting: versi baru dengan analisis yang lebih baik telah dirilis. Terima kasih kepada semua orang yang mengirim semangka, dan kirimkan lebih banyak lagi!

Source: https://habr.com/ru/post/id424099/


All Articles