Otak dari dalam (visualisasi bagian dari pola melalui model jaringan saraf tiruan)

Pendahuluan


Artikel ini ditujukan bagi mereka yang pernah tertarik pada pertanyaan tentang apa yang terjadi di dalam jaringan saraf tiruan ( JST) . Sekarang hampir semua orang dapat mengembangkan JST mereka sendiri menggunakan perpustakaan siap pakai yang tersedia di sebagian besar bahasa pemrograman. Pada artikel ini, saya akan mencoba menunjukkan bagaimana objek ( Pola ) terlihat persis, melewati lapisan JST, dikembangkan dan disusun menggunakan perpustakaan pembelajaran mendalam Tensorflow dengan add- in Keras .

Perangkat lunak bekas


Komponen berikut diperlukan (versi yang saya tentukan untuk kasus saya):

  • tensorflow 1.10.0
  • keras 2.2.4
  • matplotlib 2.2.0
  • modul-os
  • numpy1.14.3

Dimungkinkan juga untuk menggambar arsitektur jaringan, tetapi untuk ini Anda perlu menginstal alat visualisasi, dalam kasus saya keras digunakan, dan dalam metode

PLOT_PATTERN_PROCCESS(...) 

untuk membangun

PLOT_MODEL = Benar


 def PLOT_PATTERN_PROCCESS(model, pattern, FOLDER_TO_SAVE, grid_size=(3, 3), limit_size_layer=(15, 15), PLOT_MODEL=True): 

gambar

Ide utama


Penting untuk memilih satu pola (bagian yang akan kita amati), setelah memilihnya, jaringan dibagi menjadi lapisan tensor . Dalam siklus dari lapisan kedua ke lapisan terakhir, jaringan baru dibuat, di mana output adalah jumlah lapisan dalam siklus, dan melewatkan pola, hasil pada output jaringan adalah array n-dimensi.

Implementasi


Menghubungkan perpustakaan

 from keras.models import * from keras.layers import * import matplotlib.pyplot as plt import os import numpy as np 

Metode yang digunakan:

  • def PLOT_PATTERN_PROCCESS (model, pola, FOLDER_TO_SAVE, grid_size = (3, 3), limit_size_layer = (15, 15), PLOT_MODEL = Benar):
     def PLOT_PATTERN_PROCCESS(model, pattern, FOLDER_TO_SAVE, grid_size=(3, 3), limit_size_layer=(15, 15), PLOT_MODEL=True): """ :param model:   keras :type model: Sequential :param pattern:  ,       :type pattern: np.array :param FOLDER_TO_SAVE:       :type FOLDER_TO_SAVE: str :param grid_size:     :type grid_size: tuple :param limit_size_layer:      :type limit_size_layer: tuple :param PLOT_MODEL:    :type PLOT_MODEL: PLOT_MODEL """ SAVE_AR_LIST = [] for num_layer in range(1, len(model.layers)): LO = model.layers[num_layer].output _model = Model(inputs=model.input, outputs=LO) if ( len(_model.output_shape) == 3 and _model.output_shape[1] > limit_size_layer[0] and _model.output_shape[2] > limit_size_layer[1] ): _output = _model.predict(pattern)[0] SAVE_AR_LIST.append( [ num_layer, model.layers[num_layer].name, _output.tolist() ] ) ### PIC_NUM = 0 while len(SAVE_AR_LIST) > 0: fig, axs = plt.subplots(nrows=grid_size[0], ncols=grid_size[1], figsize=(10, 10), tight_layout=True) xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() for ax in axs.flat: [num_layer, layer_name, ar] = SAVE_AR_LIST.pop(0) ax.imshow(np.array(ar), cmap='viridis', extent=(xmin, xmax, ymin, ymax)) ax.set_title(layer_name + " " + str(np.array(ar).shape)) if len(SAVE_AR_LIST) == 0: break # plt.show() plt.savefig(os.path.join(FOLDER_TO_SAVE, str(PIC_NUM) + '.png'), fmt='png') plt.close(fig) PIC_NUM += 1 ### if PLOT_MODEL: from keras.utils.vis_utils import plot_model plot_model( model=model, to_file=os.path.join(FOLDER_TO_SAVE, model.name + " neural network architecture.png"), show_shapes=True, show_layer_names=True ) ### 

  • def build_model (IN_SHAPE = 50, CLASSES = 5) -> Sequential:
     def build_model(IN_SHAPE=50,CLASSES=5) -> Sequential: inputs_LAYER0 = Input(shape=(IN_SHAPE,IN_SHAPE)) Dense_2_2 = Dense(75, activation='relu')(inputs_LAYER0) Dense_2_3 = Dense(50, activation='relu', name="my_dense")(Dense_2_2) Dense_2_4 = Dense(25, activation='relu')(Dense_2_3) Dense_2_5 = Dense(10, activation='relu')(Dense_2_4) flat_f_0 = Flatten()(Dense_2_5) final_layer= Dense(CLASSES, activation='softmax')(flat_f_0) # model = Model(input=inputs_LAYER0, output=final_layer, name="simple model") model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.summary() return model 


Kode program

 model_ = build_model() pattern = np.random.sample((1,50,50)) os.makedirs("PLOT_PATTERN_PROCCESS") PLOT_PATTERN_PROCCESS( model = model_, pattern = pattern, FOLDER_TO_SAVE = "PLOT_PATTERN_PROCCESS", PLOT_MODEL=False, grid_size=(2, 2) ) 

Deskripsi Program


Metode

 build_model() 

mengembalikan model JST dalam format Sequential , yang dirancang untuk mengklasifikasikan sesuatu ke dalam 5 kelas.

model.summary ()
 _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) (None, 50, 50) 0 _________________________________________________________________ dense_1 (Dense) (None, 50, 75) 3825 _________________________________________________________________ my_dense (Dense) (None, 50, 50) 3800 _________________________________________________________________ dense_2 (Dense) (None, 50, 25) 1275 _________________________________________________________________ dense_3 (Dense) (None, 50, 10) 260 _________________________________________________________________ flatten_1 (Flatten) (None, 500) 0 _________________________________________________________________ dense_4 (Dense) (None, 5) 2505 ================================================================= Total params: 11,665 Trainable params: 11,665 Non-trainable params: 0 _________________________________________________________________ 


Seperti yang dapat Anda lihat dari arsitektur, sebuah pola adalah array ukuran 50x50. Variabel

 pattern 

dan ada objek yang bisa diamati.
Selanjutnya, direktori dibuat

 os.makedirs("PLOT_PATTERN_PROCCESS") 
,
di mana seluruh hasil akan disimpan.

Deskripsi Metode PLOT_PATTERN_PROCCESS


Saya menjelaskan arti dari metode di atas, tetapi penting untuk mengatakan bahwa kita tidak memerlukan semua layer, karena output dari beberapa layer tidak dapat ditampilkan atau ini tidak akan informatif.
Mendapatkan pola output terjadi di sini:

 _output = _model.predict(pattern)[0] 

Dalam implementasi ini, Anda dapat menampilkan pola output dua dimensi yang dimensinya tidak kurang dari parameter

 limit_size_layer 

Bergantian melalui lapisan model JST, variabel

 SAVE_AR_LIST 
secara bertahap diisi dengan data:

  1. Nomor lapisan

     num_layer 
  2. Nama lapisan

     model.layers[num_layer].name 
  3. Output array dua dimensi

      _output.tolist() 

Secara bertahap mengecualikan satu hasil dari

 SAVE_AR_LIST 
,
dan menaruhnya di sel kanvas

 ax.imshow(np.array(ar), cmap='viridis', extent=(xmin, xmax, ymin, ymax)) 
.
Hasilnya adalah file (0.png)

gambar

Rekomendasi


  • Atur nama layer sebagai berikut:

     Dense_2_3 = Dense(50, activation='relu', name="my_dense")(Dense_2_2) 

    Ini sangat nyaman ketika mengevaluasi dan membandingkan dengan neuroarchitecture.
  • Dengan menggunakan pendekatan ini, menarik untuk menyaksikan bagaimana pola berubah ketika melewati jaringan ketika belajar dari zaman ke zaman
  • Jangan pasang kisi

     grid_size 

    besar karena ukuran gambar yang ditampilkan akan kecil dan tidak informatif
  • Jika Anda mengamati bagian dalam dinamika (selama pelatihan atau melewati sekumpulan pola), kita sudah membicarakan informasi ukuran besar. Untuk mengurangi RAM yang ditempati oleh aplikasi, lebih baik menyimpan array ke file di PC, misalnya, dalam format JSON , dan setelah memproses semua pola, lakukan iterasi file satu per satu dan ubah menjadi gambar

Semoga beruntung

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


All Articles