{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Import erfolgreich\n" ] } ], "source": [ "from tensorflow.keras.models import Sequential\n", "from tensorflow.keras.layers import Dense, GlobalAveragePooling2D\n", "from tensorflow.keras.applications import ResNet50\n", "from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau\n", "import tensorflow as tf\n", "print(\"Import erfolgreich\")\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 361 images belonging to 3 classes.\n", "Found 89 images belonging to 3 classes.\n", "Aktueller Arbeitspfad: c:\\Users\\lukas\\Studium\\6. Semester\\KI Anwendungen\\PIcture\n", "Verzeichnisinhalt: ['.history', '.ipynb_checkpoints', 'app.py', 'main.ipynb', 'pokemon']\n" ] } ], "source": [ "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", "from sklearn.model_selection import train_test_split\n", "import os\n", "\n", "base_dir = 'pokemon'\n", "\n", "image_size = (224, 224)\n", "batch_size = 32\n", "\n", "train_datagen = ImageDataGenerator(\n", " rescale=1./255,\n", " rotation_range=40,\n", " width_shift_range=0.2,\n", " height_shift_range=0.2,\n", " shear_range=0.2,\n", " zoom_range=0.2,\n", " horizontal_flip=True,\n", " fill_mode='nearest',\n", " validation_split=0.2 \n", ")\n", "\n", "train_generator = train_datagen.flow_from_directory(\n", " base_dir,\n", " target_size=image_size,\n", " batch_size=batch_size,\n", " class_mode='categorical',\n", " subset='training' \n", ")\n", "\n", "validation_generator = train_datagen.flow_from_directory(\n", " base_dir,\n", " target_size=image_size,\n", " batch_size=batch_size,\n", " class_mode='categorical',\n", " subset='validation' \n", ")\n", "\n", "# Aktuellen Arbeitspfad drucken\n", "print(\"Aktueller Arbeitspfad:\", os.getcwd())\n", "\n", "# Inhalte im aktuellen Verzeichnis auflisten\n", "print(\"Verzeichnisinhalt:\", os.listdir())" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))\n", "\n", "base_model.trainable = False\n", "\n", "model = Sequential([\n", " base_model,\n", " GlobalAveragePooling2D(),\n", " Dense(512, activation='relu'),\n", " Dense(3, activation='softmax') \n", "])\n", "\n", "model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n", "\n", "early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\n", "model_checkpoint = ModelCheckpoint('best_model.keras', save_best_only=True)\n", "reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=2, min_lr=1e-7)\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/10\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\lukas\\anaconda3\\envs\\kia\\lib\\site-packages\\keras\\src\\trainers\\data_adapters\\py_dataset_adapter.py:121: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored.\n", " self._warn_if_super_not_called()\n", "c:\\Users\\lukas\\anaconda3\\envs\\kia\\lib\\site-packages\\PIL\\Image.py:1000: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images\n", " warnings.warn(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m82s\u001b[0m 5s/step - accuracy: 0.3422 - loss: 1.4997 - val_accuracy: 0.3258 - val_loss: 1.1893 - learning_rate: 0.0010\n", "Epoch 2/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m60s\u001b[0m 4s/step - accuracy: 0.3986 - loss: 1.1751 - val_accuracy: 0.4045 - val_loss: 1.1911 - learning_rate: 0.0010\n", "Epoch 3/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m59s\u001b[0m 4s/step - accuracy: 0.4265 - loss: 1.1501 - val_accuracy: 0.5393 - val_loss: 1.0268 - learning_rate: 0.0010\n", "Epoch 4/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m51s\u001b[0m 4s/step - accuracy: 0.5038 - loss: 1.0047 - val_accuracy: 0.6180 - val_loss: 0.9316 - learning_rate: 0.0010\n", "Epoch 5/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m47s\u001b[0m 3s/step - accuracy: 0.4520 - loss: 1.0198 - val_accuracy: 0.4831 - val_loss: 0.9292 - learning_rate: 0.0010\n", "Epoch 6/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m45s\u001b[0m 3s/step - accuracy: 0.5053 - loss: 0.9459 - val_accuracy: 0.6292 - val_loss: 0.9976 - learning_rate: 0.0010\n", "Epoch 7/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m46s\u001b[0m 3s/step - accuracy: 0.5592 - loss: 0.9549 - val_accuracy: 0.5618 - val_loss: 0.8820 - learning_rate: 0.0010\n", "Epoch 8/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m53s\u001b[0m 4s/step - accuracy: 0.4919 - loss: 0.9838 - val_accuracy: 0.5281 - val_loss: 0.8794 - learning_rate: 0.0010\n", "Epoch 9/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m60s\u001b[0m 4s/step - accuracy: 0.5190 - loss: 0.9214 - val_accuracy: 0.6180 - val_loss: 0.8400 - learning_rate: 0.0010\n", "Epoch 10/10\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m51s\u001b[0m 4s/step - accuracy: 0.5295 - loss: 0.9299 - val_accuracy: 0.5730 - val_loss: 0.8847 - learning_rate: 0.0010\n" ] } ], "source": [ "history = model.fit(\n", " train_generator,\n", " epochs=10,\n", " validation_data=validation_generator,\n", " callbacks=[early_stopping, model_checkpoint, reduce_lr]\n", ")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 10/20\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m101s\u001b[0m 7s/step - accuracy: 0.4401 - loss: 3.5201 - val_accuracy: 0.4607 - val_loss: 0.9513 - learning_rate: 1.0000e-05\n", "Epoch 11/20\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m78s\u001b[0m 6s/step - accuracy: 0.5555 - loss: 2.0987 - val_accuracy: 0.4157 - val_loss: 1.0550 - learning_rate: 1.0000e-05\n", "Epoch 12/20\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m73s\u001b[0m 6s/step - accuracy: 0.4555 - loss: 1.7529 - val_accuracy: 0.4157 - val_loss: 1.2538 - learning_rate: 1.0000e-05\n", "Epoch 13/20\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m72s\u001b[0m 6s/step - accuracy: 0.5554 - loss: 1.0633 - val_accuracy: 0.4157 - val_loss: 1.4237 - learning_rate: 2.0000e-06\n", "Epoch 14/20\n", "\u001b[1m12/12\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m75s\u001b[0m 6s/step - accuracy: 0.5212 - loss: 1.2389 - val_accuracy: 0.4157 - val_loss: 1.7295 - learning_rate: 2.0000e-06\n" ] } ], "source": [ "base_model.trainable = True\n", "fine_tune_at = 100\n", "\n", "# Set the earlier layers to not be trainable\n", "for layer in base_model.layers[:fine_tune_at]:\n", " layer.trainable = False\n", "\n", "# Ensure you include a loss function here\n", "model.compile(optimizer=tf.keras.optimizers.Adam(1e-5), \n", " loss='categorical_crossentropy', # This should be the loss function you used initially\n", " metrics=['accuracy'])\n", "\n", "fine_tune_epochs = 10\n", "total_epochs = history.epoch[-1] + fine_tune_epochs + 1\n", "\n", "history_fine = model.fit(\n", " train_generator,\n", " epochs=total_epochs,\n", " initial_epoch=history.epoch[-1],\n", " validation_data=validation_generator,\n", " callbacks=[early_stopping, model_checkpoint, reduce_lr]\n", ")\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "model.save('pokemon_classifier_model.keras')\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.19" } }, "nbformat": 4, "nbformat_minor": 2 }