{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":25954,"databundleVersionId":2091745,"sourceType":"competition"},{"sourceId":277115,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":237325,"modelId":259010},{"sourceId":277138,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":237347,"modelId":259031}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport glob\n\n# Base path to the dataset\ndataset_path = '/kaggle/input/birdclef-2021'\n\n# Verify the directory structure\nprint(\"Listing all audio files...\")\naudio_files = glob.glob(os.path.join(dataset_path, '**', '*.ogg'), recursive=True)\n\nprint(f\"Total audio files found: {len(audio_files)}\")\nprint(f\"Example file: {audio_files[0] if audio_files else 'No files found'}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:31:52.559174Z","iopub.execute_input":"2025-03-06T11:31:52.559461Z","iopub.status.idle":"2025-03-06T11:33:35.462481Z","shell.execute_reply.started":"2025-03-06T11:31:52.55943Z","shell.execute_reply":"2025-03-06T11:33:35.461414Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Install required libraries\n!pip install librosa\n\n# Import libraries\nimport os\nimport glob\nimport librosa\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport warnings\nwarnings.filterwarnings('ignore')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:33:35.464012Z","iopub.execute_input":"2025-03-06T11:33:35.464287Z","iopub.status.idle":"2025-03-06T11:34:02.051533Z","shell.execute_reply.started":"2025-03-06T11:33:35.46426Z","shell.execute_reply":"2025-03-06T11:34:02.050545Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def audio_to_melspectrogram(file_path, n_mels=128):\n    try:\n        y, sr = librosa.load(file_path, sr=None)  # Load audio file\n        mel_spec = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=n_mels)\n        mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max)  # Convert to decibels\n        return mel_spec_db\n    except Exception as e:\n        print(f\"Error processing {file_path}: {e}\")\n        return None","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:34:02.053753Z","iopub.execute_input":"2025-03-06T11:34:02.054338Z","iopub.status.idle":"2025-03-06T11:34:02.061029Z","shell.execute_reply.started":"2025-03-06T11:34:02.054304Z","shell.execute_reply":"2025-03-06T11:34:02.059565Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prepare spectrograms and labels\nX, y = [], []\nlabel_map = {}  # To map bird names to numeric labels\n\n# Iterate through audio files\nfor idx, file_path in enumerate(audio_files[:100]):  # Limit to first 100 files for simplicity\n    # Extract bird label (modify this based on dataset folder structure)\n    bird_name = os.path.basename(os.path.dirname(file_path))\n    if bird_name not in label_map:\n        label_map[bird_name] = len(label_map)  # Assign new label\n\n    # Convert audio to spectrogram\n    mel_spec = audio_to_melspectrogram(file_path)\n    if mel_spec is not None:\n        X.append(mel_spec)\n        y.append(label_map[bird_name])\n\nprint(f\"Total spectrograms created: {len(X)}\")\nprint(f\"Unique labels: {label_map}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:34:02.062801Z","iopub.execute_input":"2025-03-06T11:34:02.06329Z","iopub.status.idle":"2025-03-06T11:35:19.437639Z","shell.execute_reply.started":"2025-03-06T11:34:02.06324Z","shell.execute_reply":"2025-03-06T11:35:19.434695Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import img_to_array\n\n# Resize spectrograms to fixed size (128x128)\nimport cv2\nX_resized = [cv2.resize(x, (128, 128)) for x in X]\n\n# Convert to NumPy arrays and expand dimensions\nX_resized = np.array([img_to_array(x) for x in X_resized])  # Shape: (num_samples, 128, 128, 1)\ny_resized = np.array(y)\n\n# Normalize the data\nX_resized = X_resized / 255.0\n\n# One-hot encode labels\ny_categorical = to_categorical(y_resized)\n\n# Split into train and test sets\nX_train, X_test, y_train, y_test = train_test_split(X_resized, y_categorical, test_size=0.2, random_state=42)\n\nprint(f\"Train set size: {X_train.shape}, Test set size: {X_test.shape}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:35:19.439387Z","iopub.execute_input":"2025-03-06T11:35:19.440516Z","iopub.status.idle":"2025-03-06T11:35:19.749997Z","shell.execute_reply.started":"2025-03-06T11:35:19.440442Z","shell.execute_reply":"2025-03-06T11:35:19.748755Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = Sequential([\n    Conv2D(32, (3, 3), activation='relu', input_shape=(128, 128, 1)),\n    MaxPooling2D((2, 2)),\n    \n    Conv2D(64, (3, 3), activation='relu'),\n    MaxPooling2D((2, 2)),\n    \n    Conv2D(128, (3, 3), activation='relu'),\n    MaxPooling2D((2, 2)),\n\n    Flatten(),\n    Dense(128, activation='relu'),\n    Dropout(0.3),\n    Dense(len(label_map), activation='softmax')  # Output layer\n])\n\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:35:19.751322Z","iopub.execute_input":"2025-03-06T11:35:19.751785Z","iopub.status.idle":"2025-03-06T11:35:19.917446Z","shell.execute_reply.started":"2025-03-06T11:35:19.751711Z","shell.execute_reply":"2025-03-06T11:35:19.916254Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Train the model\nearly_stop = EarlyStopping(monitor='val_loss', patience=3)\n\nhistory = model.fit(\n    X_train, y_train,\n    validation_data=(X_test, y_test),\n    epochs=20,\n    batch_size=32,\n    callbacks=[early_stop]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:35:19.918574Z","iopub.execute_input":"2025-03-06T11:35:19.918909Z","iopub.status.idle":"2025-03-06T11:35:30.49379Z","shell.execute_reply.started":"2025-03-06T11:35:19.918877Z","shell.execute_reply":"2025-03-06T11:35:30.492527Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\n\n# Check Model Accuracy\nloss, accuracy = model.evaluate(X_test, y_test)\nprint(f\"Test Accuracy: {accuracy * 100:.2f}%\")\n\n# Pick a random test sample\nimport random\nidx = random.randint(0, len(X_test) - 1)\nsample = X_test[idx:idx+1]\n\n# Visualize the spectrogram of the chosen sample\nplt.imshow(sample[0].reshape(128, 128), cmap='gray')\nplt.title(\"Test Spectrogram (Random Sample)\")\nplt.axis('off')\nplt.show()\n\n# Make prediction\nprediction = model.predict(sample)\npredicted_label = list(label_map.keys())[np.argmax(prediction)]\ntrue_label = list(label_map.keys())[np.argmax(y_test[idx])]\n\n# Print detailed prediction results\nprint(f\"True Label: {true_label}\")\nprint(f\"Predicted Label: {predicted_label}\")\nprint(f\"Prediction Probabilities: {prediction}\")\n\n# Check for label consistency\nprint(f\"Label Map: {label_map}\")\n\n# Visualize training loss and accuracy curves\nif 'history' in globals():\n    plt.figure(figsize=(12, 5))\n    plt.subplot(1, 2, 1)\n    plt.plot(history.history['loss'], label='Train Loss')\n    plt.plot(history.history['val_loss'], label='Validation Loss')\n    plt.legend()\n    plt.title('Loss Curve')\n\n    plt.subplot(1, 2, 2)\n    plt.plot(history.history['accuracy'], label='Train Accuracy')\n    plt.plot(history.history['val_accuracy'], label='Validation Accuracy')\n    plt.legend()\n    plt.title('Accuracy Curve')\n    plt.show()\nelse:\n    print(\"Training history not found. Make sure your 'model.fit' call is stored in a 'history' variable.\")\n\n# Check data leakage or incorrect splitting\nunique_train_labels = np.unique(np.argmax(y_train, axis=1))\nunique_test_labels = np.unique(np.argmax(y_test, axis=1))\n\nprint(f\"Unique labels in train set: {unique_train_labels}\")\nprint(f\"Unique labels in test set: {unique_test_labels}\")\n\n# Check for class imbalance\nclass_counts = np.sum(y_train, axis=0)\nprint(f\"Class distribution in training data: {class_counts}\")\n\n# Let me know what you find after running this! We can refine the model based on the outputs. 🚀\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport random\n\n# Check Model Accuracy\nloss, accuracy = model.evaluate(X_test, y_test)\nprint(f\"Test Accuracy: {accuracy * 100:.2f}%\")\n\n# Pick a random test sample\nidx = random.randint(0, len(X_test) - 1)\nsample = X_test[idx:idx + 1]\n\n# Visualize the spectrogram of the chosen sample\nplt.imshow(sample[0].reshape(128, 128), cmap='gray')\nplt.title(\"Test Spectrogram (Random Sample)\")\nplt.axis('off')\nplt.show()\n\n# Make prediction\nprediction = model.predict(sample)\npredicted_label = list(label_map.keys())[np.argmax(prediction)]\ntrue_label = list(label_map.keys())[np.argmax(y_test[idx])]\n\n# Print detailed prediction results\nprint(f\"True Label: {true_label}\")\nprint(f\"Predicted Label: {predicted_label}\")\nprint(f\"Prediction Probabilities: {prediction}\")\n\n# Check for label consistency\nprint(f\"Label Map: {label_map}\")\n\n# Visualize training loss and accuracy curves\nif 'history' in globals():\n    plt.figure(figsize=(12, 5))\n    plt.subplot(1, 2, 1)\n    plt.plot(history.history['loss'], label='Train Loss')\n    plt.plot(history.history['val_loss'], label='Validation Loss')\n    plt.legend()\n    plt.title('Loss Curve')\n\n    plt.subplot(1, 2, 2)\n    plt.plot(history.history['accuracy'], label='Train Accuracy')\n    plt.plot(history.history['val_accuracy'], label='Validation Accuracy')\n    plt.legend()\n    plt.title('Accuracy Curve')\n    plt.show()\nelse:\n    print(\"Training history not found. Make sure your 'model.fit' call is stored in a 'history' variable.\")\n\n# Check data leakage or incorrect splitting\nunique_train_labels = np.unique(np.argmax(y_train, axis=1))\nunique_test_labels = np.unique(np.argmax(y_test, axis=1))\n\nprint(f\"Unique labels in train set: {unique_train_labels}\")\nprint(f\"Unique labels in test set: {unique_test_labels}\")\n\n# Check for class imbalance\nclass_counts = np.sum(y_train, axis=0)\nprint(f\"Class distribution in training data: {class_counts}\")\n\n# Optionally, manually test a specific known sample\nknown_idx = 5  # Change as needed\nsample_known = X_test[known_idx:known_idx + 1]\n\nprediction_known = model.predict(sample_known)\npredicted_label_known = list(label_map.keys())[np.argmax(prediction_known)]\ntrue_label_known = list(label_map.keys())[np.argmax(y_test[known_idx])]\n\nplt.imshow(X_test[known_idx].reshape(128, 128), cmap='gray')\nplt.title(f\"Known Sample - Predicted: {predicted_label_known}, True: {true_label_known}\")\nplt.axis('off')\nplt.show()\n\nprint(f\"True Label (Known Sample): {true_label_known}\")\nprint(f\"Predicted Label (Known Sample): {predicted_label_known}\")\nprint(f\"Prediction Probabilities (Known Sample): {prediction_known}\")\n\n# This should help debug and check for data/label issues or model underperformance! 🚀","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T12:21:48.177717Z","iopub.execute_input":"2025-03-06T12:21:48.178724Z","iopub.status.idle":"2025-03-06T12:21:49.372926Z","shell.execute_reply.started":"2025-03-06T12:21:48.178682Z","shell.execute_reply":"2025-03-06T12:21:49.371757Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Test with a local audio file\nfile_path = \"path/to/your/audio/file.wav\"\n\n# Convert the audio to a mel spectrogram\nmel_spec = audio_to_melspectrogram(\"/kaggle/input/av/other/default/1/649390__5ro4__pigeon-territorial-coo.wav\")\n\nif mel_spec is not None:\n    # Resize the spectrogram to match the input shape\n    mel_spec_resized = cv2.resize(mel_spec, (128, 128))\n    mel_spec_resized = img_to_array(mel_spec_resized) / 255.0\n    mel_spec_resized = np.expand_dims(mel_spec_resized, axis=0)  # Add batch dimension\n\n    # Make a prediction\n    prediction = model.predict(mel_spec_resized)\n    predicted_label = list(label_map.keys())[np.argmax(prediction)]\n    confidence = np.max(prediction) * 100\n\n    # Show the spectrogram and prediction\n    plt.imshow(mel_spec_resized[0].reshape(128, 128), cmap='gray')\n    plt.title(f\"Predicted: {predicted_label} ({confidence:.2f}%)\")\n    plt.axis('off')\n    plt.show()\n\nelse:\n    print(\"Failed to process the audio file.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T12:10:34.342032Z","iopub.execute_input":"2025-03-06T12:10:34.342491Z","iopub.status.idle":"2025-03-06T12:10:34.775302Z","shell.execute_reply.started":"2025-03-06T12:10:34.342454Z","shell.execute_reply":"2025-03-06T12:10:34.774093Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install beautifulsoup4 requests\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:50:35.302098Z","iopub.execute_input":"2025-03-06T11:50:35.302489Z","iopub.status.idle":"2025-03-06T11:50:45.678343Z","shell.execute_reply.started":"2025-03-06T11:50:35.302454Z","shell.execute_reply":"2025-03-06T11:50:45.676669Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install wikipedia","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:50:49.851922Z","iopub.execute_input":"2025-03-06T11:50:49.852386Z","iopub.status.idle":"2025-03-06T11:51:02.822576Z","shell.execute_reply.started":"2025-03-06T11:50:49.852347Z","shell.execute_reply":"2025-03-06T11:51:02.821299Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import wikipedia\nfrom bs4 import BeautifulSoup\nimport requests\n\n\ndef get_species_info(species_name):\n    try:\n        page = wikipedia.page(species_name)\n        url = page.url\n        response = requests.get(url)\n        soup = BeautifulSoup(response.text, 'html.parser')\n        \n        def get_section(title):\n            section = soup.find('span', id=title)\n            if section:\n                content = section.find_parent('h2').find_next_sibling()\n                paragraphs = content.find_all('p') if content else []\n                return '\\n'.join([p.text for p in paragraphs]) if paragraphs else 'Section not available.'\n            return 'Section not found.'\n        \n        info = {\n            'Title': page.title,\n            'Scientific Name': page.title.split('(')[-1].strip(')') if '(' in page.title else 'N/A',\n            'Common Names': get_section('Common names'),\n            'Taxonomy': get_section('Taxonomy'),\n            'Conservation Status': get_section('Conservation_status'),\n            'Size, Weight, Wingspan': get_section('Description'),\n            'Plumage & Patterns': get_section('Plumage'),\n            'Sexual Dimorphism': get_section('Sexual_dimorphism'),\n            'Natural Habitat': get_section('Habitat'),\n            'Geographic Range & Migration': get_section('Distribution'),\n            'Feeding Habits & Diet': get_section('Diet'),\n            'Breeding & Nesting': get_section('Breeding'),\n            'Vocalizations': get_section('Vocalizations'),\n            'Lifespan': get_section('Lifespan'),\n            'Notable Behaviors': get_section('Behavior'),\n            'Cultural Significance': get_section('In_culture'),\n            'URL': page.url\n        }\n        \n        return info\n    \n    except wikipedia.exceptions.DisambiguationError as e:\n        choice = e.options[0]\n        print(f\"Multiple results found. Automatically selecting the first option: {choice}\")\n        return get_species_info(choice)\n    except wikipedia.exceptions.PageError:\n        return \"Species not found on Wikipedia. Double-check the name.\"\n\n\n# Example usage:\n# species_name = input(\"Enter bird species name: \")\nresult = get_species_info(\"kingsisher\")\n\nif isinstance(result, dict):\n    for key, value in result.items():\n        print(f\"{key}: {value}\\n\")\nelse:\n    print(result)\n\n# Let me know if you want me to refine anything else or tweak the selection logic! 🚀\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T11:58:33.222133Z","iopub.execute_input":"2025-03-06T11:58:33.222538Z","iopub.status.idle":"2025-03-06T11:58:33.790188Z","shell.execute_reply.started":"2025-03-06T11:58:33.222505Z","shell.execute_reply":"2025-03-06T11:58:33.788837Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import wikipedia\nfrom bs4 import BeautifulSoup\nimport requests\n\n\ndef fetch_wikipedia_content(bird_name):\n    try:\n        page = wikipedia.page(bird_name)\n        url = page.url\n        \n        response = requests.get(url)\n        soup = BeautifulSoup(response.text, 'html.parser')\n        content = soup.get_text()\n        \n        return content, url\n    except Exception as e:\n        print(f\"Error fetching Wikipedia page: {e}\")\n        return None, None\n\n\ndef extract_bird_info(content, bird_name, url):\n    sections = [\n        \"Common Names\",\n        \"Taxonomy\",\n        \"Conservation Status\",\n        \"Size, Weight, Wingspan\",\n        \"Plumage & Patterns\",\n        \"Sexual Dimorphism\",\n        \"Natural Habitat\",\n        \"Geographic Range & Migration\",\n        \"Feeding Habits & Diet\",\n        \"Breeding & Nesting\",\n        \"Vocalizations\",\n        \"Lifespan\",\n        \"Notable Behaviors\",\n        \"Cultural Significance\"\n    ]\n    \n    extracted_info = {section: \"Section not found.\" for section in sections}\n\n    # Simple content search (this can be improved)\n    for section in sections:\n        if section.lower() in content.lower():\n            extracted_info[section] = f\"Information available — refer to {url} for details.\"\n\n    # Create structured output\n    result = f\"Title: {bird_name}\\n\\n\"\n    result += f\"Scientific Name: Section not found.\\n\\n\"\n    \n    for section, info in extracted_info.items():\n        result += f\"{section}: {info}\\n\\n\"\n    \n    result += f\"URL: {url}\\n\"\n    \n    return result\n\n\nif __name__ == \"__main__\":\n    # bird_name = input(\"Enter the bird name: \")\n    content, url = fetch_wikipedia_content(\"kingfisher\")\n    \n    if content and url:\n        bird_info = extract_bird_info(content, bird_name, url)\n        print(bird_info)\n    else:\n        print(\"Could not fetch bird information.\")\n\n# This script grabs the Wikipedia content and attempts to match sections, giving you a rough draft of the bird profile!\n# Want me to refine the extraction logic or add more fields? Let me know! 🚀\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-06T12:01:44.751857Z","iopub.execute_input":"2025-03-06T12:01:44.7523Z","iopub.status.idle":"2025-03-06T12:01:45.681911Z","shell.execute_reply.started":"2025-03-06T12:01:44.752269Z","shell.execute_reply":"2025-03-06T12:01:45.680763Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# Convert audio to mel spectrogram\ndef audio_to_melspectrogram(file_path, n_mels=128):\n    try:\n        y, sr = librosa.load(file_path, sr=None)\n        mel_spec = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=n_mels)\n        mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max)\n        return mel_spec_db\n    except Exception as e:\n        print(f\"Error processing {file_path}: {e}\")\n        return None\n\n# Prepare data\ndef prepare_data(audio_files, label_map, max_files=100):\n    X, y = [], []\n    \n    for idx, file_path in enumerate(audio_files[:max_files]):\n        bird_name = os.path.basename(os.path.dirname(file_path))\n        if bird_name not in label_map:\n            label_map[bird_name] = len(label_map)\n        \n        mel_spec = audio_to_melspectrogram(file_path)\n        if mel_spec is not None:\n            resized_spec = cv2.resize(mel_spec, (128, 128))\n            X.append(img_to_array(resized_spec))\n            y.append(label_map[bird_name])\n    \n    return np.array(X), np.array(y)\n\n# Load and preprocess data\nlabel_map = {}\nX, y = prepare_data(audio_files, label_map)\n\nX = X / 255.0\n\n# One-hot encode labels\ny_categorical = to_categorical(y, num_classes=len(label_map))\n\n# Split train/test\nX_train, X_test, y_train, y_test = train_test_split(X, y_categorical, test_size=0.2, random_state=42)\n\n# Model architecture\nmodel = Sequential([\n    Conv2D(32, (3, 3), activation='relu', input_shape=(128, 128, 1)),\n    MaxPooling2D((2, 2)),\n    \n    Conv2D(64, (3, 3), activation='relu'),\n    MaxPooling2D((2, 2)),\n    \n    Conv2D(128, (3, 3), activation='relu'),\n    MaxPooling2D((2, 2)),\n    \n    Flatten(),\n    Dense(128, activation='relu'),\n    Dropout(0.3),\n    Dense(len(label_map), activation='softmax')\n])\n\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# Train model\nearly_stop = EarlyStopping(monitor='val_loss', patience=5)\n\nhistory = model.fit(\n    X_train, y_train,\n    validation_data=(X_test, y_test),\n    epochs=20,\n    batch_size=32,\n    callbacks=[early_stop]\n)\n\n# Evaluate model\nloss, accuracy = model.evaluate(X_test, y_test)\nprint(f\"Test Accuracy: {accuracy * 100:.2f}%\")\n\n# Predict a random test sample\nimport random\nidx = random.randint(0, len(X_test) - 1)\nsample = X_test[idx:idx+1]\n\nprediction = model.predict(sample)\npredicted_label = list(label_map.keys())[np.argmax(prediction)]\ntrue_label = list(label_map.keys())[np.argmax(y_test[idx])]\n\nplt.imshow(sample[0].reshape(128, 128), cmap='gray')\nplt.title(f\"Predicted: {predicted_label}, True: {true_label}\")\nplt.axis('off')\nplt.show()\n\n# Check for potential issues\nprint(\"Prediction Probabilities:\", prediction)\nprint(\"Unique labels in train set:\", np.unique(np.argmax(y_train, axis=1)))\nprint(\"Unique labels in test set:\", np.unique(np.argmax(y_test, axis=1)))\nprint(\"Class distribution in training data:\", np.sum(y_train, axis=0))\nprint(\"Class distribution in test","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}