Spaces:
Runtime error
Runtime error
abdellatif-laghjaj
commited on
Upload folder using huggingface_hub
Browse files- .gitattributes +2 -0
- .gitignore +8 -0
- README.md +2 -8
- app.py +91 -0
- birdclef.ipynb +3 -0
- birdclef_2024_abdellatif_laghjaj.py +93 -0
- data.csv +0 -0
- model.joblib +3 -0
- requirements.txt +8 -0
- sounds/1000170626.ogg +3 -0
- sounds/XC134896.ogg +0 -0
.gitattributes
CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
birdclef.ipynb filter=lfs diff=lfs merge=lfs -text
|
37 |
+
sounds/1000170626.ogg filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.vscode
|
2 |
+
.idea
|
3 |
+
.DS_Store
|
4 |
+
.env
|
5 |
+
.env.local
|
6 |
+
node_modules/
|
7 |
+
venv/
|
8 |
+
flagged/
|
README.md
CHANGED
@@ -1,12 +1,6 @@
|
|
1 |
---
|
2 |
-
title: BirdCLEF
|
3 |
-
|
4 |
-
colorFrom: yellow
|
5 |
-
colorTo: pink
|
6 |
sdk: gradio
|
7 |
sdk_version: 4.36.0
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
---
|
11 |
-
|
12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: BirdCLEF-2024
|
3 |
+
app_file: app.py
|
|
|
|
|
4 |
sdk: gradio
|
5 |
sdk_version: 4.36.0
|
|
|
|
|
6 |
---
|
|
|
|
app.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import joblib
|
5 |
+
import librosa
|
6 |
+
import plotly.express as px
|
7 |
+
import wikipedia
|
8 |
+
|
9 |
+
# Load the model and class mapping data once at the beginning
|
10 |
+
model = joblib.load('model.joblib')
|
11 |
+
class_mapping_data = pd.read_csv('data.csv')
|
12 |
+
|
13 |
+
# Preprocess the class mapping data for faster lookups
|
14 |
+
class_mapping_dict = dict(zip(class_mapping_data['encoded_label'],
|
15 |
+
class_mapping_data[['scientific_name', 'latitude', 'longitude', 'primary_label']].values))
|
16 |
+
|
17 |
+
|
18 |
+
# Define the feature extraction function
|
19 |
+
def extract_features(file_path):
|
20 |
+
audio, _ = librosa.load(file_path) # No need for sample rate here
|
21 |
+
mfccs = librosa.feature.mfcc(y=audio, n_mfcc=40)
|
22 |
+
return np.mean(mfccs.T, axis=0) # Avoid unnecessary array creation
|
23 |
+
|
24 |
+
|
25 |
+
# Function to fetch Wikipedia information
|
26 |
+
def fetch_wikipedia_info(bird_name):
|
27 |
+
try:
|
28 |
+
page = wikipedia.page(bird_name)
|
29 |
+
first_section = next(iter(page.sections), None)
|
30 |
+
if first_section:
|
31 |
+
return first_section.title, first_section.text
|
32 |
+
else:
|
33 |
+
return bird_name, page.summary
|
34 |
+
except wikipedia.exceptions.PageError:
|
35 |
+
return bird_name, "No information available on Wikipedia."
|
36 |
+
|
37 |
+
|
38 |
+
# Define the prediction function
|
39 |
+
def predict_bird(audio_file):
|
40 |
+
# Extract features from the audio file
|
41 |
+
features = extract_features(audio_file)
|
42 |
+
features = features.reshape(1, -1) # Reshape for model input
|
43 |
+
|
44 |
+
# Predict the bird species
|
45 |
+
prediction = model.predict(features)[0] # Get the prediction as a scalar
|
46 |
+
|
47 |
+
# Retrieve bird information directly from the preprocessed dictionary
|
48 |
+
bird_info = class_mapping_dict[prediction]
|
49 |
+
predicted_bird = bird_info[0]
|
50 |
+
|
51 |
+
# Fetch Wikipedia information
|
52 |
+
wiki_title, wiki_info = fetch_wikipedia_info(predicted_bird)
|
53 |
+
|
54 |
+
# Remove any asterisks from the title for better display
|
55 |
+
wiki_title = wiki_title.replace('*', '')
|
56 |
+
|
57 |
+
# Create a DataFrame for plotting
|
58 |
+
tmp = pd.DataFrame([bird_info[1:]], columns=['latitude', 'longitude', 'primary_label'])
|
59 |
+
|
60 |
+
# Create a scatter mapbox plot
|
61 |
+
fig = px.scatter_mapbox(
|
62 |
+
tmp,
|
63 |
+
lat="latitude",
|
64 |
+
lon="longitude",
|
65 |
+
color="primary_label",
|
66 |
+
zoom=10,
|
67 |
+
title='Bird Recordings Location',
|
68 |
+
mapbox_style="open-street-map"
|
69 |
+
)
|
70 |
+
|
71 |
+
fig.update_layout(margin={"r": 0, "t": 30, "l": 0, "b": 0})
|
72 |
+
|
73 |
+
return predicted_bird, f"**{wiki_title}**", wiki_info, fig
|
74 |
+
|
75 |
+
|
76 |
+
# Create Gradio interface
|
77 |
+
iface = gr.Interface(
|
78 |
+
fn=predict_bird,
|
79 |
+
inputs=gr.Audio(type="filepath", label="Upload Bird Sound"),
|
80 |
+
outputs=[
|
81 |
+
gr.Textbox(label="Predicted Bird"),
|
82 |
+
gr.Textbox(label="Wikipedia Title"),
|
83 |
+
gr.Textbox(label="Wikipedia Information"),
|
84 |
+
gr.Plot(label="Bird Recordings Location"),
|
85 |
+
],
|
86 |
+
title="Bird ID: Identify Bird Species from Audio Recordings",
|
87 |
+
description="Upload an audio recording of a bird and let the app identify the species!",
|
88 |
+
)
|
89 |
+
|
90 |
+
# Launch the Gradio interface
|
91 |
+
iface.launch()
|
birdclef.ipynb
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:ddf713ab68aa1b6a2b937d7518cfb48f8a5593dfed855954a00a908e0c3de4a5
|
3 |
+
size 14518645
|
birdclef_2024_abdellatif_laghjaj.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import librosa
|
4 |
+
import soundfile as sf
|
5 |
+
import matplotlib.pyplot as plt
|
6 |
+
import noisereduce as nr
|
7 |
+
from sklearn.model_selection import train_test_split
|
8 |
+
from tensorflow.keras.models import Sequential
|
9 |
+
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
|
10 |
+
from tensorflow.keras.optimizers import Adam
|
11 |
+
from tensorflow.keras.utils import to_categorical
|
12 |
+
|
13 |
+
BASE_PATH = '/kaggle/input/birdclef-2024'
|
14 |
+
|
15 |
+
# Load metadata
|
16 |
+
train_metadata = pd.read_csv(f'{BASE_PATH}/train_metadata.csv')
|
17 |
+
train_metadata['filepath'] = BASE_PATH + '/train_audio/' + train_metadata.filename
|
18 |
+
|
19 |
+
|
20 |
+
# Data Preprocessing
|
21 |
+
def preprocess_audio(audio_path, sample_rate=32000, duration=15, nfft=2048, hop_length=512):
|
22 |
+
# Load audio
|
23 |
+
audio, sr = sf.read(audio_path)
|
24 |
+
audio = audio[:sample_rate * duration] # Trim to fixed duration
|
25 |
+
|
26 |
+
# Normalize and Denoise
|
27 |
+
audio = audio / np.max(np.abs(audio))
|
28 |
+
denoised_audio = nr.reduce_noise(y=audio, sr=sr)
|
29 |
+
|
30 |
+
# Calculate Mel Spectrogram
|
31 |
+
mel_spectrogram = librosa.feature.melspectrogram(y=denoised_audio, sr=sr, n_fft=nfft, hop_length=hop_length)
|
32 |
+
mel_spectrogram_db = librosa.power_to_db(mel_spectrogram, ref=np.max)
|
33 |
+
|
34 |
+
return mel_spectrogram_db
|
35 |
+
|
36 |
+
|
37 |
+
# Prepare Data for Training
|
38 |
+
X = []
|
39 |
+
y = []
|
40 |
+
|
41 |
+
for i in range(len(train_metadata)):
|
42 |
+
filepath = train_metadata.filepath[i]
|
43 |
+
label = train_metadata.primary_label[i]
|
44 |
+
spectrogram = preprocess_audio(filepath)
|
45 |
+
X.append(spectrogram)
|
46 |
+
y.append(label)
|
47 |
+
|
48 |
+
X = np.array(X)
|
49 |
+
y = np.array(y)
|
50 |
+
|
51 |
+
# One-Hot Encoding of Labels
|
52 |
+
unique_labels = np.unique(y)
|
53 |
+
label_to_index = {label: i for i, label in enumerate(unique_labels)}
|
54 |
+
y_encoded = np.array([label_to_index[label] for label in y])
|
55 |
+
y_encoded = to_categorical(y_encoded, num_classes=len(unique_labels))
|
56 |
+
|
57 |
+
# Train-Test Split
|
58 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y_encoded, test_size=0.2, random_state=42)
|
59 |
+
|
60 |
+
# CNN Model
|
61 |
+
model = Sequential()
|
62 |
+
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(X_train.shape[1], X_train.shape[2], 1)))
|
63 |
+
model.add(MaxPooling2D((2, 2)))
|
64 |
+
model.add(Conv2D(64, (3, 3), activation='relu'))
|
65 |
+
model.add(MaxPooling2D((2, 2)))
|
66 |
+
model.add(Flatten())
|
67 |
+
model.add(Dense(len(unique_labels), activation='softmax'))
|
68 |
+
|
69 |
+
# Compile Model
|
70 |
+
model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])
|
71 |
+
|
72 |
+
# Train Model
|
73 |
+
model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_test, y_test))
|
74 |
+
|
75 |
+
# Predictions
|
76 |
+
predictions = model.predict(X_test)
|
77 |
+
predicted_labels = np.argmax(predictions, axis=1)
|
78 |
+
|
79 |
+
# Evaluation
|
80 |
+
accuracy = model.evaluate(X_test, y_test)[1]
|
81 |
+
print("Accuracy:", accuracy)
|
82 |
+
|
83 |
+
# Visualize Spectrograms
|
84 |
+
plt.figure(figsize=(10, 5))
|
85 |
+
librosa.display.specshow(X_test[0], sr=32000, x_axis='time', y_axis='mel')
|
86 |
+
plt.colorbar(format='%+2.0f dB')
|
87 |
+
plt.title('Example Spectrogram')
|
88 |
+
plt.show()
|
89 |
+
|
90 |
+
# Create Submission File (Modify according to the competition's submission format)
|
91 |
+
submission_df = pd.DataFrame({'row_id': [i for i in range(len(predictions))],
|
92 |
+
'predictions': predictions})
|
93 |
+
submission_df.to_csv('submission.csv', index=False)
|
data.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
model.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:aa8b5fda6eda56d8b26f1d788e1d0cfb517f4d476341dada66578871a57f798e
|
3 |
+
size 32160877
|
requirements.txt
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
numpy
|
2 |
+
pandas
|
3 |
+
joblib
|
4 |
+
librosa
|
5 |
+
wikipedia
|
6 |
+
gradio
|
7 |
+
plotly
|
8 |
+
xgboost
|
sounds/1000170626.ogg
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:20a7f46b20c5be40da57e0f2a58907f75aa99933bc7f8cb3f38e7ab9187c1d28
|
3 |
+
size 1834885
|
sounds/XC134896.ogg
ADDED
Binary file (197 kB). View file
|
|