{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":21669,"databundleVersionId":1692278,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"1) Bibliotheken Importieren und der Pfade Festlegen\n\nIn diesem Block werden alle erforderlichen Bibliotheken für die Audioverarbeitung, Datenmanipulation, Visualisierung, maschinelles Lernen und Modellbewertung importiert. Die Bibliothek librosa dient der Audioanalyse, während pandas für die strukturierte Verarbeitung und Verwaltung von Daten eingesetzt wird. Für die Visualisierung von Daten kommen matplotlib und seaborn zum Einsatz. Die Bibliothek tensorflow.keras wird genutzt, um neuronale Netzwerke zu erstellen und zu trainieren. Darüber hinaus werden die Pfade zu den Trainingsdaten und Audiodateien definiert, um deren Zugriff und Verarbeitung im weiteren Verlauf des Codes zu gewährleisten.","metadata":{}},{"cell_type":"code","source":"import os\nimport librosa\nimport librosa.display  # Für die Visualisierung von Spektrogrammen\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras import layers, models\nimport matplotlib.pyplot as plt\nimport random\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, TensorBoard\nfrom sklearn.metrics import classification_report, confusion_matrix, roc_curve, auc, precision_recall_curve, average_precision_score\nfrom itertools import cycle\nfrom IPython.display import Audio, display  # Für die Wiedergabe von Audiodateien\nimport seaborn as sns\nimport datetime\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:23:16.342141Z","iopub.execute_input":"2024-11-25T01:23:16.342516Z","iopub.status.idle":"2024-11-25T01:23:16.348851Z","shell.execute_reply.started":"2024-11-25T01:23:16.342482Z","shell.execute_reply":"2024-11-25T01:23:16.347824Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"2. CSV-Datei Laden und daten Vorbereiten\n\n   Dieser Block lädt die Trainingsdaten aus der CSV-Datei train_tp.csv, welche Informationen zu den tatsächlichen positiven Beispielen enthält. Die Daten werden nach der recording_id gruppiert, sodass für jede Aufnahme eine Liste der enthaltenen Spezies (species_id) generiert wird. Zur Optimierung der Verarbeitungsgeschwindigkeit wird die Anzahl der betrachteten Aufnahmen auf 10 begrenzt. Zusätzlich wird eine Liste aller einzigartigen Spezies erstellt. Um die Labels für maschinelles Lernen vorzubereiten, wird ein Mapping von species_id zu numerischen Indizes generiert, wodurch eine effiziente Kodierung der Zielvariablen ermöglicht wird.","metadata":{}},{"cell_type":"code","source":"# Pfade zu den Daten\ndata_path = \"/kaggle/input/rfcx-species-audio-detection/\"\ntrain_tp_csv = os.path.join(data_path, 'train_tp.csv')\ntrain_audio_path = os.path.join(data_path, 'train/')\n# CSV-Datei laden\ntrain_tp = pd.read_csv(train_tp_csv)\n\n# Gruppieren der Spezies pro Aufnahme\nspecies_per_recording = train_tp.groupby('recording_id')['species_id'].apply(list).reset_index()\n\n# Begrenzen Sie die Anzahl der verarbeiteten Aufnahmen auf 10\nmax_samples = 10  # Anzahl der Aufnahmen, die Sie verarbeiten möchten\nspecies_per_recording = species_per_recording.head(max_samples)\n\n# Erstellen einer Liste aller einzigartigen Spezies\nall_species = sorted(train_tp['species_id'].unique())\nnum_classes = len(all_species)\n\n# Mapping von species_id zu Index\nspecies_id_to_index = {species_id: idx for idx, species_id in enumerate(all_species)}\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:23:16.350625Z","iopub.execute_input":"2024-11-25T01:23:16.350960Z","iopub.status.idle":"2024-11-25T01:23:16.389123Z","shell.execute_reply.started":"2024-11-25T01:23:16.350902Z","shell.execute_reply":"2024-11-25T01:23:16.388233Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"3. Definition von Funktionen für die Audioverarbeitung und Datenaugmentation\n\n   In diesem Block werden zwei zentrale Funktionen definiert:\n\n1) create_mel_spectrogram:\nDiese Funktion konvertiert ein gegebenes Audiosignal in ein normalisiertes Mel-Spektrogramm. Dabei wird sichergestellt, dass das Audiosignal die erforderliche Länge aufweist, indem es bei Bedarf mit Nullen aufgefüllt wird. Anschließend wird das Spektrogramm in die Dezibel-Skala transformiert und normalisiert, um eine konsistente Eingabe für das neuronale Netz zu gewährleisten.\n\n2) augment_audio:\nDiese Funktion führt Datenaugmentation durch, indem sie das Audiosignal zeitlich streckt oder staucht. Dies erweitert die Diversität der Trainingsdaten und verbessert die Robustheit des Modells gegenüber zeitlichen Variationen im Audiosignal.","metadata":{}},{"cell_type":"code","source":"# Funktion zur Erzeugung von Mel-Spektrogrammen aus einem Audiosignal\ndef create_mel_spectrogram(y, sr, n_mels=128, n_fft=2048, hop_length=512):\n    # Padding der Audiodatei, falls sie kürzer als n_fft ist\n    if len(y) < n_fft:\n        y = np.pad(y, (0, n_fft - len(y)), mode='constant')\n        print(f\"Audiodatei gepolstert auf {len(y)} Samples.\")\n\n    spectrogram = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=n_mels, n_fft=n_fft, hop_length=hop_length)\n    spectrogram_db = librosa.power_to_db(spectrogram, ref=np.max)\n\n    # Normalisierung des Spektrogramms\n    spectrogram_db = (spectrogram_db - np.mean(spectrogram_db)) / np.std(spectrogram_db)\n\n    return spectrogram_db, hop_length\n\n# Funktion zur Datenaugmentation durch Zeitstretchen des Audiosignals\ndef augment_audio(y, rate=1.1):\n    try:\n        y_aug = librosa.effects.time_stretch(y, rate=rate)\n    except:\n        # Falls das Zeitstretchen fehlschlägt, das Original verwenden\n        y_aug = y.copy()\n    return y_aug\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:23:16.390277Z","iopub.execute_input":"2024-11-25T01:23:16.390556Z","iopub.status.idle":"2024-11-25T01:23:16.397405Z","shell.execute_reply.started":"2024-11-25T01:23:16.390527Z","shell.execute_reply":"2024-11-25T01:23:16.396439Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"4. Laden und Vorverarbeiten der Audiodaten\n\n   In diesem Block werden die Audiodaten geladen und vorverarbeitet, um die Trainingsdaten für das Modell vorzubereiten:\n\nLaden der Audiodateien:\nFür jede Aufnahme wird die entsprechende Audiodatei geladen, sofern sie verfügbar ist.\n\nErstellen des Mel-Spektrogramms:\nDas Audiosignal wird in ein Mel-Spektrogramm umgewandelt. Dieses wird normalisiert und auf eine einheitliche Größe von \n128×128 Pixeln skaliert, um eine konsistente Eingabe für das Modell sicherzustellen.\n\nSpeichern der Daten:\nDas generierte Spektrogramm, das Roh-Audiosignal sowie die Sampling-Rate werden in separaten Listen gespeichert, um sie für die spätere Modellverarbeitung bereitzuhalten.\n\nErstellen der Labels:\nFür jede Aufnahme wird ein Multi-Hot-Encoded-Vektor generiert, der die in der Aufnahme enthaltenen Spezies repräsentiert. Dies ermöglicht eine mehrklassige Klassifikation.\n\nDatenaugmentation:\nMittels Zeitstretchen wird ein augmentiertes Audiosignal erzeugt, um die Vielfalt der Trainingsdaten zu erhöhen. Das Spektrogramm des augmentierten Signals wird berechnet und ebenfalls den Trainingsdaten hinzugefügt.\n\n","metadata":{}},{"cell_type":"code","source":"# Laden der Trainingsdaten\nX = []\ny = []\nX_audio = []  # Liste zur Speicherung der Audio-Daten\naudio_sr = []  # Liste zur Speicherung der Sampling-Raten\n\nfor index, row in species_per_recording.iterrows():\n    file_name = row['recording_id'] + \".flac\"\n    species_ids = row['species_id']  # Liste der Spezies in diesem Audio\n    file_path = os.path.join(train_audio_path, file_name)\n\n    # Überprüfen, ob die Datei existiert\n    if os.path.exists(file_path):\n        try:\n            # Audiodatei laden\n            y_waveform, sr = librosa.load(file_path, sr=None)\n            print(f\"Lade Datei: {file_path}, Länge des Audiosignals: {len(y_waveform)} Samples\")\n\n            if len(y_waveform) == 0:\n                print(f\"Warnung: Audiodatei {file_path} ist leer.\")\n                continue\n\n            # Mel-Spektrogramm erzeugen\n            spectrogram, hop_length = create_mel_spectrogram(y_waveform, sr, n_mels=128, n_fft=2048, hop_length=512)\n\n            # Padding oder Zuschneiden auf 128 Zeitachsen\n            if spectrogram.shape[1] < 128:\n                spectrogram = np.pad(spectrogram, ((0, 0), (0, 128 - spectrogram.shape[1])), mode='constant')\n            else:\n                spectrogram = spectrogram[:, :128]\n\n            # Überprüfen, ob das Spektrogramm die richtige Form hat\n            if spectrogram.shape != (128, 128):\n                print(f\"Spektrogramm hat eine unerwartete Form: {spectrogram.shape} in Datei: {file_path}\")\n                continue\n\n            # Hinzufügen des Spektrogramms und der zugehörigen Daten\n            X.append(spectrogram)\n            X_audio.append(y_waveform)\n            audio_sr.append(sr)\n\n            # Erstellen des Multi-Hot-Encoded Labels\n            label = np.zeros(num_classes)\n            for species_id in species_ids:\n                if species_id in species_id_to_index:\n                    idx = species_id_to_index[species_id]\n                    label[idx] = 1\n                else:\n                    print(f\"Unbekanntes species_id: {species_id} in Datei: {file_path}\")\n            y.append(label)\n\n            # Datenaugmentation hinzufügen (Zeitstretchen des Audiosignals)\n            y_augmented = augment_audio(y_waveform, rate=1.1)\n\n            # Mel-Spektrogramm für das augmentierte Audiosignal erstellen\n            spectrogram_aug, hop_length_aug = create_mel_spectrogram(y_augmented, sr, n_mels=128, n_fft=2048, hop_length=512)\n\n            # Padding oder Zuschneiden auf 128 Zeitachsen\n            if spectrogram_aug.shape[1] < 128:\n                spectrogram_aug = np.pad(spectrogram_aug, ((0, 0), (0, 128 - spectrogram_aug.shape[1])), mode='constant')\n            else:\n                spectrogram_aug = spectrogram_aug[:, :128]\n\n            # Überprüfen, ob das augmentierte Spektrogramm die richtige Form hat\n            if spectrogram_aug.shape != (128, 128):\n                print(f\"Augmentiertes Spektrogramm hat eine unerwartete Form: {spectrogram_aug.shape} in Datei: {file_path}\")\n                continue\n\n            # Hinzufügen des augmentierten Spektrogramms und der zugehörigen Daten\n            X.append(spectrogram_aug)\n            X_audio.append(y_augmented)  # Optional: Labels gleich bleiben\n            audio_sr.append(sr)\n            y.append(label)\n\n        except Exception as e:\n            print(f\"Fehler beim Laden von {file_path}: {e}\")\n    else:\n        print(f\"Datei nicht gefunden: {file_path}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:23:16.398702Z","iopub.execute_input":"2024-11-25T01:23:16.399440Z","iopub.status.idle":"2024-11-25T01:23:48.716084Z","shell.execute_reply.started":"2024-11-25T01:23:16.399409Z","shell.execute_reply":"2024-11-25T01:23:48.714847Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"5)  Visualisierung der Spektrogramme und Audio-Wiedergabe\n\n   In diesem Block werden die Spektrogramme und Audiodaten visualisiert sowie zur Validierung abgespielt:\n\nVisualisierung der Spektrogramme:\nEine ausgewählte Anzahl von Spektrogrammen wird dargestellt, um die Frequenzinhalte der Audiodaten über die Zeit hinweg zu analysieren und zu überprüfen.\n\nAudio-Wiedergabe:\nDie zugehörigen Audiodateien werden abgespielt, um die Qualität und Korrektheit der Daten anhand einer manuellen Überprüfung sicherzustellen.\nAnzeige der Spezies:\n\nDie in der jeweiligen Aufnahme enthaltenen Spezies werden identifiziert und zusammen mit den entsprechenden Spektrogrammen dargestellt, um die Zuordnung zwischen visuellen Merkmalen und den annotierten Labels zu verdeutlichen.","metadata":{}},{"cell_type":"code","source":"# Anzahl der zu visualisierenden Spektrogramme (hier maximal 10, da max_samples=10 und Datenaugmentation verdoppelt)\nnum_visualizations = min(10, len(X))\n\nfor i in range(num_visualizations):\n    spectrogram = X[i].squeeze()\n    label = y[i]\n    y_audio = X_audio[i]\n    sr_audio = audio_sr[i]\n\n    # Finden der Speziesnamen für das aktuelle Label\n    species_present = [str(all_species[j]) for j in range(num_classes) if label[j] == 1]\n    species_text = ', '.join(species_present)\n\n    # Audio-Wiedergabe\n    print(f\"Audio {i+1} - Spezi(e): {species_text}\")\n    display(Audio(y_audio, rate=sr_audio))\n\n    # Plotten der Waveform\n    plt.figure(figsize=(14, 5))\n    librosa.display.waveshow(y_audio, sr=sr_audio)\n    plt.title(f\"Waveform - Spezi(e): {species_text}\")\n    plt.xlabel(\"Zeit (s)\")\n    plt.ylabel(\"Amplitude\")\n    plt.tight_layout()\n    plt.show()\n\n    # Plotten des Spektrogramms mit beschrifteten Achsen\n    plt.figure(figsize=(10, 4))\n    librosa.display.specshow(spectrogram, sr=sr_audio, hop_length=512, x_axis='time', y_axis='mel', cmap='viridis')\n    plt.colorbar(format='%+2.0f dB')\n    plt.title(f\"Mel-Spektrogramm - Spezi(e): {species_text}\")\n    plt.xlabel(\"Zeit (s)\")\n    plt.ylabel(\"Frequenz (Mel)\")\n    plt.tight_layout()\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:23:48.718720Z","iopub.execute_input":"2024-11-25T01:23:48.721461Z","iopub.status.idle":"2024-11-25T01:24:00.285303Z","shell.execute_reply.started":"2024-11-25T01:23:48.721401Z","shell.execute_reply":"2024-11-25T01:24:00.284287Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"6) Vorbereitung der Daten für das Training\n\n   In diesem Block werden die Daten für das Training des Modells vorbereitet:\n\nKonvertierung in NumPy-Arrays:\nDie Listen der Spektrogramme und Labels werden in NumPy-Arrays umgewandelt, um die Daten für die Verarbeitung mit Keras vorzubereiten. Dabei wird dem Datensatz der Spektrogramme (X) eine zusätzliche Dimension hinzugefügt, sodass die Eingabe die Form (Anzahl,128,128,1) erhält. Dies stellt sicher, dass die Daten im Format eines 2D-Bildes mit einem Kanal vorliegen, wie es für neuronale Netze üblich ist.\n\nAufteilen der Daten:\nDie Daten werden in Trainings-, Validierungs- und Testdatensätze unterteilt. Dieser Schritt gewährleistet, dass das Modell auf einem Teil der Daten trainiert, seine Hyperparameter auf einem anderen Teil optimiert und schließlich auf einem unabhängigen Testdatensatz bewertet wird, um die Generalisierungsfähigkeit sicherzustellen.\n","metadata":{}},{"cell_type":"code","source":"# Umwandeln in NumPy-Arrays\nX = np.array(X)\nX = X[..., np.newaxis]  # Hinzufügen einer zusätzlichen Dimension\n\ny = np.array(y)  # Labels sind bereits Multi-Hot-Encoded\n\nprint(f\"Form von X: {X.shape}\")\nprint(f\"Form von y: {y.shape}\")\n\n# Aufteilen der Daten in Training (70%), Validation (15%) und Test (15%)\nX_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42)  # 70% Training\nX_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)  # 15% Validation, 15% Test\n\nprint(f\"Form von X_train: {X_train.shape}\")\nprint(f\"Form von y_train: {y_train.shape}\")\nprint(f\"Form von X_val: {X_val.shape}\")\nprint(f\"Form von y_val: {y_val.shape}\")\nprint(f\"Form von X_test: {X_test.shape}\")\nprint(f\"Form von y_test: {y_test.shape}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:24:00.286602Z","iopub.execute_input":"2024-11-25T01:24:00.286961Z","iopub.status.idle":"2024-11-25T01:24:00.298427Z","shell.execute_reply.started":"2024-11-25T01:24:00.286898Z","shell.execute_reply":"2024-11-25T01:24:00.297415Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"7) Aufbau und Kompilierung des CNN-Modells\n\n   In diesem Block wird das Convolutional Neural Network (CNN) erstellt und kompiliert:\n\nModellarchitektur:\nDas Modell umfasst mehrere Faltungsschichten (Convolutional Layers), die mit Batch-Normalisierung und Max-Pooling ergänzt werden, um die extrahierten Merkmale aus den Mel-Spektrogrammen zu verfeinern und die Dimensionen zu reduzieren. Nach den Faltungsschichten folgt eine Flatten-Schicht, um die Merkmalskarten in eine eindimensionale Form zu bringen. Daran schließen sich Dense-Schichten an, die durch Dropout reguliert werden, um Overfitting zu minimieren.\n\nAusgabeschicht:\nDie letzte Dense-Schicht verwendet eine Sigmoid-Aktivierungsfunktion, die für Multi-Label-Klassifikationsprobleme geeignet ist. Diese Wahl ermöglicht die gleichzeitige Vorhersage mehrerer Klassen (Spezies), da mehrere Spezies in einer Aufnahme vorhanden sein können.\n\nKompilierung:\nDas Modell wird mit dem Adam-Optimierungsalgorithmus kompiliert, der eine adaptive Lernratenanpassung bietet. Als Verlustfunktion wird die binäre Kreuzentropie gewählt, die speziell für Multi-Label-Klassifikationsprobleme geeignet ist. Die Modellleistung wird anhand der Metrik Accuracy bewertet.","metadata":{}},{"cell_type":"code","source":"# CNN-Modell erstellen\nmodel = models.Sequential([\n    layers.Input(shape=(128, 128, 1)),\n    \n    # Block 1\n    layers.Conv2D(32, (3, 3), activation='relu', padding='same'),\n    layers.BatchNormalization(),\n    layers.MaxPooling2D((2, 2)),\n    \n    # Block 2\n    layers.Conv2D(64, (3, 3), activation='relu', padding='same'),\n    layers.BatchNormalization(),\n    layers.MaxPooling2D((2, 2)),\n    \n    # Block 3\n    layers.Conv2D(128, (3, 3), activation='relu', padding='same'),\n    layers.BatchNormalization(),\n    layers.MaxPooling2D((2, 2)),\n    \n    # Block 4\n    layers.Conv2D(256, (3, 3), activation='relu', padding='same'),\n    layers.BatchNormalization(),\n    layers.MaxPooling2D((2, 2)),\n    \n    layers.Flatten(),\n    layers.Dense(512, activation='relu'),\n    layers.Dropout(0.5),\n    layers.Dense(num_classes, activation='sigmoid')\n])\n\n# Modell kompilieren\nmodel.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:24:00.299702Z","iopub.execute_input":"2024-11-25T01:24:00.300060Z","iopub.status.idle":"2024-11-25T01:24:00.506669Z","shell.execute_reply.started":"2024-11-25T01:24:00.300020Z","shell.execute_reply":"2024-11-25T01:24:00.505787Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"8)  Definieren von Callbacks und Training des Modells\n\nIn diesem Block wird das Modell trainiert und durch geeignete Callbacks überwacht:\n\nEinrichten der Callbacks:\n\nEarlyStopping: Überwacht die Validierungsverluste und beendet das Training frühzeitig, wenn sich die Leistung über mehrere Epochen hinweg nicht verbessert. Dies verhindert Übertraining und spart Rechenressourcen.\n\nModelCheckpoint: Speichert das Modell mit der besten Validierungsleistung, um sicherzustellen, dass das beste Modell unabhängig vom Fortschreiten des Trainings erhalten bleibt.\n\nTensorBoard: Ermöglicht die detaillierte Visualisierung des Trainingsverlaufs (z. B. Verluste, Genauigkeit) in der TensorBoard-Umgebung, um die Trainings- und Validierungsmetriken nachzuverfolgen.\n\nModelltraining:\nDas Modell wird mit den Trainingsdaten über mehrere Epochen trainiert, während die Validierungsdaten zur Überwachung der Modellleistung und Generalisierung verwendet werden. Die maximale Anzahl der Epochen ist auf 10 begrenzt, kann jedoch bei Bedarf angepasst werden, um eine optimale Leistung zu erzielen.\n","metadata":{}},{"cell_type":"code","source":"# Callbacks definieren\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\nmodel_checkpoint = ModelCheckpoint('best_model.keras', save_best_only=True, monitor='val_loss')  # Dateiendung geändert\n\n# TensorBoard-Callback definieren\nlog_dir = \"logs/fit/\" + datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")\ntensorboard_callback = TensorBoard(log_dir=log_dir, histogram_freq=1)\n\n# Modell trainieren mit Callbacks und auf 10 Epochen begrenzen\nhistory = model.fit(\n    X_train, y_train,\n    epochs=10,  \n    validation_data=(X_val, y_val),\n    callbacks=[early_stopping, model_checkpoint, tensorboard_callback]\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:24:00.507774Z","iopub.execute_input":"2024-11-25T01:24:00.508097Z","iopub.status.idle":"2024-11-25T01:24:25.174770Z","shell.execute_reply.started":"2024-11-25T01:24:00.508067Z","shell.execute_reply":"2024-11-25T01:24:25.173334Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"9) In diesem Block wird das trainierte Modell bewertet:\n\nVisualisierung des Trainingsverlaufs:\nDer Verlauf der Trainings- und Validierungsgenauigkeit sowie der Verluste wird über die Epochen hinweg geplottet. Diese Analyse ermöglicht die Beurteilung des Modellverhaltens und gibt Aufschluss darüber, ob das Modell Overfitting (Überanpassung an die Trainingsdaten) oder Underfitting (unzureichendes Lernen) zeigt.\n\nBewertung des Modells:\nDie Leistung des Modells wird mithilfe der Validierungs- und Testdaten quantitativ bewertet. Diese Bewertung dient dazu, die Generalisierungsfähigkeit des Modells zu prüfen und sicherzustellen, dass es auch auf bisher ungesehene Daten zuverlässige Vorhersagen treffen kann.","metadata":{}},{"cell_type":"code","source":"# Trainings- und Validierungskurven plotten\nplt.figure(figsize=(12, 5))\n\n# Genauigkeit plotten\nplt.subplot(1, 2, 1)\nplt.plot(history.history['accuracy'], label='Training Genauigkeit')\nplt.plot(history.history['val_accuracy'], label='Validierung Genauigkeit')\nplt.title('Genauigkeit pro Epoche')\nplt.xlabel('Epoche')\nplt.ylabel('Genauigkeit')\nplt.legend()\n\n# Verlust plotten\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'], label='Training Verlust')\nplt.plot(history.history['val_loss'], label='Validierung Verlust')\nplt.title('Verlust pro Epoche')\nplt.xlabel('Epoche')\nplt.ylabel('Verlust')\nplt.legend()\n\nplt.tight_layout()\nplt.show()\n\n# Modellbewertung auf den Validierungsdaten\nval_loss, val_acc = model.evaluate(X_val, y_val, verbose=2)\nprint(f\"Validierungsgenauigkeit: {val_acc:.2f}\")\n\n# Modellbewertung auf Testdaten\ntest_loss, test_acc = model.evaluate(X_test, y_test, verbose=2)\nprint(f\"Testgenauigkeit: {test_acc:.2f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:24:25.176570Z","iopub.execute_input":"2024-11-25T01:24:25.176975Z","iopub.status.idle":"2024-11-25T01:24:25.878438Z","shell.execute_reply.started":"2024-11-25T01:24:25.176879Z","shell.execute_reply":"2024-11-25T01:24:25.877371Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"10) Detaillierte Evaluierung mit Vorhersagen und Metriken\n\nIn diesem Block wird die Leistung des Modells detailliert analysiert:\n\nGenerieren von Vorhersagen:\nDas trainierte Modell wird verwendet, um Vorhersagen für die Testdaten zu erzeugen. Diese Vorhersagen dienen als Grundlage für die Bewertung der Modellgenauigkeit und Klassifikationsleistung.\n\nKlassifikationsbericht:\nEin umfassender Bericht mit Metriken wie Präzision, Recall und F1-Score wird für jede Klasse erstellt. Diese Metriken bieten detaillierte Einblicke in die Leistung des Modells bei der Unterscheidung der einzelnen Spezies und helfen, Schwächen bei spezifischen Klassen zu identifizieren.\n\nKonfusionsmatrix:\nEine Konfusionsmatrix wird erstellt und visualisiert, um die Verteilung der korrekten und falschen Vorhersagen darzustellen. Dies ermöglicht eine tiefergehende Analyse von Fehlklassifikationen und zeigt, in welchen Klassen das Modell gut oder weniger gut unterscheidet.","metadata":{}},{"cell_type":"code","source":"# Vorhersagen auf Testdaten\npredictions = model.predict(X_test)\n\n# Klassifikationsbericht erstellen\n# Konvertieren der target_names zu Strings\ntarget_names = [str(species_id) for species_id in all_species]\n\ny_pred = (predictions > 0.5).astype(int)\nprint(classification_report(y_test, y_pred, target_names=target_names, zero_division=0))\n\n# Konfusionsmatrix plotten\ncm = confusion_matrix(y_test.argmax(axis=1), y_pred.argmax(axis=1))\nplt.figure(figsize=(12, 10))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues',\n            xticklabels=target_names, yticklabels=target_names)\nplt.xlabel('Vorhergesagte Klasse')\nplt.ylabel('Tatsächliche Klasse')\nplt.title('Konfusionsmatrix')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:24:25.879592Z","iopub.execute_input":"2024-11-25T01:24:25.879934Z","iopub.status.idle":"2024-11-25T01:24:26.619267Z","shell.execute_reply.started":"2024-11-25T01:24:25.879879Z","shell.execute_reply":"2024-11-25T01:24:26.618289Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"11) Plotten von ROC- und Precision-Recall-Kurven\n\nIn diesem Block wird eine detaillierte Evaluierung des Modells durchgeführt:\n\nROC-Kurven:\nDie Receiver Operating Characteristic (ROC)-Kurven werden für jede Klasse berechnet und visualisiert, um die Fähigkeit des Modells zur Unterscheidung zwischen positiven und negativen Klassen zu bewerten. Die Fläche unter der Kurve (Area Under the Curve, AUC) dient als Metrik zur Quantifizierung der Trennschärfe, wobei eine höhere AUC auf eine bessere Klassifikationsleistung hindeutet.\n\nPrecision-Recall-Kurven:\nPrecision-Recall-Kurven werden für jede Klasse erstellt, um die Beziehung zwischen Präzision und Recall zu analysieren. Diese Visualisierung ist besonders bei unausgeglichenen Datensätzen von Bedeutung, da sie besser als ROC-Kurven aufzeigt, wie das Modell in Szenarien mit unterschiedlich häufig vorkommenden Klassen performt.","metadata":{}},{"cell_type":"code","source":"# ROC-Kurven und AUC plotten\nfpr = dict()\ntpr = dict()\nroc_auc = dict()\nfor i in range(num_classes):\n    fpr[i], tpr[i], _ = roc_curve(y_test[:, i], predictions[:, i])\n    roc_auc[i] = auc(fpr[i], tpr[i])\n\nplt.figure(figsize=(10, 8))\ncolors = cycle(['aqua', 'darkorange', 'cornflowerblue', 'red', 'green', 'purple', 'brown', 'pink', 'gray', 'olive'])\n\nfor i, color in zip(range(num_classes), colors):\n    plt.plot(fpr[i], tpr[i], color=color, lw=2,\n             label='ROC-Kurve der Klasse {0} (AUC = {1:0.2f})'\n             ''.format(target_names[i], roc_auc[i]))\n\nplt.plot([0, 1], [0, 1], 'k--', lw=2)\nplt.xlim([-0.01, 1.0])\nplt.ylim([0.0, 1.05])\nplt.xlabel('Falsch Positive Rate')\nplt.ylabel('True Positive Rate')\nplt.title('Receiver Operating Characteristic (ROC) Kurven')\nplt.legend(loc=\"lower right\")\nplt.show()\n\n# Precision-Recall-Kurven plotten\nprecision = dict()\nrecall = dict()\naverage_precision = dict()\nfor i in range(num_classes):\n    precision[i], recall[i], _ = precision_recall_curve(y_test[:, i], predictions[:, i])\n    average_precision[i] = average_precision_score(y_test[:, i], predictions[:, i])\n\nplt.figure(figsize=(10, 8))\ncolors = cycle(['navy', 'turquoise', 'darkorange', 'cornflowerblue', 'teal', 'purple', 'green', 'red', 'brown', 'gray'])\n\nfor i, color in zip(range(num_classes), colors):\n    plt.plot(recall[i], precision[i], color=color, lw=2,\n             label='Precision-Recall Kurve der Klasse {0} (AP = {1:0.2f})'\n             ''.format(target_names[i], average_precision[i]))\n\nplt.xlabel('Recall')\nplt.ylabel('Precision')\nplt.title('Precision-Recall-Kurven')\nplt.legend(loc=\"upper right\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-25T01:24:26.621603Z","iopub.execute_input":"2024-11-25T01:24:26.621958Z","iopub.status.idle":"2024-11-25T01:24:27.652465Z","shell.execute_reply.started":"2024-11-25T01:24:26.621898Z","shell.execute_reply":"2024-11-25T01:24:27.651448Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"","metadata":{}}]}