diff --git a/regression/code/errorSurface.m b/regression/code/errorSurface.m new file mode 100644 index 0000000..421c11c --- /dev/null +++ b/regression/code/errorSurface.m @@ -0,0 +1,31 @@ +clear +close all + +load('lin_regression.mat'); + +slopes = -5:0.25:5; +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([slopes(i), intercepts(j)], x, y); + end +end + + +% plot the error surface +figure() +[N,M] = meshgrid(intercepts, slopes); +s = surface(M,N,error_surf); +xlabel('slope', 'rotation', 7.5) +ylabel('intercept', 'rotation', -22.5) +zlabel('error') +set(gca,'xtick', (-5:2.5:5)) +grid on +view(3) +set(gcf, 'paperunits', 'centimeters', 'papersize', [15, 15], ... + 'paperposition', [0., 0., 15, 15]) + +saveas(gcf, 'error_surface', 'pdf') \ No newline at end of file diff --git a/regression/code/lsq_error.m b/regression/code/lsqError.m similarity index 89% rename from regression/code/lsq_error.m rename to regression/code/lsqError.m index a648e48..b701b35 100644 --- a/regression/code/lsq_error.m +++ b/regression/code/lsqError.m @@ -1,4 +1,4 @@ -function error = lsq_error(parameter, x, y) +function error = lsqError(parameter, x, y) % Objective function for fitting a linear equation to data. % % Arguments: parameter, vector containing slope and intercept (1st and 2nd element) diff --git a/regression/code/lsqGradient.m b/regression/code/lsqGradient.m new file mode 100644 index 0000000..c848b81 --- /dev/null +++ b/regression/code/lsqGradient.m @@ -0,0 +1,7 @@ +function gradient = lsqGradient(parameter, x, y) +h = 1e-6; + +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]; \ No newline at end of file diff --git a/regression/code/lsq_gradient.m b/regression/code/lsq_gradient.m deleted file mode 100644 index 6773c4e..0000000 --- a/regression/code/lsq_gradient.m +++ /dev/null @@ -1,7 +0,0 @@ -function gradient = lsq_gradient(parameter, x, y) -h = 1e-6; - -partial_m = (lsq_error([parameter(1)+h, parameter(2)],x,y) - lsq_error(parameter,x,y))/ h; -partial_n = (lsq_error([parameter(1), parameter(2)+h],x,y) - lsq_error(parameter,x,y))/ h; - -gradient = [partial_m, partial_n]; \ No newline at end of file diff --git a/regression/code/mean_square_error.m b/regression/code/meanSquareError.m similarity index 100% rename from regression/code/mean_square_error.m rename to regression/code/meanSquareError.m diff --git a/regression/lecture/figures/error_gradient.pdf b/regression/lecture/figures/error_gradient.pdf new file mode 100644 index 0000000..159c684 Binary files /dev/null and b/regression/lecture/figures/error_gradient.pdf differ diff --git a/regression/lecture/figures/error_surface.pdf b/regression/lecture/figures/error_surface.pdf new file mode 100644 index 0000000..53e76dc Binary files /dev/null and b/regression/lecture/figures/error_surface.pdf differ diff --git a/regression/lecture/regression.tex b/regression/lecture/regression.tex index 0d5d473..1eb22a4 100644 --- a/regression/lecture/regression.tex +++ b/regression/lecture/regression.tex @@ -69,7 +69,7 @@ Stellen sind. \url{http://en.wikipedia.org/wiki/Linear_least_squares_(mathematics)}} \label{leastsquareerrorfig} \end{figure} -\begin{exercise}{mean_square_error.m}{} +\begin{exercise}{meanSquareError.m}{}\label{mseexercise} Schreibt eine Funktion, die die mittlere quardatische Abweichung zwischen den beobachteten Werten $y$ und der Vorhersage $y_{est}$ berechnet. @@ -77,18 +77,18 @@ Stellen sind. \section{Zielfunktion --- Objective function} -Schliesst man in die Fehlerfunktion von oben die Vorhersage des Modells -mit ein spricht man von der Zielfunktion oder Englisch ``objective -function'': +Schliesst man in die Fehlerfunktion von oben (\"Ubung +\ref{mseexercise}) die Vorhersage des Modells mit ein spricht man von +der Zielfunktion oder Englisch ``objective function'': \[e(m,n) = \frac{1}{N}\sum^{N}_{1=1} \left( y_i - f_{m, n}(x_i)\right )^2\] Das Ziel der Parameteranpassung ist es, den Fehler zu minimieren, die -Passung zu Optimieren. +Passung zu optimieren. -\begin{exercise}{lsq_error.m}{} - Implementiere die Zielfunktion (\code{lsq\_error}) f\"ur die +\begin{exercise}{lsqError.m}{} + Implementiere die Zielfunktion (\code{lsqError}) f\"ur die Optimierung mit der linearen Geradengleichung. \begin{itemize} \item Die Funktion \"ubernimmt drei Argumente: das erste ist ein @@ -102,64 +102,155 @@ Passung zu Optimieren. \section{Fehlerfl\"ache} -Die beiden Parameter $m$ und $n$ spanngen eine 2-dimensionale F\"ache -auf. F\"ur jede Kombination aus $m$ und $n$ erhalten wir -Vorhersagewerte, die von den gemessenen Werten abweichen. Es gibt also -f\ur jeden Punkt in der sogenannten \emph{Fehlerfl\"ache} einen -Fehler. In diesem Beispiel kann man die Fehlerfl\"ache graphisch durch -einen 3-d ``surface-plot'' darstellen. Wobei auf der x- und y-Achse -die beiden Parameter und auf der z-Achse der Fehlerwert aufgetragen -wird (Abbildung \ref{errorsurfacefig}). +Die beiden Parameter $m$ und $n$ spanngen eine F\"ache auf. F\"ur jede +Kombination aus $m$ und $n$ erhalten wir Vorhersagewerte, die von den +gemessenen Werten abweichen werden. 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 man die +Fehlerfl\"ache graphisch durch einen 3-d ``surface-plot'' +darstellen. Wobei auf der x- und y-Achse die beiden Parameter und auf +der z-Achse der Fehlerwert aufgetragen wird (Abbildung +\ref{errorsurfacefig}). +\clearpage \begin{figure} - \includegraphics[width=0.5\columnwidth]{figures/surface.pdf} - \caption{\textbf{Fehlerfl\"ache.} }\label{errorsurfacefig} + \includegraphics[width=0.75\columnwidth]{figures/error_surface.pdf} + \caption{\textbf{Fehlerfl\"ache.} Die beiden freien Parameter + unseres Modells spannen die Grundfl\"ache des Plots auf. F\"ur + jede Kombination von Steigung und y-Achsenabschnitt wird die + errechnete Vorhersage des Modells mit den Messwerten verglichen + und der Fehlerwert geplottet.}\label{errorsurfacefig} \end{figure} +Die Fehlerfl\"ache zeigt uns nun an bei welcher Parameterkombination +der Fehler minimal, beziehungsweise die Parametertrisierung optimal an +die Daten angepasst ist. Wie kann die Fehlerfunktion und die durch sie +definierte Fehlerfl\"ache nun benutzt werden um den +Optimierungsprozess zu leiten? - \textbf{Aufgabe} - \begin{enumerate} - \item Ladet den Datensatz \textit{lin\_regression.mat} in den - Workspace. Wie sehen die Daten aus? - \item Schreibt eine Funktion \code{lsq\_error}, die den Fehler - brechnet: - \begin{itemize} - \item \"Ubernimmt einen 2-elementigen Vektor, der die Parameter - \code{m} und \code{n} enth\"alt, die x-Werte und y-Werte. - \item Die Funktion gibt den Fehler zur\"uck. - \end{itemize} - \item Schreibt ein Skript dass den Fehler in Abh\"angigkeit von - \code{m} und \code{n} als surface plot darstellt (\code{surf} - Funktion). - \item Wie k\"onnen wir diesen Plot benutzen um die beste Kombination - zu finden? - \item Wo lieft die beste Kombination? - \end{enumerate} +\begin{exercise}{errorSurface.m}{}\label{errorsurfaceexercise} + Ladet den Datensatz \textit{lin\_regression.mat} in den + Workspace. und schreibt ein Skript \code{errorSurface.m} dass den + Fehler in Abh\"angigkeit von \code{m} und \code{n} als surface plot + darstellt (siehe Hilfe f\"ur die \code{surf} Funktion). +\end{exercise} \section{Gradient} +Man kann sich den Optimierungsprozess veranschaulichen wenn man sich +vorstellt, dass eine Parameterkombination einen Punkt auf der +Fehlerfl\"ache definiert. Wenn von diesem Punkt aus eine Kugel +losgelassen w\"urde, dann w\"urde sie, dem steilsten Gef\"alle +folgend, zum Minimum der Fehlerfl\"ache rollen und dort zum Stehen +kommen. Um dem Computer zu sagen, in welche Richtung die Position +ver\"andert werden soll muss also die Steigung an der aktellen +Position berechnet werden. + +Die Steigung einer Funktion an einer Stelle ist die Ableitung der +Funktion an dieser Stelle, die durch den Differenzquotienten f\"ur +unendlich kleine Schritte bestimmt wird. + +\[f'(x) = \lim\limits_{h \rightarrow 0} \frac{f(x + h) - f(x)}{h} \] +Bei unserem Fittingproblem h\"angt die Fehlerfunktion von zwei +Parametern ab und wir bestimmen die Steigung partiell f\"ur jeden +Parameter einzeln. Die Partielle Ableitung nach \code{m} sieht so aus: +\[\frac{\partial g(m,n)}{\partial m} = \lim\limits_{h \rightarrow 0} \frac{g(m + h, n) - g(m,n)}{h}\] +Da wir die Ver\"anderung des Fehlers in Abh\"angigkeit der beiden +Parameter bewerten ist der Gradient an der Stelle $(m,n)$ ein +zweielementigen Vektor der aus den partiellen Ableitungen nach $m$ und +nach $n$ besteht. Die Richtung des Gradienten zeigt die Richtung der +gr\"o{\ss}ten Steigung an, seine L\"ange repr\"asentiert die St\"arke +des Gef\"alles. + +\[\bigtriangledown g(m,n) = \left( \frac{\partial g(m,n)}{\partial m}, \frac{\partial g(m,n)}{\partial n}\right)\] +Die partiellen Ableitungen m\"ussen nicht analytisch berechnet werden +sondern wir n\"ahern sie numerisch durch einen sehr kleinen Schritt +an. +\[\frac{\partial g(m,n)}{\partial m} = \lim\limits_{h \rightarrow + 0} \frac{g(m + h, n) - g(m,n)}{h} \approx \frac{g(m + h, n) - + g(m,n)}{h}\] + +Die graphische Dargestellung der Gradienten (Abbildung +\ref{gradientquiverfig}) zeigt, dass diese in die Richtung der +gr\"o{\ss}ten Steigung zeigen. Um zum Minimum der Fehlerfunktion zu +gelangen sollte man also die entgegengesetzte Richtung einschlagen. + +\begin{figure} + \includegraphics[width=0.75\columnwidth]{figures/error_gradient} + \caption{\textbf{Darstellung der Gradienten f\"ur jede + Parameterkombination.} Jeder Pfeil zeigt die Richtung und die + Steigung f\"ur verschiedene Parameterkombination aus Steigung und + y-Achsenabschnitt an. Die Kontourlinien im Hintergrund + illustrieren die Fehlerfl\"ache. Warme Farben stehen f\"ur + gro{\ss}e Fehlerwerte, kalte Farben f\"ur kleine. Jede + Kontourlinie steht f\"ur eine Linie gleichen + Fehlers.}\label{gradientquiverfig} +\end{figure} + +\begin{exercise}{lsqGradient.m}{}\label{gradientexercise} + Implementiert eine Funktion \code{lsqGradient}, die den aktuellen + Parametersatz als 2-elementigen Vektor, die x-Werte und die y-Werte + als Argumente entgegennimmt und den Gradienten zur\"uckgibt. +\end{exercise} + +\begin{exercise}{errorGradient.m}{} + Benutzt die Funktion aus verheriger \"Ubung (\ref{gradientexercise}) + um f\"ur die jede Parameterkombination aus der Fehlerfl\"ache + (\"Ubung \ref{errorsurfaceexercise}) auch den Gradienten zu + berechnen und darzustellen. Vektoren im Raum kann man mithilfe der + Funktion \code{quiver} geplottet werden. +\end{exercise} + +\section{Der Gradientenabstieg} + +Zu guter Letzt muss ``nur'' noch der Gradientenabstieg implementiert +werden. Die daf\"ur ben\"otigten Zutaten sollten wir aus den +vorangegangenen \"Ubungen haben. Wir brauchen: 1. Die Fehlerfunktion +(\code{meanSquareError.m}), 2. die Zielfunktion (\code{lsqError.m}) +und 3. den Gradienten (\code{lsqGradient.m}). Der Algorithmus +f\"ur den Abstieg lautet: +\begin{enumerate} +\item Starte mit einer beliebigen Parameterkombination $p_0 = (m_0, + n_0)$. +\item Wiederhole die folgenden Schritte solange, wie die der Gradient \"uber einer bestimmten + Schwelle ist (Es kann z.B. die L\"ange des Gradienten \code{norm(gradient) > 0.1} + benutzt werden): \begin{itemize} - \item Wie findet man die Extrempunkte in einer Kurve?\pause - \item Ableitung der Funktion auf Null setzen und nach x aufl\"osen. - \item Definition der Ableitung:\\ \vspace{0.25cm} - \begin{center} - $ f'(x) = \lim\limits_{h \rightarrow 0} \frac{f(x + h) - f(x)}{h} $ - \vspace{0.25cm}\pause - \end{center} - \item Bei zwei Parametern $g(m,n)$ k\"onnen wie die partielle - Ableitung bez\"uglich eines Parameters benutzen um die - Ver\"anderung des Fehlers bei Ver\"anderung eines Parameters - auszuwerten. - \item Partielle Ableitung nach \code{m}?\\\pause - \vspace{0.25cm} - \begin{center} - $\frac{\partial g(m,n)}{\partial m} = \lim\limits_{h \rightarrow 0} \frac{g(m + h, n) - g(m,n)}{h}$ - \vspace{0.25cm} - \end{center} + \item Berechne den Gradienten an der akutellen Position $p_t$. + \item Gehe einen kleinen Schritt ($\epsilon = 0.01$) in die entgegensetzte Richtung des + Gradienten: + \[p_{t+1} = p_t - \epsilon \cdot \bigtriangledown g(m_t, n_t)\] \end{itemize} +\end{enumerate} -\section{Der Gradientenabstieg} +Abbildung \ref{gradientdescentfig} zeigt den Verlauf des +Gradientenabstiegs. Von einer Startposition aus wird die Position +solange ver\"andert, wie der Gradint eine bestimmte Gr\"o{\ss}e +\"uberschreitet. An den Stellen, an denen der Gradient sehr stark ist +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} + \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 + Optimierungsschritt an.} \label{gradientdescentfig} +\end{figure} + +\clearpage +\begin{exercise}{gradientDescent.m}{} + Implementiere den Gradientenabstieg f\"ur das Problem der + Parameteranpassung der linearen Geradengleichung an die Messdaten in + der Datei \code{lin\_regression.mat}. + \begin{enumerate} + \item Merke Dir f\"ur jeden Schritt den Fehler zwischen + Modellvorhersage und Daten. + \item Erstelle eine Plot, der die Entwicklung des Fehlers als + Funktion der Optimierungsschritte zeigt. + \item Erstelle einen Plot, der den besten Fit in die Daten plottet. + \end{enumerate} +\end{exercise}