Tensor Flow ist ein Framework zum Aufbau und zur Arbeit mit neuronalen Netzen von Google. Ermöglicht es Ihnen, von den internen Details des maschinellen Lernens zu abstrahieren und sich direkt auf die Lösung Ihres Problems zu konzentrieren. Es ist eine sehr leistungsstarke Funktion, mit der Sie neuronale Netze aller bekannten Typen erstellen, trainieren und verwenden können. Ich habe zu diesem Thema keinen einzigen vernünftigen Text über Habré gefunden, also schreibe ich meinen eigenen. Im Folgenden wird die Implementierung der Lösung für das Problem der Pilze mithilfe der Tensor Flow-Bibliothek beschrieben. Der unten beschriebene Algorithmus eignet sich übrigens für Vorhersagen in nahezu jedem Bereich. Zum Beispiel die Wahrscheinlichkeit von Krebs bei einer Person in der Zukunft oder Karten bei einem Gegner beim Poker.
Herausforderung
Das Wesentliche des Problems: Auf der Grundlage der Eingabeparameter des Pilzes, um seine Essbarkeit zu bestimmen. Die Besonderheit ist, dass diese Parameter kategorisch und nicht numerisch sind. Beispielsweise kann der Parameter "Hutform" auf "flach" oder "konvex" oder "kegelförmig" eingestellt werden. Pilzdatensatz für das Netzwerklernen aus dem
Repository für
maschinelles Lernen . Daher kann die Lösung des Problems als eine Art Hallo-Welt im Bereich des maschinellen Lernens bezeichnet werden, zusammen mit dem
Problem der Iris , bei der die Blumenparameter in digitalen Werten ausgedrückt werden.
Quellcode
Sie können alle Quellen aus meinem Repository auf Github herunterladen:
Link . Tun Sie dies, um den Code in Aktion zu sehen. Verwenden Sie nur Quellcodes, da dort alle erforderlichen Einrückungen und Codierungen beachtet werden. Im Folgenden wird der gesamte Prozess ausführlich besprochen.
Vorbereitung
Es wird davon ausgegangen, dass Sie eine vorinstallierte Tensor Flow-Installation haben. Wenn nicht, können Sie den
Link installieren.
Quellcode
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
Laden Sie Daten aus dem Repository herunter und bereiten Sie sie vor
Wir werden die Daten zum Trainieren und Testen des neuronalen Netzwerks aus
dem speziell dafür erstellten
Repository für
maschinelles Lernen herunterladen. Alle Daten werden in zwei Dateien dargestellt: agaricus-lepiota.data und agaricus-lepiota.names. Die ersten 8124 Zeilen und 22 Spalten. Eine Zeile enthält einen Pilz, jede Spalte ist einer der 22 Parameter des Pilzes in Form eines Reduktionszeichens aus dem gesamten Parameterwort. Die Legende aller Zeichen befindet sich in der Datei agarius-lepiota.names.
Daten aus dem Repository müssen verarbeitet werden, um eine für Tensor Flow akzeptable Form zu erhalten. Zuerst importieren wir einige Bibliotheken für die Arbeit
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
Dann bilden wir aus den Parametern des Pilzes für Tensor Flow einen Header, damit die Bibliothek weiß, welche Spalte in der Datendatei welchem Parameter entspricht. Der Hut wird auf die Datendatei geklebt. Wir bilden in Form eines Arrays, dessen Elemente aus der Datei agaricus-lepiota.names stammen.
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)
Jetzt müssen Sie sich mit den fehlenden Daten befassen. In diesem Fall wird das Symbol "?" In der Datei agaricus-lepiota.data anstelle des Parameters festgelegt. Es gibt viele Methoden, um solche Fälle zu behandeln, aber wir werden einfach die gesamte Zeile mit mindestens einem fehlenden Parameter löschen.
df.replace('?', np.nan, inplace=True) df.dropna(inplace=True)
Als Nächstes müssen Sie den symbolischen Essbarkeitsparameter manuell durch einen digitalen ersetzen. Das heißt, ersetzen Sie "p" und "e" durch 0 und 1.
df['class'].replace('p', 0, inplace=True) df['class'].replace('e', 1, inplace=True)
Danach können Sie den Rest der Daten in eine Ziffer konvertieren. Dies ist, was die Funktion get_dummies der Pandas-Bibliothek tut.
cols_to_transform = header[1:] df = pd.get_dummies(df, columns=cols_to_transform)
Jedes neuronale Netzwerk muss trainiert werden. Daneben muss es aber auch kalibriert werden, um die Arbeitsgenauigkeit unter realen Bedingungen zu erhöhen. Dazu teilen wir unseren Datensatz in zwei Bereiche auf - Training und Kalibrierung. Der erste ist größer als der zweite, wie es sein sollte.
df_train, df_test = train_test_split(df, test_size=0.1)
Und der letzte. Für Tensor Flow muss die Anzahl der Zeilen und Spalten der Datei am Anfang der Datendateien angegeben werden. Wir werden diese Informationen manuell aus unseren Trainings- und Kalibrierungsdatensätzen extrahieren und dann in die resultierenden CSV-Dateien schreiben.
Am Ende sollten Sie diese Dateien erhalten:
Training und
Kalibrierung .
Werfen Sie die generierten Daten in Tensor Flow
Nachdem wir die CSV-Dateien aus dem Repository heruntergeladen und mit Pilzdaten verarbeitet haben, können Sie sie zur Schulung an Tensor Flow senden. Dies erfolgt mit der Funktion load_csv_with_header (), die vom Framework selbst bereitgestellt wird:
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)
Die Funktion load_csv_with_header () bildet einen Trainingsdatensatz aus den oben gesammelten Dateien. Zusätzlich zur Datendatei verwendet die Funktion target_dtype als Argument. Dies ist ein Datentyp, der am Ende vorhergesagt wird. In unserem Fall ist es notwendig, dem neuronalen Netzwerk beizubringen, die Essbarkeit oder Toxizität des Pilzes vorherzusagen, was durch die Werte 1 oder 0 ausgedrückt werden kann. In unserem Fall ist target_dtype also ein ganzzahliger Wert. features_dtype - Parameter, bei dem der Typ der für das Training akzeptierten Parameter festgelegt wird. In unserem Fall ist es auch eine Ganzzahl (anfangs waren sie Zeichenfolgen, aber wie Sie sich erinnern, haben wir sie in eine Zahl umgewandelt). Am Ende wird der Parameter target_column festgelegt. Dies ist der Index der Spalte mit dem Parameter, den das neuronale Netzwerk vorhersagen soll. Das heißt, mit dem Essbarkeitsparameter.
Erstellen Sie ein Tensor Flow Classifier-Objekt
Das heißt, ein Objekt einer Klasse, das direkt an der Vorhersage des Ergebnisses beteiligt ist. Mit anderen Worten, die Klasse des neuronalen Netzwerks selbst.
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")
Der erste Parameter ist feature_columns. Dies sind die Parameter von Pilzen. Bitte beachten Sie, dass der Parameterwert genau dort etwas höher erstellt wird. Dort wird am Eingang der Wert 98 des Dimensionsparameters genommen, dh 98 verschiedene Parameter des Pilzes mit Ausnahme der Essbarkeit.
hidden_units - Die Anzahl der Neuronen in jeder Schicht des neuronalen Netzwerks. Die richtige Auswahl der Anzahl der Schichten und Neuronen in ihnen ist etwas auf der Ebene der Kunst im Bereich des maschinellen Lernens. Es ist möglich, diese Werte erst nach Erfahrung korrekt zu bestimmen. Wir haben diese Zahlen nur genommen, weil sie in einem der Tensor Flow-Tutorials aufgeführt sind. Und sie arbeiten.
n_classes - Die Anzahl der vorherzusagenden Klassen. Wir haben zwei davon - essbar und nicht.
model_dir - Der Pfad, in dem das trainierte Modell des neuronalen Netzwerks gespeichert wird. Und in Zukunft wird es verwendet, um Ergebnisse vorherzusagen, um das Netzwerk nicht jedes Mal zu trainieren.
Schulung
Um die Arbeit in Zukunft zu vereinfachen, werden wir zwei Funktionen erstellen:
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
Jede Funktion stellt ihre eigenen Eingabedaten bereit - zum Training und zur Kalibrierung. x und y sind die Tensor Flow-Konstanten, die das Framework zum Arbeiten benötigt. Gehen Sie nicht auf Details ein, sondern akzeptieren Sie nur, dass diese Funktionen ein Vermittler zwischen Daten und einem neuronalen Netzwerk sein sollten.
Wir trainieren ein Netzwerk:
classifier.fit(input_fn=get_train_inputs, steps=2000)
Der erste Parameter verwendet die direkt darüber gebildeten Eingabedaten, der zweite die Anzahl der Trainingsschritte. Auch hier wurde die Nummer in einem der Tensor Flow-Handbücher verwendet, und das Verständnis dieser Einstellung wird Ihnen mit Erfahrung einfallen.
Kalibrieren Sie als Nächstes das trainierte Netzwerk. Dies erfolgt anhand des oben generierten Kalibrierungsdatensatzes. Das Ergebnis der Arbeit wird die Genauigkeit zukünftiger Netzwerkvorhersagen sein (Genauigkeitscore).
accuracy_score = classifier.evaluate(input_fn=get_test_inputs, steps=1)["accuracy"] print("\n : {0:f}\n".format(accuracy_score))
Wir werden in testen
Jetzt ist das neuronale Netzwerk bereit und Sie können versuchen, mit seiner Hilfe die Essbarkeit des Pilzes vorherzusagen.
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)
Die obige Funktion gibt die Daten von zwei völlig neuen Pilzen an, die weder im Training noch in den Kalibrierungssätzen vorhanden waren (tatsächlich wurden sie einfach aus letzteren gezogen). Stellen Sie sich zum Beispiel vor, Sie haben sie auf dem Markt gekauft und versuchen zu verstehen, ob sie gegessen werden können. Der folgende Code definiert dies:
predictions = list(classifier.predict(input_fn=new_samples)) print(" : {}\n" .format(predictions))
Das Ergebnis der Arbeit sollte folgendes sein:
: [0, 1]
Und das bedeutet, dass der erste Pilz giftig ist, der zweite vollständig essbar. Auf diese Weise können Sie Vorhersagen basierend auf beliebigen Daten treffen, sei es Pilze, Menschen, Tiere oder irgendetwas. Es reicht aus, die Eingabedaten korrekt zu bilden. Und um beispielsweise die Wahrscheinlichkeit einer zukünftigen Arrhythmie eines Patienten oder die Aktienkursbewegung an der Börse vorherzusagen.