Skip to content
Snippets Groups Projects
Commit b802d438 authored by linushelfman's avatar linushelfman
Browse files

Aufgabe 6 fix + pdf

parent 645995e5
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
# Übung 6: Transfer learning
Gruppe 2: Albrecht Oster, Linus Helfmann
%% Cell type:markdown id: tags:
Neuronal Netze benötigen oft eine große Menge an Trainingsdaten, damit es nicht zu overfitting kommt. Transfer learning erlaubt es, mit relativ geringen Datenmenge dennoch erfolgreiche große Netze zu trainieren. Dabei verwendet man ein bereits auf einen anderen Datensatz (z.b. ImageNet) vortrainiertes Netzwerk, und ersetzt nur das letzte Layer durch ein neues. In dieser Übung geht es darum, ein Netzwerk für die Erkennung von Geparden und Leoparden in der freien Wildbahn zu trainineren.
%% Cell type:markdown id: tags:
## Daten laden
Lade die Daten hier herunter: http://tonic.imp.fu-berlin.de/cv_data/data.tar.gz
(die Daten liegen auch entpackt hier: http://tonic.imp.fu-berlin.de/cv_data/data/)
Die Daten wurde bereits in ein Trainings- und Validierungsset geteilt. Die Ordnerstruktur ist wie bei vielen Bildklassifierungsdatensetzen so aufgebaut. Es gibt zwei Unterordner für die Trainings- und Validierunsdaten. In diesen Ordnern liegen dann jeweils alle Bilder von einer Klasse in einem Unterordner mit dem Namen der Klasse.
Ein Beispiel: Die Trainingsbilder für die Klasse "cheetah" liegen in dem Unterordner train/cheetah
Diese Orderstruktur wird auch von dem in keras enhaltenen ImageDataGenerator unterstützt.
%% Cell type:code id: tags:
``` python
import tensorflow as tf
import numpy as np
from sklearn.metrics import roc_auc_score, confusion_matrix
from keras.backend.tensorflow_backend import set_session, get_session
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.optimizers import RMSprop
from keras.datasets import mnist
from keras.utils import np_utils
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
set_session(tf.Session(config=config))
import os
from keras.preprocessing.image import ImageDataGenerator
```
%% Output
C:\Anaconda3\envs\tensorflow\lib\site-packages\h5py\__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
from ._conv import register_converters as _register_converters
Using TensorFlow backend.
%% Cell type:code id: tags:
``` python
EPOCHEN=3
batch_size = 32
image_input_size = (224, 224)
data_path = 'cheetas/'
```
%% Cell type:code id: tags:
``` python
train_data_path = os.path.join(data_path, 'train')
val_data_path = os.path.join(data_path, 'val')
izw_classes = ('unknown', 'cheetah', 'leopard')
generator = ImageDataGenerator(horizontal_flip=True)
val_generator = ImageDataGenerator(horizontal_flip=False)
train_gen = generator.flow_from_directory(
train_data_path,
target_size=image_input_size,
classes=izw_classes,
batch_size=batch_size)
val_gen = val_generator.flow_from_directory(
val_data_path,
target_size=image_input_size,
classes=izw_classes,
batch_size=batch_size)
# Labels als array
val = []
for i in range(0,len(val_gen)):
val.append(val_gen[i][1])
val = np.concatenate(val)
val_labels = np.argmax(val, axis=1)
```
%% Output
Found 17857 images belonging to 3 classes.
Found 1915 images belonging to 3 classes.
%% Cell type:markdown id: tags:
## Training ohne transfer learning
Trainiere zuerst ein kleines Classifer-Netzwerk ohne transfer learning. Falls du keine Grafikkarte hast, solltest du nicht die volle Auflösung (siehe Variable image_input_size) verwenden, da das Training sonst zu lange dauert. Eine Bildgröße von 32x32 Pixeln wäre zum Beispiel möglich.
%% Cell type:code id: tags:
``` python
model = Sequential()
model.add(Conv2D(64, (5, 5), activation='relu',
input_shape=image_input_size + (3,)))
model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(1000, activation='relu'))
model.add(Dense(3, activation='softmax'))
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', \
metrics=['accuracy'])
#model.summary()
```
%% Cell type:code id: tags:
``` python
history = model.fit_generator(train_gen, epochs=EPOCHEN, verbose=1)
```
%% Output
Epoch 1/3
559/559 [==============================] - 142s 255ms/step - loss: 5.7077 - acc: 0.6459
Epoch 2/3
559/559 [==============================] - 139s 249ms/step - loss: 5.7073 - acc: 0.6459
Epoch 3/3
559/559 [==============================] - 139s 248ms/step - loss: 5.6794 - acc: 0.6476
%% Cell type:markdown id: tags:
Erstelle eine Confusion matrix basierend auf den Ausgaben des Netzes für die Validierungsdaten und berechne den ROC AUC für die Klasse cheetah. Du kannst hierfür optional die scikit-learn Bibliothek verwenden.
%% Cell type:code id: tags:
``` python
def classes2BinaryForROC(array):
return np.stack([array[:,1],array[:,0]+array[:,2]], axis=1)
def evaluate(predict, predict_labels):
print("Konfusionsmatrix")
print(izw_classes)
cm = confusion_matrix(val_labels, predict_labels)
print(cm)
print("Accuracy:",(cm[0,0]+cm[1,1]+cm[2,2])/(cm.sum()))
print("ROC AUC",roc_auc_score(classes2BinaryForROC(val),classes2BinaryForROC(predict)))
print("ROC AUC",roc_auc_score(classes2BinaryForROC(val), \
classes2BinaryForROC(predict)))
```
%% Cell type:code id: tags:
``` python
predict = model.predict_generator(val_gen)
```
%% Cell type:code id: tags:
``` python
predict_labels = np.argmax(predict, axis=1)
evaluate(predict, predict_labels)
```
%% Output
Konfusionsmatrix
('unknown', 'cheetah', 'leopard')
[[ 0 364 0]
[ 0 1440 0]
[ 0 111 0]]
Accuracy: 0.7519582245430809
ROC AUC 0.5
%% Cell type:markdown id: tags:
## Pretrained network
Lade nun ein auf Imagenet vortrainiertes Netzwerk und klassifiziere damit die Validierungsdaten. Eine Anleitung für keras findest du hier: https://keras.io/applications
Du kannst selber entscheiden, welche Netzwerkarchitektur du verwendest.
%% Cell type:code id: tags:
``` python
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
# create the base pre-trained model
modelInceptionV3 = InceptionV3(weights='imagenet', include_top=True)
# compile the model
modelInceptionV3.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
modelInceptionV3.compile(optimizer='rmsprop', loss='categorical_crossentropy', \
metrics=['accuracy'])
```
%% Cell type:markdown id: tags:
Da der ImageNet-Datensatz auch die Klassen cheetah und leopard enthält, können wir sogar ohne transfer learning das vortrainierte Netzwerk evaluieren. Interpretiere alle Klassen außer cheetah und leopard als unknown und berechne wie im vorherigen Schritt die Confusion matrix und den ROC AUC score für die Klasse cheetah.
%% Cell type:code id: tags:
``` python
predict_original = modelInceptionV3.predict_generator(val_gen)
```
%% Cell type:code id: tags:
``` python
predict_labels = np.argmax(predict_original, axis=1)
#? ist leopard => nach 2 mappen
#725 ist cheetah => 1
# sonst => 0
for i in range(predict_labels.shape[0]):
if predict_labels[i] == 916: #???
predict_labels[i] = 2
elif predict_labels[i] == 725:
predict_labels[i] = 1
else:
predict_labels[i] = 0
predict = np.zeros(val.shape)
for i in range(predict_labels.shape[0]):
predict[i][predict_labels[i]] = 1
```
%% Cell type:code id: tags:
``` python
evaluate(predict, predict_labels)
```
%% Output
Konfusionsmatrix
('unknown', 'cheetah', 'leopard')
[[ 91 241 32]
[339 968 133]
[ 23 77 11]]
Accuracy: 0.5587467362924282
ROC AUC 0.5013742690058479
%% Cell type:markdown id: tags:
## Transfer learning
Das vortrainierte Netzwerk kann nun mit unseren Daten weitertrainiert werden. Ersetze dafür das letzte Layer in dem Netzwerk mit einem Dense Layer mit 3 Ausgaben für unsere Klassen cheetah, leopard und unknown. Du kannst selbst entscheiden, ob du nun das komplette Netzwerk mit trainierst oder nur das neu eingefügte, letzte Layer.
Auch hierfür kannst du dich wieder an der keras Anleitung orientieren: https://keras.io/applications
%% Cell type:code id: tags:
``` python
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
# create the base pre-trained model
base_model = InceptionV3(weights='imagenet', include_top=False)
# füge ein Dense Layer mit 3 Ausgaben hinzu
x = base_model.output
x = GlobalAveragePooling2D()(x)
predictions = Dense(3, activation='softmax')(x)
# this is the model we will train
model = Model(inputs=base_model.input, outputs=predictions)
# train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
layer.trainable = False
# compile the model (should be done *after* setting layers to non-trainable)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', \
metrics=['accuracy'])
```
%% Cell type:code id: tags:
``` python
# train the model on the new data for a few epochs
model.fit_generator(train_gen, epochs=EPOCHEN, verbose=1)
```
%% Output
Epoch 1/3
559/559 [==============================] - 139s 249ms/step - loss: 0.5136 - acc: 0.8008
Epoch 2/3
559/559 [==============================] - 139s 249ms/step - loss: 0.3883 - acc: 0.8505
Epoch 3/3
559/559 [==============================] - 135s 242ms/step - loss: 0.3555 - acc: 0.8672
<keras.callbacks.History at 0x11da9114ba8>
%% Cell type:markdown id: tags:
Evaluiere das so trainierte Netzwerk wie in den letzten beiden Aufgaben.
%% Cell type:code id: tags:
``` python
predict = model.predict_generator(val_gen)
```
%% Cell type:code id: tags:
``` python
predict_labels = np.argmax(predict, axis=1)
evaluate(predict, predict_labels)
```
%% Output
Konfusionsmatrix
('unknown', 'cheetah', 'leopard')
[[ 3 361 0]
[ 3 1437 0]
[ 0 111 0]]
Accuracy: 0.7519582245430809
ROC AUC 0.49802302631578954
%% Cell type:markdown id: tags:
## Auswertung
Beschreibe kurz qualitativ die Resultate. Wie unterscheiden sich die trainierten Netzwerke, zum Beispiel im Bezug auf die Genauigkeit oder die Laufzeit? Welche Entscheidungen musstest du bei der Erfüllung der Aufgaben treffen und warum hast du dich für den von dir gewählten Weg entschieden?
%% Cell type:markdown id: tags:
**Eignes Netzwerk**
Da der Unterschied im Fellmuster sehr eindeutig zu sehen ist, haben wir uns entschieden mehrere Conv-Layer hintereinander zu nutzen, damit der Algorithmus diese gut erkennen kann.
Dies schien im Trainig auch gut zu funktionieren, da wir schnell eine gute Genauigkeit bekommen haben.
Leider kam es dabei zu einem starken overfitting, wir hatten im Training 95%, beim Validieren aber nur knapp über 50.
Oder es kam nur zu einer Genauigkeit von 64%. Dann hat er einfach immer "Cheetah" ausgegeben.
**Vortrainiertes Netzwerk**
Das Vortrainierte Netzwerk hat den Vorteil das man nicht selber trainieren muss, ist aber vorhersagen nicht viel besser, da es auf sehr viele Klassen trainiert wurde, die uns hier nicht interessieren.
Es war unbekannt welche Klasse welche ausgabe ist, hier mussten wir statistisch die klassen nehmen die am besten passten.
**Transfer Learning**
Das Netz sah beim Training noch gut aus, hat beim Validieren dann einfach nur "Cheetah" ausgegeben.
%% Cell type:code id: tags:
``` python
```
......
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment