{"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":"# Matheus Inácio Silva Mol\n\nImplementar um python notebook no kaggle.com para identificar raças de cães: https://www.kaggle.com/competitions/dog-breed-identification\n\nA entrega deve ser um link para um notebook de acesso público implementado no Kaggle.\n","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\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":{"execution":{"iopub.status.busy":"2023-06-25T18:37:37.822094Z","iopub.execute_input":"2023-06-25T18:37:37.822569Z","iopub.status.idle":"2023-06-25T18:37:54.488189Z","shell.execute_reply.started":"2023-06-25T18:37:37.822533Z","shell.execute_reply":"2023-06-25T18:37:54.487199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_dir = '../input/dog-breed-identification/train'\nlabels = pd.read_csv('../input/dog-breed-identification/labels.csv')","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:37:54.494391Z","iopub.execute_input":"2023-06-25T18:37:54.495926Z","iopub.status.idle":"2023-06-25T18:37:54.532494Z","shell.execute_reply.started":"2023-06-25T18:37:54.495891Z","shell.execute_reply":"2023-06-25T18:37:54.531502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\ndef 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-25T18:37:54.533806Z","iopub.execute_input":"2023-06-25T18:37:54.534515Z","iopub.status.idle":"2023-06-25T18:37:54.540307Z","shell.execute_reply.started":"2023-06-25T18:37:54.534483Z","shell.execute_reply":"2023-06-25T18:37:54.539377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = os.path.join(base_dir, 'train')\nmake_dir(train_dir)","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:37:54.543877Z","iopub.execute_input":"2023-06-25T18:37:54.544299Z","iopub.status.idle":"2023-06-25T18:37:54.553381Z","shell.execute_reply.started":"2023-06-25T18:37:54.544268Z","shell.execute_reply":"2023-06-25T18:37:54.552333Z"},"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    # Copy images to the corresponding folders\n    images = labels[labels.breed == breed]['id']\n    for image in images:\n        source = os.path.join(dataset_dir, f'{image}.jpg')\n        destination = os.path.join(train_dir, breed,f'{image}.jpg')                             \n        shutil.copyfile(source, destination)","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:37:54.555330Z","iopub.execute_input":"2023-06-25T18:37:54.555631Z","iopub.status.idle":"2023-06-25T18:39:08.927983Z","shell.execute_reply.started":"2023-06-25T18:37:54.555597Z","shell.execute_reply":"2023-06-25T18:39:08.926863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 64","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:39:08.929568Z","iopub.execute_input":"2023-06-25T18:39:08.929962Z","iopub.status.idle":"2023-06-25T18:39:08.936530Z","shell.execute_reply.started":"2023-06-25T18:39:08.929923Z","shell.execute_reply":"2023-06-25T18:39:08.935510Z"},"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(rescale=1./255) # 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',\n    seed=123)","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:39:08.937905Z","iopub.execute_input":"2023-06-25T18:39:08.938918Z","iopub.status.idle":"2023-06-25T18:39:09.573380Z","shell.execute_reply.started":"2023-06-25T18:39:08.938884Z","shell.execute_reply":"2023-06-25T18:39:09.572432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications import InceptionResNetV2\n\ninception_bottleneck = InceptionResNetV2(weights='imagenet', include_top=False, input_shape=(299, 299, 3))","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:39:09.574897Z","iopub.execute_input":"2023-06-25T18:39:09.575498Z","iopub.status.idle":"2023-06-25T18:39:23.077748Z","shell.execute_reply.started":"2023-06-25T18:39:09.575462Z","shell.execute_reply":"2023-06-25T18:39:23.076740Z"},"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]","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:39:23.079077Z","iopub.execute_input":"2023-06-25T18:39:23.079449Z","iopub.status.idle":"2023-06-25T18:39:23.092066Z","shell.execute_reply.started":"2023-06-25T18:39:23.079411Z","shell.execute_reply":"2023-06-25T18:39:23.090753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Number of training samples\ntrain_samples = len(labels)\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\n        \nsize = sys.getsizeof(X_train)/(1024*1024)","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:39:23.093454Z","iopub.execute_input":"2023-06-25T18:39:23.094012Z","iopub.status.idle":"2023-06-25T18:43:05.901614Z","shell.execute_reply.started":"2023-06-25T18:39:23.093938Z","shell.execute_reply":"2023-06-25T18:43:05.900640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Flatten the feature tensors to 1D vectors \nX_train = np.reshape(X_train, (train_samples, h*w*d)) ","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:43:05.903145Z","iopub.execute_input":"2023-06-25T18:43:05.903730Z","iopub.status.idle":"2023-06-25T18:43:05.909330Z","shell.execute_reply.started":"2023-06-25T18:43:05.903679Z","shell.execute_reply":"2023-06-25T18:43:05.908094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Build the final fully connected dense layers for classification\nn_class = len(labels.breed.unique())\n\nmodel = models.Sequential()\nmodel.add(layers.Dense(512, activation='relu', input_dim=h*w*d))\nmodel.add(layers.Dropout(0.2))\nmodel.add(layers.Dense(512, activation='relu'))\nmodel.add(layers.Dropout(0.2))\nmodel.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.compile(optimizer='adam',\n              loss='sparse_categorical_crossentropy',\n              metrics=['accuracy'])\n\n# Print model summary\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:43:05.911168Z","iopub.execute_input":"2023-06-25T18:43:05.911512Z","iopub.status.idle":"2023-06-25T18:43:06.003596Z","shell.execute_reply.started":"2023-06-25T18:43:05.911481Z","shell.execute_reply":"2023-06-25T18:43:06.002902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\nearly_stop = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=10)\nepochs = 20\n\nhistory = model.fit(X_train, y_train,\n         epochs=epochs,\n         batch_size=batch_size,\n         validation_split=0.1,\n         callbacks=[early_stop],\n         verbose=1)","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:43:06.007139Z","iopub.execute_input":"2023-06-25T18:43:06.007488Z","iopub.status.idle":"2023-06-25T18:44:36.323445Z","shell.execute_reply.started":"2023-06-25T18:43:06.007456Z","shell.execute_reply":"2023-06-25T18:44:36.322246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot result\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs = range(1, len(acc) + 1)\n\n# Accuracy\nplt.plot(epochs, acc, label='Train accuracy')\nplt.plot(epochs, val_acc, label='Val accuracy')\nplt.title('Training & validation accuracy')\nplt.legend()\n\n# Loss\nplt.figure()\nplt.plot(epochs, loss, label='Train loss')\nplt.plot(epochs, val_loss, label='Val loss')\nplt.title('Training & validation loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-25T18:44:36.332841Z","iopub.execute_input":"2023-06-25T18:44:36.333578Z","iopub.status.idle":"2023-06-25T18:44:37.255303Z","shell.execute_reply.started":"2023-06-25T18:44:36.333540Z","shell.execute_reply":"2023-06-25T18:44:37.254381Z"},"trusted":true},"execution_count":null,"outputs":[]}]}