Entwicklung eines neuronalen Netzes mithilfe von Python Keras
Im folgenden Beitrag zeige ich, wie man ein neuronales Netz mithilfe von Python
und Keras
entwickelt und implementiert. Keras
basiert auf Googles Machine-Learning-Plattform TensorFlow
. Das neuronale Netzwerk war Teil eines früheren Projekts, mit dem Ziel, die statistisch relevantesten Keywords einer Website zu extrahieren und diese in die jeweilige Branchenkategorie einzuordnen. In diesem Beitrag wird der Algorithmus mit einem Datensatz trainiert, der 16.000 Unternehmen und deren wichtigste Website-Keywords als Input-Variablen sowie mehr als 30 verschiedene Branchenkategorien als Output-Variablen umfasst.
Obwohl Machine Learning Modelle auf umfangreicher mathematischer Theorie basieren, ist der Prozess der Entwicklung, des Trainings, des Testens und der Anwendung eines Modells tatsächlich ein experimenteller Prozess. Dabei werden verschiedene Modifikationen des Algorithmus entwickelt und getestet und bei jedem Durchgang analysiert, welches Modell am besten funktioniert. Die Entwicklung und Implementierung der meisten Machine Learning Algorithmen besteht grundsätzlich aus fünf Schritten: (1) die Extraktion der Merkmale, (2) Reduktion der Dimension, (3) Training, (4) Testen sowie (5) die praktische Anwendung des Modells auf reale Daten.
Neuronale Netze sind äußerst leistungsstarke Algorithmen und basieren auf einer äußerst soliden mathematischen Grundlage. Grundsätzlich sind künstliche neuronale Netze eine abstrakte Nachbildung der Funktionsweise biologischer Gehirne. In biologischen Gehirnen empfangen die Neuronen Signale über ihre Dendriten, die je nach Häufigkeit und Wichtigkeit gewichtet und im sogenannten Nukleus, also dem Zellkern, akkumuliert werden. Sobald ein bestimmter Schwellenwert erreicht ist, leitet das Neuron das Signal an andere Neuronen weiter.
Das Beispiel in der Abbildung unten zeigt ein künstliches neuronales Netzwerk mit einem Input-Layer, drei nachgelagerte Layer und einem Output-Layer. Jeder dieser Layer besteht aus Neuronen, die mit den Neuronen des nächsten Layers verbunden sind.
Neuronale Netze können mathematisch durch die folgende Formel ausgedrückt werden, die aus drei Hauptkomponenten besteht: (1) Topologie, (2) Trainingsalgorithmus und (3) Aktivierungsfunktion – Elemente, die fast alle neuronalen Netze charakterisieren.
Die Topologie definiert die allgemeine Struktur des Netzwerks, zum Beispiel, wie viele Layer das Netzwerk enthält oder wie viele Neuronen jeder Layer umfasst. Der Trainingsalgorithmus wird verwendet, um die Gewichte zu berechnen, und die Aktivierungsfunktion leitet das Signal an das nächste verbundene Neuron weiter, wenn das Eingangssignal einen bestimmten Schwellenwert erreicht hat. Für dieses neuronale Netz implementiere ich eine Softmax-Funktion, die sich vor allem für Multi-Class Klassifikationen eignet.
Bevor wir mit dem Training beginnen, führen wir eine Merkmalsextraktion und eine Reduktion der Dimensionen mit einem LSTM-Vektorisierer durch. Ein LSTM-Vektorisierer transformiert jeden Text in einen Vektor, der während des Trainingsloops Informationen speichert. Dadurch kann der Algorithmus ein Wort im Kontext eines anderen Wortes platzieren, da er relevante frühere Informationen im LSTM-Vektor während des Trainingsprozesses speichert. Für das folgende neuronale Netz umfasst die Topologie vier Layer: (1) einen Input Layer mit maximal 50.000 Wörtern und einer Dimension von 100, (2) eine räumlichen Dropout-Layer mit einer Dropout-Rate von 0,2, (3) einen LSTM-Layer mit 100 Speicherobjekten und (4) einen dense Layer mit der Länge der Gesamtkategorien und einer Aktivierungsfunktion.
Nun implementieren wir dies mit Python
und Keras
. Im Code unten importieren wir zunächst die Python
Libraries, die wir für das Training und die Tests des Modells benötigen. Wir verwenden Keras
, das auf Googles TensorFlow
basiert, um das Modell zu erstellen und zu trainieren.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Dense, Embedding, LSTM, SpatialDropout1D
from sklearn.model_selection import train_test_split
from keras.utils.np_utils import to_categorical
from keras.callbacks import EarlyStopping
from keras.layers import Dropout
import pickle
Im nächsten Schritt laden wir den Datensatz in das Programm und erstellen daraus ein Pandas
DataFrame
-Objekt.
df = pd.read_csv('Training_Data_Raw_Clean_True_Sample_500_FINAL.csv', sep=',',
encoding='utf-8')
Um sicherzustellen, dass wir einen ausgewogenen Datensatz haben, kontrollieren wir die Verteilung der Klassen. Möglicherweise müssen wir weitere Daten organisieren oder die Daten nach ihrer Verteilung gewichten. Wichtig bei neuronalen Netzen ist, dass alle Klassen gleich viele Datenpunkte umfassen.
fig, ax = plt.subplots()
fig.suptitle('Class', fontsize=12)
dtf['Class'].reset_index().groupby('Class').count().sort_values(by='index').plot(kind='barh',
legend=False, ax=ax).grid(axis='x')
plt.show()
Im nächsten Schritt definieren wir einige Parameter, bevor wir mit einigen Datenvorverarbeitungsschritten fortfahren. Dabei definieren wir die maximale Anzahl von Wörtern mit den häufigsten Schlüsselwörtern, die maximale Länge eines Dokuments und die Größe des Embedding Layers.
MAX_NB_WORDS = 50000
MAX_SEQUENCE_LENGTH = 100
EMBEDDING_DIM = 100
Als Nächstes erstellen wir einen Tokenizer, passen den Text an den Tokenizer an und erstellen einen Wortindex. Nachdem das Modell trainiert wurde, speichern wir den Tokenizer als Pickle-Datei, da wir ihn später für die Vorhersage neuer Daten benötigen.
tokenizer = Tokenizer(num_words=MAX_NB_WORDS, filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~',
lower=True)
tokenizer.fit_on_texts(df['Text_Top100'].values)
word_index = tokenizer.word_index
print('Dataset includes %s unique tokens.' % len(word_index))
Wir verwenden nun den Tokenizer, um die Merkmale zu reduzieren und in einen Vektor mit derselben Länge für das Modell umzuwandeln.
X = tokenizer.texts_to_sequences(df['Text_Top100'].values)
X = pad_sequences(X, maxlen=MAX_SEQUENCE_LENGTH)
print('Shape of data tensor:', X.shape)
Im nächsten Schritt transformieren wir die Klassen (Y) in Dummy-Variablen. Der Grund dafür ist, dass Klassen keine kardinalen oder ordinalen Variablen darstellen, weshalb wir sie in eine Sprache umwandeln müssen, die eine Maschine verstehen kann.
Y = pd.get_dummies(df['Class']).values
print('Shape of label tensor:', Y.shape)
Nun teilen wir den Datensatz in einen Trainings- und einen Testdatensatz auf, wobei der Trainingsdatensatz 90 % aller Unternehmen im Datensatz umfasst und der Testdatensatz 10 %. Der Parameter random state
ist ein Seed-Wert, der es uns ermöglicht, denselben zufälligen Datensplit zu reproduzieren.
X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size = 0.10,
random_state = 42)
print(X_train.shape,Y_train.shape)
print(X_test.shape,Y_test.shape)
Nun können wir das Modell entwickeln. Im Code-Snippet unten initialisieren wir das Modell und definieren seine Layer und deren Parameter.
model = Sequential()
model.add(Embedding(MAX_NB_WORDS, EMBEDDING_DIM, input_length=X.shape[1]))
model.add(SpatialDropout1D(0.2))
model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(30, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
Nachdem das Modell definiert ist, legen wir einige Parameter für den Trainingsprozess fest und trainieren das Modell. Der Parameter batch size
hilft uns, während des Trainingsprozesses einen Memory Overload zu vermeiden.
epochs = 10
batch_size = 64
history = model.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size,
validation_split=0.1, callbacks=[EarlyStopping(monitor='val_loss', patience=3, min_delta=0.0001)])
"""
Epoch 1/10
190/190 [==============================] - 48s 233ms/step - loss: 3.3299
accuracy: 0.0568 - val_loss: 2.7465 - val_accuracy: 0.1616
Epoch 2/10
190/190 [==============================] - 46s 243ms/step - loss: 2.6218
accuracy: 0.2174 - val_loss: 2.4607 - val_accuracy: 0.2276
Epoch 3/10
190/190 [==============================] - 55s 287ms/step - loss: 2.1239
accuracy: 0.3501 - val_loss: 1.9390 - val_accuracy: 0.3988
Epoch 4/10
190/190 [==============================] - 47s 249ms/step - loss: 1.5604
accuracy: 0.5294 - val_loss: 1.5267 - val_accuracy: 0.5448
Epoch 5/10
190/190 [==============================] - 46s 242ms/step - loss: 1.0613
accuracy: 0.6898 - val_loss: 1.4558 - val_accuracy: 0.5589
Epoch 6/10
190/190 [==============================] - 47s 249ms/step - loss: 0.7276
accuracy: 0.7973 - val_loss: 1.2062 - val_accuracy: 0.6679
Epoch 7/10
190/190 [==============================] - 46s 240ms/step - loss: 0.4754
accuracy: 0.8782 - val_loss: 1.0980 - val_accuracy: 0.7116
Epoch 8/10
190/190 [==============================] - 45s 236ms/step - loss: 0.3312
accuracy: 0.9184 - val_loss: 1.3245 - val_accuracy: 0.6575
Epoch 9/10
190/190 [==============================] - 46s 242ms/step - loss: 0.3163
accuracy: 0.9246 - val_loss: 1.1268 - val_accuracy: 0.7079
Epoch 10/10
190/190 [==============================] - 45s 237ms/step - loss: 0.2286
accuracy: 0.9479 - val_loss: 1.0447 - val_accuracy: 0.7487
Nach Abschluss des Trainingsprozesses bewerten wir das Modell anhand der Testdaten und analysieren die Genauigkeit und Verlustfunktion.
accr = model.evaluate(X_test,Y_test)
print('Test set\n Loss: {:0.3f}\n Accuracy: {:0.3f}'.format(accr[0],accr[1]))
plt.title('Loss')
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend()
plt.show();
plt.title('Accuracy')
plt.plot(history.history['accuracy'], label='train')
plt.plot(history.history['val_accuracy'], label='test')
plt.legend()
plt.show();
Nun können wir das Modell anwenden, um neue Input-Daten vorherzusagen. Wir benötigen den Tokenizer, um die neuen Input-Daten zu transformieren. Beachten Sie, dass die Reihenfolge der Labels keine Rolle spielt, da Keras
sie alphabetisch anordnet.
New_Website = ['PORR Management World Tiefbau Video Hochbau Infrastruktur
Medien Publikationen Nachhaltigkeit Public Hansen Lehre Erdbau Altlasten
Umwelttechnik Design Engineering Abdichtung Jobbörse Investor Relations
Compliance Einkauf Karrierewege Weiterbildung Images flags czech eská
Republika e tina Organisation Magazin Digitales Fachmagazin Länderseiten
Français Polska Polski România Român Slovensko Sloven Revitalisierung Palais
Hotel Bauüberwachung Großprojekte Einkaufszentren Industrie Sonderbauten Bauten
Stadien Wohnbau Bahnbau Brückenbau Ingenieurbau Kraftwerksbau Leitungsbau
Spezialtiefbau Straßenbau Tunnelbau Überregionaler Wasserbau Rückbau Deponie
Kies Transport Umweltlabor Architektur Bauphysik Bauvorbereitung Brandschutz
Building Modeling Generalplanung LEAN Techn Tragwerksplanung Beschichtung
Betondeckenbau Facility Fassadenbau Feste Fahrbahn Flughafenbau Health Care
Hochgebirgsbau Hochhäuser Partnership Property Stahlbau Broschüren
Ansprechpersonen Öffentliche Abbruch Traineeprogramm']
sequence = tokenizer.texts_to_sequences(New_Website)
padded_sequence = pad_sequences(sequence, maxlen=MAX_SEQUENCE_LENGTH)
pred = model.predict(padded_sequence)
labels = ['Class_10_Holzverarbeitung',
'Class_11_Glas_Keramik_Porzellan',
'Class_12_Optik_Schmuck_Uhren_Edelmetalle',
'Class_13_Zellstoffe_Papier_Verpackungen',
'Class_14_Textilien_Leder',
'Class_15_Lebensmittelerzeugung_Genussmittel',
'Class_16_Landwirtschaft_Forstwirtschaft_Gartenbau',
'Class_17_Logistik_Transport',
'Class_1_Abfallwirtschaft_Energie_Wasserwirtschaft',
'Class_20_Medizin_Healthcare',
'Class_21_Pflege_Betreuung_Soziale_Dienste',
'Class_22_Banking',
'Class_23_Unternehmensberatung_BWL_Dienste',
'Class_24_Immobilien',
'Class_25_Rechtswesen_Anwaelte',
'Class_26_Marketing',
'Class_27_Medien_Druck_Verlagswesen',
'Class_28_Kultur_Kunst_Brauchtum',
'Class_29_Sport_Freizeit_Events',
'Class_2_EDV_Telekommunikation_Elektronik',
'Class_30_Gastwirtschaft_Restaurant_Touristik',
'Class_31_Friseure_Beauty_Wellness',
'Class_32_Schulen_Fortbildungseinrichtungen',
'Class_33_Behoerden_Parteien_Verbaende',
'Class_3_Maschinen_Anlagen_Werkzeuge',
'Class_4_Automobil_Fahrzeuge_Motoren',
'Class_5_Metallverarbeitung',
'Class_6_Pharmazie_Biotechnologie_Bio_Engineering',
'Class_8_Baubranche_Handwerk',
'Class_9_Rohstoffe_Baustoffe']
print(pred, labels[np.argmax(pred)])
['Class_8_Baubranche_Handwerk']
Schließlich speichern wir das Modell und den Tokenizer, sodass wir sie später verwenden und in der realen Welt anwenden können.
model.save('C:/Users/Dokumente/Developing/Python/Branch Classifyer')
filename = 'Tokenizer_ANN.sav'
pickle.dump(tokenizer, open(filename, 'wb'))
Falls wir das Modell später verwenden möchten, könnten wir das gespeicherte Modell und den Tokenizer einfach mit den folgenden Befehlen in das Programm laden.
model = keras.models.load_model('C:/Users/Dokumente/Developing/Python/Branch Classifyer')
tokenizer = pickle.load(open('Tokenizer_ANN.sav', 'rb'))
Das war's