{"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":"none","dataSources":[{"sourceType":"competition","sourceId":70203,"databundleVersionId":8068726}],"dockerImageVersionId":31328,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\n\nprint(os.listdir(\"/kaggle/input\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T13:57:11.310559Z","iopub.execute_input":"2026-05-18T13:57:11.311473Z","iopub.status.idle":"2026-05-18T13:57:11.316149Z","shell.execute_reply.started":"2026-05-18T13:57:11.311423Z","shell.execute_reply":"2026-05-18T13:57:11.315329Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"path = \"/kaggle/input/competitions\"\n\nprint(os.listdir(path))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T13:57:13.798363Z","iopub.execute_input":"2026-05-18T13:57:13.798713Z","iopub.status.idle":"2026-05-18T13:57:13.804056Z","shell.execute_reply.started":"2026-05-18T13:57:13.798676Z","shell.execute_reply":"2026-05-18T13:57:13.803228Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\npath = \"/kaggle/input/competitions/birdclef-2024\"\n\nprint(os.listdir(path))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T13:57:16.366763Z","iopub.execute_input":"2026-05-18T13:57:16.367097Z","iopub.status.idle":"2026-05-18T13:57:16.372917Z","shell.execute_reply.started":"2026-05-18T13:57:16.367067Z","shell.execute_reply":"2026-05-18T13:57:16.372036Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\ndf = pd.read_csv(\"/kaggle/input/competitions/birdclef-2024/train_metadata.csv\")\n\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T13:57:18.530594Z","iopub.execute_input":"2026-05-18T13:57:18.531686Z","iopub.status.idle":"2026-05-18T13:57:18.754898Z","shell.execute_reply.started":"2026-05-18T13:57:18.531628Z","shell.execute_reply":"2026-05-18T13:57:18.753604Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"audio_path = \"/kaggle/input/competitions/birdclef-2024/train_audio\"\n\nprint(os.listdir(audio_path)[:10])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T13:57:22.283522Z","iopub.execute_input":"2026-05-18T13:57:22.284676Z","iopub.status.idle":"2026-05-18T13:57:22.29777Z","shell.execute_reply.started":"2026-05-18T13:57:22.28462Z","shell.execute_reply":"2026-05-18T13:57:22.296685Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport librosa\n\ndef audio_to_melspectrogram(file_path, max_len=128):\n\n    audio, sr = librosa.load(file_path, sr=32000, duration=5.0) # تحميل الصوت\n\n    mel = librosa.feature.melspectrogram( # تحويل الصوت الي صوره \n        y=audio,\n        sr=sr,\n        n_mels=128\n    )\n    \n       #\"حوّل طاقة الصوت إلى Decibel Scale باستخدام أعلى قيمة كمرجع\"\n    mel_db = librosa.power_to_db(mel, ref=np.max) # يحول من power to Decibel values يعني بدل ارقام ضخمه -> تكون معقوله شويه \n\n    \n    if mel_db.shape[1] < max_len:         #\"هل عرض الصورة أقل من 128؟\"\n        pad = max_len - mel_db.shape[1]ً  #  قد إيه ناقص عشان نوصل لـ 128 \n        mel_db = np.pad(\n            mel_db,\n            ((0,0),(0,pad)), # بعمل Padding واضيف اصفار  \n            mode='constant') \n        \n    else: #لو الصوره اكبر من 128 نقصها \n        mel_db = mel_db[:, :max_len]\n\n    #Normalization / Standardization  نخلي القيم متقاربه مستقره اسهل للموديل \n    mel_db = (mel_db - np.mean(mel_db)) / (np.std(mel_db) + 1e-6)\n    # بنحول ال spector Dالي 3\n    return np.expand_dims(mel_db, axis=-1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T13:57:25.461078Z","iopub.execute_input":"2026-05-18T13:57:25.461415Z","iopub.status.idle":"2026-05-18T13:57:25.468814Z","shell.execute_reply.started":"2026-05-18T13:57:25.461384Z","shell.execute_reply":"2026-05-18T13:57:25.467718Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = []   #input\ny = []   #output\n\nMAX_FILES = 20 #خدي فقط 20 ملف صوت لكل نوع طائر","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T13:57:28.423939Z","iopub.execute_input":"2026-05-18T13:57:28.424301Z","iopub.status.idle":"2026-05-18T13:57:28.429557Z","shell.execute_reply.started":"2026-05-18T13:57:28.424268Z","shell.execute_reply":"2026-05-18T13:57:28.428734Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#هنا يلف ع طائر طائر  واخد شويه اصوات احولهم ل spect\n\nfor bird_class in os.listdir(audio_path):  \n\n    class_path = os.path.join(audio_path, bird_class)\n\n    if not os.path.isdir(class_path):#لو مش فولدر تجاهله \n        continue\n\n    count = 0 #نحدد عدد الملفات اللي هنستخدمها لكل class\n\n    for file in os.listdir(class_path): #لف على كل الملفات الصوتية داخل الطائر ده\n\n        if count >= MAX_FILES: #لو أخدت العدد المطلوب خلاص وقف\n            break\n\n        file_path = os.path.join(class_path, file) #بنكوّن المسار الكامل للملف الصوتي\n\n        #هناخد الملف الصوتي نحوله ل spect وبعد كده نحطه ف ال x\n        try:\n            X.append(audio_to_melspectrogram(file_path))\n            y.append(bird_class) #نحط اسم الطائر في y\n            count += 1\n        except:\n            pass","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T13:57:30.863369Z","iopub.execute_input":"2026-05-18T13:57:30.863726Z","iopub.status.idle":"2026-05-18T14:00:08.168889Z","shell.execute_reply.started":"2026-05-18T13:57:30.863691Z","shell.execute_reply":"2026-05-18T14:00:08.168055Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# LabelEncoder دي اداه بتحول ال text\"name of the bird\" to number \nfrom sklearn.preprocessing import LabelEncoder\n\n #بننشئ object جديد من الأداة\nencoder = LabelEncoder()\n\n#يتعلم أسماء الطيور وبعد كده يحولها ل ارقام \ny = encoder.fit_transform(y)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T14:00:38.688331Z","iopub.execute_input":"2026-05-18T14:00:38.688682Z","iopub.status.idle":"2026-05-18T14:00:38.731876Z","shell.execute_reply.started":"2026-05-18T14:00:38.688635Z","shell.execute_reply":"2026-05-18T14:00:38.730905Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#هنحول list to array \nX = np.array(X)\ny = np.array(y)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T14:00:40.91971Z","iopub.execute_input":"2026-05-18T14:00:40.920477Z","iopub.status.idle":"2026-05-18T14:00:41.017397Z","shell.execute_reply.started":"2026-05-18T14:00:40.920435Z","shell.execute_reply":"2026-05-18T14:00:41.016521Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nX_train, X_test, y_train, y_test = train_test_split(\n    X, y,\n    test_size=0.2,\n    random_state=42\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T14:00:43.385703Z","iopub.execute_input":"2026-05-18T14:00:43.386157Z","iopub.status.idle":"2026-05-18T14:00:43.63594Z","shell.execute_reply.started":"2026-05-18T14:00:43.386112Z","shell.execute_reply":"2026-05-18T14:00:43.634965Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\n\nnum_classes = len(np.unique(y))\n\nmodel = tf.keras.Sequential([\n    \n    tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(128,128,1)),\n    tf.keras.layers.MaxPooling2D((2,2)),\n\n    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D((2,2)),\n\n    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D((2,2)),\n\n    tf.keras.layers.GlobalAveragePooling2D(),\n\n    tf.keras.layers.Dense(256, activation='relu'),\n    tf.keras.layers.Dropout(0.3),\n\n    tf.keras.layers.Dense(num_classes, activation='softmax')\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T14:00:46.367223Z","iopub.execute_input":"2026-05-18T14:00:46.367849Z","iopub.status.idle":"2026-05-18T14:00:46.494256Z","shell.execute_reply.started":"2026-05-18T14:00:46.367813Z","shell.execute_reply":"2026-05-18T14:00:46.493316Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(\n    optimizer='adam',\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T14:00:50.645136Z","iopub.execute_input":"2026-05-18T14:00:50.645491Z","iopub.status.idle":"2026-05-18T14:00:50.663164Z","shell.execute_reply.started":"2026-05-18T14:00:50.645457Z","shell.execute_reply":"2026-05-18T14:00:50.662073Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(\n    X_train, y_train,\n    epochs=10,\n    batch_size=32,\n    validation_data=(X_test, y_test)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T14:00:52.995986Z","iopub.execute_input":"2026-05-18T14:00:52.996309Z","iopub.status.idle":"2026-05-18T14:07:37.338904Z","shell.execute_reply.started":"2026-05-18T14:00:52.996281Z","shell.execute_reply":"2026-05-18T14:07:37.337066Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss, acc = model.evaluate(X_test, y_test)\nprint(\"Accuracy:\", acc)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T14:07:42.376057Z","iopub.execute_input":"2026-05-18T14:07:42.376424Z","iopub.status.idle":"2026-05-18T14:07:45.070355Z","shell.execute_reply.started":"2026-05-18T14:07:42.376388Z","shell.execute_reply":"2026-05-18T14:07:45.06853Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def predict_bird(file_path):\n\n    features = audio_to_melspectrogram(file_path)\n    features = np.expand_dims(features, axis=0)\n\n    pred = model.predict(features)\n\n    class_id = np.argmax(pred)\n\n    return encoder.inverse_transform([class_id])[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-18T14:13:22.705687Z","iopub.execute_input":"2026-05-18T14:13:22.706025Z","iopub.status.idle":"2026-05-18T14:13:22.711839Z","shell.execute_reply.started":"2026-05-18T14:13:22.705995Z","shell.execute_reply":"2026-05-18T14:13:22.710796Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}