NVIDIA Jetson Nano: Tes dan Kesan Pertama - Bagian 2, Tes AI

Hai, Habr.

Pada bagian pertama , NVIDIA Jetson Nano dianggap - papan dalam faktor bentuk Raspberry Pi, fokus pada komputasi kinerja menggunakan GPU. Sudah saatnya untuk menguji papan dalam apa itu diciptakan - untuk perhitungan berorientasi AI.



Pertimbangkan bagaimana berbagai tugas dilakukan di papan tulis, seperti mengklasifikasikan gambar atau mengenali pejalan kaki atau anjing laut (di mana tanpanya). Untuk semua tes, kode sumber dapat dijalankan di desktop, Jetson Nano atau Raspberry Pi. Bagi yang berminat, lanjutkan di bawah cut.

Ada dua cara untuk menggunakan papan ini. Yang pertama adalah menjalankan kerangka kerja standar seperti Keras dan Tensorflow. Ini akan bekerja pada prinsipnya, itu akan, tetapi seperti yang sudah terlihat dari bagian pertama, Jetson Nano, tentu saja, lebih rendah daripada desktop yang penuh atau kartu video laptop. Pengguna harus mengambil tugas mengoptimalkan model. Cara kedua adalah mengambil kelas siap pakai yang datang dengan papan tulis. Lebih sederhana dan bekerja "di luar kotak", minusnya adalah bahwa semua detail implementasi disembunyikan ke tingkat yang jauh lebih besar, di samping itu, Anda harus mempelajari dan menggunakan custom-SDK, yang, selain papan ini, tidak akan berguna di tempat lain. Namun, kita akan melihat kedua cara, mulai dengan yang pertama.

Klasifikasi gambar


Pertimbangkan masalah pengenalan gambar. Untuk ini, kami akan menggunakan model ResNet50 yang disertakan dengan Keras (model ini adalah pemenang dari Tantangan ImageNet di 2015). Untuk menggunakannya, beberapa baris kode sudah cukup.

import tensorflow as tf import numpy as np import time IMAGE_SIZE = 224 IMG_SHAPE = (IMAGE_SIZE, IMAGE_SIZE, 3) resnet = tf.keras.applications.ResNet50(input_shape=IMG_SHAPE) img = tf.contrib.keras.preprocessing.image.load_img('cat.png', target_size=(IMAGE_SIZE, IMAGE_SIZE)) t_start = time.time() img_data = tf.contrib.keras.preprocessing.image.img_to_array(img) x = tf.contrib.keras.applications.resnet50.preprocess_input(np.expand_dims(img_data, axis=0)) probabilities = resnet.predict(x) print(tf.contrib.keras.applications.resnet50.decode_predictions(probabilities, top=5)) print("dT", time.time() - t_start) 

Saya bahkan tidak mulai menghapus kode di bawah spoiler, karena dia sangat kecil. Seperti yang Anda lihat, gambar pertama kali diubah ukurannya menjadi 224x224 (ini adalah format jaringan input), pada akhirnya, fungsi prediksi melakukan semua pekerjaan.

Kami mengambil foto kucing dan menjalankan program.



Hasil:

 [[('n02123045', 'tabby', 0.765179), ('n02123159', 'tiger_cat', 0.19059166), ('n02124075', 'Egyptian_cat', 0.013605555), ('n04493381', 'tub', 0.0025916891), ('n04553703', 'washbasin', 0.0021566998)]] 

Sekali lagi, kesal dengan pengetahuannya tentang bahasa Inggris (saya ingin tahu berapa banyak orang non-pribumi yang tahu apa itu "kucing"?), Saya memeriksa hasilnya dengan kamus, ya, semuanya berfungsi.

Waktu eksekusi kode PC adalah 0,5 detik untuk perhitungan pada CPU dan 2 detik (!) Untuk perhitungan pada GPU. Dilihat oleh log, masalahnya ada di model atau di Tensorflow, tetapi ketika dimulai, kode mencoba mengalokasikan banyak memori, menerima beberapa peringatan dari bentuk โ€œAllocator (GPU_0_bfc) kehabisan memori mencoba mengalokasikan 2.13GiB dengan freed_by_count = 0.โ€ . Ini adalah peringatan dan bukan kesalahan, kode ini berfungsi, tetapi jauh lebih lambat dari yang seharusnya.

Di Jetson Nano, masih lebih lambat: 2.8c pada CPU dan 18.8c pada GPU, sementara outputnya terlihat seperti ini:



Secara umum, bahkan 3s per gambar, ini belum real time. Mengatur opsi gpu_options.allow_growth yang direkomendasikan pada stack overflow tidak membantu, jika ada yang tahu cara lain, tulis di komentar.

Sunting : seperti yang diminta dalam komentar, awal pertama tensorflow selalu memakan waktu lama, dan tidak tepat untuk mengukur waktu menggunakannya. Memang, saat memproses file kedua dan selanjutnya, hasilnya jauh lebih baik - 0,6 tanpa GPU dan 0,2 dengan GPU. Pada desktop, kecepatannya masing-masing adalah 2,0 detik dan 0,05 detik.

Fitur nyaman dari ResNet50 adalah bahwa pada mulanya ia memompa seluruh model ke disk (sekitar 100 MB), kemudian kode berfungsi sepenuhnya secara mandiri, tanpa registrasi dan SMS. Yang sangat bagus, mengingat sebagian besar layanan AI modern hanya bekerja di server, dan tanpa Internet, perangkat berubah menjadi "labu".

Kucing vs anjing


Pertimbangkan masalah berikut. Menggunakan Keras, kami akan membuat jaringan saraf yang dapat membedakan antara kucing dan anjing. Ini akan menjadi jaringan saraf convolutional (CNN - Convolutional Neural Network), kami akan mengambil desain jaringan dari publikasi ini . Seperangkat pelatihan gambar kucing dan anjing sudah termasuk dalam paket tensorflow_datasets, jadi Anda tidak perlu memotretnya sendiri.

Kami memuat serangkaian gambar dan membaginya menjadi tiga blok - pelatihan, verifikasi, dan pengujian. Kami "menormalkan" setiap gambar, membawa warna ke kisaran 0..1.

 import tensorflow as tf from tensorflow.keras import layers import tensorflow_datasets as tfds from keras.preprocessing import image import numpy as np import time IMAGE_SIZE = 64 IMG_SHAPE = (IMAGE_SIZE, IMAGE_SIZE, 3) splits = tfds.Split.TRAIN.subsplit(weighted=(80, 10, 10)) (cat_train, cat_valid, cat_test), info = tfds.load('cats_vs_dogs', split=list(splits), with_info=True, as_supervised=True) label_names = info.features['label'].int2str def pre_process_image(image, label): image = tf.cast(image, tf.float32) image = image / 255.0 # Normalize image: 0..255 -> 0..1 image = tf.image.resize(image, (IMAGE_SIZE, IMAGE_SIZE)) return image, label BATCH_SIZE = 32 SHUFFLE_BUFFER_SIZE = 1000 train_batch = cat_train.map(pre_process_image).shuffle(SHUFFLE_BUFFER_SIZE).repeat().batch(BATCH_SIZE) validation_batch = cat_valid.map(pre_process_image).repeat().batch(BATCH_SIZE) 

Kami menulis fungsi menghasilkan jaringan saraf convolutional.

 def custom_model(): # Source: https://medium.com/@ferhat00/deep-learning-with-keras-classifying-cats-and-dogs-part-1-982067594856 classifier = tf.keras.Sequential() # Step 1 โ€” Convolution classifier.add(layers.Conv2D(32, (3, 3), input_shape=IMG_SHAPE, activation='relu')) # Step 2 โ€” Pooling classifier.add(layers.MaxPooling2D(pool_size=(2, 2))) # Adding a second convolutional layer classifier.add(layers.Conv2D(32, (3, 3), activation='relu')) classifier.add(layers.MaxPooling2D(pool_size=(2, 2))) # Step 3 โ€” Flattening classifier.add(layers.Flatten()) # Step 4 โ€” Full connection classifier.add(layers.Dense(units=128, activation='relu')) classifier.add(layers.Dense(units=1, activation='sigmoid')) # Compiling the CNN we shall use the Adam stochastic optimisation method, binary cross entropy loss function classifier.compile(optimizer=tf.keras.optimizers.Adam(), loss='binary_crossentropy', metrics=['accuracy']) return classifier 

Sekarang kita bisa menjalankan pelatihan jaringan pada kit "kucing-anjing" kita. Pelatihan ini memakan waktu lama (20 menit pada GPU dan 1-2 jam pada CPU), jadi pada akhirnya kami menyimpan model ke file.

 tl_model = custom_model() t_start = time.time() tl_model.fit(train_batch, steps_per_epoch=8000, epochs=2, validation_data=validation_batch, validation_steps=10, callbacks=None) print("Training done, dT:", time.time() - t_start) print(tl_model.summary()) validation_steps = 20 loss0, accuracy0 = tl_model.evaluate(validation_batch, steps=validation_steps) print("Loss: {:.2f}".format(loss0)) print("Accuracy: {:.2f}".format(accuracy0)) tl_model.save("dog_cat_model.h5") 

Omong-omong, upaya untuk meluncurkan pelatihan langsung pada Jetson Nano gagal - setelah 5 menit, papan terlalu panas dan digantung. Untuk perhitungan intensif sumber daya, pendingin diperlukan untuk papan, meskipun pada umumnya, tidak ada gunanya melakukan tugas-tugas seperti itu secara langsung di Jetson Nano - Anda dapat melatih model pada PC dan menggunakan file yang disimpan jadi pada Nano.

Kemudian jebakan lain keluar - perpustakaan tensowflow versi 14 diinstal pada PC, dan versi terbaru untuk Jetson Nano sejauh ini adalah 13. Dan model yang disimpan dalam versi 14 tidak dibaca pada tanggal 13, saya harus menginstal versi yang sama menggunakan pip.

Akhirnya, kita dapat memuat model dari file dan menggunakannya untuk mengenali gambar.

 def predict_model(model, image_file): img = image.load_img(image_file, target_size=(IMAGE_SIZE, IMAGE_SIZE)) t_start = time.time() img_arr = np.expand_dims(img, axis=0) result = model.predict_classes(img_arr) print("Result: {}, dT: {}".format(label_names(result[0][0]), time.time() - t_start)) model = tf.keras.models.load_model('dog_cat_model.h5') predict_model(model, "cat.png") predict_model(model, "dog1.png") predict_model(model, "dog2.png") 

Foto kucing digunakan sama, tetapi untuk tes "anjing" 2 gambar digunakan:



Yang pertama menebak dengan benar, dan yang kedua pada awalnya memiliki kesalahan dan jaringan saraf mengira itu adalah kucing, saya harus meningkatkan jumlah iterasi pelatihan. Namun, saya mungkin akan melakukan kesalahan pertama kali;)

Waktu eksekusi di Jetson Nano ternyata cukup kecil - foto pertama diproses dalam 0,3s, tetapi semua yang berikutnya jauh lebih cepat, tampaknya data di-cache dalam memori.



Secara umum, kita dapat mengasumsikan bahwa pada jaringan saraf sederhana seperti itu kecepatan papan sudah cukup bahkan tanpa optimasi, 100fps adalah nilai yang cukup bahkan untuk video secara real time.

Kesimpulan


Seperti yang Anda lihat, bahkan model standar dari Keras dan Tensorflow dapat digunakan pada Nano, meskipun dengan berbagai keberhasilan - sesuatu berfungsi, sesuatu tidak. Namun, hasilnya dapat ditingkatkan, petunjuk tentang cara mengoptimalkan model dan mengurangi ukuran memori dapat dibaca di sini .

Tapi untungnya bagi kita, produsen sudah melakukan ini untuk kita. Jika pembaca masih memiliki minat, bagian terakhir akan dikhususkan untuk perpustakaan siap pakai yang dioptimalkan untuk bekerja dengan Jetson Nano.

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


All Articles