Das Gehirn von innen (Visualisierung des Durchgangs des Musters durch das künstliche neuronale Netzwerkmodell)

Einführung


Der Artikel richtet sich an diejenigen, die sich jemals für die Frage interessiert haben, was innerhalb des künstlichen neuronalen Netzwerks ( ANN) geschieht. Jetzt kann fast jeder seine eigene ANN mit den vorgefertigten Bibliotheken entwickeln, die in den meisten Programmiersprachen verfügbar sind. In diesem Artikel werde ich versuchen zu zeigen, wie das Objekt ( Muster ) genau aussieht, indem es die Ebenen des ANN durchläuft, die mithilfe der Tensorflow Deep Learning- Bibliothek mit dem Keras- Add- In entwickelt und kompiliert wurden.

Gebrauchte Software


Die folgenden Komponenten sind erforderlich (die Versionen, die ich für meinen Fall angegeben habe):

  • Tensorflow 1.10.0
  • Keras 2.2.4
  • matplotlib 2.2.0
  • modul-os
  • numpy1.14.3

Es ist auch möglich, die Netzwerkarchitektur zu zeichnen, aber dafür ist es notwendig, Visualisierungstools zu installieren, in meinem Fall wurden Keras verwendet, und in der Methode

PLOT_PATTERN_PROCCESS(...) 

zu etablieren

PLOT_MODEL = True


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

Bild

Hauptidee


Es ist notwendig, ein Muster auszuwählen (die Passage, die wir beobachten werden). Nach der Auswahl wird das Netzwerk in Tensorschichten unterteilt. Im Zyklus von der zweiten bis zur letzten Schicht wird ein neues Netzwerk erstellt, wobei die Ausgabe die Nummer der Schicht im Zyklus ist. Wenn das Muster übersprungen wird, ist das Ergebnis am Netzwerkausgang ein n-dimensionales Array.

Implementierung


Bibliotheken verbinden

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

Verwendete Methoden:

  • def PLOT_PATTERN_PROCCESS (Modell, Muster, FOLDER_TO_SAVE, grid_size = (3, 3), limit_size_layer = (15, 15), PLOT_MODEL = True):
     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) -> Sequentiell:
     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 


Programmcode

 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) ) 

Programmbeschreibung


Methode

 build_model() 

Gibt ein ANN-Modell im sequentiellen Format zurück, mit dem etwas in 5 Klassen eingeteilt werden soll.

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 _________________________________________________________________ 


Wie Sie der Architektur entnehmen können, ist ein Muster ein Array der Größe 50 x 50. Variable

 pattern 

und es gibt ein beobachtbares Objekt.
Als nächstes wird ein Verzeichnis erstellt

 os.makedirs("PLOT_PATTERN_PROCCESS") 
,
wo das gesamte Ergebnis gespeichert wird.

Methodenbeschreibung PLOT_PATTERN_PROCCESS


Ich habe die Bedeutung der Methode oben beschrieben, aber es ist wichtig zu sagen, dass wir nicht alle Ebenen benötigen, da die Ausgaben einiger Ebenen nicht angezeigt werden können oder dies nicht informativ ist.
Das Abrufen des Ausgabemusters erfolgt hier:

 _output = _model.predict(pattern)[0] 

In dieser Implementierung können Sie ein zweidimensionales Ausgabemuster anzeigen, dessen Abmessungen nicht kleiner als der Parameter sind

 limit_size_layer 

Abwechselnd durch die Ebenen des ANN-Modells die Variable

 SAVE_AR_LIST 
allmählich mit Daten gefüllt:

  1. Ebenennummer

     num_layer 
  2. Ebenenname

     model.layers[num_layer].name 
  3. Zweidimensionales Array ausgeben

      _output.tolist() 

Ein Ergebnis nach und nach ausschließen

 SAVE_AR_LIST 
,
und in die Leinwandzelle legen

 ax.imshow(np.array(ar), cmap='viridis', extent=(xmin, xmax, ymin, ymax)) 
.
Das Ergebnis ist eine Datei (0.png)

Bild

Empfehlungen


  • Stellen Sie den Ebenennamen wie folgt ein:

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

    Dies ist sehr praktisch beim Bewerten und Vergleichen mit der Neuroarchitektur.
  • Mit diesem Ansatz ist es interessant zu beobachten, wie sich das Muster beim Passieren des Netzwerks ändert, wenn Sie von Ära zu Ära lernen
  • Installieren Sie das Gitter nicht

     grid_size 

    groß weil Die Größe der angezeigten Bilder ist klein und nicht aussagekräftig
  • Wenn Sie die Passage in der Dynamik beobachten (beim Lernen oder Übergeben einer Reihe von Mustern), sprechen wir bereits über Informationen von großer Größe. Um den von der Anwendung belegten Arbeitsspeicher zu reduzieren, ist es besser, die Arrays in Dateien auf einem PC zu speichern, z. B. im JSON-Format , und nach der Verarbeitung aller Muster die Dateien einzeln zu durchlaufen und sie in Bilder umzuwandeln

Viel Glück!

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


All Articles