Spaces:
Sleeping
Sleeping
| from datetime import datetime | |
| import librosa | |
| import numpy as np | |
| from pathlib import Path | |
| from src.musiclime.explainer import MusicLIMEExplainer | |
| from src.musiclime.wrapper import MusicLIMEPredictor | |
| from src.musiclime.print_utils import green_bold | |
| def explain(): | |
| # Start timing and time stamp to record how long the entire explanation thingy is | |
| start_time = datetime.now() | |
| print( | |
| green_bold( | |
| f"[MusicLIME] Started at: {start_time.strftime('%Y-%m-%d %H:%M:%S')}" | |
| ) | |
| ) | |
| # Create musiclime-related instances | |
| explainer = MusicLIMEExplainer() | |
| predictor = MusicLIMEPredictor() | |
| # Set the path for audio and lyrics [these are samples only - song is Silver Spring] | |
| audio_path = Path("data/external/sample_2.mp3") | |
| lyrics_path = Path("data/external/sample_2.txt") | |
| # Load the audio as an object + load the lyrics as string | |
| y, sr = librosa.load(audio_path) | |
| lyrics_text = lyrics_path.read_text(encoding="utf-8") | |
| # Generate explanations using musiclime | |
| explanation = explainer.explain_instance( | |
| audio=y, | |
| lyrics=lyrics_text, | |
| predict_fn=predictor, | |
| num_samples=1000, | |
| labels=(1,), | |
| ) | |
| # Get original prediction (first sample is always the orig meaning unperturbed) | |
| original_prediction = explanation.predictions[0] | |
| predicted_class = np.argmax(original_prediction) | |
| confidence = original_prediction[predicted_class] | |
| # Create song info from the prediction | |
| song_info = { | |
| "filename": "sample.mp3", | |
| "duration": f"{len(y)/44100:.1f}s", | |
| "original_prediction": { | |
| "class": "Human-Composed" if predicted_class == 1 else "AI-Generated", | |
| "confidence": float(confidence), | |
| "raw_probabilities": { | |
| "AI": float(original_prediction[0]), | |
| "Human": float(original_prediction[1]), | |
| }, | |
| }, | |
| } | |
| # Save with prediction data | |
| explanation.save_to_json( | |
| filepath=f"musiclime_explanation_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json", | |
| song_info=song_info, | |
| num_features=10, | |
| ) | |
| # Print explanations | |
| results = explanation.get_explanation(label=1, num_features=10) | |
| print("\n" + "=" * 80) | |
| print( | |
| f"[MusicLIME] Top 10 most important features for {"Human-Composed" if predicted_class == 1 else "AI-Generated"} prediction" | |
| ) | |
| print("=" * 80) | |
| for i, item in enumerate(results, 1): | |
| print( | |
| f"#{i:2d} | {item['type']:6s} | {item['feature'][:50]:50s} | weight: {item['weight']:+.6f}" | |
| ) | |
| print("=" * 80) | |
| print(f"[MusicLIME] Total features analyzed: {len(results)}") | |
| print("[MusicLIME] Higher absolute weights = more important for the prediction") | |
| # End timing and timestamp | |
| end_time = datetime.now() | |
| total_duration = end_time - start_time | |
| total_minutes = total_duration.total_seconds() / 60 | |
| print(f"\n[MusicLIME] Finished at: {end_time.strftime('%Y-%m-%d %H:%M:%S')}") | |
| print( | |
| green_bold( | |
| f"[MusicLIME] Total execution time: {total_minutes:.2f} minutes ({total_duration.total_seconds():.1f} seconds)" | |
| ) | |
| ) | |
| if __name__ == "__main__": | |
| explain() | |