{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":7327,"databundleVersionId":861871,"isSourceIdPinned":false}],"dockerImageVersionId":31329,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Dog Breed Identification","metadata":{}},{"cell_type":"markdown","source":"<img src=\"https://cdn.karaca.com/cms/koepek_cinsleri_186422067b.webp\" width=\"1000\">","metadata":{}},{"cell_type":"markdown","source":"## Project Objective and Goals","metadata":{}},{"cell_type":"markdown","source":"The objective of this project is to develop a robust Deep Learning model capable of identifying 120 different breeds of dogs from unstructured image data. Utilizing the \"Dog Breed Identification\" dataset provided by Kaggle, the study focuses on solving a fine-grained image classification problem where inter-class variance is often subtle. The technical approach involves leveraging state-of-the-art Convolutional Neural Network (CNN) architectures through Transfer Learning. By employing pre-trained models such as ResNet, Inception, or EfficientNet, the project aims to optimize feature extraction layers to recognize intricate physiological patterns in various breeds. The final implementation includes comprehensive data augmentation, hyperparameter tuning, and a Softmax-based classification head to output probability distributions across 120 categories, evaluated primarily via Multi-Class Log Loss.","metadata":{}},{"cell_type":"markdown","source":"## Importing Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom PIL import Image\nimport cv2\nfrom sklearn.model_selection import train_test_split\nimport tensorflow as tf\nfrom tensorflow.keras.applications.efficientnet import preprocess_input\nfrom tensorflow.keras.models import Sequential, Model\nfrom tensorflow.keras.layers import (Dense, Flatten, Dropout, BatchNormalization, GlobalAveragePooling2D, Input)\nfrom tensorflow.keras import layers, models, optimizers\nfrom tensorflow.keras.applications import EfficientNetB0\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping\nfrom sklearn.metrics import classification_report, confusion_matrix, accuracy_score","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:00:43.332744Z","iopub.execute_input":"2026-04-18T17:00:43.333040Z","iopub.status.idle":"2026-04-18T17:00:43.345647Z","shell.execute_reply.started":"2026-04-18T17:00:43.333016Z","shell.execute_reply":"2026-04-18T17:00:43.344665Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Reading Dataset","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/competitions/dog-breed-identification/labels.csv\")\ndf['id'] = df['id'] + '.jpg'\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T16:59:46.147003Z","iopub.execute_input":"2026-04-18T16:59:46.147764Z","iopub.status.idle":"2026-04-18T16:59:46.172136Z","shell.execute_reply.started":"2026-04-18T16:59:46.147731Z","shell.execute_reply":"2026-04-18T16:59:46.171196Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"path = '/kaggle/input/competitions/dog-breed-identification' \nprint(os.listdir(path))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T16:59:47.919529Z","iopub.execute_input":"2026-04-18T16:59:47.920242Z","iopub.status.idle":"2026-04-18T16:59:47.924687Z","shell.execute_reply.started":"2026-04-18T16:59:47.920212Z","shell.execute_reply":"2026-04-18T16:59:47.923885Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df['id'] = path + '/train/' + df['id']\ndf['breed'] = df['breed'].astype(str)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T16:59:49.571270Z","iopub.execute_input":"2026-04-18T16:59:49.572118Z","iopub.status.idle":"2026-04-18T16:59:49.578809Z","shell.execute_reply.started":"2026-04-18T16:59:49.572083Z","shell.execute_reply":"2026-04-18T16:59:49.578111Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df['id'][0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T16:59:51.538489Z","iopub.execute_input":"2026-04-18T16:59:51.539433Z","iopub.status.idle":"2026-04-18T16:59:51.544757Z","shell.execute_reply.started":"2026-04-18T16:59:51.539398Z","shell.execute_reply":"2026-04-18T16:59:51.544013Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## EDA","metadata":{}},{"cell_type":"code","source":"df['breed'].nunique()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T16:59:53.227039Z","iopub.execute_input":"2026-04-18T16:59:53.227946Z","iopub.status.idle":"2026-04-18T16:59:53.234432Z","shell.execute_reply.started":"2026-04-18T16:59:53.227906Z","shell.execute_reply":"2026-04-18T16:59:53.233670Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df['breed'].value_counts().head(20)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T16:59:54.682421Z","iopub.execute_input":"2026-04-18T16:59:54.683211Z","iopub.status.idle":"2026-04-18T16:59:54.691209Z","shell.execute_reply.started":"2026-04-18T16:59:54.683178Z","shell.execute_reply":"2026-04-18T16:59:54.690448Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"top_20_breeds = df['breed'].value_counts().head(20).index\nplt.figure(figsize=(10, 8))\nsns.countplot(data=df[df['breed'].isin(top_20_breeds)],y='breed',palette='viridis',order=top_20_breeds).set_title('Top 20 Dog Breeds by Number of Images');","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T16:59:56.762654Z","iopub.execute_input":"2026-04-18T16:59:56.763089Z","iopub.status.idle":"2026-04-18T16:59:57.153044Z","shell.execute_reply.started":"2026-04-18T16:59:56.763059Z","shell.execute_reply":"2026-04-18T16:59:57.152382Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"top_10 = df['breed'].value_counts().head(10).index\nplt.figure(figsize=(20, 8))\nfor i, name in enumerate(top_10):\n    img_path = df[df['breed'] == name].sample(1).id.values[0]\n    plt.subplot(2, 5, i + 1)\n    plt.imshow(plt.imread(img_path))\n    plt.title(name.replace('_', ' ').title())\n    plt.axis('off');","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:00:04.135409Z","iopub.execute_input":"2026-04-18T17:00:04.136020Z","iopub.status.idle":"2026-04-18T17:00:05.478061Z","shell.execute_reply.started":"2026-04-18T17:00:04.135971Z","shell.execute_reply":"2026-04-18T17:00:05.477112Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Data Processing","metadata":{}},{"cell_type":"code","source":"train_df, val_df = train_test_split(df,test_size=0.15, random_state=42, stratify=df['breed'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:00:07.214978Z","iopub.execute_input":"2026-04-18T17:00:07.215656Z","iopub.status.idle":"2026-04-18T17:00:07.234322Z","shell.execute_reply.started":"2026-04-18T17:00:07.215623Z","shell.execute_reply":"2026-04-18T17:00:07.233380Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    preprocessing_function=preprocess_input, \n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    horizontal_flip=True,\n    zoom_range=0.2\n)\n\nval_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)\n\n# Gen'leri tekrar tanımla\ntrain_gen = train_datagen.flow_from_dataframe(train_df, x_col='id', y_col='breed', target_size=(224, 224), batch_size=32, class_mode='categorical')\nval_gen = val_datagen.flow_from_dataframe(val_df, x_col='id', y_col='breed', target_size=(224, 224), batch_size=32, class_mode='categorical')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:01:53.178517Z","iopub.execute_input":"2026-04-18T17:01:53.178842Z","iopub.status.idle":"2026-04-18T17:01:56.246536Z","shell.execute_reply.started":"2026-04-18T17:01:53.178808Z","shell.execute_reply":"2026-04-18T17:01:56.245522Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## EfficientNetB0","metadata":{}},{"cell_type":"code","source":"base_model = EfficientNetB0(weights='imagenet', include_top=False, input_shape=(224, 224, 3))\nbase_model.trainable = False \n\ninputs = tf.keras.Input(shape=(224, 224, 3))\n\nx = base_model(inputs, training=False)\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.BatchNormalization()(x) \nx = layers.Dense(512, activation='relu')(x)\nx = layers.Dropout(0.4)(x) \nx = layers.BatchNormalization()(x)\nx = layers.Dense(256, activation='relu')(x) \nx = layers.Dropout(0.3)(x)\n\noutputs = layers.Dense(120, activation='softmax')(x)\n\nmodel = models.Model(inputs, outputs)\n\nmodel.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),loss='categorical_crossentropy',metrics=['accuracy', tf.keras.metrics.AUC(name='auc')])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:02:10.982787Z","iopub.execute_input":"2026-04-18T17:02:10.983353Z","iopub.status.idle":"2026-04-18T17:02:11.988363Z","shell.execute_reply.started":"2026-04-18T17:02:10.983318Z","shell.execute_reply":"2026-04-18T17:02:11.987446Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:02:13.398590Z","iopub.execute_input":"2026-04-18T17:02:13.399112Z","iopub.status.idle":"2026-04-18T17:02:13.425133Z","shell.execute_reply.started":"2026-04-18T17:02:13.399071Z","shell.execute_reply":"2026-04-18T17:02:13.424521Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"early_stop = EarlyStopping(monitor='val_accuracy', patience=5, restore_best_weights=True,verbose=1)\ncheckpoint = ModelCheckpoint('best_dog_model.keras',monitor='val_accuracy', save_best_only=True,verbose=1)\nreduce_lr = ReduceLROnPlateau(monitor='val_loss',factor=0.2,patience=3, min_lr=1e-6,verbose=1)\ncallbacks_list = [early_stop, checkpoint, reduce_lr]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:02:16.317323Z","iopub.execute_input":"2026-04-18T17:02:16.317936Z","iopub.status.idle":"2026-04-18T17:02:16.324698Z","shell.execute_reply.started":"2026-04-18T17:02:16.317888Z","shell.execute_reply":"2026-04-18T17:02:16.323674Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(train_gen,epochs=10,validation_data=val_gen,callbacks=callbacks_list,verbose=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:02:18.653640Z","iopub.execute_input":"2026-04-18T17:02:18.653947Z","iopub.status.idle":"2026-04-18T17:22:34.215769Z","shell.execute_reply.started":"2026-04-18T17:02:18.653922Z","shell.execute_reply":"2026-04-18T17:22:34.215070Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_model.trainable = True                                        \nfor layer in base_model.layers[:-20]:\n    layer.trainable = False\n    \nmodel.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5), loss='categorical_crossentropy',metrics=['accuracy', tf.keras.metrics.AUC(name='auc')])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:22:36.900102Z","iopub.execute_input":"2026-04-18T17:22:36.900804Z","iopub.status.idle":"2026-04-18T17:22:36.931987Z","shell.execute_reply.started":"2026-04-18T17:22:36.900773Z","shell.execute_reply":"2026-04-18T17:22:36.931354Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history_fine = model.fit(train_gen,epochs=10, validation_data=val_gen,callbacks=callbacks_list,verbose=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:37:31.227137Z","iopub.execute_input":"2026-04-18T17:37:31.227821Z","iopub.status.idle":"2026-04-18T17:56:17.627498Z","shell.execute_reply.started":"2026-04-18T17:37:31.227784Z","shell.execute_reply":"2026-04-18T17:56:17.626526Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save('best_dog_model.keras')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:56:59.645377Z","iopub.execute_input":"2026-04-18T17:56:59.645832Z","iopub.status.idle":"2026-04-18T17:57:00.341264Z","shell.execute_reply.started":"2026-04-18T17:56:59.645797Z","shell.execute_reply":"2026-04-18T17:57:00.340352Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\nplt.plot(history.history['accuracy'], label='Train Accuracy', marker='o')\nplt.plot(history.history['val_accuracy'], label='Val Accuracy', marker='x')\nplt.title('Training and Validation Accuracy')\nplt.grid(True, alpha=0.3);","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T17:57:20.428296Z","iopub.execute_input":"2026-04-18T17:57:20.428740Z","iopub.status.idle":"2026-04-18T17:57:20.588948Z","shell.execute_reply.started":"2026-04-18T17:57:20.428711Z","shell.execute_reply":"2026-04-18T17:57:20.588098Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"As shown in the \"Training and Validation Accuracy\" graph, the model demonstrated a steady and healthy learning curve. The validation accuracy (orange line) consistently remained at a high level, reaching a peak of 82.66%. The convergence of the training (blue) and validation lines indicates that the EfficientNetB0 architecture successfully generalized the features of 120 different breeds without overfitting. This stability is the most critical indicator of the model's reliability for real-world deployment.","metadata":{}},{"cell_type":"markdown","source":"## Testing and Visual Results","metadata":{}},{"cell_type":"code","source":"x_batch, y_batch = next(val_gen)\npred_labels = np.argmax(model.predict(x_batch), axis=1)\ntrue_labels = np.argmax(y_batch, axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T18:06:30.288846Z","iopub.execute_input":"2026-04-18T18:06:30.289524Z","iopub.status.idle":"2026-04-18T18:06:30.535820Z","shell.execute_reply.started":"2026-04-18T18:06:30.289493Z","shell.execute_reply":"2026-04-18T18:06:30.535014Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10, 8))\nlabels = list(train_gen.class_indices.keys())\n\nfor i in range(8):\n    plt.subplot(2, 4, i + 1)\n    plt.imshow((x_batch[i] - x_batch[i].min()) / (x_batch[i].max() - x_batch[i].min()))\n    color = 'green' if pred_labels[i] == true_labels[i] else 'red'\n    plt.title(f\"G: {labels[true_labels[i]]}\\nT: {labels[pred_labels[i]]}\", color=color, fontsize=10)\n    plt.axis('off')\nplt.tight_layout();","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T18:06:31.989967Z","iopub.execute_input":"2026-04-18T18:06:31.990261Z","iopub.status.idle":"2026-04-18T18:06:32.644819Z","shell.execute_reply.started":"2026-04-18T18:06:31.990238Z","shell.execute_reply":"2026-04-18T18:06:32.643709Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Final Evaluation","metadata":{}},{"cell_type":"markdown","source":"The final model was rigorously evaluated using a randomized testing batch to ensure its reliability across 120 distinct dog breeds. Based on the experimental results and the accuracy curves provided above, the fine-tuned model achieved a significant validation accuracy of 82.66%, demonstrating high discriminative power. The visual analysis confirms that the model accurately captures complex morphological features such as ear shape, coat texture, and facial structure. While the model shows near-perfect precision in most classes (indicated in green), minor misclassifications (indicated in red) only occur between visually similar breeds, which is expected given the high number of categories. The consistent upward trend in the accuracy graph proves that the training process reached an optimal convergence, making the SmartPaw Identifier a robust and high-performance solution for automated breed recognition tasks.","metadata":{}}]}