{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":7327,"databundleVersionId":861871,"sourceType":"competition"}],"dockerImageVersionId":31011,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Dog Breed Identification ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:12:57.262108Z","iopub.execute_input":"2025-05-07T15:12:57.262342Z","iopub.status.idle":"2025-05-07T15:12:57.266768Z","shell.execute_reply.started":"2025-05-07T15:12:57.262315Z","shell.execute_reply":"2025-05-07T15:12:57.265935Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"\"** You are provided with a training set and a test set of images of dogs. Each image has a filename that is its unique id. The dataset comprises 120 breeds of dogs. The goal of the competition is to create a classifier capable of determining a dog's breed from a photo. The list of breeds is as follows: **\"","metadata":{}},{"cell_type":"markdown","source":"affenpinscher\nafghan_hound\nafrican_hunting_dog\nairedale\namerican_staffordshire_terrier\nappenzeller\naustralian_terrier\nbasenji\nbasset\nbeagle\nbedlington_terrier\nbernese_mountain_dog\nblack-and-tan_coonhound\nblenheim_spaniel\nbloodhound\nbluetick\nborder_collie\nborder_terrier\nborzoi\nboston_bull\nbouvier_des_flandres\nboxer\nbrabancon_griffon\nbriard\nbrittany_spaniel\nbull_mastiff\ncairn\ncardigan\nchesapeake_bay_retriever\nchihuahua\nchow\nclumber\ncocker_spaniel\ncollie\ncurly-coated_retriever\ndandie_dinmont\ndhole\ndingo\ndoberman\nenglish_foxhound\nenglish_setter\nenglish_springer\nentlebucher\neskimo_dog\nflat-coated_retriever\nfrench_bulldog\ngerman_shepherd\ngerman_short-haired_pointer\ngiant_schnauzer\ngolden_retriever\ngordon_setter\ngreat_dane\ngreat_pyrenees\ngreater_swiss_mountain_dog\ngroenendael\nibizan_hound\nirish_setter\nirish_terrier\nirish_water_spaniel\nirish_wolfhound\nitalian_greyhound\njapanese_spaniel\nkeeshond\nkelpie\nkerry_blue_terrier\nkomondor\nkuvasz\nlabrador_retriever\nlakeland_terrier\nleonberg\nlhasa\nmalamute\nmalinois\nmaltese_dog\nmexican_hairless\nminiature_pinscher\nminiature_poodle\nminiature_schnauzer\nnewfoundland\nnorfolk_terrier\nnorwegian_elkhound\nnorwich_terrier\nold_english_sheepdog\notterhound\npapillon\npekinese\npembroke\npomeranian\npug\nredbone\nrhodesian_ridgeback\nrottweiler\nsaint_bernard\nsaluki\nsamoyed\nschipperke\nscotch_terrier\nscottish_deerhound\nsealyham_terrier\nshetland_sheepdog\nshih-tzu\nsiberian_husky\nsilky_terrier\nsoft-coated_wheaten_terrier\nstaffordshire_bullterrier\nstandard_poodle\nstandard_schnauzer\nsussex_spaniel\ntibetan_mastiff\ntibetan_terrier\ntoy_poodle\ntoy_terrier\nvizsla\nwalker_hound\nweimaraner\nwelsh_springer_spaniel\nwest_highland_white_terrier\nwhippet\nwire-haired_fox_terrier\nyorkshire_terrier","metadata":{}},{"cell_type":"markdown","source":"# Data pre-processing","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport seaborn as sns\nimport matplotlib\nimport os\nfrom shutil import copyfile\nimport matplotlib.pyplot as plt\n#%matplotlib inline","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:12:57.267479Z","iopub.execute_input":"2025-05-07T15:12:57.267718Z","iopub.status.idle":"2025-05-07T15:13:01.185142Z","shell.execute_reply.started":"2025-05-07T15:12:57.267691Z","shell.execute_reply":"2025-05-07T15:13:01.18429Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:13:01.18668Z","iopub.execute_input":"2025-05-07T15:13:01.187049Z","iopub.status.idle":"2025-05-07T15:13:01.223765Z","shell.execute_reply.started":"2025-05-07T15:13:01.187028Z","shell.execute_reply":"2025-05-07T15:13:01.222942Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nlabels_dict = {i:j for i,j in zip(labels['id'],labels['breed'])}\nclasses = set(labels_dict.values())\nimages = [f for f in os.listdir('/kaggle/input/dog-breed-identification/train')]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:13:01.224569Z","iopub.execute_input":"2025-05-07T15:13:01.224792Z","iopub.status.idle":"2025-05-07T15:13:01.529169Z","shell.execute_reply.started":"2025-05-07T15:13:01.224773Z","shell.execute_reply":"2025-05-07T15:13:01.528427Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if  not os.path.exists('training_images'):\n        os.makedirs('training_images')\n\nif  not os.path.exists('validation_images'):\n    os.makedirs('validation_images')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:13:01.530113Z","iopub.execute_input":"2025-05-07T15:13:01.530313Z","iopub.status.idle":"2025-05-07T15:13:01.535201Z","shell.execute_reply.started":"2025-05-07T15:13:01.530295Z","shell.execute_reply":"2025-05-07T15:13:01.534579Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.chdir('training_images')\nfor curClass in classes:    \n    if  not os.path.exists(curClass):\n        os.makedirs(curClass)\n        #os.rmdir(curClass)\n\nos.chdir('../validation_images')\nfor curClass in classes:    \n    if  not os.path.exists(curClass):\n        os.makedirs(curClass)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:13:01.536056Z","iopub.execute_input":"2025-05-07T15:13:01.536305Z","iopub.status.idle":"2025-05-07T15:13:01.564446Z","shell.execute_reply.started":"2025-05-07T15:13:01.536281Z","shell.execute_reply":"2025-05-07T15:13:01.563702Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.chdir('..')\ncount = 0\n\n# 設定可寫入的目標資料夾\ntrain_dir = '/kaggle/working/training_images/'\nval_dir = '/kaggle/working/validation_images/'\n\n# 建立主要資料夾 (如果不存在)\nos.makedirs(train_dir, exist_ok=True)\nos.makedirs(val_dir, exist_ok=True)\n\n# 複製圖片\nfor item in images:\n    # 選擇目標資料夾 (前8000張為訓練集，之後為驗證集)\n    destination_directory = train_dir if count <= 7999 else val_dir\n    \n    # 取得圖像對應的標籤\n    filekey = os.path.splitext(item)[0]\n    label = labels_dict[filekey]\n    \n    # 建立犬種資料夾 (如果不存在)\n    breed_dir = os.path.join(destination_directory, label)\n    os.makedirs(breed_dir, exist_ok=True)\n    \n    # 複製圖片\n    source_path = os.path.join('/kaggle/input/dog-breed-identification/train/', item)\n    destination_path = os.path.join(breed_dir, item)\n    if not os.path.exists(destination_path):\n        copyfile(source_path, destination_path)\n    \n    count += 1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:13:01.565354Z","iopub.execute_input":"2025-05-07T15:13:01.565625Z","iopub.status.idle":"2025-05-07T15:14:06.136491Z","shell.execute_reply.started":"2025-05-07T15:13:01.565603Z","shell.execute_reply":"2025-05-07T15:14:06.135768Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Displaying the original image of \"Afghan Hound\"","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.utils import load_img\n\nimg = load_img('/kaggle/working/training_images/afghan_hound/0d5a88f0ab2db8d34b533c69768135e8.jpg') \nimg","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:14:06.137347Z","iopub.execute_input":"2025-05-07T15:14:06.137908Z","iopub.status.idle":"2025-05-07T15:14:20.849436Z","shell.execute_reply.started":"2025-05-07T15:14:06.137881Z","shell.execute_reply":"2025-05-07T15:14:20.848655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img\n\npreview_dir = '/kaggle/working/preview_images/'\nos.makedirs(preview_dir, exist_ok=True)\n\ndatagen = ImageDataGenerator(\n        rotation_range=50,\n        width_shift_range=0.3,\n        height_shift_range=0.2,\n        shear_range=0.3,\n        zoom_range=0.3,\n        horizontal_flip=True,\n        fill_mode='nearest')\n\nimg = load_img('/kaggle/working/training_images/afghan_hound/0d5a88f0ab2db8d34b533c69768135e8.jpg') \nx = img_to_array(img)\nx = x.reshape((1,) + x.shape)\n\ni = 0\nfor batch in datagen.flow(x, batch_size=1,\n                          save_to_dir= preview_dir, save_prefix='dog_breed', save_format='jpeg'):\n    i += 1\n    if i > 20:\n        break  # otherwise the generator would loop indefinitely","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:14:20.85256Z","iopub.execute_input":"2025-05-07T15:14:20.853103Z","iopub.status.idle":"2025-05-07T15:14:21.771194Z","shell.execute_reply.started":"2025-05-07T15:14:20.85308Z","shell.execute_reply":"2025-05-07T15:14:21.770264Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Displaying the image after image augmentation for 3 trials for \"Afghan Hound\"","metadata":{}},{"cell_type":"code","source":"import os\nfrom tensorflow.keras.preprocessing.image import load_img\nimport matplotlib.pyplot as plt\n\n# 列出產生的圖片\ngenerated_files = [f for f in os.listdir(preview_dir) if f.endswith('.jpeg')]\n\n# 顯示第一張圖片\nif generated_files:\n    img_path = os.path.join(preview_dir, generated_files[0])\n    img = load_img(img_path)\n    plt.imshow(img)\n    plt.axis('off')\n    plt.title(generated_files[0])\n    plt.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:14:21.772176Z","iopub.execute_input":"2025-05-07T15:14:21.772507Z","iopub.status.idle":"2025-05-07T15:14:22.061631Z","shell.execute_reply.started":"2025-05-07T15:14:21.772482Z","shell.execute_reply":"2025-05-07T15:14:22.060765Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Implementing Convolution Neural Network ","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.layers import Convolution2D\nfrom keras.layers import MaxPooling2D\nfrom keras.layers import Flatten\nfrom keras.layers import Dense\nfrom keras.layers import Conv2D,Dropout\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:14:22.062546Z","iopub.execute_input":"2025-05-07T15:14:22.062843Z","iopub.status.idle":"2025-05-07T15:14:22.070975Z","shell.execute_reply.started":"2025-05-07T15:14:22.062817Z","shell.execute_reply":"2025-05-07T15:14:22.069971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n        rescale=1./255,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n#check class_mode in keras documentation https://keras.io/preprocessing/image/\ntraining_set = train_datagen.flow_from_directory(\n        '/kaggle/working/training_images',\n        target_size=(128, 128),\n        batch_size=20,\n        class_mode='categorical')\n\ntest_set = test_datagen.flow_from_directory(\n        '/kaggle/working/validation_images',\n        target_size=(128, 128),\n        batch_size=20,\n        class_mode='categorical')\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:14:22.071976Z","iopub.execute_input":"2025-05-07T15:14:22.07231Z","iopub.status.idle":"2025-05-07T15:14:22.282169Z","shell.execute_reply.started":"2025-05-07T15:14:22.072276Z","shell.execute_reply":"2025-05-07T15:14:22.281185Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from keras.layers import Dropout\nclf = Sequential()\n#Convolution\n#32 is number of kernals of 3x3, we can use 64 128 256 etc in next layers\n#input shape can be 128, 256 later\nclf.add(Conv2D(32,(3,3),input_shape=(128,128,3),activation='relu'))\n#Max Pooling size reduces divided by 2\nclf.add(MaxPooling2D(pool_size=(2,2)))      \n\n\n#clf.add(Dropout(0.5))\n\nclf.add(Conv2D(32,(3,3), activation='relu'))\nclf.add(MaxPooling2D(pool_size=(2,2)))\n#clf.add(Dropout(0.25))\n\nclf.add(Conv2D(64, (3, 3), activation='relu'))\nclf.add(MaxPooling2D(pool_size=(2, 2)))\n#clf.add(Dropout(0.10))\n#Flattening\nclf.add(Flatten())\n        \n#Adding An ANN\n#lets take 128 hidden nodes in hidden layer\n#clf.add(Dense(units=128,activation='relu'))\nclf.add(Dense(units=64, activation='relu'))\nclf.add(Dropout(0.5))\nclf.add(Dense(units=120,activation='softmax'))\n#stochastic gradient descent -Adam -optimizer\n#loss func categorical cross entropy\n#metrics = accuracy\nclf.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:14:22.282865Z","iopub.execute_input":"2025-05-07T15:14:22.283056Z","iopub.status.idle":"2025-05-07T15:14:25.454338Z","shell.execute_reply.started":"2025-05-07T15:14:22.283041Z","shell.execute_reply":"2025-05-07T15:14:25.453785Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping\nearly_stopping_monitor=EarlyStopping(patience=6)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:14:25.455316Z","iopub.execute_input":"2025-05-07T15:14:25.455535Z","iopub.status.idle":"2025-05-07T15:14:25.459607Z","shell.execute_reply.started":"2025-05-07T15:14:25.455518Z","shell.execute_reply":"2025-05-07T15:14:25.459053Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hist = clf.fit(\n    training_set,\n    epochs=50,\n    validation_data=test_set,\n    callbacks=[early_stopping_monitor]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:14:25.460231Z","iopub.execute_input":"2025-05-07T15:14:25.46043Z","iopub.status.idle":"2025-05-07T15:46:56.22092Z","shell.execute_reply.started":"2025-05-07T15:14:25.460395Z","shell.execute_reply":"2025-05-07T15:46:56.219924Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport pandas as pd\n\ntest_set = []\ntest_set_ids = []\ntest_dir = '/kaggle/input/dog-breed-identification/test/'  \n\nfor curImage in os.listdir(test_dir):\n    test_set_ids.append(os.path.splitext(curImage)[0])\n    curImage = cv2.imread(os.path.join(test_dir, curImage))\n    test_set.append(cv2.resize(curImage, (128, 128)))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:46:56.221971Z","iopub.execute_input":"2025-05-07T15:46:56.222357Z","iopub.status.idle":"2025-05-07T15:48:26.86764Z","shell.execute_reply.started":"2025-05-07T15:46:56.222326Z","shell.execute_reply":"2025-05-07T15:48:26.867022Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_set = np.array(test_set, np.float32)/255.0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:26.868285Z","iopub.execute_input":"2025-05-07T15:48:26.868497Z","iopub.status.idle":"2025-05-07T15:48:27.884628Z","shell.execute_reply.started":"2025-05-07T15:48:26.868481Z","shell.execute_reply":"2025-05-07T15:48:27.883436Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions= clf.predict(test_set)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:27.886163Z","iopub.execute_input":"2025-05-07T15:48:27.886846Z","iopub.status.idle":"2025-05-07T15:48:35.544845Z","shell.execute_reply.started":"2025-05-07T15:48:27.886817Z","shell.execute_reply":"2025-05-07T15:48:35.544051Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions[0].shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:35.54579Z","iopub.execute_input":"2025-05-07T15:48:35.546007Z","iopub.status.idle":"2025-05-07T15:48:35.551546Z","shell.execute_reply.started":"2025-05-07T15:48:35.545991Z","shell.execute_reply":"2025-05-07T15:48:35.550752Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_set.class_indices","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:35.55222Z","iopub.execute_input":"2025-05-07T15:48:35.552566Z","iopub.status.idle":"2025-05-07T15:48:35.567364Z","shell.execute_reply.started":"2025-05-07T15:48:35.552547Z","shell.execute_reply":"2025-05-07T15:48:35.56668Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"classes= {index:breed for breed,index in training_set.class_indices.items()}\ncolumn_names = [classes[i] for i in range(120)]\ncolumn_names","metadata":{"scrolled":true,"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:35.568053Z","iopub.execute_input":"2025-05-07T15:48:35.568284Z","iopub.status.idle":"2025-05-07T15:48:35.58356Z","shell.execute_reply.started":"2025-05-07T15:48:35.568263Z","shell.execute_reply":"2025-05-07T15:48:35.582982Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions_df = pd.DataFrame(predictions)\npredictions_df.columns = column_names\npredictions_df.insert(0,'id', test_set_ids)\n#predictions_df.index = test_set_ids\npredictions_df","metadata":{"scrolled":true,"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:35.584192Z","iopub.execute_input":"2025-05-07T15:48:35.584451Z","iopub.status.idle":"2025-05-07T15:48:35.63513Z","shell.execute_reply.started":"2025-05-07T15:48:35.584401Z","shell.execute_reply":"2025-05-07T15:48:35.634454Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions_df.to_csv('interim_submission.csv',sep=\",\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:35.635881Z","iopub.execute_input":"2025-05-07T15:48:35.636113Z","iopub.status.idle":"2025-05-07T15:48:36.925276Z","shell.execute_reply.started":"2025-05-07T15:48:35.636098Z","shell.execute_reply":"2025-05-07T15:48:36.924687Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Graph representation of validation loss vs  number of epochs","metadata":{}},{"cell_type":"code","source":"plt.plot(hist.history['val_loss'])\nplt.xlabel('epochs')\nplt.ylabel('validation loss')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:36.926039Z","iopub.execute_input":"2025-05-07T15:48:36.926265Z","iopub.status.idle":"2025-05-07T15:48:37.071746Z","shell.execute_reply.started":"2025-05-07T15:48:36.926248Z","shell.execute_reply":"2025-05-07T15:48:37.071047Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Graph representation of test accuracy","metadata":{}},{"cell_type":"code","source":"plt.plot(hist.history['accuracy'])\nplt.xlabel('epochs')\nplt.ylabel('accuracy')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:48:37.072475Z","iopub.execute_input":"2025-05-07T15:48:37.07268Z","iopub.status.idle":"2025-05-07T15:48:37.199079Z","shell.execute_reply.started":"2025-05-07T15:48:37.072664Z","shell.execute_reply":"2025-05-07T15:48:37.198447Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(hist.history['accuracy'],label=\"Accuracy\")\nplt.plot(hist.history['val_accuracy'], label=\"Validation accuracy\")\nplt.legend()\nplt.xlabel('epochs')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:52:00.37678Z","iopub.execute_input":"2025-05-07T15:52:00.377369Z","iopub.status.idle":"2025-05-07T15:52:00.517811Z","shell.execute_reply.started":"2025-05-07T15:52:00.377334Z","shell.execute_reply":"2025-05-07T15:52:00.517091Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(hist.history['loss'],label=\"traing loss\")\nplt.plot(hist.history['val_loss'], label=\"Validation loss\")\nplt.legend()\nplt.xlabel('epochs')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T15:52:04.065042Z","iopub.execute_input":"2025-05-07T15:52:04.065519Z","iopub.status.idle":"2025-05-07T15:52:04.230457Z","shell.execute_reply.started":"2025-05-07T15:52:04.065499Z","shell.execute_reply":"2025-05-07T15:52:04.229834Z"}},"outputs":[],"execution_count":null}]}