{"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":"gpu","dataSources":[{"sourceId":84511,"databundleVersionId":9468663,"sourceType":"competition"}],"dockerImageVersionId":30805,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#### This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-17T20:58:06.132866Z","iopub.execute_input":"2024-12-17T20:58:06.133220Z","iopub.status.idle":"2024-12-17T20:58:06.449253Z","shell.execute_reply.started":"2024-12-17T20:58:06.133187Z","shell.execute_reply":"2024-12-17T20:58:06.448404Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train = np.load(\"/kaggle/input/dl-itba-cifar-100-2024-q-1/x_train.npy\")/255.\nx_test = np.load(\"/kaggle/input/dl-itba-cifar-100-2024-q-1/x_test.npy\")/255.\ny_train_coarse = np.load(\"/kaggle/input/dl-itba-cifar-100-2024-q-1/y_train_coarse.npy\")\ny_train_fine = np.load(\"/kaggle/input/dl-itba-cifar-100-2024-q-1/y_train_fine.npy\")","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:06.450897Z","iopub.execute_input":"2024-12-17T20:58:06.451259Z","iopub.status.idle":"2024-12-17T20:58:08.571075Z","shell.execute_reply.started":"2024-12-17T20:58:06.451231Z","shell.execute_reply":"2024-12-17T20:58:08.570375Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:08.571989Z","iopub.execute_input":"2024-12-17T20:58:08.572277Z","iopub.status.idle":"2024-12-17T20:58:09.129974Z","shell.execute_reply.started":"2024-12-17T20:58:08.572250Z","shell.execute_reply":"2024-12-17T20:58:09.129313Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pickle\nwith open(\"/kaggle/input/dl-itba-cifar-100-2024-q-1/fine_label_names.pck\", \"rb\") as f:\n    labels_fine = pickle.load(f)\nwith open(\"/kaggle/input/dl-itba-cifar-100-2024-q-1/coarse_label_names.pck\", \"rb\") as f:\n    labels_coarse = pickle.load(f)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:09.130961Z","iopub.execute_input":"2024-12-17T20:58:09.131345Z","iopub.status.idle":"2024-12-17T20:58:09.143169Z","shell.execute_reply.started":"2024-12-17T20:58:09.131316Z","shell.execute_reply":"2024-12-17T20:58:09.142482Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train,x_val, y_train, y_val = train_test_split(x_train, y_train_fine, test_size=0.1, random_state=42, stratify=y_train_fine)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:09.145829Z","iopub.execute_input":"2024-12-17T20:58:09.146070Z","iopub.status.idle":"2024-12-17T20:58:09.532940Z","shell.execute_reply.started":"2024-12-17T20:58:09.146046Z","shell.execute_reply":"2024-12-17T20:58:09.531992Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Preprocesamos las imágenes y hacemos data augmentation. Se gira un poco a las imágenes, se le hace un poco de zoom y se las flipea horizontalmente. Además, se les modifica el brillo para generar ruido en las imágenes.**","metadata":{}},{"cell_type":"code","source":"# Agregamos ruido a las imágenes\nbrightness_factor = np.random.uniform(0.75, 1.25, (x_train.shape[0], 1,1,1))\nx_train = x_train * brightness_factor\n\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.utils import array_to_img, img_to_array, load_img\n\n#Creamos un generador de imagenes\ndatagen = ImageDataGenerator(\n        width_shift_range=0.07,\n        height_shift_range=0.07,\n        shear_range=0.07,\n        zoom_range = 0.07,\n        horizontal_flip=True)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T20:58:09.534116Z","iopub.execute_input":"2024-12-17T20:58:09.534481Z","iopub.status.idle":"2024-12-17T20:58:21.063921Z","shell.execute_reply.started":"2024-12-17T20:58:09.534452Z","shell.execute_reply":"2024-12-17T20:58:21.063252Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from matplotlib import pyplot as plt\n%load_ext tensorboard","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:21.064919Z","iopub.execute_input":"2024-12-17T20:58:21.065403Z","iopub.status.idle":"2024-12-17T20:58:21.091689Z","shell.execute_reply.started":"2024-12-17T20:58:21.065376Z","shell.execute_reply":"2024-12-17T20:58:21.090877Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train_bis = x_train[:,:,::-1,:]\nplt.figure(figsize=(1,1))\nplt.imshow(x_train_bis[2])","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:21.092934Z","iopub.execute_input":"2024-12-17T20:58:21.093312Z","iopub.status.idle":"2024-12-17T20:58:21.222994Z","shell.execute_reply.started":"2024-12-17T20:58:21.093274Z","shell.execute_reply":"2024-12-17T20:58:21.222117Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(y_train[2])","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:21.224215Z","iopub.execute_input":"2024-12-17T20:58:21.224528Z","iopub.status.idle":"2024-12-17T20:58:21.229743Z","shell.execute_reply.started":"2024-12-17T20:58:21.224492Z","shell.execute_reply":"2024-12-17T20:58:21.228927Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels_fine[50]","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:21.230593Z","iopub.execute_input":"2024-12-17T20:58:21.230907Z","iopub.status.idle":"2024-12-17T20:58:21.240184Z","shell.execute_reply.started":"2024-12-17T20:58:21.230870Z","shell.execute_reply":"2024-12-17T20:58:21.239381Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train_dup = np.concatenate([x_train, x_train_bis],axis=0)\ny_train_dup = np.concatenate([y_train, y_train], axis=0)\nx_train_bis = x_train_dup.copy()\nx_train_bis_bis = x_train_dup.copy()\nx_train_bis[:,:,1:,:] =x_train_dup[:,:,:-1,:]\nx_train_bis_bis[:,:,:-1,:] =x_train_dup[:,:,1:,:]\nx_train_dup = np.concatenate([x_train_dup, x_train_bis, x_train_bis_bis],axis=0)\ny_train_dup = np.concatenate([y_train_dup, y_train_dup, y_train_dup], axis=0)\n","metadata":{"execution":{"iopub.status.busy":"2024-12-17T20:58:21.241207Z","iopub.execute_input":"2024-12-17T20:58:21.241516Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train_dup.shape, y_train_dup.shape","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Me fijo para una categoría de grano grueso, cuáles son las categorías de grano fino\ncoarse = 10\nprint(f\"Grano grueso: {labels_coarse[coarse]}\")\nfor fine in np.unique(y_train_fine[y_train_coarse == coarse]):\n    print(f\"Grano fino: {labels_fine[fine]}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential, Model\nfrom tensorflow.keras.layers import Dense, Dropout, BatchNormalization, Flatten, Conv2D, MaxPooling2D, GlobalAveragePooling2D, Activation\nfrom tensorflow.keras.optimizers import SGD, Adam, RMSprop\nfrom tensorflow.keras.regularizers import l1, l2\nfrom tensorflow.keras.constraints import MaxNorm\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping, ModelCheckpoint, TensorBoard","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Probamos: (TP_Final)** \n\n1- En este trabajo utilizamos Data Augmentation similar a lo implementado en el TP1. Inicialmente probamos con una arquitectura sencilla, que incluía tres capas convolucionales con filtros de tamaño 5x5 (la primera) y 3x3 el resto (sin padding, configurado como \"same\"), max pooling de 2x2, y al final tres capas densas de neuronas (3072 y 1536 y 100 respectivamente). Las capas convolucionales tenían 16, 32 y 64 filtros. Los resultados obtenidos fueron un CV de 0.3424 y un Train de 0.3542. Parando en el epoch 55 debido a Early Stopping. Le falta complejidad a la red.\n\n2- Dado que el tamaño se reducía rápidamente al no utilizar padding igual a \"same\", se decidió activarlo para mitigar el problema de underfitting. Esto permitió alcanzar un Train de 0.7107 y un CV de 0.5804, mostrando una mejora en el rendimiento sobre el conjunto de entrenamiento.\n\n3- Incrementamos los filtros a 32, 64 y 128, logrando un Train moderadamente alto y un CV de 0.5943. Apenas mejor que el anterior. Aunque el modelo alcanzó valores muy altos en Train, evidenció overfitting, sugiriendo la necesidad de aplicar regularización.\n\n4- Incorporamos Batch Normalization al final de cada capa convolucional, logrando un Train de 0.8911 y un CV de 0.6388.\n\n5- Sumamos una capa convolucional extra con 128 filtros al final. Y decidimos duplicar la cantidad de filtros en cada capa, lo que resultó en una mejora significativa, alcanzando un Train de 0.9311 y un CV de 0.6622.","metadata":{}},{"cell_type":"code","source":"model = Sequential()\n\nmodel.add(Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same', input_shape=(32,32,3)))\nmodel.add(Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(BatchNormalization())\n\n\nmodel.add(Conv2D(128, kernel_size=(3, 3), activation='relu', padding='same'))\nmodel.add(Conv2D(128, kernel_size=(3, 3), activation='relu', padding='same'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(BatchNormalization())\n\n\nmodel.add(Conv2D(256, kernel_size=(3, 3), activation='relu', padding='same'))\nmodel.add(Conv2D(256, kernel_size=(3, 3), activation='relu', padding='same'))\nmodel.add(Conv2D(256, kernel_size=(3, 3), activation='relu', padding='same'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n#model.add(Dropout(0.25))\nmodel.add(BatchNormalization())\n\nmodel.add(Flatten())\n\nmodel.add(Dense(3*32*32, use_bias=False))\nmodel.add(BatchNormalization())\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.5))\n\nmodel.add(Dense(1572, use_bias=False))\nmodel.add(BatchNormalization())\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.5))\n\nmodel.add(Dense(100, use_bias=False))\nmodel.add(BatchNormalization()) # se lo sacamos por la recomendación de solo poner normalization en las capas intermedias\nmodel.add(Activation('softmax'))\n\nmodel.compile(loss=\"sparse_categorical_crossentropy\", metrics = [\"accuracy\"], optimizer = Adam(learning_rate=0.001))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"rlrop = ReduceLROnPlateau(\n    monitor = \"val_accuracy\",\n    factor = 0.5,\n    patience = 3,\n    verbose = 1,\n    min_lr = 1e-5\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"mc = ModelCheckpoint(\n    \"best_weights.weights.h5\",\n    monitor = \"val_accuracy\",\n    verbose = 1,\n    save_best_only = True,\n    save_weights_only = True,\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"es = EarlyStopping(\n    monitor = \"val_accuracy\",\n    patience = 15, \n    verbose = 1,\n    restore_best_weights = True,\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tb = TensorBoard(\n    log_dir=\"logs\",\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"indexes = list(range(len(x_train_dup)))\nnp.random.shuffle(indexes)\nx_train_dup = x_train_dup[indexes]\ny_train_dup = y_train_dup[indexes]\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(\n    datagen.flow(x_train, y_train, batch_size=128), # aplicamos el generador de imagenes\n    epochs=200, \n    validation_data = (x_val, y_val), \n    callbacks= [\n        rlrop,\n        es,\n        mc\n    ]\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!mkdir logs","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(history.history[\"loss\"])\nplt.plot(history.history[\"val_loss\"])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(history.history[\"accuracy\"])\nplt.plot(history.history[\"val_accuracy\"])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%tensorboard --logdir logs","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions = model.predict(x_test).argmax(axis=1)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.DataFrame(predictions, columns=[\"Label\"])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.index.name = \"Id\"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.to_csv(\"submission.csv\")","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}