Neural networks: implementasi tugas tentang jamur pada Tensor Flow dan Python

Tensor Flow adalah kerangka kerja untuk membangun dan bekerja dengan jaringan saraf dari Google. Memungkinkan Anda untuk mengabstraksi dari detail internal pembelajaran mesin dan fokus langsung pada penyelesaian masalah Anda. Suatu hal yang sangat kuat, memungkinkan Anda untuk membuat, melatih, dan menggunakan jaringan saraf jenis apa pun yang dikenal. Saya tidak menemukan satu pun teks masuk akal tentang HabrΓ© tentang topik ini, jadi saya menulis sendiri. Di bawah ini kami akan menjelaskan implementasi solusi untuk masalah jamur menggunakan perpustakaan Tensor Flow. Omong-omong, algoritma yang dijelaskan di bawah ini cocok untuk prediksi di hampir semua bidang. Misalnya, kemungkinan kanker pada seseorang di masa depan atau kartu pada lawan dalam poker.

Tantangan


Inti dari masalah: berdasarkan parameter input jamur untuk menentukan kemampuannya untuk dimakan. Spesifisitasnya adalah bahwa parameter ini kategorikal, bukan numerik. Misalnya, parameter "bentuk topi" dapat diatur ke "datar" atau "cembung" atau "berbentuk kerucut". Dataset jamur untuk pembelajaran jaringan yang diambil dari repositori pembelajaran mesin . Dengan demikian, solusi masalah dapat disebut semacam Hello World di bidang pembelajaran mesin, bersama dengan masalah iris , di mana parameter bunga dinyatakan dalam nilai digital.

Kode sumber


Anda dapat mengunduh semua sumber dari repositori saya di tautan Github :. Lakukan ini untuk melihat kode dalam aksi. Gunakan hanya kode sumber, karena semua indentasi dan pengodean yang diperlukan diamati di sana. Di bawah ini seluruh proses akan dibahas secara rinci.

Persiapan


Diasumsikan bahwa Anda memiliki instalasi Tensor Flow yang sudah diinstal sebelumnya. Jika tidak, Anda dapat menginstal tautannya .

Kode sumber


from __future__ import absolute_import from __future__ import division from __future__ import print_function import tensorflow as tf import numpy as np import pandas as pd from sklearn.model_selection import train_test_split import os #       . #     CSV-    Tensor Flow       .  ,       (0  1) def prepare_data(data_file_name): header = ['class', 'cap_shape', 'cap_surface', #  CSV-   ,     'agaricus-lepiota.name'   'cap_color', 'bruises', 'odor', 'gill_attachment', 'gill_spacing', 'gill_size', 'gill_color', 'stalk_shape', 'stalk_root', 'stalk_surface_above_ring', 'stalk_surface_below_ring', 'stalk_color_above_ring', 'stalk_color_below_ring', 'veil_type', 'veil_color', 'ring_number', 'ring_type', 'spore_print_color', 'population', 'habitat'] df = pd.read_csv(data_file_name, sep=',', names=header) #   "?"      #        df.replace('?', np.nan, inplace=True) df.dropna(inplace=True) #         #  'e'  'p' .       # ,   0  , 1 -    df['class'].replace('p', 0, inplace=True) df['class'].replace('e', 1, inplace=True) #       , #     . Tensor Flow      # .  Pandas    "get_dummies" #      cols_to_transform = header[1:] df = pd.get_dummies(df, columns=cols_to_transform) #      #    -    () #      () df_train, df_test = train_test_split(df, test_size=0.1) #           num_train_entries = df_train.shape[0] num_train_features = df_train.shape[1] - 1 num_test_entries = df_test.shape[0] num_test_features = df_test.shape[1] - 1 #      csv-, .. #          #  csv,    Tensor Flow df_train.to_csv('train_temp.csv', index=False) df_test.to_csv('test_temp.csv', index=False) #     ,    open("mushroom_train.csv", "w").write(str(num_train_entries) + "," + str(num_train_features) + "," + open("train_temp.csv").read()) open("mushroom_test.csv", "w").write(str(num_test_entries) + "," + str(num_test_features) + "," + open("test_temp.csv").read()) #   ,     os.remove("train_temp.csv") os.remove("test_temp.csv") #        Tensor Flow def get_test_inputs(): x = tf.constant(test_set.data) y = tf.constant(test_set.target) return x, y #        Tensor Flow def get_train_inputs(): x = tf.constant(training_set.data) y = tf.constant(training_set.target) return x, y #        #    ( : , ) #  ,         def new_samples(): return np.array([[0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]], dtype=np.int) if __name__ == "__main__": MUSHROOM_DATA_FILE = "agaricus-lepiota.data" #     Tensor Flow, #   CSV- (  ) prepare_data(MUSHROOM_DATA_FILE) #    training_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename='mushroom_train.csv', target_dtype=np.int, features_dtype=np.int, target_column=0) test_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename='mushroom_test.csv', target_dtype=np.int, features_dtype=np.int, target_column=0) # ,        ( ) feature_columns = [tf.contrib.layers.real_valued_column("", dimension=98)] #   DNN-  10, 20  10    classifier = tf.contrib.learn.DNNClassifier( feature_columns=feature_columns, hidden_units=[10, 20, 10], n_classes=2, model_dir="/tmp/mushroom_model") #   classifier.fit(input_fn=get_train_inputs, steps=2000) #        accuracy_score = classifier.evaluate(input_fn=get_test_inputs, steps=1)["accuracy"] print("\n : {0:f}\n".format(accuracy_score)) #         predictions = list(classifier.predict_classes(input_fn=new_samples)) print("   : {}\n" .format(predictions)) 

Unduh dan siapkan data dari repositori


Kami akan mengunduh data untuk pelatihan dan menguji jaringan saraf dari repositori pembelajaran mesin yang dibuat khusus untuk ini. Semua data disajikan dalam dua file: agaricus-lepiota.data dan agaricus-lepiota.names. 8124 baris pertama dan 22 kolom. Satu baris menyediakan satu jamur, setiap kolom adalah salah satu dari 22 parameter jamur dalam bentuk karakter reduksi dari seluruh kata parameter. Legenda semua karakter ada di file agarius-lepiota.names.

Data dari repositori perlu diproses untuk membawanya ke bentuk yang dapat diterima untuk Tensor Flow. Pertama, kami mengimpor beberapa perpustakaan untuk bekerja

 from __future__ import absolute_import from __future__ import division from __future__ import print_function import tensorflow as tf import numpy as np import pandas as pd from sklearn.model_selection import train_test_split import os 

Kemudian kita akan membentuk tajuk dari parameter jamur untuk Tensor Flow, sehingga pustaka tahu kolom mana dalam file data yang sesuai dengan parameter mana. Topi terpaku pada file data. Kami membentuk dalam bentuk array, yang unsur-unsurnya diambil dari file agaricus-lepiota.names.

 header = ['class', 'cap_shape', 'cap_surface', 'cap_color', 'bruises', 'odor', 'gill_attachment', 'gill_spacing', 'gill_size', 'gill_color', 'stalk_shape', 'stalk_root', 'stalk_surface_above_ring', 'stalk_surface_below_ring', 'stalk_color_above_ring', 'stalk_color_below_ring', 'veil_type', 'veil_color', 'ring_number', 'ring_type', 'spore_print_color', 'population', 'habitat'] df = pd.read_csv(data_file_name, sep=',', names=header) 

Sekarang Anda harus berurusan dengan data yang hilang. Dalam hal ini, simbol "?" Apakah diatur dalam file agaricus-lepiota.data, bukan parameter. Ada banyak metode untuk menangani kasus seperti itu, tetapi kami hanya akan menghapus seluruh baris dengan setidaknya satu parameter yang hilang.

 df.replace('?', np.nan, inplace=True) df.dropna(inplace=True) 

Selanjutnya, Anda harus secara manual mengganti parameter edibilitas simbolis dengan yang digital. Yaitu, ganti "p" dan "e" dengan 0 dan 1.

 df['class'].replace('p', 0, inplace=True) df['class'].replace('e', 1, inplace=True) 

Dan setelah itu, Anda dapat mengubah sisa data menjadi digit. Inilah yang fungsi get_dummies dari perpustakaan panda.

 cols_to_transform = header[1:] df = pd.get_dummies(df, columns=cols_to_transform) 

Setiap jaringan saraf perlu dilatih. Namun selain itu, juga perlu dikalibrasi untuk meningkatkan akurasi kerja dalam kondisi nyata. Untuk melakukan ini, kami akan membagi set data kami menjadi dua - pelatihan dan kalibrasi. Yang pertama akan lebih besar dari yang kedua, sebagaimana mestinya.

 df_train, df_test = train_test_split(df, test_size=0.1) 

Dan yang terakhir. Tensor Flow membutuhkan jumlah baris dan kolom file yang ditunjukkan pada awal file data. Kami akan secara manual mengekstrak informasi ini dari kumpulan data pelatihan dan kalibrasi kami dan kemudian menulis ke file CSV yang dihasilkan.

 #         num_train_entries = df_train.shape[0] num_train_features = df_train.shape[1] - 1 num_test_entries = df_test.shape[0] num_test_features = df_test.shape[1] - 1 #     CSV df_train.to_csv('train_temp.csv', index=False) df_test.to_csv('test_temp.csv', index=False) #       CSV,      open("mushroom_train.csv", "w").write(str(num_train_entries) + "," + str(num_train_features) + "," + open("train_temp.csv").read()) open("mushroom_test.csv", "w").write(str(num_test_entries) + "," + str(num_test_features) + "," + open("test_temp.csv").read()) 

Pada akhirnya, Anda harus mendapatkan file-file ini: pelatihan dan kalibrasi .

Lemparkan data yang dihasilkan ke Tensor Flow


Sekarang kami telah mengunduh dari repositori dan memproses file CSV dengan data jamur, Anda dapat mengirimnya ke Tensor Flow untuk pelatihan. Ini dilakukan menggunakan fungsi load_csv_with_header () yang disediakan oleh framework itu sendiri:

 training_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename='mushroom_train.csv', target_dtype=np.int, features_dtype=np.int, target_column=0) test_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename='mushroom_test.csv', target_dtype=np.int, features_dtype=np.int, target_column=0) 

Fungsi load_csv_with_header () terlibat dalam pembentukan set data pelatihan dari file yang telah kami kumpulkan di atas. Selain file data, fungsi tersebut menggunakan target_dtype sebagai argumen, yang merupakan tipe data yang diprediksi pada akhirnya. Dalam kasus kami, perlu untuk mengajarkan jaringan saraf untuk memprediksi edibilitas atau toksisitas jamur, yang dapat dinyatakan dengan nilai 1 atau 0. Dengan demikian, dalam kasus kami, target_dtype adalah nilai integer. features_dtype - parameter di mana jenis parameter yang diterima untuk pelatihan diatur. Dalam kasus kami, itu juga bilangan bulat (awalnya mereka adalah string, tetapi, seperti yang Anda ingat, kami menyalipnya menjadi angka). Pada akhirnya, parameter target_column diatur, yang merupakan indeks kolom dengan parameter yang diprediksi oleh jaringan saraf. Yaitu, dengan parameter edibilitas.

Buat Obyek Klasifikasi Tensor Aliran


Yaitu, objek kelas yang terlibat langsung dalam memprediksi hasil. Dengan kata lain, kelas jaringan saraf itu sendiri.

 feature_columns = [tf.contrib.layers.real_valued_column("", dimension=98)] classifier = tf.contrib.learn.DNNClassifier( feature_columns=feature_columns, hidden_units=[10, 20, 10], n_classes=2, model_dir="/tmp/mushroom_model") 

Parameter pertama adalah feature_columns. Ini adalah parameter jamur. Harap dicatat bahwa nilai parameter dibuat di sana, sedikit lebih tinggi. Di sana, pada input, nilai 98 dari parameter dimensi diambil, yang berarti 98 parameter jamur yang berbeda, dengan pengecualian dapat dimakan.

hidden_units - jumlah neuron di setiap lapisan jaringan saraf. Pilihan yang tepat dari jumlah lapisan dan neuron di dalamnya adalah sesuatu pada tingkat seni di bidang pembelajaran mesin. Adalah mungkin untuk menentukan nilai-nilai ini dengan benar hanya setelah pengalaman. Kami mengambil angka-angka ini hanya karena terdaftar di salah satu tutorial Tensor Flow. Dan mereka bekerja.

n_classes - jumlah kelas yang akan diprediksi. Kami memiliki dua dari mereka - dapat dimakan dan tidak.

model_dir - jalur di mana model terlatih dari jaringan saraf akan disimpan. Dan di masa depan itu akan digunakan untuk memprediksi hasil, agar tidak melatih jaringan setiap saat.

Pelatihan


Untuk kemudahan pekerjaan di masa mendatang, kami akan membuat dua fungsi:

 def get_test_inputs(): x = tf.constant(test_set.data) y = tf.constant(test_set.target) return x, y def get_train_inputs(): x = tf.constant(training_set.data) y = tf.constant(training_set.target) return x, y 

Setiap fungsi menyediakan set input data sendiri - untuk pelatihan dan kalibrasi. x dan y adalah konstanta Tensor Flow yang dibutuhkan kerangka kerja. Jangan merinci, cukup terima bahwa fungsi-fungsi ini harus menjadi perantara antara data dan jaringan saraf.

Kami melatih jaringan:

 classifier.fit(input_fn=get_train_inputs, steps=2000) 

Parameter pertama mengambil input data yang terbentuk tepat di atas, yang kedua - jumlah langkah pelatihan. Sekali lagi, nomor itu digunakan dalam salah satu manual Tensor Flow, dan pemahaman tentang pengaturan ini akan datang kepada Anda dengan pengalaman.

Selanjutnya, kalibrasikan jaringan terlatih. Ini dilakukan dengan menggunakan set data kalibrasi yang dihasilkan di atas. Hasil pekerjaan akan menjadi akurasi prediksi jaringan di masa mendatang (akurasi_score).

 accuracy_score = classifier.evaluate(input_fn=get_test_inputs, steps=1)["accuracy"] print("\n : {0:f}\n".format(accuracy_score)) 

Kami akan menguji


Sekarang jaringan saraf siap, dan Anda dapat mencoba untuk memprediksi dengan bantuan kelayakan jamur.

 def new_samples(): return np.array([[0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]], dtype=np.int) 

Fungsi di atas memberikan data dua jamur yang sama sekali baru yang tidak ada dalam pelatihan atau dalam set kalibrasi (pada kenyataannya, mereka hanya ditarik dari yang terakhir). Bayangkan, misalnya, bahwa Anda membelinya di pasar, dan berusaha memahami apakah mereka bisa dimakan. Kode di bawah ini akan mendefinisikan ini:

 predictions = list(classifier.predict(input_fn=new_samples)) print("   : {}\n" .format(predictions)) 

Hasil pekerjaan harus sebagai berikut:

    : [0, 1] 

Dan ini berarti jamur pertama beracun, yang kedua bisa dimakan. Dengan demikian, Anda dapat membuat prediksi berdasarkan data apa pun, baik itu jamur, manusia, hewan, atau apa pun. Cukup dengan benar membentuk input data. Dan untuk memprediksi, misalnya, kemungkinan aritmia pasien di masa depan atau pergerakan harga saham di bursa efek.

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


All Articles