{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nfrom tensorflow import keras\nimport os, shutil, pathlib\nfrom tensorflow.keras.utils import image_dataset_from_directory\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:21:49.393711Z","iopub.execute_input":"2025-07-10T19:21:49.394267Z","iopub.status.idle":"2025-07-10T19:21:49.398662Z","shell.execute_reply.started":"2025-07-10T19:21:49.394240Z","shell.execute_reply":"2025-07-10T19:21:49.397781Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!unzip -qq /kaggle/input/dogs-vs-cats/train.zip","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:21:49.400594Z","iopub.execute_input":"2025-07-10T19:21:49.400852Z","iopub.status.idle":"2025-07-10T19:22:00.338141Z","shell.execute_reply.started":"2025-07-10T19:21:49.400833Z","shell.execute_reply":"2025-07-10T19:22:00.336946Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!unzip -qq /kaggle/input/dogs-vs-cats/test1.zip","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:00.340205Z","iopub.execute_input":"2025-07-10T19:22:00.340538Z","iopub.status.idle":"2025-07-10T19:22:05.619180Z","shell.execute_reply.started":"2025-07-10T19:22:00.340505Z","shell.execute_reply":"2025-07-10T19:22:05.618086Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"original_train_dir = pathlib.Path('/kaggle/working/train')  # Now a Path object\nnew_base_dir = pathlib.Path('cats_vs_dogs_train')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:05.620690Z","iopub.execute_input":"2025-07-10T19:22:05.621067Z","iopub.status.idle":"2025-07-10T19:22:05.626293Z","shell.execute_reply.started":"2025-07-10T19:22:05.621013Z","shell.execute_reply":"2025-07-10T19:22:05.625614Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def make_subset(subset_name, start_index, end_index):\n  for category in ('cat', 'dog'):\n    dir = new_base_dir / subset_name / category\n    os.makedirs(dir, exist_ok=True)\n    fnames = [f\"{category}.{i}.jpg\" for i in range(start_index, end_index)]\n    for fname in fnames:\n      shutil.copyfile(src=original_train_dir / fname,\n                      dst=dir / fname)\n      \nmake_subset('train', start_index=0, end_index=10000)\nmake_subset('validation', start_index=10000, end_index=12500)\n#make_subset('test', start_index=1500, end_index=2500)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:05.627857Z","iopub.execute_input":"2025-07-10T19:22:05.628080Z","iopub.status.idle":"2025-07-10T19:22:08.548682Z","shell.execute_reply.started":"2025-07-10T19:22:05.628064Z","shell.execute_reply":"2025-07-10T19:22:08.547770Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = image_dataset_from_directory(\n    new_base_dir / 'train',\n    image_size=(180, 180), \n    batch_size=32\n)\nvalidation_dataset = image_dataset_from_directory(\n    new_base_dir / 'validation',\n    image_size=(180, 180),\n    batch_size=32\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:08.549707Z","iopub.execute_input":"2025-07-10T19:22:08.549995Z","iopub.status.idle":"2025-07-10T19:22:14.095077Z","shell.execute_reply.started":"2025-07-10T19:22:08.549972Z","shell.execute_reply":"2025-07-10T19:22:14.094344Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing import image_dataset_from_directory\n\ntest_dir = \"/kaggle/working/test1\"  # Path to your test folder\nimg_size = (180, 180)  # Should match your model's expected input shape\nbatch_size = 32\n\n# Load test dataset (unlabeled)\ntest_dataset = image_dataset_from_directory(\n    directory=test_dir,\n    labels=None,            # No labels available\n    image_size=img_size,    # Resize to model's expected input\n    batch_size=batch_size,\n    shuffle=False,          # Keep original order for submission\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:54:16.530064Z","iopub.execute_input":"2025-07-10T19:54:16.530746Z","iopub.status.idle":"2025-07-10T19:54:16.794270Z","shell.execute_reply.started":"2025-07-10T19:54:16.530724Z","shell.execute_reply":"2025-07-10T19:54:16.793747Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for data_batch, labels_batch in train_dataset:\n  print(data_batch.shape)\n  print(labels_batch.shape)\n  break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:14.398251Z","iopub.execute_input":"2025-07-10T19:22:14.398582Z","iopub.status.idle":"2025-07-10T19:22:14.577853Z","shell.execute_reply.started":"2025-07-10T19:22:14.398553Z","shell.execute_reply":"2025-07-10T19:22:14.576957Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:14.578842Z","iopub.execute_input":"2025-07-10T19:22:14.579189Z","iopub.status.idle":"2025-07-10T19:22:14.583158Z","shell.execute_reply.started":"2025-07-10T19:22:14.579167Z","shell.execute_reply":"2025-07-10T19:22:14.582503Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"conv_base = keras.applications.vgg16.VGG16(\n    weights='imagenet',\n    include_top=False\n)\nconv_base.trainable = False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:14.583926Z","iopub.execute_input":"2025-07-10T19:22:14.584237Z","iopub.status.idle":"2025-07-10T19:22:16.190465Z","shell.execute_reply.started":"2025-07-10T19:22:14.584210Z","shell.execute_reply":"2025-07-10T19:22:16.189835Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_augmentation = keras.Sequential(\n    [\n layers.RandomFlip(\"horizontal\"),\n layers.RandomRotation(0.1),\n layers.RandomZoom(0.2),\n    ]\n )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:16.192658Z","iopub.execute_input":"2025-07-10T19:22:16.192869Z","iopub.status.idle":"2025-07-10T19:22:16.208027Z","shell.execute_reply.started":"2025-07-10T19:22:16.192852Z","shell.execute_reply":"2025-07-10T19:22:16.207285Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inputs = keras.Input(shape=(180, 180, 3))\nx = data_augmentation(inputs)\nx = keras.applications.vgg16.preprocess_input(x)\nx = conv_base(x)\nx = layers.Flatten()(x)\nx = layers.Dense(256)(x)\nx = layers.Dropout(0.5)(x)\noutputs = layers.Dense(1, activation='sigmoid')(x)\nmodel = keras.Model(inputs, outputs)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:16.208873Z","iopub.execute_input":"2025-07-10T19:22:16.209181Z","iopub.status.idle":"2025-07-10T19:22:16.259724Z","shell.execute_reply.started":"2025-07-10T19:22:16.209154Z","shell.execute_reply":"2025-07-10T19:22:16.259100Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"conv_base.trainable = True\nfor layer in conv_base.layers[:-4]:\n  layer.trainable = False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:16.260491Z","iopub.execute_input":"2025-07-10T19:22:16.260737Z","iopub.status.idle":"2025-07-10T19:22:16.265350Z","shell.execute_reply.started":"2025-07-10T19:22:16.260709Z","shell.execute_reply":"2025-07-10T19:22:16.264589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(loss='binary_crossentropy',\n              optimizer=keras.optimizers.RMSprop(learning_rate=1e-5),\n              metrics=['accuracy'])\ncallbacks = [\n    keras.callbacks.ModelCheckpoint(\n    filepath=\"fine_tuning.keras\",\n    save_best_only=True,\n    monitor=\"val_loss\")\n ]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:16.266250Z","iopub.execute_input":"2025-07-10T19:22:16.266488Z","iopub.status.idle":"2025-07-10T19:22:16.294846Z","shell.execute_reply.started":"2025-07-10T19:22:16.266471Z","shell.execute_reply":"2025-07-10T19:22:16.293979Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.fit(\n    train_dataset,\n    epochs=10,\n    validation_data=validation_dataset,\n    callbacks=callbacks\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:22:16.295615Z","iopub.execute_input":"2025-07-10T19:22:16.295908Z","iopub.status.idle":"2025-07-10T19:38:48.151224Z","shell.execute_reply.started":"2025-07-10T19:22:16.295881Z","shell.execute_reply":"2025-07-10T19:38:48.150567Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\ntest_dir = \"/kaggle/working/test1\"  # Adjust if different\n\n\ntest_filenames = os.listdir(test_dir)\n\ntest_df = pd.DataFrame({\n    'filename': test_filenames\n})","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:53:39.573124Z","iopub.execute_input":"2025-07-10T19:53:39.573705Z","iopub.status.idle":"2025-07-10T19:53:39.593604Z","shell.execute_reply.started":"2025-07-10T19:53:39.573681Z","shell.execute_reply":"2025-07-10T19:53:39.593025Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions = model.predict(test_dataset)\ntest_df['label'] = (predictions > 0.5).astype(int).ravel()\ntest_df['id'] = test_df['filename'].str.extract('(\\d+)').astype(int)\n\n# Create submission\nsubmission_df = test_df[['id', 'label']]\nsubmission_df.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:55:01.641015Z","iopub.execute_input":"2025-07-10T19:55:01.641570Z","iopub.status.idle":"2025-07-10T19:55:38.387846Z","shell.execute_reply.started":"2025-07-10T19:55:01.641538Z","shell.execute_reply":"2025-07-10T19:55:38.387039Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save('cats_vs_dogs_model.h5')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:58:05.328547Z","iopub.execute_input":"2025-07-10T19:58:05.329186Z","iopub.status.idle":"2025-07-10T19:58:05.536187Z","shell.execute_reply.started":"2025-07-10T19:58:05.329161Z","shell.execute_reply":"2025-07-10T19:58:05.535372Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save_weights('model_weights.weights.h5')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-10T19:58:54.451748Z","iopub.execute_input":"2025-07-10T19:58:54.452683Z","iopub.status.idle":"2025-07-10T19:58:54.668146Z","shell.execute_reply.started":"2025-07-10T19:58:54.452648Z","shell.execute_reply":"2025-07-10T19:58:54.667555Z"}},"outputs":[],"execution_count":null}]}