Vorhersage von Werten mit Deep Learning und Keras
Mit Keras können wir eine Deep Learning Black Box erstellen, die zukünftige Werte vorhersagen kann
Ich habe einen Datensatz, viele Zeilen mit N Eingaben und 1 Ausgabe, und möchte den Ausgabewert für jede neue Kombination von Eingabewerten vorhersagen. Ich bin auch ein Noob in Sachen Datenwissenschaft, aber die Geschichten im Internet über Deep Learning legen nahe, dass wir ganz einfach eine Art Blackbox mit einigen Neuronen, Knoten, darin erstellen und dann den Datensatz zum Trainieren der Blackbox verwenden können. Danach können wir beliebige Eingaben machen und unsere Blackbox liefert uns Ausgabewerte mit einer gewissen Fehlerspanne. Klingt zu schön, um wahr zu sein? Ist es wirklich so einfach?
Beginnen Sie mit KISS (Keep It Simple Stupid)
Wenn Sie im Internet nach "python data prediction" suchen, erhalten Sie natürlich eine Menge Treffer. Es gibt viele Beispiele, die mir gefallen, aber die meisten sind viel zu komplex für einen Anfänger. Aktienkurse anhand von Zeitreihen vorhersagen, zu komplex. Hauspreise vorhersagen, viel besser. Es gibt auch einen Datensatz zur Weinqualität. Ich mag Wein. kann gut sein, vielleicht ein anderes Mal.
In diesem Beitrag versuche ich, ein triviales Problem zu lösen. Ich ersetze die Funktion:
y = x0 + 2*x1
durch:
- ein lineares Regressionsmodell, und,
- ein Deep Learning, in der Tat ein neuronales Netz, eine Black Box
Ein großer Vorteil ist, dass ich den Datensatz selbst erstellen kann. Das bedeutet auch, dass ich die Vorhersagen mit den erwarteten Werten vergleichen kann.
Machine Learning: Regression vs. Klassifizierung
Um den richtigen Algorithmus zu wählen, ist es zunächst wichtig zu verstehen, ob es sich bei der Aufgabe Machine Learning um ein Regressions- oder ein Klassifikationsproblem handelt. Regression und Klassifizierung sind beides Arten von Supervised Machine Learning -Algorithmen. Supervised Machine Learning verwendet das Konzept der Verwendung von Datensätzen mit bekannten Ausgabewerten, um Vorhersagen zu treffen.
Die Regression ist ein Algorithmus, der mit einem Datensatz trainiert werden kann, um numerische Ausgabewerte, also Zahlen, vorherzusagen. Classification ist ein Algorithmus, der mit einem Datensatz trainiert werden kann, um Ausgaben vorherzusagen, bei denen es sich um Bezeichnungen, Kategorien, normalerweise 0 und 1, handelt.
Beispiel für Regression
Wir haben einen Datensatz, der aus Zeilen mit 2 Eingaben und einer Ausgabe von 1 besteht, wobei der Ausgabewert eine Zahl ist, die "jeden" Wert haben kann. Betrachten wir einen Datensatz für ein Haus, bei dem die Eingaben die Anzahl der Personen, die in dem Haus wohnen können, und die Anzahl der Zimmer sind, und die Ausgabe der Preis ist.
persons | rooms | price
---------+-------+--------
5 | 4 | 20.000
3 | 2 | 24.000
Wenn wir einen ausreichend großen Datensatz haben, können wir einen Regressionsalgorithmus verwenden, um den Preis für jede Kombination von Personen und Zimmern vorherzusagen. Die Ausgabe ist dann 22.500, 18.100 usw.
Beispiel Classification
Wir haben einen Datensatz, der aus Zeilen mit 3 Eingaben und einer Ausgabe von 1 besteht. Der Ausgabewert ist eine Zahl, die 0 oder 1 ist. Die Eingaben sind die Anzahl der Personen, die in dem Haus wohnen können, die Anzahl der Zimmer und der Preis, und die Ausgabe ist 0 oder 1, je nachdem, ob das Haus von Personen, die auf einer Website nach einem Haus suchen, bevorzugt wird.
persons | rooms | price | liked
---------+-------+---------+--------
5 | 4 | 20.000 | 0
3 | 2 | 24.000 | 1
Wenn wir einen ausreichend großen Datensatz haben, können wir einen Klassifizierungsalgorithmus verwenden, um vorherzusagen, ob ein Haus für eine beliebige Kombination von Personen, Zimmern und Preis beliebt ist. Die Ausgabe ist dann 0 (nicht beliebt) oder 1 (beliebt).
Unteranpassung und Überanpassung
Unser Datensatz wird in einen Trainingsdatensatz und einen Testdatensatz aufgeteilt. Anhand dieser Daten können wir feststellen, wie gut oder schlecht unser Modell oder Algorithmus abschneidet.
Underfitting bedeutet, dass das Modell nicht in der Lage war, die relevanten Beziehungen zwischen den Daten zu bestimmen. Wahrscheinlich ist das Modell zu einfach. Ein Beispiel ist der Versuch, nichtlineare Beziehungen mit einem linearen Modell darzustellen.
Unteranpassung:
- Funktioniert schlecht mit Trainingsdaten
- Funktioniert schlecht mit Testdaten
Überanpassung bedeutet, dass das Modell auch Beziehungen zwischen Daten und zufälligen Schwankungen ermittelt. Wahrscheinlich ist das Modell zu komplex, es lernt zu gut.
Überanpassung:
- Funktioniert gut mit Trainingsdaten
- Funktioniert schlecht mit Testdaten
Beide Fälle können auch auftreten, wenn nicht genügend Daten in unserem Datensatz vorhanden sind.
Lineare Regression
Ich schlage vor, dass Sie die Beispiele in dem großartigen Tutorial 'Linear Regression in Python' durchlesen, siehe Links unten. Im Folgenden zeige ich meine Version mit zwei Eingaben, Trainings- und Testdaten und der Vorhersage eines Wertes. Da wir mit linearer Regression modellieren, ist es nicht überraschend, dass das Bestimmtheitsmaß 1,0 beträgt und wir nur eine sehr kleine Menge an Trainingsdaten benötigen.
# Linear regression: y = x0 + 2*x1
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
# generate dataset
X_items = []
y_items = []
for x0 in range(0, 3):
for x1 in range(3, 5):
y = x0 + 2*x1
X_items.append([x0, x1])
y_items.append(y)
X = np.array(X_items).reshape((-1, 2))
y = np.array(y_items)
print('X = {}'.format(X))
print('y = {}'.format(y))
# split dataset in training and test data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)
print('X_train = {}'.format(X_train))
print('y_train = {}'.format(y_train))
print('X_test = {}'.format(X_test))
print('y_test = {}'.format(y_test))
# create model
model = LinearRegression()
# mess up a training value
#X_train[0][0] += 2
# calculate optimal values of weights b0 and b1
model.fit(X_train, y_train)
# show results, mess up test data
print('model result:')
print('- intercept (b0) = {}'.format(model.intercept_))
print('- slope (b1) = {}'.format(model.coef_))
print('- coefficient of determination for training data = {}'.
format(model.score(X_train, y_train)))
print('- coefficient of determination for test data = {}'.
format(model.score(X_test, y_test)))
x = np.array([8, 9]).reshape((-1, 2))
y_pred = model.predict(x)
print('predicted response for x = {}: {}'.format(x, y_pred))
Das Skript liefert die folgende Ausgabe:
X = [[0 3]
[0 4]
[1 3]
[1 4]
[2 3]
[2 4]]
y = [ 6 8 7 9 8 10]
X_train = [[2 3]
[0 3]
[1 4]
[2 4]]
y_train = [ 8 6 9 10]
X_test = [[1 3]
[0 4]]
y_test = [7 8]
model result:
- intercept (b0) = -3.552713678800501e-15
- slope (b1) = [1. 2.]
- coefficient of determination for training data = 1.0
- coefficient of determination for test data = 1.0
predicted response for x = [[8 9]]: [26.]
Um ein wenig Unruhe zu stiften, habe ich einen Trainingswert geändert, siehe oben. Dies ergibt das Ergebnis:
model result:
- intercept (b0) = -2.3529411764705817
- slope (b1) = [0.52941176 2.76470588]
- coefficient of determination for training data = 0.9865546218487395
- coefficient of determination for test data = -0.5570934256055304
predicted response for x = [[8 9]]: [26.76470588]
Wenn wir mehr Trainingsdaten hinzufügen, erhalten wir eine bessere Anpassung.
Deep Learning mit Keras
Dies sollte eher dem Blackbox-Ansatz entsprechen. Ich füge einfach ein paar Neuronen und Schichten hinzu und das sollte alles sein. Aber ist es das wirklich? Hier verwende ich Keras, weil es sehr populär zu sein scheint. Das folgende Beispiel war sehr hilfreich: 'Keras 101: A simple (and interpretable) Neural Network model for House Pricing regression', siehe Links unten. Die Darstellung des Verlusts und des mittleren Durchschnittsfehlers war sehr sinnvoll.
Wir werden die folgenden Schritte durchführen:
- Laden der Daten
- Definieren des Modells
- Kompilieren des Modells
- Trainieren (Anpassen) des Modells
- Auswerten des Modells
- Vorhersagen machen
Laden der Daten Hier erzeugen wir die Daten selbst, siehe auch oben.
Definieren des Modells Die erste dichte Schicht benötigt den Parametersatz input_shape . Ich habe mit 100 Neuronen in der ersten Schicht, 50 in der zweiten Schicht und 25 in der dritten Schicht begonnen. Und warum? Ich habe keine Ahnung, ich habe mir das noch nicht angesehen.
Kompilieren des Modells Dazu gibt es nicht viel zu sagen.
Trainieren (Anpassen) des Modells Wir verwenden den Parameter validation_split, ohne ihn können wir nicht plotten. Wenn validation_split angegeben ist, wird ein Teil der Trainingsdaten für die Validierung verwendet. Die für die Validierung verwendeten Daten können sich während der Anpassung ändern. Es ist wahrscheinlich besser, feste Daten zu verwenden, da wir sonst jedes Mal eine andere Anpassung erhalten.
Evaluieren des Modells Hier werden die Testdaten verwendet.
Vorhersagen Verwenden Sie einfach model.predict().
Natürlich brauchen wir hier mehr Trainingsdaten. Aber auch nicht wirklich viel mehr. Ich habe auch Code zum Speichern und Laden des Modells hinzugefügt. Unten ist der Code, den ich erstellt habe.
# Keras deep learning: y = x0 + 2*x1
from keras.models import Sequential, load_model
from keras.layers import Dense
import numpy as np
from plotly.subplots import make_subplots
import plotly.graph_objects as go
from sklearn.model_selection import train_test_split
use_saved_model = False
#use_saved_model = True
# create dataset
def fx(x0, x1):
return x0 + 2*x1
X_items = []
y_items = []
for x0 in range(0, 18, 3):
for x1 in range(2, 27, 3):
y = fx(x0, x1)
X_items.append([x0, x1])
y_items.append(y)
X = np.array(X_items).reshape((-1, 2))
y = np.array(y_items)
print('X = {}'.format(X))
print('y = {}'.format(y))
X_data_shape = X.shape
print('X_data_shape = {}'.format(X_data_shape))
class DLM:
def __init__(
self,
model_name='default_model',
):
self.model_name = model_name
self.dense_input_shape=(2, )
self.dense_neurons = [100, 50, 25]
self.fit_params = {
'epochs': 100,
'validation_split': 0.1,
'verbose': 0,
}
def data_split_train_test(
self,
X,
y,
):
self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(X, y, test_size=0.3, random_state=1)
print('self.X_train = {}'.format(self.X_train))
print('self.X_test = {}'.format(self.X_test))
print('self.y_train = {}'.format(self.y_train))
print('self.y_test = {}'.format(self.y_test))
print('training data row count = {}'.format(len(self.y_train)))
print('test data row count = {}'.format(len(self.y_test)))
X_train_data_shape = self.X_train.shape
print('X_train_data_shape = {}'.format(X_train_data_shape))
def get_model(
self,
):
self.model = Sequential()
self.model.add(Dense(self.dense_neurons[0], input_shape=self.dense_input_shape, activation='relu', name='dense_input'))
for i, n in enumerate(self.dense_neurons[1:]):
self.model.add(Dense(n, activation='relu', name='dense_hidden_' + str(i)))
self.model.add(Dense(1, activation='linear', name='dense_output'))
self.model.compile(optimizer='adam', loss='mse', metrics=['mean_absolute_error'])
self.model_summary()
return self.model
def model_summary(
self,
):
self.model.summary()
def train(
self,
model,
plot=False,
):
history = model.fit(self.X_train, self.y_train, **self.fit_params)
if plot:
fig = go.Figure()
fig.add_trace(go.Scattergl(y=history.history['loss'], name='Train'))
fig.add_trace(go.Scattergl(y=history.history['val_loss'], name='Valid'))
fig.update_layout(height=500, width=700, xaxis_title='Epoch', yaxis_title='Loss')
fig.show()
fig = go.Figure()
fig.add_trace(go.Scattergl(y=history.history['mean_absolute_error'], name='Train'))
fig.add_trace(go.Scattergl(y=history.history['val_mean_absolute_error'], name='Valid'))
fig.update_layout(height=500, width=700, xaxis_title='Epoch', yaxis_title='Mean Absolute Error')
fig.show()
return history
def evaluate(
self,
model,
):
mse_nn, mae_nn = model.evaluate(self.X_test, self.y_test)
print('Mean squared error on test data: ', mse_nn)
print('Mean absolute error on test data: ', mae_nn)
return mse_nn, mae_nn
def predict(
self,
model,
x0,
x1,
fx=None,
):
x = np.array([[x0, x1]]).reshape((-1, 2))
predictions = model.predict(x)
expected = ''
if fx is not None:
expected = ', expected = {}'.format(fx(x0, x1))
print('for x = {}, predictions = {}{}'.format(x, predictions, expected))
return predictions
def save_model(
self,
model,
):
model.save(self.model_name)
def load_saved_model(
self,
):
self.model = load_model(self.model_name)
return self.model
# create & save or used saved
dlm = DLM()
if use_saved_model:
model = dlm.load_saved_model()
else:
dlm.data_split_train_test(X, y)
model = dlm.get_model()
dlm.train(model, plot=True)
dlm.evaluate(model)
dlm.save_model(model)
# predict
dlm.predict(model, 4, 17, fx=fx)
dlm.predict(model, 23, 79, fx=fx)
dlm.predict(model, 40, 33, fx=fx)
Das Skript liefert die folgende Ausgabe, ohne die Eingabedaten:
training data row count = 37
test data row count = 17
X_train_data_shape = (37, 2)
2022-01-28 16:00:30.598860: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory
2022-01-28 16:00:30.598886: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)
2022-01-28 16:00:30.598911: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (myra): /proc/driver/nvidia/version does not exist
2022-01-28 16:00:30.599110: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_input (Dense) (None, 100) 300
dense_hidden_0 (Dense) (None, 50) 5050
dense_hidden_1 (Dense) (None, 25) 1275
dense_output (Dense) (None, 1) 26
=================================================================
Total params: 6,651
Trainable params: 6,651
Non-trainable params: 0
_________________________________________________________________
1/1 [==============================] - 0s 25ms/step - loss: 0.1018 - mean_absolute_error: 0.2752
Mean squared error on test data: 0.10178931057453156
Mean absolute error on test data: 0.27519676089286804
2022-01-28 16:00:33.549267: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
for x = [[ 4 17]], predictions = [[38.0433]], expected = 38
for x = [[23 79]], predictions = [[177.94098]], expected = 181
for x = [[40 33]], predictions = [[103.54724]], expected = 106
Verbesserung der Leistung von Deep Learning
Während ich diesen Beitrag schrieb, änderte ich die Anzahl der Neuronen, die dichten Schichten und den Parameter validation_split. All das führte zu einigen Änderungen, manchmal gut, manchmal schlecht. Die größte Verbesserung besteht zweifellos darin, mehr Trainingsdaten hinzuzufügen, aber wie viel ist genug?
Zusammenfassung
Das Wichtigste, was ich gelernt habe, ist, dass Deep Learning einen großen Datensatz benötigt, je größer, desto besser. Mag ich die Blackbox? Ja, und bisher habe ich noch nicht wirklich hineingeschaut. Ich kann das jetzt als Ausgangspunkt für einige Projekte in der realen Welt verwenden. Es gibt auch Dinge wie die Normalisierung der Eingaben, das Hinzufügen von Gewichten zu den Eingaben. Viel mehr zu lesen ...
Links / Impressum
How to find the value for Keras input_shape/input_dim?
https://www.machinecurve.com/index.php/2020/04/05/how-to-find-the-value-for-keras-input_shape-input_dim
Keras 101: A simple (and interpretable) Neural Network model for House Pricing regression
https://towardsdatascience.com/keras-101-a-simple-and-interpretable-neural-network-model-for-house-pricing-regression-31b1a77f05ae
Keras examples
https://keras.io/examples
Linear Regression in Python
https://realpython.com/linear-regression-in-python
Predictive Analysis in Python
https://medium.com/my-data-camp-journey/predictive-analysis-in-python-97ca5b64e97f
Regression Tutorial with the Keras Deep Learning Library in Python
https://machinelearningmastery.com/regression-tutorial-keras-deep-learning-library-python
Mehr erfahren
Deep Learning Machine Learning
Neueste
- Ausblenden der Primärschlüssel der Datenbank UUID Ihrer Webanwendung
- Don't Repeat Yourself (DRY) mit Jinja2
- SQLAlchemy, PostgreSQL, maximale Anzahl von Zeilen pro user
- Anzeige der Werte in den dynamischen Filtern SQLAlchemy
- Sichere Datenübertragung mit Public Key Verschlüsselung und pyNaCl
- rqlite: eine hochverfügbare und distverteilte SQLite -Alternative
Meistgesehen
- Verwendung von Pythons pyOpenSSL zur Überprüfung von SSL-Zertifikaten, die von einem Host heruntergeladen wurden
- Verwendung von UUIDs anstelle von Integer Autoincrement Primary Keys mit SQLAlchemy und MariaDb
- Verbindung zu einem Dienst auf einem Docker -Host von einem Docker -Container aus
- PyInstaller und Cython verwenden, um eine ausführbare Python-Datei zu erstellen
- SQLAlchemy: Verwendung von Cascade Deletes zum Löschen verwandter Objekte
- Flask RESTful API Validierung von Anfrageparametern mit Marshmallow-Schemas