diff --git a/regression/code/errorGradient.m b/regression/code/errorGradient.m index 5a5998b..ac484ec 100644 --- a/regression/code/errorGradient.m +++ b/regression/code/errorGradient.m @@ -1,4 +1,3 @@ -clear load('lin_regression.mat') ms = -1:0.5:5; @@ -23,9 +22,9 @@ hold on %surface(M,N, error_surf, 'FaceAlpha', 0.5); contour(M,N, error_surf, 50); quiver(M,N, gradient_m, gradient_n) -xlabel('slope') -ylabel('intercept') -zlabel('error') -set(gcf, 'paperunits', 'centimeters', 'papersize', [15, 12.5], ... - 'paperposition', [0., 0., 15, 12.5]) +xlabel('Slope m') +ylabel('Intercept b') +zlabel('Mean squared error') +set(gcf, 'paperunits', 'centimeters', 'papersize', [15, 10.5], ... + 'paperposition', [0., 0., 15, 10.5]) saveas(gcf, 'error_gradient', 'pdf') \ No newline at end of file diff --git a/regression/code/errorSurface.m b/regression/code/errorSurface.m index ba3b7fe..4bd3fd2 100644 --- a/regression/code/errorSurface.m +++ b/regression/code/errorSurface.m @@ -6,7 +6,7 @@ intercepts = -30:1:30; error_surf = zeros(length(slopes), length(intercepts)); for i = 1:length(slopes) for j = 1:length(intercepts) - error_surf(i,j) = lsqError(x, y, [slopes(i), intercepts(j)]); + error_surf(i,j) = lsqError([slopes(i), intercepts(j)], x, y); end end diff --git a/regression/code/lsqError.m b/regression/code/lsqError.m index 3ba0974..3547266 100644 --- a/regression/code/lsqError.m +++ b/regression/code/lsqError.m @@ -1,13 +1,13 @@ -function error = lsqError(x, y, parameter) +function error = lsqError(parameter, x, y) % Objective function for fitting a linear equation to data. % -% Arguments: x, the input values -% y, the corresponding measured output values -% parameter, vector containing slope and intercept +% Arguments: parameter, vector containing slope and intercept % as the 1st and 2nd element +% x, vector of the input values +% y, vector of the corresponding measured output values % % Returns: the estimation error in terms of the mean sqaure error -y_est = x .* parameter(1) + parameter(2); -error = meanSquareError(y, y_est); + y_est = x .* parameter(1) + parameter(2); + error = meanSquareError(y, y_est); end diff --git a/regression/code/lsqGradient.m b/regression/code/lsqGradient.m index 2736370..4041d9e 100644 --- a/regression/code/lsqGradient.m +++ b/regression/code/lsqGradient.m @@ -1,17 +1,17 @@ -function gradient = lsqGradient(x, y, parameter) +function gradient = lsqGradient(parameter, x, y) % The gradient of the least square error % -% Arguments: x, the input values -% y, the corresponding measured output values -% parameter, vector containing slope and intercept +% Arguments: parameter, vector containing slope and intercept % as the 1st and 2nd element +% x, vector of the input values +% y, vector of the corresponding measured output values % % Returns: the gradient as a vector with two elements h = 1e-6; % stepsize for derivatives - partial_m = (lsqError(x, y, [parameter(1)+h, parameter(2)]) - lsqError(x, y, parameter))/ h; -partial_n = (lsqError(x, y, [parameter(1), parameter(2)+h]) - lsqError(x, y, parameter))/ h; + partial_m = (lsqError([parameter(1)+h, parameter(2)], x, y) - lsqError(parameter, x, y))/ h; + partial_n = (lsqError([parameter(1), parameter(2)+h], x, y) - lsqError(parameter, x, y))/ h; gradient = [partial_m, partial_n]; end diff --git a/regression/lecture/figures/error_gradient.pdf b/regression/lecture/figures/error_gradient.pdf index 159c684..38d9fca 100644 Binary files a/regression/lecture/figures/error_gradient.pdf and b/regression/lecture/figures/error_gradient.pdf differ diff --git a/regression/lecture/gradient.py b/regression/lecture/gradient.py index b762217..5f1d35c 100644 --- a/regression/lecture/gradient.py +++ b/regression/lecture/gradient.py @@ -22,7 +22,7 @@ ax.set_xlabel('x') ax.set_ylabel('y', rotation='horizontal') ax.set_xticks(np.arange(x1, x2+0.1, 1.0)) ax.set_yticks(np.arange(x1, x2+0.1, 1.0)) -ax.contour(X, Y, Z, zorder=0) +ax.contour(X, Y, Z, linewidths=2, zorder=0) # gradients: xxg = [-1.1, 1.4, -1.0] diff --git a/regression/lecture/regression.tex b/regression/lecture/regression.tex index 4985637..061f979 100644 --- a/regression/lecture/regression.tex +++ b/regression/lecture/regression.tex @@ -63,7 +63,7 @@ unabh\"angig ob sie \"uber oder unter der Gerade liegen. Statt der Summe k\"onnen wir genauso gut fordern, dass der \emph{mittlere} Abstand \begin{equation} \label{meanabserror} - e(\{(x_i, y_i)\}|\{y^{est}_i\}) = \frac{1}{N} \sum_{i=1}^N |y_i - y^{est}_i| + f_{dist}(\{(x_i, y_i)\}|\{y^{est}_i\}) = \frac{1}{N} \sum_{i=1}^N |y_i - y^{est}_i| \end{equation} der Menge der $N$ Datenpaare $(x_i, y_i)$ gegeben die Modellvorhersagen $y_i^{est}$ klein sein soll. @@ -73,7 +73,7 @@ Am h\"aufigsten wird jedoch bei einem Kurvenfit der \determ{mittlere \enterm{mean squared error}) \begin{equation} \label{meansquarederror} - e(\{(x_i, y_i)\}|\{y^{est}_i\}) = \frac{1}{N} \sum_{i=1}^N (y_i - y^{est}_i)^2 + f_{mse}(\{(x_i, y_i)\}|\{y^{est}_i\}) = \frac{1}{N} \sum_{i=1}^N (y_i - y^{est}_i)^2 \end{equation} verwendet (\figref{leastsquareerrorfig}). Wie beim Betrag sind die quadratischen Abst\"ande immer positiv, unabh\"angig ob die Datenwerte @@ -90,7 +90,7 @@ zus\"atzlich gro{\ss}e Abst\"ande st\"arker gewichtet. \section{Zielfunktion} -$e(\{(x_i, y_i)\}|\{y^{est}_i\})$ ist eine sogenannte +$f_{cost}(\{(x_i, y_i)\}|\{y^{est}_i\})$ ist eine sogenannte \determ{Zielfunktion}, oder \determ{Kostenfunktion} (\enterm{objective function}, \enterm{cost function}), da wir die Modellvorhersage so anpassen wollen, dass der mittlere quadratische Abstand, also die @@ -117,15 +117,14 @@ Abstand sein. Je nach Problemstellung kann die Kostenfunktion eine beliebige Funktion sein, die die Parameter eines Modells auf einen Wert abbildet, der in irgendeiner Weise die Qualit\"at des Modells quantifiziert. Ziel ist es dann, diejenigen Parameterwerte zu finden, -bei der die Kostenfunktion --- oder eben ``Zielfunktion'' --- -minimiert wird. +bei der die Kostenfunktion minimiert wird. %%% Einfaches verbales Beispiel? Wenn wir nun in unsere Gleichung \eqref{meansquarederror} f\"ur die Modellvorhersage $y^{est}$ die Geradengleichung einsetzen, erhalten wir f\"ur die Zielfunktion \begin{eqnarray} - e(\{(x_i, y_i)\}|m,b) & = & \frac{1}{N} \sum_{i=1}^N (y_i - f(x_i;m,b)^2 \label{msefunc} \\ + f_{cost}(\{(x_i, y_i)\}|m,b) & = & \frac{1}{N} \sum_{i=1}^N (y_i - f(x_i;m,b))^2 \label{msefunc} \\ & = & \frac{1}{N} \sum_{i=1}^N (y_i - m x_i - b)^2 \label{mseline} \end{eqnarray} den mittleren quadratischen Abstand der Datenpaare $(x_i, y_i)$ @@ -137,11 +136,11 @@ der Fehler \eqnref{mseline} minimal wird. Implementiere die Zielfunktion f\"ur die Optimierung mit der linearen Geradengleichung als Funktion \code{lsqError}. \begin{itemize} - \item Die Funktion \"ubernimmt drei Argumente: Das erste ist ein - Vektor mit den $x$-Werten, an denen gemessen wurde, und das zweite - ein Vektor mit den zugeh\"origen $y$-Werten. Das dritte Argument + \item Die Funktion \"ubernimmt drei Argumente: Das erste Argument ist ein 2-elementiger Vektor, der die Parameter \code{m} und - \code{b} enth\"alt. + \code{b} enth\"alt. Das zweite ist ein Vektor mit den $x$-Werten, + an denen gemessen wurde, und das dritte ein Vektor mit den + zugeh\"origen $y$-Werten. \item Die Funktion gibt als Ergebniss den Fehler als mittleren quadratischen Abstand \eqnref{mseline} zur\"uck. \item Die Funktion soll die Funktion \code{meanSquareError} der @@ -155,10 +154,15 @@ der Fehler \eqnref{mseline} minimal wird. Die beiden Parameter $m$ und $b$ der Geradengleichung spannen eine F\"ache auf. F\"ur jede Kombination aus $m$ und $b$ k\"onnen wir den Wert der Zielfunktion, hier der mittlere quadratische Abstand -\eqnref{meansquarederror}, berechnen. Es gibt also f\"ur jeden Punkt -in der sogenannten \emph{Fehlerfl\"ache} einen Fehler. In diesem -Beispiel eines 2-dimensionalen Problems (zwei freie Parameter) kann -die Fehlerfl\"ache graphisch durch einen 3-d ``surface-plot'' +\eqnref{meansquarederror}, berechnen. Wir betrachten also die +Kostenfunktion $f_{cost}(\{(x_i, y_i)\}|m,b)$ nun als Funktion +$f_{cost}(m,b)$, die die beiden Variablen $m$ und $b$ auf einen +Fehlerwert abbildet. + +Es gibt also f\"ur jeden Punkt in der sogenannten +\emph{Fehlerfl\"ache} einen Fehlerwert. In diesem Beispiel eines +2-dimensionalen Problems (zwei freie Parameter) kann die +Fehlerfl\"ache graphisch durch einen 3-d \enterm{surface-plot} dargestellt werden. Dabei werden auf der $x$- und der $y$-Achse die beiden Parameter und auf der $z$-Achse der Fehlerwert aufgetragen (\figref{errorsurfacefig}). @@ -197,7 +201,7 @@ rechenintensiv, da f\"ur jede m\"ogliche Kombination der Parameter der Fehler berechnet werden muss. Die Anzahl der n\"otigen Berechnungen steigt exponentiell mit der Anzahl der Parameter (``Fluch der Dimension''). Auch eine bessere Genauigkeit, mit der das Minimum -bestimmt werden soll erh\"oht die Anzahl der n\"otigen +bestimmt werden soll, erh\"oht die Anzahl der n\"otigen Berechnungen. Wir suchen also ein Verfahren, dass das Minimum der Kostenfunktion mit m\"oglichst wenigen Berechnungen findet. @@ -206,16 +210,27 @@ Kostenfunktion mit m\"oglichst wenigen Berechnungen findet. \hfill \begin{minipage}[b]{0.63\textwidth} Der Differenzenquotient - \[ m = \frac{f(x + \Delta x) - f(x)}{\Delta x} \] einer Funktion $y = f(x)$ ist - die Steigung der Sekante (rot) durch die beiden Punkte $(x,f(x))$ und - $(x+\Delta x,f(x+\Delta x))$ mit dem Abstand $\Delta x$. + \begin{equation} + \label{difffrac} + m = \frac{f(x + \Delta x) - f(x)}{\Delta x} + \end{equation} + einer Funktion $y = f(x)$ ist die Steigung der Sekante (rot) durch + die beiden Punkte $(x,f(x))$ und $(x+\Delta x,f(x+\Delta x))$ mit + dem Abstand $\Delta x$. Die Steigung einer Funktion $y=f(x)$ an einer Stelle $x$ (gelb) wird durch die Ableitung $f'(x)$ der Funktion an dieser Stelle berechnet. Die Ableitung ist \"uber den Grenzwert (orange) des Differenzenquotienten f\"ur unendlich kleine Abst\"ande $\Delta x$ definiert: - \[f'(x) = \frac{{\rm d} f(x)}{{\rm d}x} = \lim\limits_{\Delta x \to 0} \frac{f(x + \Delta x) - f(x)}{\Delta x} \] - \end{minipage} + \begin{equation} + \label{derivative} + f'(x) = \frac{{\rm d} f(x)}{{\rm d}x} = \lim\limits_{\Delta x \to 0} \frac{f(x + \Delta x) - f(x)}{\Delta x} \end{equation} + \end{minipage}\vspace{2ex} + + Numerisch kann der Grenzwert \eqnref{derivative} nicht + gebildet werden. Die Ableitung kann nur durch den + Differenzenquotienten \eqnref{difffrac} mit gen\"ugend kleinem + $\Delta x$ angen\"ahert werden. \end{ibox} \begin{ibox}[t]{\label{partialderivativebox}Partielle Ableitungen und Gradient} @@ -255,32 +270,34 @@ Kostenfunktion mit m\"oglichst wenigen Berechnungen findet. Wenn eine Kugel an einem beliebigen Startpunkt auf der Fehlerfl\"ache \figref{errorsurfacefig} losgelassen werden w\"urde, dann w\"urde sie -entlang des steilsten Gef\"alles zum Minimum der Fehlerfl\"ache rollen -und dort zum Stehen kommen. Um den Weg der Kugel mit einem -Computerprogramm nachvollziehen zu k\"onnen, ben\"otigen wir -Information \"uber die Richtung des steilsten Gef\"alles an der -jeweils aktuellen Position. +entlang des steilsten Gef\"alles auf schnellsten Wege zum Minimum der +Fehlerfl\"ache rollen und dort zum Stehen kommen (wenn sie keine +Tr\"agheit besitzen w\"urde). Den Weg der Kugel wollen wir nun als +Grundlage unseres Algorithmus zur Bestimmung des Minimums der +Kostenfunktion verwenden. Da die Kugel immer entlang des steilsten +Gef\"alles rollt, ben\"otigen wir Information \"uber die Richtung des +Gef\"alles an der jeweils aktuellen Position. Der Gradient (Box~\ref{partialderivativebox}) der Kostenfunktion -\[ \nabla e(m,b) = \left( \begin{array}{c} \frac{\partial - e(m,b)}{\partial m} \\[1ex] \frac{\partial f(m,b)}{\partial - b} \end{array} \right) \] -bzgl. der beiden Parameter $m$ und $b$ der Geradengleichung ist ein -Vektor, der in Richtung des steilsten Anstiegs der Kostenfunktion -$e(m,b)$ zeigt. Die L\"ange des Gradienten gibt die St\"arke des -Anstiegs an (\figref{gradientquiverfig})). Da wir aber abw\"arts zum -Minimum laufen wollen, m\"ussen wir die dem Gradienten -entgegengesetzte Richtung einschlagen. +\[ \nabla f_{cost}(m,b) = \left( \frac{\partial e(m,b)}{\partial m}, + \frac{\partial f(m,b)}{\partial b} \right) \] bzgl. der beiden +Parameter $m$ und $b$ der Geradengleichung ist ein Vektor, der in +Richtung des steilsten Anstiegs der Kostenfunktion $f_{cost}(m,b)$ zeigt. +Die L\"ange des Gradienten gibt die St\"arke des Anstiegs an +(\figref{gradientquiverfig})). Da wir aber abw\"arts zum Minimum +laufen wollen, m\"ussen wir die dem Gradienten entgegengesetzte +Richtung einschlagen. Die partiellen Ableitungen m\"ussen nicht analytisch berechnet werden sondern k\"onnen numerisch entsprechend dem Differenzenquotienten (Box~\ref{differentialquotientbox}) mit kleinen Schrittweiten $\Delta -m$ und $\Delta b$ angen\"ahert werden: -\[\frac{\partial e(m,b)}{\partial m} = \lim\limits_{\Delta m \to - 0} \frac{e(m + \Delta m, b) - e(m,b)}{\Delta m} \approx \frac{e(m + \Delta m, b) - - e(m,b)}{\Delta m} \; . \] +m$ und $\Delta b$ angen\"ahert werden. z.B. approximieren wir die +partielle Ableitung nach $m$ durch +\[\frac{\partial f_{cost}(m,b)}{\partial m} = \lim\limits_{\Delta m \to + 0} \frac{f_{cost}(m + \Delta m, b) - f_{cost}(m,b)}{\Delta m} \approx \frac{f_{cost}(m + \Delta m, b) - + f_{cost}(m,b)}{\Delta m} \; . \] -\begin{figure} +\begin{figure}[t] \includegraphics[width=0.75\columnwidth]{error_gradient} \titlecaption{Der Gradienten der Fehlerfl\"ache.} {Jeder Pfeil zeigt die Richtung und die @@ -293,14 +310,14 @@ m$ und $\Delta b$ angen\"ahert werden: \end{figure} \begin{exercise}{lsqGradient.m}{}\label{gradientexercise}% - Implementiere eine Funktion \code{lsqGradient}, die die $x$- und - $y$-Werte der Messdaten sowie den Parametersatz $(m, b)$ der - Geradengleichung als 2-elementigen Vektor als Argumente + Implementiere eine Funktion \code{lsqGradient}, die den + Parametersatz $(m, b)$ der Geradengleichung als 2-elementigen Vektor + sowie die $x$- und $y$-Werte der Messdaten als Argumente entgegennimmt und den Gradienten an dieser Stelle zur\"uckgibt. \end{exercise} \begin{exercise}{errorGradient.m}{} - Benutzt die Funktion aus der vorherigen \"Ubung (\ref{gradientexercise}), + Benutze die Funktion aus der vorherigen \"Ubung (\ref{gradientexercise}), um f\"ur jede Parameterkombination aus der Fehlerfl\"ache (\"Ubung \ref{errorsurfaceexercise}) auch den Gradienten zu berechnen und darzustellen. Vektoren im Raum k\"onnen mithilfe der @@ -328,7 +345,7 @@ f\"ur den Abstieg lautet: wird (z.B. \code{norm(gradient) < 0.1}). \item \label{gradientstep} Gehe einen kleinen Schritt ($\epsilon = 0.01$) in die entgegensetzte Richtung des Gradienten: - \[p_{i+1} = p_i - \epsilon \cdot \nabla e(m_i, b_i)\] + \[p_{i+1} = p_i - \epsilon \cdot \nabla f_{cost}(m_i, b_i)\] \item Wiederhole die Schritte \ref{computegradient} -- \ref{gradientstep}. \end{enumerate} @@ -339,8 +356,8 @@ solange ver\"andert, wie der Gradient eine bestimmte Gr\"o{\ss}e ist auch die Ver\"anderung der Position gro{\ss} und der Abstand der Punkte in Abbildung \ref{gradientdescentfig} gro{\ss}. -\begin{figure}[hb] - \includegraphics[width=0.6\columnwidth]{figures/gradient_descent} +\begin{figure}[t] + \includegraphics[width=0.6\columnwidth]{gradient_descent} \caption{\textbf{Gradientenabstieg.} Es wird von einer beliebigen Position aus gestartet und der Gradient berechnet und die Position ver\"andert. Jeder Punkt zeigt die Position nach jedem @@ -364,32 +381,38 @@ Punkte in Abbildung \ref{gradientdescentfig} gro{\ss}. \section{Fazit} Mit dem Gradientenabstieg haben wir eine wichtige Methode zur Bestimmung eines globalen Minimums einer Kostenfunktion -kennengelernt. F\"ur den Fall des Kurvenfits mit einer -Geradengleichung zeigt der mittlere quadratische Abstand als -Kostenfunktion in der Tat ein einziges klar definiertes Minimum. - -Wie wir im n\"achsten Kapitel sehen werden, kann die Position des -Minimums bei Geradengleichungen sogar analytisch bestimmt werden, der -Gradientenabstieg w\"are also gar nicht n\"otig -\matlabfun{polyfit}. Bei allen nichtlinearen Funktionen, wie z.B. der -Exponentialfunktion $f(x;\lambda) = \exp(\lambda x)$ gibt es aber -keine analytische L\"osung, und das Minimum der Kostenfunktion muss -numerisch, z.B. mit dem Gradientenabstiegsverfhren bestimmt werden. - -Um noch schneller das Minimum zu finden, kann der Gradientenabstieg -auf vielf\"altige Wei{\ss}e verfeinert werden. z.B. kann die -Schrittweite an die St\"arke des Gradienten angepasst werden. Diese -numerischen Tricks sind in bereits vorhandenen Funktionen -implementiert. Allgemeine Funktionen sind f\"ur beliebige +kennengelernt. + +F\"ur den Fall des Kurvenfits mit einer Geradengleichung zeigt der +mittlere quadratische Abstand als Kostenfunktion in der Tat ein +einziges klar definiertes Minimum. Wie wir im n\"achsten Kapitel +sehen werden, kann die Position des Minimums bei Geradengleichungen +sogar analytisch bestimmt werden, der Gradientenabstieg w\"are also +gar nicht n\"otig \matlabfun{polyfit}. + +F\"ur Parameter, die nichtlinear in einer Funktion +enthalten sind, wie z.B. die Rate $\lambda$ als Parameter in der +Exponentialfunktion $f(x;\lambda) = \exp(\lambda x)$, gibt es keine +analytische L\"osung, und das Minimum der Kostenfunktion muss +numerisch, z.B. mit dem Gradientenabstiegsverfahren bestimmt werden. + +Um noch schneller das Minimum zu finden, kann das Verfahren des +Gradientenabstiegs auf vielf\"altige Weise verbessert +werden. z.B. kann die Schrittweite an die St\"arke des Gradienten +angepasst werden. Diese numerischen Tricks sind in bereits vorhandenen +Funktionen implementiert. Allgemeine Funktionen sind f\"ur beliebige Kostenfunktionen gemacht \matlabfun{fminsearch}, w\"ahrend spezielle Funktionen z.B. f\"ur die Minimierung des quadratischen Abstands bei einem Kurvenfit angeboten werden \matlabfun{lsqcurvefit}. \begin{important} Das Finden des globalen Minimums ist leider nur selten so leicht wie - bei einem Geradenfit. Oft gibt es viele Nebenminima, in denen der - Gradientenabstieg enden kann, obwohl das gesuchte globale Minimum - noch weit entfernt ist. Darum ist es meist sehr wichtig, wirklich - gute Startwerte f\"ur die zu bestimmenden Parameter der - Kostenfunktion zu haben. + bei einem Geradenfit. Oft hat die Kostenfunktion viele Nebenminima, + in denen der Gradientenabstieg enden kann, obwohl das gesuchte + globale Minimum noch weit entfernt ist. Darum ist es meist sehr + wichtig, wirklich gute Startwerte f\"ur die zu bestimmenden + Parameter der Kostenfunktion zu haben. Auch sollten nur so wenig wie + m\"oglich Parameter gefittet werden, da jeder zus\"atzliche + Parameter den Optimierungsprozess schwieriger und + rechenaufw\"andiger macht. \end{important}