{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.17","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"tpu1vmV38","dataSources":[{"sourceId":21154,"databundleVersionId":1243559,"sourceType":"competition"}],"dockerImageVersionId":31042,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.applications import EfficientNetB0\nfrom tensorflow.keras import layers, models\n\n\n# 0. PREPROCESSING DATA\nIMAGE_SIZE = [192, 192]\nBATCH_SIZE = 128\nAUTO = tf.data.AUTOTUNE\n\ndef decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.image.resize(image, IMAGE_SIZE)\n    image = tf.cast(image, tf.float32) / 255.0\n    return image\n\ndef read_labeled_tfrecord(example):\n    LABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"class\": tf.io.FixedLenFeature([], tf.int64),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image = decode_image(example[\"image\"])\n    label = tf.cast(example[\"class\"], tf.int32)\n    return image, label\n\ndef load_dataset(filenames, labeled=True):\n    ignore_order = tf.data.Options()\n    ignore_order.experimental_deterministic = False\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTO)\n    dataset = dataset.with_options(ignore_order)\n    if labeled:\n        dataset = dataset.map(read_labeled_tfrecord, num_parallel_calls=AUTO)\n    return dataset\n\ndef get_dataset(filenames, labeled=True):\n    dataset = load_dataset(filenames, labeled=labeled)\n    if labeled:\n        dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(BATCH_SIZE).prefetch(buffer_size=AUTO)\n    return dataset\n\n# Beispiel für 192x192 TFRecords\ntrain_files = tf.io.gfile.glob(\"/kaggle/input/tpu-getting-started/tfrecords-jpeg-192x192/train/*.tfrec\")\nval_files = tf.io.gfile.glob(\"/kaggle/input/tpu-getting-started/tfrecords-jpeg-192x192/val/*.tfrec\")\n\ntrain_data = get_dataset(train_files, labeled=True)\nval_data = get_dataset(val_files, labeled=True)\n\n# Performance optimieren\nAUTOTUNE = tf.data.AUTOTUNE\ntrain_data = train_data.prefetch(buffer_size=AUTOTUNE)\nval_data = val_data.prefetch(buffer_size=AUTOTUNE)\n\n# Data Augementation\ndata_augmentation = tf.keras.Sequential([\n    tf.keras.layers.RandomFlip(\"horizontal\"),\n    tf.keras.layers.RandomRotation(0.1),\n    tf.keras.layers.RandomZoom(0.1),\n    tf.keras.layers.RandomContrast(0.1),\n    tf.keras.layers.RandomBrightness(0.1),\n    tf.keras.layers.RandomTranslation(0.1, 0.1),\n])\n\ntrain_data = train_data.map(lambda x, y: (data_augmentation(x, training=True), y), num_parallel_calls=AUTO)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T14:02:35.250730Z","iopub.execute_input":"2025-06-13T14:02:35.251067Z","iopub.status.idle":"2025-06-13T14:03:02.747877Z","shell.execute_reply.started":"2025-06-13T14:02:35.251039Z","shell.execute_reply":"2025-06-13T14:03:02.743079Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tpu = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='local')  # Lokale TPU ansprechen\ntf.config.experimental_connect_to_cluster(tpu)\ntf.tpu.experimental.initialize_tpu_system(tpu)\nstrategy = tf.distribute.TPUStrategy(tpu)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T14:03:15.302052Z","iopub.execute_input":"2025-06-13T14:03:15.302372Z","iopub.status.idle":"2025-06-13T14:03:20.166858Z","shell.execute_reply.started":"2025-06-13T14:03:15.302346Z","shell.execute_reply":"2025-06-13T14:03:20.162756Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 1. + 2. BUILDING + COMPILING\nwith strategy.scope():\n    base_model = EfficientNetB0(input_shape=(*IMAGE_SIZE, 3), include_top=False, weights='imagenet')\n    base_model.trainable = False  # Erst einfrieren FREEZE\n\n    model = tf.keras.Sequential([\n        base_model,\n        tf.keras.layers.GlobalAveragePooling2D(),\n        tf.keras.layers.Dense(128, activation='relu'),\n        tf.keras.layers.Dropout(0.3),\n        tf.keras.layers.Dense(104, activation='softmax')\n    ])\n\n    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(\n        initial_learning_rate=1e-4,\n        decay_steps=1000,\n        decay_rate=0.96\n        )\n\n    model.compile(\n        optimizer=tf.keras.optimizers.Adam(learning_rate=lr_schedule),\n        loss='sparse_categorical_crossentropy',\n        metrics=['accuracy']\n    )\n\nmodel.fit(train_data, validation_data=val_data, epochs=50)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T14:03:55.260505Z","iopub.execute_input":"2025-06-13T14:03:55.260814Z","iopub.status.idle":"2025-06-13T14:05:41.832697Z","shell.execute_reply.started":"2025-06-13T14:03:55.260790Z","shell.execute_reply":"2025-06-13T14:05:41.826283Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 3. FITTING\n\n# Feintuning — alles nochmal innerhalb des strategy.scope\nwith strategy.scope():\n    base_model.trainable = True # FINE-TUNING\n\n    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(\n        initial_learning_rate=1e-4,\n        decay_steps=1000,\n        decay_rate=0.96\n    )\n\n    model.compile(\n        optimizer=tf.keras.optimizers.Adam(learning_rate=lr_schedule),\n        loss='sparse_categorical_crossentropy',\n        metrics=['accuracy']\n    )\n\nmodel.fit(train_data, validation_data=val_data, epochs=60)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T14:06:09.985850Z","iopub.execute_input":"2025-06-13T14:06:09.986236Z","iopub.status.idle":"2025-06-13T14:08:59.513709Z","shell.execute_reply.started":"2025-06-13T14:06:09.986208Z","shell.execute_reply":"2025-06-13T14:08:59.508210Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 4. SAVING\ndef read_test_tfrecord(example):\n    TEST_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"id\": tf.io.FixedLenFeature([], tf.string),  # id als String (bytes)\n    }\n    example = tf.io.parse_single_example(example, TEST_TFREC_FORMAT)\n    image = decode_image(example[\"image\"])\n    idstr = example[\"id\"]  # bytestring\n    return image, idstr\n\ndef load_test_dataset(filenames):\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTO)\n    dataset = dataset.map(read_test_tfrecord, num_parallel_calls=AUTO)\n    dataset = dataset.batch(BATCH_SIZE).prefetch(AUTO)\n    return dataset\n\n# Test TFRecord Dateien laden\ntest_files = tf.io.gfile.glob(\"/kaggle/input/tpu-getting-started/tfrecords-jpeg-192x192/test/*.tfrec\")\ntest_data = load_test_dataset(test_files)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T14:11:02.057815Z","iopub.execute_input":"2025-06-13T14:11:02.058272Z","iopub.status.idle":"2025-06-13T14:11:02.158325Z","shell.execute_reply.started":"2025-06-13T14:11:02.058241Z","shell.execute_reply":"2025-06-13T14:11:02.152622Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nall_ids = []\nall_preds = []\n\nfor images, ids in test_data:\n    probs = model.predict(images, verbose=0)\n    labels = np.argmax(probs, axis=1)\n    all_preds.extend(labels)\n    \n    # Wichtig: ids sind Bytes, in Python-Strings konvertieren!\n    all_ids.extend([id.numpy().decode('utf-8') for id in ids])\n\n# Submission DataFrame mit korrekten IDs als Strings\nsubmission = pd.DataFrame({\n    'id': all_ids,\n    'label': all_preds\n})\n\nsubmission.to_csv('submission.csv', index=False)\nprint(\"✅ submission.csv gespeichert mit\", len(submission), \"Zeilen\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T14:11:52.964652Z","iopub.execute_input":"2025-06-13T14:11:52.965025Z","iopub.status.idle":"2025-06-13T14:13:04.430412Z","shell.execute_reply.started":"2025-06-13T14:11:52.964999Z","shell.execute_reply":"2025-06-13T14:13:04.424651Z"}},"outputs":[],"execution_count":null}]}