{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":90860,"databundleVersionId":10652987,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport torch\nfrom transformers import CLIPProcessor, CLIPModel\nfrom PIL import Image\nimport pandas as pd\nimport csv\nfrom IPython.display import HTML, display","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_name = \"openai/clip-vit-large-patch14\"\nmodel = CLIPModel.from_pretrained(model_name).to(device)\nprocessor = CLIPProcessor.from_pretrained(model_name)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Function to load animal classes from a file\ndef load_animal_classes(file_path):\n    animal_classes = []\n    with open(file_path, 'r') as file:\n        for line in file:\n            parts = line.strip().split()\n            animal_name = ' '.join(parts[1:])  # Handle multi-word class names\n            animal_classes.append(animal_name)\n    return animal_classes","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# cell for genrating text prompt from multiple templates \ndef generate_text_prompts(animal_classes):\n    templates = [\n        \"A photo of a {}.\",\n        \"A realistic photo of a {}.\",\n        \"An image of a {} in the wild.\",\n        \"A {} in its natural habitat.\",\n        \"A close-up of a {}.\"\n    ]\n    text_prompts = [template.format(animal) for animal in animal_classes for template in templates]\n    return text_prompts","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Function to normalize embeddings\ndef normalize_embeddings(embeddings):\n    return embeddings / embeddings.norm(dim=-1, keepdim=True)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Function to classify test images\ndef classify_images(test_image_dir, animal_classes, text_embeddings):\n    test_images = [\n        os.path.join(test_image_dir, f)\n        for f in os.listdir(test_image_dir)\n        if f.endswith(\".jpg\")\n    ]\n    print(f\"Found {len(test_images)} images for classification.\")\n    results = []\n\n    for img_path in test_images:\n        image = Image.open(img_path).convert(\"RGB\")\n        with torch.no_grad():\n            # these lines preprocess the images which clip does according to it and then does image encoding\n            image_inputs = processor(images=image, return_tensors=\"pt\").to(device)\n            image_embeddings = model.get_image_features(**image_inputs)\n            image_embeddings = normalize_embeddings(image_embeddings)\n\n            # these lines calculate similiarity scores \n            similarity_scores = image_embeddings @ text_embeddings.T\n            best_match_idx = similarity_scores.argmax(dim=-1).item()\n            predicted_class = animal_classes[best_match_idx]\n            results.append({\"Image Path\": img_path, \"Predicted Class\": predicted_class})\n\n            print(f\"Image: {os.path.basename(img_path)}, Predicted Class: {predicted_class}\")\n    return results","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# this cell saves result to csv file \ndef save_results_to_csv(results, output_file):\n    with open(output_file, mode='w', newline='') as file:\n        writer = csv.writer(file)\n        writer.writerow(['Image Path', 'Predicted Class'])\n        for result in results:\n            writer.writerow([result['Image Path'], result['Predicted Class']])\n    print(f\"Classification results saved to {output_file}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# this cell deals with sorting the csv file \ndef sort_csv(input_file, output_file):\n    df = pd.read_csv(input_file)\n    df_sorted = df.sort_values(by='Image Path')\n    df_sorted.to_csv(output_file, index=False)\n    print(f\"Sorted CSV file saved to {output_file}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Main function\nif __name__ == '__main__':\n     classes_file_path = \"/kaggle/input/vlg-recruitment-24-challenge/vlg-dataset/vlg-dataset/classes.txt\"\n    test_image_dir = \"/kaggle/input/vlg-recruitment-24-challenge/vlg-dataset/vlg-dataset/test\"\n    output_csv_file = 'predictions.csv'\n    sorted_csv_file = 'sorted_predictions.csv'\n\n    \n    animal_classes = load_animal_classes(classes_file_path)\n    print(f\"Loaded {len(animal_classes)} animal classes.\")\n\n    # using function to generate text prompt and therefore gets text embeddings\n    text_prompts = generate_text_prompts(animal_classes)\n    with torch.no_grad():\n        text_inputs = processor(text=text_prompts, return_tensors=\"pt\", padding=True).to(device)\n        text_embeddings = model.get_text_features(**text_inputs)\n        text_embeddings = normalize_embeddings(text_embeddings)\n\n        # aggregating embeddings\n        num_templates = len(text_prompts) // len(animal_classes)\n        aggregated_embeddings = text_embeddings.view(len(animal_classes), num_templates, -1).mean(dim=1)\n        aggregated_embeddings = normalize_embeddings(aggregated_embeddings)\n        \n    results = classify_images(test_image_dir, animal_classes, aggregated_embeddings)\n\n    save_results_to_csv(results, output_csv_file)\n    sort_csv(output_csv_file, sorted_csv_file)\n\n    print(f\"Classification completed. Results saved to {sorted_csv_file}.\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# this cell creates downloading link for the csv file \nfile_path = sorted_csv_file\ndownload_link = f'<a href=\"{file_path}\" download>Download sorted_predictions.csv</a>'\ndisplay(HTML(download_link))","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}