{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Atividade Transfer Learning\n## Notebook para a disciplina de Redes Neurais do Mestrado em Inteligência Artificial\n> Aluno: André Vitória\n\nEste notebook foi construido com base nos trabalhos de [johnnychau](https://www.kaggle.com/code/jhnyc3/dog-recognition-w-inceptionresnetv2).","metadata":{}},{"cell_type":"code","source":"# Import libraries\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom tensorflow.keras import models\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport os\nimport shutil\nimport sys","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-28T13:35:14.927500Z","iopub.execute_input":"2023-06-28T13:35:14.928007Z","iopub.status.idle":"2023-06-28T13:35:14.934439Z","shell.execute_reply.started":"2023-06-28T13:35:14.927956Z","shell.execute_reply":"2023-06-28T13:35:14.933545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Carregando dados de treino e validação","metadata":{}},{"cell_type":"code","source":"# Load dataset\ndataset_dir = '../input/dog-breed-identification/train'\nlabels = pd.read_csv('../input/dog-breed-identification/labels.csv')","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:35:14.936788Z","iopub.execute_input":"2023-06-28T13:35:14.937558Z","iopub.status.idle":"2023-06-28T13:35:14.975857Z","shell.execute_reply.started":"2023-06-28T13:35:14.937525Z","shell.execute_reply":"2023-06-28T13:35:14.974999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_dir(x):\n    if os.path.exists(x)==False:\n        os.makedirs(x)\n        \nbase_dir = './subset'\nmake_dir(base_dir)","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:35:14.977343Z","iopub.execute_input":"2023-06-28T13:35:14.977695Z","iopub.status.idle":"2023-06-28T13:35:14.982548Z","shell.execute_reply.started":"2023-06-28T13:35:14.977658Z","shell.execute_reply":"2023-06-28T13:35:14.981626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Number of classes\nn_class = len(labels.breed.unique())\nn_class","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:35:14.984110Z","iopub.execute_input":"2023-06-28T13:35:14.984855Z","iopub.status.idle":"2023-06-28T13:35:15.004491Z","shell.execute_reply.started":"2023-06-28T13:35:14.984823Z","shell.execute_reply":"2023-06-28T13:35:15.003640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set up directories for the training data\ntrain_dir = os.path.join(base_dir, 'train')\nmake_dir(train_dir)\n# Set up directories for the validation data\nval_dir = os.path.join(base_dir, 'validation')\nmake_dir(val_dir)","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:35:15.007965Z","iopub.execute_input":"2023-06-28T13:35:15.008536Z","iopub.status.idle":"2023-06-28T13:35:15.013853Z","shell.execute_reply.started":"2023-06-28T13:35:15.008506Z","shell.execute_reply":"2023-06-28T13:35:15.012966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Loop through images\nbreeds = labels.breed.unique()\nfor breed in breeds:\n    # Make folder for each breed\n    _ = os.path.join(train_dir, breed)\n    make_dir(_)\n    \n    _ = os.path.join(val_dir, breed)\n    make_dir(_)\n    \n    # Copy images to the corresponding folders\n    images = labels[labels.breed == breed]['id']\n    i = 0\n    for image in images:\n        source = os.path.join(dataset_dir, f'{image}.jpg')\n        if i % 10 < 2:\n            destination = os.path.join(val_dir, breed,f'{image}.jpg')\n        else:\n            destination = os.path.join(train_dir, breed,f'{image}.jpg')\n        shutil.copyfile(source, destination)\n        i+= 1","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:35:15.015251Z","iopub.execute_input":"2023-06-28T13:35:15.015601Z","iopub.status.idle":"2023-06-28T13:36:35.292107Z","shell.execute_reply.started":"2023-06-28T13:35:15.015543Z","shell.execute_reply":"2023-06-28T13:36:35.291109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set batch size 64 as global variable\nbatch_size = 64","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:36:35.295410Z","iopub.execute_input":"2023-06-28T13:36:35.296333Z","iopub.status.idle":"2023-06-28T13:36:35.300805Z","shell.execute_reply.started":"2023-06-28T13:36:35.296299Z","shell.execute_reply":"2023-06-28T13:36:35.299376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import image_dataset_from_directory\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(\n    rescale=1./255,\n    validation_split=0.2,\n\n) # rescale pixel values to [0,1] to reduce memory usage\n\ntrain_generator = datagen.flow_from_directory(\n    directory=train_dir,\n    target_size=(299, 299),\n    batch_size=batch_size,\n    class_mode='sparse',#\"categorical\",\n    seed=123)\n","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:36:35.302413Z","iopub.execute_input":"2023-06-28T13:36:35.302953Z","iopub.status.idle":"2023-06-28T13:36:35.787792Z","shell.execute_reply.started":"2023-06-28T13:36:35.302916Z","shell.execute_reply":"2023-06-28T13:36:35.786844Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validation_generator  = datagen.flow_from_directory(\n    directory=val_dir,\n    target_size=(299, 299),\n    batch_size=batch_size,\n    class_mode='sparse',#\"categorical\",\n    seed=123)","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:36:35.789277Z","iopub.execute_input":"2023-06-28T13:36:35.789638Z","iopub.status.idle":"2023-06-28T13:36:35.935817Z","shell.execute_reply.started":"2023-06-28T13:36:35.789607Z","shell.execute_reply":"2023-06-28T13:36:35.934961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Carregando modelo Pré Treinado","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import InceptionResNetV2\nfrom tensorflow.keras.applications import InceptionV3\n\ninception_bottleneck = InceptionResNetV2(weights='imagenet', include_top=False, input_shape=(299, 299, 3))","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:36:35.938537Z","iopub.execute_input":"2023-06-28T13:36:35.938853Z","iopub.status.idle":"2023-06-28T13:36:42.061880Z","shell.execute_reply.started":"2023-06-28T13:36:35.938829Z","shell.execute_reply":"2023-06-28T13:36:42.060867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The shape of the features\nfeature_shape = inception_bottleneck.layers[-1].output_shape[1:]\nprint(f'The shape of each feature tensor is: {feature_shape}')\n\n# Height, width and depth of the tensor\nh = inception_bottleneck.layers[-1].output_shape[1]\nw = inception_bottleneck.layers[-1].output_shape[2]\nd = inception_bottleneck.layers[-1].output_shape[3]\n(h,w,d)","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:36:42.066503Z","iopub.execute_input":"2023-06-28T13:36:42.068698Z","iopub.status.idle":"2023-06-28T13:36:42.087068Z","shell.execute_reply.started":"2023-06-28T13:36:42.068661Z","shell.execute_reply":"2023-06-28T13:36:42.086288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Number of training samples\nval_samples = validation_generator.n\n\n# Initialize tensors with zeros\nX_val = np.zeros(shape=(val_samples, h, w, d), dtype=np.float32) # specify dtype as float32\ny_val = np.zeros(shape=(val_samples))\n\n# Update the tensors with the features outputed by the bottleneck model\nlen_ = 0\nfor input_batch, label_batch in validation_generator:\n    features_batch = inception_bottleneck.predict(input_batch)\n    X_val[len_:len_+len(features_batch)] = features_batch\n    y_val[len_:len_+len(features_batch)] = label_batch\n    len_+=len(features_batch)\n    if len_ == val_samples:\n        break","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:36:42.090927Z","iopub.execute_input":"2023-06-28T13:36:42.093296Z","iopub.status.idle":"2023-06-28T13:37:17.201962Z","shell.execute_reply.started":"2023-06-28T13:36:42.093263Z","shell.execute_reply":"2023-06-28T13:37:17.200991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Number of training samples\ntrain_samples = train_generator.n\n\n# Initialize tensors with zeros\nX_train = np.zeros(shape=(train_samples, h, w, d), dtype=np.float32) # specify dtype as float32\ny_train = np.zeros(shape=(train_samples))\n\n# Update the tensors with the features outputed by the bottleneck model\nlen_ = 0\nfor input_batch, label_batch in train_generator:\n    features_batch = inception_bottleneck.predict(input_batch)\n    X_train[len_:len_+len(features_batch)] = features_batch\n    y_train[len_:len_+len(features_batch)] = label_batch\n    len_+=len(features_batch)\n    if len_ == train_samples:\n        break","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:37:17.207442Z","iopub.execute_input":"2023-06-28T13:37:17.209310Z","iopub.status.idle":"2023-06-28T13:38:40.598934Z","shell.execute_reply.started":"2023-06-28T13:37:17.209283Z","shell.execute_reply":"2023-06-28T13:38:40.597959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = np.reshape(X_train, (train_samples, h*w*d)) \nshape = X_train.shape\nprint(f'Train Shape: {shape}')\n","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:38:40.600404Z","iopub.execute_input":"2023-06-28T13:38:40.600991Z","iopub.status.idle":"2023-06-28T13:38:40.606806Z","shell.execute_reply.started":"2023-06-28T13:38:40.600957Z","shell.execute_reply":"2023-06-28T13:38:40.605622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nX_val = np.reshape(X_val, (val_samples, h*w*d)) \nshape = X_val.shape\nprint(f'Validation Shape: {shape}')\n","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:38:40.608286Z","iopub.execute_input":"2023-06-28T13:38:40.609032Z","iopub.status.idle":"2023-06-28T13:38:40.619529Z","shell.execute_reply.started":"2023-06-28T13:38:40.608919Z","shell.execute_reply":"2023-06-28T13:38:40.618301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Construíndo a arquitetura da Rede","metadata":{}},{"cell_type":"code","source":"# Build the final fully connected dense layers for classification\nmodel_2 = models.Sequential()\nmodel_2.add(layers.Dense(512, activation='relu', input_dim=h*w*d))\nmodel_2.add(layers.Dropout(0.2))\nmodel_2.add(layers.Dense(512, activation='relu'))\nmodel_2.add(layers.Dropout(0.2))\nmodel_2.add(layers.Dense(n_class, activation='softmax')) # using softmax, the result could be interpreted in probability distribution\n\n# Compile model using the popular'adam' optimizer\nmodel_2.compile(optimizer='adam',\n              loss='sparse_categorical_crossentropy',\n              metrics=['accuracy'])\n\n# Print model summary\nmodel_2.summary()","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:38:40.621045Z","iopub.execute_input":"2023-06-28T13:38:40.621439Z","iopub.status.idle":"2023-06-28T13:38:40.729820Z","shell.execute_reply.started":"2023-06-28T13:38:40.621400Z","shell.execute_reply":"2023-06-28T13:38:40.729096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Treinando modelo","metadata":{}},{"cell_type":"code","source":"from keras.callbacks import ModelCheckpoint\n# Train the model\ncheckpointer = ModelCheckpoint(filepath='../working/my_model/weights.best.InceptionV3.hdf5', \n                               verbose=1, save_best_only=True)\nearly_stop = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=10)\nepochs = 50\n\nhistory = model_2.fit(\n    X_train,\n    y_train,\n    epochs=epochs,\n    batch_size=batch_size,\n    #validation_split=0.1,\n    validation_data=(X_val, y_val),\n    callbacks=[checkpointer, early_stop],\n    verbose=1\n)","metadata":{"execution":{"iopub.status.busy":"2023-06-28T13:38:40.731086Z","iopub.execute_input":"2023-06-28T13:38:40.731419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del X_train\ndel y_train\ndel train_generator\ndel validation_generator","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_2.save('../working/model/model_2.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Executando Validação","metadata":{}},{"cell_type":"code","source":"model_2.evaluate(X_val, y_val)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del X_val\ndel y_val","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Carregando amostra de teste","metadata":{}},{"cell_type":"code","source":"test_dataset_dir = '../input/dog-breed-identification/test'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nfrom path import Path\n\ntest_dir = Path.joinpath(base_dir, 'test/no_class')\nif not test_dir.exists():\n    shutil.copytree(test_dataset_dir, test_dir)\nprint(len(test_dir.listdir()))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_generator = datagen.flow_from_directory(\n    directory=Path(test_dir).parent,\n    target_size=(299, 299),\n    batch_size=batch_size,\n    class_mode=None,\n    shuffle=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Number of training samples\ntest_samples = test_generator.n\n\n# Initialize tensors with zeros\n#X_test = np.zeros(shape=(test_samples, h, w, d), dtype=np.float32) # specify dtype as float32\ny_pred = np.zeros(shape=(test_samples, len(breeds)))\n\n# Update the tensors with the features outputed by the bottleneck model\nlen_ = 0\n\n#test_generator = [test_generator[0], test_generator[1]]\n\nfor input_batch in test_generator:\n    features_batch = inception_bottleneck.predict(input_batch)\n    #X_test[len_:len_+len(features_batch)] = features_batch\n    features_batch = np.reshape(features_batch, (features_batch.shape[0], h*w*d))\n    #y_pred.append(model_2.predict(features_batch))\n    y_pred[len_:len_+len(features_batch)] = model_2.predict(features_batch)\n    len_+=len(features_batch)\n    if len_ == test_samples:\n        break","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del test_generator","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nX_test = np.reshape(X_test, (test_samples, h*w*d)) \nshape = X_test.shape\nprint(f'Validation Shape: {shape}')\n\nX_test.shape\n\"\"\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predição dos resultados da amostra de teste","metadata":{}},{"cell_type":"code","source":"#y_pred = model_2.predict(X_test)\ny_pred","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#del X_test","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Salvando Submissão do resultado","metadata":{}},{"cell_type":"code","source":"result_path = Path('../working/results/result.csv')\n\nif not result_path.parent.exists():\n    result_path.parent.makedirs()\nfiles_id_list = Path('../input/dog-breed-identification/test').listdir()\n\nwith open(result_path, 'wt') as f:\n    f.writelines(','.join(['id'] + breeds.tolist()) + '\\n')\n    for index, row in enumerate(y_pred):\n        f.writelines(','.join([files_id_list[index].name[:-4]] + row.astype(str).tolist()) + '\\n')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result_path.copy2('submission.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}