\item Warum ist es nicht sinnvoll eine lineare Funktion $(y=\alpha x+b)$ als Aktivierungsfunktion in den verdeckten Schichten eines neuronalen Netzes zu verwenden?
\item Im Wesentlichen ist Backpropagation ein Algorithmus, der zur schnellen Berechnung von Ableitungen verwendet wird
\item auch Fehlerrückführung oder Rückwärtspropagierung
\item um einen Gradientenabstieg in Bezug auf Gewichtungen zu berechnen
\item gewünschte Ausgaben werden mit erreichten Systemausgaben verglichen, und dann werden die Systeme durch Anpassung der Verbindungsgewichte so eingestellt, dass der Unterschied zwischen den beiden so gering wie möglich ist
\item der Algorithmus hat seinen Namen daher, dass die Gewichtungen rückwärts aktualisiert werden, von der Ausgabe zur Eingabe
\item Durch Vergleich der Ausgabe der verifizierten Testdaten mit realen Ergebnissen um den Unterschied zwischen Richtigen, Falsch-Richtigen, Falschen und Falsch-Richtigen Ergebnissen zu einem Wert, der Güte, zusammenzufassen
\item kleine fehlerhafte oder ungenaue Bild-Sektionen können zu größeren Fehlern und Abweichungen von dem Original führen die durch die Hochauflösung überdeckt oder verschoben werden
\subsection{Notebook 1: Grundkenntnisse zur Anwendung von Deep Learning}
\subsubsection{Aufgabe 1a) Erstellen eines einfachen neuronalen Netzes}
Gegeben ist ein neuronales Netz (NN). Berechne von Hand mit den gegebenen Gewichten den Output des Netzes für die Inputs $x =-1, 1$ und $2$. Die Aktivierungsfunktion aller Neuronen sei 'ReLu'.
Im Folgenden soll die eben gelöste Aufgabe erneut mit der Bibliothek ,,keras'' gelöst werden. Erzeuge mit Hilfe der Befehle aus der Vorbereitung das NN. Dazu werden zunächst die benötigten Bibliotheken geladen. Neue Schichten können mit dem Befehl `model.add()` hinzugefügt werden.
\begin{lstlisting}[language=python]
# Import der benötigten Bibliotheken
exec(open(r"../data/notebook1_code.py").read())
%matplotlib inline
# Laden eines Modelltyps für das neuronale Netz
model=tf.keras.models.Sequential()
# TODO: Füge die drei benötigten Schichten zum Netz hinzu
# Hinweis: Vergessen Sie nicht im ersten Layer die Inputdimension anzugeben
# TODO: Übergebe die Gewichtsmatrizen (weight_list)
model.set_weights(weight_list)
\end{lstlisting}
Nutze nun die predict-Funktion, um die handschriftlichen Rechnungen zu überprüfen.
\begin{lstlisting}[language=python]
# TODO: Führe eine Prediction für drei Werte [-1, 1, 2] durch.
model.predict([-1, 1, 2])
\end{lstlisting}
Ausgabe:
\begin{lstlisting}[language=python]
array([[0.], [6.], [7.]], dtype=float32)
\end{lstlisting}
\textbf{Antwort:} Der Rechenweg und das Neuronale Netzwerk liefern dasselbe Ergebnis.
\subsubsection{Aufgabe 1b) Neuronales Netz zur Funktionsapproximation}
Statt nur einzelne Punkte zu predicten können auch größere Bereiche auf dem Zahlenstrahl abgetastet werden. Gebe dazu 50 Werte von -5 bis 5 in die predict-Funktion.
\begin{lstlisting}[language=python]
# Importieren der Bibliothek für die Darstellung der Kurve
from matplotlib import pyplot as plt
# TODO: Gebe die Werte -5 bis 5 in 50 Schritten auf die predict-Funktion und speicher die Ausgabe in der Variable result
Mit diesem Netz soll die R-Zacke eines QRS-Komplexes approximiert werden. Lade dazu mit der folgenden Funktion ein Widget. Mit diesem kann der Einfluss einzelner Parameter des Netzes aus Aufgabe 1 a) auf die approximierte Funktion untersucht werden. Versuche die Form der blauen Kurve möglichst der roten anzupassen. Die rote Kurve stellt einen realen QRS-Komplex dar. Die blaue Kurve zeigt die Funktion, welche Ihr Netz mit den aktuell eingestellten Parametern realisiert.
\begin{lstlisting}[language=python]
# Lade das Widget
weight_widget_relu()
\end{lstlisting}
\textbf{Kommentar:} Die Einstellung ist nur mit Maus schwer umzusetzten und liefert nur ungenaue Ergebnisse. Eine Veränderung des Ausschnittrahmens wäre ebenfalls hilfreich.
Die vom Netz realisierte Funktion besitzt eine einfache Form. Mit NN lassen sich Funktionen beliebiger Form approximieren. Je komplexer die Form der zu approximierenden Funktion, desto mehr Neuronen werden benötigt.
In der Praxis ist das Vorgehen aus dem vorherigen Aufgabenteil zu aufwändig. Daher können NN in keras automatisch optimiert werden.
Dazu werden Trainingsdaten benötigt. Im Folgenden soll das obige Netz mit 10 QRS-Komplexen trainiert werden. Dabei lernt es automatisch die Gewichte zur Approximation der QRS-Komplexe. Die folgende Zelle zeigt die verwendeten QRS-Komplexe, lädt die Daten und verarbeitet sie vor.
\begin{lstlisting}[language=python]
# Lesen der Daten von CSV-Datei
dataset = pd.read_csv("../data/data_ekg.csv")
# Plotten der Daten
plot_EKG_data(dataset)
\end{lstlisting}
Das Netz wird nun mit diesen Daten trainiert. Führe die folgende Zelle aus, um das Training zu starten.
\subsubsection{Aufgabe 1c) Neuronales Netz zur Erkennung handschriftlicher Ziffern}
Im Folgenden wird sich mit der Bilddatenklassifikation beschäftigt. Dabei wird der MNIST-Datensatz verwendet. Dieser enthält Bilder handschriftlicher Ziffern. Die korrekte Klassifikation solcher könnte die Digitalisierung von Patientenakten vereinfachen.
Lade zunächst die Daten. Nehme anschließend das Netz aus Aufgabenteil 1 und erweitere es so, dass eine Verarbeitung der Bilddaten und ihrer Label möglich ist. Die x-Variable enthält jeweils die Bilddaten und die y-Variable die Label.
# Erzeugen des NN nach der oben festgelegten Struktur
model.compile(optimizer='adam',
loss="categorical_crossentropy",
metrics=["accuracy"])
\end{lstlisting}
In der nächsten Zelle hat sich ein logischer Fehler eingeschlichen. Versuche Schritt für Schritt den Code nachzuvollziehen und korrigiere den Fehler.
\begin{lstlisting}[language=python]
# TODO
# Training des NN
history = model.fit(x_train, y_train, batch_size=1, epochs=10, verbose=1)
# Klassifizierung der Bilder mit Hilfe des NN
result = model.predict(x_test)
# Anzeigen der Ergebnisse (Index der wahrscheinlichsten Klasse)
print("Bild0 = "+str(np.argmax(result[0])))
print("Bild1 = "+str(np.argmax(result[1])))
print("Bild2 = "+str(np.argmax(result[2])))
print("Bild3 = "+str(np.argmax(result[3])))
'''
Folgenden Code nicht ändern
'''
model=tf.keras.models.Sequential()
\end{lstlisting}
Spiele mit den Hyperparametern des Netzes, also der Anzahl der Hidden Layer und der Neuronen. Vergleiche die erreichte Accuracy im Training bei zwei verschiedenen Konfigurationen. Was wäre ein Beispiel für ein zu kleines Netz?
\textbf{Antwort:} Zu kleine Netze sind Netze die nicht den Bildraum der Eingabebilder abdecken, so z.B. bei 28x28 Pixeln eine Hidden-Layer Größe von 10x10 Neuronen. Ein solch kleines Netz wird größere Schwierigkeiten und Fehler liefern als das Netz das eine Größe entsprechend der Eingangspixel enthält.
Nun wird das NN trainiert und eine Klassifikation der obigen Bilder vorgenommen. Stimmt etwas mit den Klassifikationsergebnissen nicht? Erkläre anhand der folgenden Bilder, warum ein NN bei dieser Aufgabenstellung nie 100\% Accuracy erreichen kann.
\textbf{Antwort:} Sehr große Ähnlichkeit zwischen einzelnen Bildern/Buchstaben und Zahlen, Klassifikation nicht auf Zahlen sondern Buchstaben, ein anderer Datensatz wird verwendet als er für die Bilder notwenig wäre.
\subsection{Notebook 2: Anwendung von Deep Learning in der Biomedizintechnik}
\subsubsection{Aufgabe 2a: Data Sanitization mit Hilfe von Pandas}
Im Folgenden wurde ein Patientendatenblatt und das dazugehörige pandas-DataFrame zur Verfügung gestellt.
Im Rahmen eines fiktiven Machine Learning-Projektes wurden diese Daten über Umwege (Excel, etc.) in eine csv-Datei übertragen. Dabei ist es zu Konvertierungsfehlern gekommen. Die csv-Datei kann mit pandas eingelesen werden.
\begin{lstlisting}[language=python]
# Import der benötigten Bibliotheken
import pandas as pd
exec(open(r"../data/notebook2_code.py").read())
# Einlesen des Datenblattes in ein pandas-DataFrame
data = pd.read_csv(r"../data/datenblatt.csv", sep=";", encoding="latin1")
Ein NN soll mit diesen Daten trainiert werden. Es soll bestimmt werden, ob der Patient einem gesundheitlichen Risiko unterliegt. Dazu werden die Blutwerte der Nummerierung in pandas entsprechend auf das NN gegeben. Der Prozess der Data Sanitization ist meist nicht so einfach wie oben angegeben.
TODO: Korrigiere mögliche Fehler in den Daten.
\begin{lstlisting}[language=python]
# Einlesen des Datenblattes in ein pandas-DataFrame
data = pd.read_csv(r"../data/datenblatt.csv", sep=";", encoding="latin1")
# TODO: Modifizieren Sie die Daten im pandas-Dataframe
Das Training konnte mit den gegebenen Daten erfolgreich durchgeführt werden!
\end{lstlisting}
\subsubsection{Aufgabe 2b: Neuronales Netz zur Klassifikation von OCT-Aufnahmen}
Im Folgenden sollen OCT-Aufnahmen klassifiziert werden. Diese zeigen Querschnittsaufnahmen der Netzhaut. Im Datensatz sind Bilder von gesunden Probanden vorhanden. Außerdem gibt es solche mit \hyperref{https://en.wikipedia.org/wiki/Choroidal_neovascularization}{choroidaler Neovaskularisation} (CNV), \hyperref{https://en.wikipedia.org/wiki/Macular_edema}{Makulaödem} (DME) und \hyperref{https://en.wikipedia.org/wiki/Drusen}{Drusen} (DRUSEN). Es werden vier Bilder gegeben.
Welche Bilder wurden richtig klassifiziert? Erkläre die Entscheidung des Netzes anhand seiner Ausgabe (Hinweis: Es wird ein Softmax-Output verwendet, der Klassenwahrscheinlichkeiten repräsentiert. Eine Outputzeile entspricht dem Output für ein Bild).
\textbf{Antwort:} Kein Bild wurde richtig klassifiziert. Nur mit vier Bildern lässt sich die Unterscheidung schlecht erklären, insbesondere da CNV und DME optisch (für Menschen) leicht unterscheidbar sind, das NN es aber für CNV hält. Grund ist wahrscheinlich ein sehr kleiner Datensatz und wenige konkrete Unterscheidungspunkte zwischen den Bildern.
Das oben verwendete Netz erreicht auf einem Testdatensatz 69\% Accuracy. Dieses Ergebnis kann verbessert werden, indem ein größerer Trainingsdatensatz verwendet wird. Durch Data Augmentation kann der Trainingsdatensatz vergrößert werden, ohne dass neue Daten erhoben werden müssen.
Das heißt, es sollen veränderte Bilder erzeugt werden, die dieselben Informationen enthalten wie das Original. Dazu stehen verschiedene Möglichkeiten zur Verfügung. Im Folgenden werden einige Beispiele aufgelistet.
\begin{itemize}
\item np.flipud(img) = Spiegeln an der horizontalen Achse
\item np.fliplr(img) = Spiegeln an der vertikalen Achse
\item tf.keras.preprocessing.image.apply\_affine\_transform(img,theta= 10) = Rotieren des Bildes, um den Winkel theta
\item keras.preprocessing.image.apply\_brightness\_shift(img, brightness) = Ändern der Bildhelligkeit
\item add\_noise(noise\_typ,img[:,:,0]) = Verrauschen des Bildes(Rauscharten= 's\&p', 'gauss', 'poisson', 'speckle')
\end{itemize}
Wähle aus den gegebenen Transformationen drei aus, die für die gegebene Anwendung geeignet sind. Führe diese an einem Beispielbild durch und speichere die manipulierten Bilder. Stelle das Ergebnisse im Protokoll dar. Begründe im Protokoll den Ausschluss der nicht gewählten Operationen.
\textbf{Antwort:} Spiegelungen und Rotationen können zur Augmentation genutzt werden, da diese keinen Einfluss auf die Diagnose haben. Eine Veränderung der Bilder durch Rauschen oder Helligkeit kann Informationen und Details für das Neuronale Netzwerk unkenntlich machen oder verfälschen.
\subsection{Notebook 3: Grenzen von Deep Learning}
Im Bereich der Medizin spielt Vertrauen in die Technik eine große Rolle. Für das Vertrauen ist es wichtig zu wissen, auf welcher Grundlage die Entscheidungen für eine Klasse getroffen werden. Bisher wurden NN angewendet und sich auf deren Ausgaben verlassen. Die Entscheidungskriterien waren unbekannt. Da NN als ,,Black-Box'' betrachtet werden können, ist dies mit vielen Gefahren verbunden. Diese sollen im Folgenden verdeutlicht werden.
\begin{lstlisting}[language=python]
# Import der benötigten Bibliotheken
exec(open(r"../data/notebook3_code.py").read())
\end{lstlisting}
Es ist ein NN gegeben. Dieses wurde auf einem Datensatz von MRT-Scans trainiert. Diese sehen z.B. wie folgt aus:
Je nach Herkunft können die Bilder mit Datumsstempeln oder Wasserzeichen versehen sein. Diese können bei der Anwendung des Netzes später zu Problemen führen.
Die Daten haben die Klassen ,,gesund'' (Klasse 1) und ,,abnormal'' (Klasse 2). Ein Großteil der als ,,abnormal'' gelabelten Daten stammt von einer (fiktiven) Studie der TU Ilmenau.
Es sind zwei als ,,abnormal'' gelabelte Bilder gegeben.
Führe nun eine Klassifikation der obigen Bilder durch. Das NN verwendet einen Softmax-Output.
\begin{lstlisting}[language=python]
# TODO: Führen Sie die Klassifikation durch
result = model.predict(im_array)
print("Bild0 = "+str(np.argmax(result[0])))
print("Bild1 = "+str(np.argmax(result[1])))
\end{lstlisting}
Ergebnis:
\begin{lstlisting}[language=python]
Bild0 = 1
Bild1 = 0
\end{lstlisting}
Bei diesem Ergebnis ist Skepsis geboten! Interpretiere das Ergebnis.
\textbf{Antwort:} beide Knie sind abnormal. Das NN klassifiziert jedoch eines als Normal. Problematisch wird der unterschiedliche Ausschnitt sein, sowie weniger/mehr rot-gekennzeichnete Zonen.
Im Folgenden soll untersucht werden, worauf das NN seine Entscheidung stützt. Dazu wird der Class Activation Map (CAM)-Algorithmus verwendet. Dieser ordnet einem Bild eine Heatmap zu, welche die Wichtigkeiten der Pixel für die Klassifikationsentscheidung angibt.
Nutze dafür die im Praktikum zur Verfügung gestellte visualize\_class\_activation\_map-Funktion. Diese gibt die zu einem Inputbild gehörende Heatmap der Wichtigkeiten aus.
\textbf{Antwort:} In Bild 1 ist das Knie nicht betrachtungspunkt des NN. In Bild 2 wird das Knie, besonders der untere Knochen und der vordere Teil, in die Betrachtung mit einbezogen. D.h. bei Bild 1 wird eine völlig falsche Stelle untersucht und für die Diagnose verwendet. Möglicherweise sind Bilddaten falsch interpretiert oder Präperiert worden.
Die Verwendung einer anderen Colormap kann weitere Informationen ersichtlich machen. Führe den oben verwendeten plt.imshow-Befehl dazu mit anderen Colormaps aus. Können mit einer anderen Colormap das Problem, welches bei diesem NN vorliegt, besser verdeutlicht werden? Erzeuge einen Screenshot für die Colormaps ,,summer'', ,,flag'' und ,,rainbow''.