Wenn Sie neu im Bereich Information Science oder maschinelles Lernen sind, könnten Sie versucht sein, sofort zu Kaggle zu gehen und mit der Arbeit an großen Projekten zu beginnen, und das kann ich Ihnen nicht verübeln; Auch ich liebe es, an Projekten zu arbeiten und mich selbst herauszufordern. Während der beste Weg, das Programmieren zu lernen, darin besteht, an Projekten zu arbeiten und aus Ihren Fehlern zu lernen, gibt es einen entscheidenden grundlegenden Schritt, auf den Sie achten sollten. Dank Frameworks wie TensorFlow oder PyTorch sind Sie nur noch wenige Codezeilen davon entfernt, ein Deep-Studying-Neuronales Netzwerkmodell zu erstellen und eine gute Genauigkeit zu erzielen, aber haben Sie nicht das Gefühl, dass etwas fehlt? Oder Sie sind vielleicht neugierig, was unter der Haube passiert und wie diese neuronalen Netzwerkmodelle funktionieren. Ich schreibe diesen Artikel, um ein paar Schritte zurück zur Regression zu gehen und die Grundlagen zu überprüfen, um eine stärkere Grundlage zu haben, auf der Sie aufbauen können.
Der Grundgedanke…
Beginnen wir mit der Darstellung einiger Datenpunkte.
import numpy as np
import matplotlib.pyplot as pltX = np.array([0,1,2,3,4,5,6,7,8,9,10])
y = np.array([1,3,5,4,7,5,8,9,11,10,13])
plt.scatter(X,y)
Regression ist eine statistische Technik zur Modellierung der Beziehung zwischen abhängigen und unabhängigen Variablen. Es findet die am besten passende Linie oder Kurve, um die abhängige Variable basierend auf den unabhängigen Variablen vorherzusagen. Dabei werden Koeffizienten (Wj) geschätzt:
Die folgende Gleichung kann unsere Linie darstellen:
w0: Bias-Wert, der den Wert von y bei x=0 erhöht oder verringert.
w1: Gewicht unserer x-Variablen, das unsere x-Variable erhöht oder verringert.
An dieser Stelle wollen wir die optimalen Gewichte finden (w0 und w1) so dass die Summe unserer Fehler (Vertikelversätze) ist klein. Wir verwenden die Kostenfunktion Sähm von Squadriert EFehler (SSE) um dies zu tun:
Diese Funktion berücksichtigt die Gewichte – in diesem Fall (w0,w1) – und berechnet dann die Differenz zwischen unserem vorhergesagten y-Wert und dem wahren y-Wert, quadriert die Ergebnisse und summiert sie dann. Folgendes möchte ich Ihnen aus dieser schönen Gleichung mitnehmen. Dies ist die Kostenfunktion, die als J(w), Wo w ist ein Vektor [w0,w1]. Da wir nur mit zwei Variablen arbeiten, können wir dies darstellen als J(w0,w1). Diese Kostenfunktion erstellt eine dreidimensionale Oberfläche mit einer w0-Achse und einer w1-Achse; Die Ausgabe ist unser Kostenwert entlang der Z-Achse (der dritten Dimension). Natürlich könnten wir diese 3D-Oberfläche betrachten und den tiefsten Punkt betrachten, aber wenn wir mit Deep-Studying-Modellen arbeiten, hat die Kostenfunktion Millionen und manchmal Milliarden von Parametern oder Gewichten. Da wir additionally weder die millionste noch die vierte Dimension visualisieren können, benötigen wir eine bessere Möglichkeit, die beste Kombination von Gewichtswerten zu finden, um das globale Minimal zu erreichen. Dank der Evaluation gibt es eine einfache Möglichkeit, dies zu tun; wir nennen es das Gradientenabstieg.
Der Lernprozess
Die Lernphase eines jeden Modells findet statt, wenn die Gewichte so aktualisiert werden, dass jeder Schritt zum Gegenteil des Gradienten führt, da der Gradient zum steilsten Anstiegspunkt zeigt und wir zum steilsten Abfallpunkt der Kostenfunktionsoberfläche gehen wollen. So aktualisieren wir die Gewichte:
Wobei n die Lernrate ist, die bestimmt, wie klein die Schritte zum Abstieg sind; Wenn wir zu große Schritte machen, kann es sein, dass wir über das Ziel hinausschießen und das globale Kostenminimum verfehlen, und wenn unsere Schritte zu klein sind, dauert das Trainieren des Modells ewig, was auch nicht perfect ist. Bevor wir uns mit der partiellen Ableitung (Gradient) befassen, visualisieren wir unsere Kostenfunktion in 3D.
Die anfänglichen Gewichte wurden zufällig ausgewählt, und dann begannen unsere Gewichte, sich auf den tiefsten Punkt der Oberfläche zuzubewegen; Dies wird als Gradientenabstieg bezeichnet. Dieser in neuronalen Netzen verwendete Berechnungsprozess wird Backpropagation genannt, auf den wir später etwas näher eingehen werden.
Partielle Ableitungen
Die partielle Ableitung unserer Kostenfunktion erhält man durch Ableitung nach JGewicht:
Wenn Sie mit Infinitesimalrechnung nicht vertraut sind, machen Sie sich keine allzu großen Sorgen. Versuchen Sie, die Hauptideen zu verstehen, die wir hier diskutieren. Dann schlage ich vor, dass Sie sich Tutorials zu Derivaten, partiellen Derivaten und Gradientenabstieg ansehen. Ich kann den Youtube-Tutor mit dem Namen “ wärmstens empfehlen.Der Nachhilfelehrer für organische Chemie.„Hier ist eine von ihm erstellte Calculus-Playlist.
Nachdem wir nun die Kostenfunktion abgeleitet haben:
Wir können dies in Python implementieren:
import numpy as np
from numpy import random
import math
import time
import pandas as pd
import matplotlib.pyplot as plt
random.seed(seed=1234)class LinearRegression(object):
def __init__(self, eta=0.01, n_iter=20):
self.eta = eta #Studying Price
self.n_iter = n_iter #Variety of instances we replace our weights.
def match(self, X, y):
self.w_ = np.random.randn(1 + X.form[1]) #Preliminary Weights
self.cost_ = []
for i in vary(self.n_iter):
output = self.net_input(X)
errors = (y - output)
self.w_[1:] += self.eta * X.T.dot(errors) #X.T.dot(errors) is the Gradient Descent of the Price perform.
self.w_[0] += self.eta * errors.sum()
value = (errors**2).sum() / 2.0
self.cost_.append(value)
return self
def net_input(self, X):
return np.dot(X, self.w_[1:]) + self.w_[0]
def predict(self, X):
return self.net_input(X)
Nach dem Coaching unseres Modells ist hier die vorhergesagte Linie:
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_std = sc.fit_transform(X)
y_std = sc.fit_transform(y[:, np.newaxis]).flatten()
lr = LinearRegression()
lr.match(X_std, y_std)def lin_regplot(X, y, mannequin):
plt.scatter(X, y, c='steelblue', edgecolor='white', s=70)
plt.plot(X, mannequin.predict(X), coloration='black', lw=2)
return None
lin_regplot(X_std, y_std, lr)
plt.xlabel('X (standardized)')
plt.ylabel('y (standardized)')
plt.present()
SSE für jede Epoche darstellen (n_iter):
plt.plot(vary(1, lr.n_iter+1), lr.cost_)
plt.ylabel('SSE')
plt.xlabel('Epoch')
plt.present()
print(f"SSE: {lr.cost_[-1]}")
Lassen Sie uns nun unsere Kostenfunktion grafisch darstellen und unsere Anfangs- und Endgewichte anzeigen.
random.seed(seed=1234)# Let's outline the vary for w0 and w1
w0_range = np.linspace(-2, 2, 100)
w1_range = np.linspace(-2, 2, 100)
w0, w1 = np.meshgrid(w0_range, w1_range)
# Calculating the price perform for every mixture of w0 and w1
cost_f = np.zeros_like(w0)
for i in vary(len(w0_range)):
for j in vary(len(w1_range)):
errors = (y - w1[i, j] * X) + w0[i, j]
cost_f[i, j] = (errors ** 2).sum() / 2.0
w_i = np.random.randn(1 + X.form[1]) #preliminary random weights utilized in our mannequin.
w0_i = int(w_i[0])
w1_i = int(w_i[1])
w0_f = int(lr.w_[0]) #Our remaining weights from the mannequin
w1_f = int(lr.w_[1])
fig = plt.determine(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(w0, w1, cost_f, cmap='viridis')
ax.plot([w0_i, w0_i], [w1_i, w1_i], [0, cost_f[w0_i, w1_i]], coloration='purple', linewidth=2, label='Preliminary Weights', zorder=10)
ax.plot([w0_f, w0_f], [w1_f, w1_f], [0, cost_f[w0_f, w1_f]], coloration='blue', linewidth=2, label='Closing Weights', zorder=10)
ax.set_xlabel('w0')
ax.set_ylabel('w1')
ax.set_zlabel('Price')
ax.set_title('Price Operate')
ax.view_init(elev=20, azim=155) # Set the elevation and azimuth angles
ax.legend()
# Present the plot
plt.present()
A number of lineare Regression
Sie fragen sich vielleicht: Ist die Mathematik dieselbe, wenn wir mehrere Variablen haben? Die Antwort ist ja. Beginnen wir mit der Arbeit mit zwei unabhängigen Variablen, die wir x1 und x2 nennen. Erstellen wir ein Array mit der Kind (50,2); das heißt, 50 Zeilen und zwei Spalten.
n = 50 # Variety of knowledge factors
X = np.random.randint(0,10,(n,2)) # Impartial variables
y = 2 * X[:,0] + 3 * X[:,1] + np.random.randn(n)* 0.5 # Dependent variable (goal)
Im Allgemeinen können wir die Ebene der multiplen linearen Regression wie folgt definieren:
x0 = 1, was unser Bias-Gewicht w0 ergibt.
Unter Verwendung desselben Codes und derselben Kostenfunktion, die wir zuvor verwendet haben, sind hier die angepasste Hyperebene und unsere Datenpunkte X1 und X2 standardisiert:
A number of lineare Regression vs. Adaline
Abschließend möchte ich zeigen, wie ähnlich der Lernprozess in Adaline ist (Adaptives lineares Neuron) ist zu unserem Regressionsmodell. Hier ist eine schematische Darstellung einer einfachen Wahrnehmung:
Die Gewichte werden hier mithilfe des Gradientenabstiegs auf die gleiche Weise aktualisiert, wie es in unserem Regressionsmodell der Fall ist. Der Hauptunterschied besteht darin, dass unser Netto-Enter Aktivierungs- und Schwellenwertfunktionen durchläuft, die für den anderen Teil des überwachten Lernens verwendet werden, den wir Klassifizierung nennen. Schließlich können wir, wie oben gezeigt, mehrere Neuronen in einer Schicht hinzufügen, die vollständig mit der Eingabe- und Ausgabeschicht verbunden ist. Wir nennen dieses Multilayer-Perzeptron oder ein Multilayer-Feedforward-Neuronales Netzwerk:
Die Berechnung des Gradientenabstiegs in neuronalen Netzen nennen wir ‚Rückausbreitung‘; Dies ist der Zeitpunkt, an dem die Gewichtungen aktualisiert werden und sich von rechts nach hyperlinks bewegen. Nachdem unser Modell die durchlaufen hat ‚Feedforward‘ Mit seinen aktuellen Gewichtungswerten übergeben, übernimmt Backpropagation die Aktualisierung der Gewichte.