{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n\n# --- Load official CIFAR-10\n(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data()\nprint(\"Shapes:\", x_train.shape, x_test.shape)   # (50000,32,32,3) (10000,32,32,3)\n\n# --- Preprocess: scale to [0,1]; keep labels as integers 0-9 ---\nx_train = x_train.astype(\"float32\") / 255.0\nx_test  = x_test.astype(\"float32\")  / 255.0\ny_train = y_train.ravel()\ny_test  = y_test.ravel()\n\n# --- Augmentation, active only during training (inactive at predict/evaluate) ---\naugment = keras.Sequential([\n    layers.RandomFlip(\"horizontal\"),        # horizontal only — a flipped car is still a car; a flipped '6' would not be\n    layers.RandomTranslation(0.1, 0.1),\n], name=\"augment\")\n\n# --- VGG-style ConvNet, randomly initialized (no pre-trained weights) ---\ndef conv_block(x, filters, dropout):\n    for _ in range(2):\n        x = layers.Conv2D(filters, 3, padding=\"same\", use_bias=False)(x)\n        x = layers.BatchNormalization()(x)\n        x = layers.Activation(\"relu\")(x)\n    x = layers.MaxPooling2D()(x)\n    x = layers.Dropout(dropout)(x)\n    return x\n\ninputs = keras.Input(shape=(32, 32, 3))\nx = augment(inputs)\nx = conv_block(x, 32, 0.2)\nx = conv_block(x, 64, 0.3)\nx = conv_block(x, 128, 0.4)\nx = layers.Flatten()(x)\nx = layers.Dense(128, use_bias=False)(x)\nx = layers.BatchNormalization()(x)\nx = layers.Activation(\"relu\")(x)\nx = layers.Dropout(0.5)(x)\noutputs = layers.Dense(10, activation=\"softmax\")(x)\n\nmodel = keras.Model(inputs, outputs)\nmodel.compile(optimizer=keras.optimizers.Adam(1e-3),\n              loss=\"sparse_categorical_crossentropy\",\n              metrics=[\"accuracy\"])\nmodel.summary()\n\nreduce_lr = keras.callbacks.ReduceLROnPlateau(\n    monitor=\"val_accuracy\", factor=0.5, patience=8, min_lr=1e-5, verbose=1)\n\nhistory = model.fit(x_train, y_train,\n                    validation_data=(x_test, y_test),\n                    epochs=100, batch_size=64,\n                    callbacks=[reduce_lr], verbose=2)\n\ntest_loss, test_acc = model.evaluate(x_test, y_test, verbose=0)\nprint(\"Estimated Kaggle score (official test accuracy):\", test_acc)\n\nmodel.save(\"cifar10_cnn.keras\")   # so Phase C can reuse it without retraining","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-09-22T05:32:11.36713Z","iopub.execute_input":"2026-09-22T05:32:11.367711Z","iopub.status.idle":"2026-09-22T06:48:13.916784Z","shell.execute_reply.started":"2026-09-22T05:32:11.367683Z","shell.execute_reply":"2026-09-22T06:48:13.916056Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import py7zr\npath_to_7z = glob.glob('/kaggle/input/**/test.7z', recursive=True)[0]\nwith py7zr.SevenZipFile(path_to_7z, mode='r') as z:\n    z.extractall(path='.')\n\nprint(len(glob.glob('test/*.png')))   # expect 300000","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-22T07:04:56.553466Z","iopub.execute_input":"2026-09-22T07:04:56.554426Z","iopub.status.idle":"2026-09-22T07:08:24.250576Z","shell.execute_reply.started":"2026-09-22T07:04:56.554393Z","shell.execute_reply":"2026-09-22T07:08:24.249859Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom tensorflow.keras.utils import load_img, img_to_array\n\nclass_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck']\n\nids = list(range(1, 300001))\n\nX_sub = np.zeros((300000, 32, 32, 3), dtype='uint8')\nfor i, img_id in enumerate(ids):\n    X_sub[i] = img_to_array(load_img(f'test/{img_id}.png')).astype('uint8')\n    if (i + 1) % 50000 == 0:\n        print(i + 1, \"loaded\")\n\nX_sub = X_sub.astype('float32') / 255.0\n\nprobs = model.predict(X_sub, batch_size=256, verbose=1)\npred_labels = [class_names[k] for k in probs.argmax(axis=1)]\n\nsubmission = pd.DataFrame({'id': ids, 'label': pred_labels})\nsubmission.to_csv('submission.csv', index=False)\nprint(submission.head())\nprint(submission.shape)   # (300000, 2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-22T07:09:04.069632Z","iopub.execute_input":"2026-09-22T07:09:04.070081Z","iopub.status.idle":"2026-09-22T07:10:14.918947Z","shell.execute_reply.started":"2026-09-22T07:09:04.070051Z","shell.execute_reply":"2026-09-22T07:10:14.91816Z"}},"outputs":[],"execution_count":null}]}