<jupyter_start><jupyter_text>Machine Learning Sommersemester 2021Prof. Dr. <NAME><jupyter_code>import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import os
import urllib.request<jupyter_output><empty_output><jupyter_text>CNN mit Keras: Hausnummern erkennenIn dieser Aufgabe wollen wir einen Datensatz verwenden, der Bildausschnitte mit einzelnen Ziffern von Hausnummern enthält.Die Daten ähneln damit vom Prinzip her dem MNIST Datensatz.Da es sich um (Farb-) Fotos handelt, die zudem noch recht verrauscht sind, ist das Problem, die Ziffern zu erkennen, aber deutlich schwieriger.Wir laden zunächst die Bidler von der URL http://ufldl.stanford.edu/housenumbers herunter.Details zum Datensatz finden Sie in [1].<jupyter_code>import pandas as pd
import os
import tarfile
import urllib.request


url = [f"http://ufldl.stanford.edu/housenumbers/{n}_32x32.mat" for n in ("train", "test")]
dfile = [f"./{n}_32x32.mat" for n in ("train", "test")]


for i in range(len(url)):
    if not os.path.isfile(dfile[i]):
        urllib.request.urlretrieve(url[i], dfile[i])<jupyter_output><empty_output><jupyter_text>Die Daten liegen im `.mat`-Format vor, dass zumeist in Matlab verwendet wird.Wir importieren die Daten über die Funktion `scipy.io.loadmat` und extrahieren dann die Attribute und Labels jeweils aus den Test- und Trainings-Daten.<jupyter_code>from scipy.io import loadmat
train_raw = loadmat('./train_32x32.mat')
test_raw = loadmat('./test_32x32.mat')
                   
train_images = np.array(train_raw['X'])
test_images = np.array(test_raw['X'])

train_labels = train_raw['y']
test_labels = test_raw['y']
                   
print(train_images.shape)
print(test_images.shape)<jupyter_output><empty_output><jupyter_text>Wenn Sie sich die Dimension der Datensätze ansehen, stellen Sie fest, dass die Daten unpassend strukturiert sind.In den ersten Dimensionen haben wir die (RGB) Pixel der einzelnen Bilder, in der letzten Dimension die einzelnen Bilder.Daher sortieren wir die Dimensionen, bzw. die Axen unserer Datensätze um, sodass die erste Dimension dem Index eines Bildes entspricht.<jupyter_code># Fix the axes of the images

train_images = np.moveaxis(train_images, -1, 0)
test_images = np.moveaxis(test_images, -1, 0)

print(train_images.shape)
print(test_images.shape)<jupyter_output><empty_output><jupyter_text>Nun können wir ein zufälliges Bild ausgeben:<jupyter_code>import matplotlib.pyplot as plt
import random 
# Plot a random image and its label

plt.imshow(train_images[random.randint(0,len(train_images))])
plt.show()

print('Label: ', train_labels[13529])
train_images = train_images.astype('float64')
test_images = test_images.astype('float64')

train_labels = train_labels.astype('int64')
test_labels = test_labels.astype('int64')

train_images /= 255.0
test_images /= 255.0

train_labels -= 1
test_labels -= 1<jupyter_output><empty_output><jupyter_text>Wir stellen nun ein sequenziellen Keras Model auf. Das Modell hat 2 Schichten.Die erste Schicht besitzt 128 Neuronen und verwendet ReLU als Aktivierungsfunktion.Die zweite Schicht besitzt 10 Neuronen und verwendet als Aktivierungsfunktion die Softmax-Funktion.<jupyter_code>#Modell definieren

def create_model():
    model = keras.Sequential()
    model.add(keras.layers.Flatten(input_shape=(32, 32, 3)))
    model.add(keras.layers.Dense(128, activation=tf.nn.relu))
    model.add(keras.layers.Dense(10, activation=tf.nn.softmax))
    return model

model = create_model()<jupyter_output><empty_output><jupyter_text>Nun wählen wir geeignete Parameter für das Modell aus<jupyter_code>#Modellparameter
optimizer =  'sgd'
loss = 'sparse_categorical_crossentropy'
metrics = ['accuracy']

#Modell erzeugen
model.compile(optimizer,loss,metrics)<jupyter_output><empty_output><jupyter_text>Nun können wir das Modell trainieren.<jupyter_code>mfile = "./model.h5"

if not os.path.isfile(mfile):
    model = create_model()
    model.compile(optimizer,loss,metrics)
else:
    print("Load Model from file", mfile)
    model = tf.keras.models.load_model(mfile)

history = model.fit(train_images, train_labels, epochs=5)
model.save(mfile)


#Trainiertes Modell auswerten
test_loss, test_acc = model.evaluate (test_images, test_labels)
print('Classification Accuracy (Test):', test_acc)
import matplotlib.pyplot as plt
# summarize history for accuracy
plt.plot(history.history['accuracy'])
plt.title('Classification Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoche')
plt.legend(['Test'], loc='upper left')
plt.show()
# summarize history for loss
plt.plot(history.history['loss'])
plt.title('Kostenfunktion')
plt.ylabel('Fehler')
plt.xlabel('Epoche')
plt.legend(['Test'], loc='upper left')
plt.show()<jupyter_output><empty_output><jupyter_text>**Aufgabe:** Erstellen Sie ein Faltungsnetz (CNN) mit folgenden Schichten über die *Keras Sequential API*:1. Die erste Schicht soll ein `Conv2D`-Layer sein. Sie benötigen keinen zusätzlichen `Flatten`-Layer. Verwenden Sie in der ersten Schicht einfach den Parameter `input_shape` und setzen Sie ihn auf das 3-Tupel `(32, 32, 3)` (32x32 Pixel im RGB Format). Die `Conv2D`-Schicht soll 16 Filtermasken einer Größe von $3\times{}3$ Pixeln verwenden. Als Aktivierungsfunktion verwenden Sie `relu`.2. Die zweite Schicht ist ein Pooling-Layer. Fassen Sie immer $2\times{}2$ Pixel mit Max-Pooling (`MaxPooling2D`) zusammen.3. Um Overfitting zu vermeiden, führen wir ein Dropout-Layer ein. Verwenden die eine Dropout-Rate von 30%.4. Fügen Sie je eine weitere `Conv2D`, `MaxPooling2D` und `Dropout` Schicht ein. Die Parameter sollen wie bei 1.-3. gewählt werden, mit der Ausnahme, dass die `Conv2D`-Schicht nun doppelt so viele (also 32) Filtermasken verwenden soll.5. Transformieren Sie die 2D-Daten in 1D- Daten mit einem `Flatten`-Layer. `Flatten` benötigt keine Parameter.6. Fügen Sie dem Modell eine voll-vermaschte Schicht (`Dense`) mit 256 Neuronen hinzu. Als Aktivierungsfunktion soll hier acuh `relu` verwendet werden.7. Fügen Sie ein Dropout Schicht mit 30% Dropout rate ein8. Fügen Sie dem Modell einen Eine Ausgabeschicht mit 10 Neuronen hinzu (`Dense`). Die Aktivierungsfunktion hier sollte `softmax` sein.<jupyter_code>#Modell definieren
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense

def create_model():
    model = keras.Sequential()
    # YOUR CODE HERE
    raise NotImplementedError()
    return model

model = create_model()<jupyter_output><empty_output><jupyter_text>Nun trainieren wir das Modell und schreiben die Trainierten Parameter erneut in eine Datei.(*Hinweis:* Achten Sie darauf, die Datei zu löschen, falls Sie ein neues Modell erzeugt haben)<jupyter_code>mfile = "./model_cnn.h5"

if not os.path.isfile(mfile):
    model = create_model()
    model.compile(optimizer,loss,metrics)
else:
    print("Load Model from file", mfile)
    model = tf.keras.models.load_model(mfile)

history = model.fit(train_images, train_labels, epochs=5)
model.save(mfile)<jupyter_output><empty_output><jupyter_text>Wir können nun das trainierte Modell bewerten.<jupyter_code>#Trainiertes Modell auswerten
test_loss, test_acc = model.evaluate (test_images, test_labels)
print('Test accuracy:', test_acc)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10096551724137931, 'fraction_numerical': 0.016, 'mean_word_length': 5.8664772727272725, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '549508', 'license': 'MIT', 'n_tokens_mistral': 2607, 'n_tokens_neox': 2522, 'n_words': 690, 'path': 'p7/17_CNN_Keras.ipynb', 'repo_name': 'fh-swf-hgi/ml', 'size': '7258'}