muzikk / app.py
ssenaay's picture
Upload app.py
3e671d3 verified
Raw
History Blame Contribute Delete
9.95 kB
# app.py
import pandas as pd
from transformers import pipeline
import gradio as gr
import numpy as np
import os
from PIL import Image # Görüntü işleme için Pillow kütüphanesi
# 1. Kaggle Veri Setini Yükle (Örnek bir Spotify veri seti kullanacağız)
DATA_URL = "https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-01-21/spotify_songs.csv"
DATA_PATH = "spotify_songs.csv"
print("Veri seti indiriliyor...")
try:
if not os.path.exists(DATA_PATH):
import requests
response = requests.get(DATA_URL)
response.raise_for_status()
with open(DATA_PATH, 'wb') as f:
f.write(response.content)
print(f"Veri seti {DATA_PATH} konumuna başarıyla indirildi.")
else:
print(f"Veri seti {DATA_PATH} zaten mevcut, indirme atlandı.")
df = pd.read_csv(DATA_PATH)
df = df[['track_name', 'track_artist', 'playlist_genre', 'valence', 'energy', 'tempo', 'danceability']]
df = df.dropna()
df = df.drop_duplicates(subset=['track_name', 'track_artist'])
df = df.rename(columns={'playlist_genre': 'genre', 'track_name': 'name', 'track_artist': 'artist'})
print("Veri seti başarıyla yüklendi ve işlendi. Toplam şarkı sayısı:", len(df))
except Exception as e:
print(f"Veri seti yüklenirken veya işlenirken bir hata oluştu: {e}")
print("Lütfen alternatif bir CSV dosyası deneyin veya manuel yükleyin.")
df = pd.DataFrame(columns=['name', 'artist', 'genre', 'valence', 'energy', 'tempo', 'danceability'])
# 2. Hugging Face Duygu Analizi Modeli Yükle (Metin için)
print("\nHugging Face duygu analizi modeli yükleniyor (Metin için)...")
sentiment_analyzer = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english")
print("Metin duygu modeli yüklendi.")
# 3. Hugging Face Görüntü Sınıflandırma Modeli Yükle (Görsel için)
# Bu model, sıfır atışlı görüntü sınıflandırma için kullanılır (yani önceden eğitilmemiş etiketlerle bile çalışır)
print("\nHugging Face sıfır-atış görüntü sınıflandırma modeli yükleniyor (Görsel için)...")
image_classifier = pipeline("zero-shot-image-classification", model="openai/clip-vit-base-patch32")
print("Görüntü sınıflandırma modeli yüklendi.")
# Görüntü sınıflandırma için aday etiketler (bu etiketler müzik ruh halleriyle ilişkilendirilecek)
candidate_image_labels = [
"happy photo", "sad photo", "energetic photo", "calm photo",
"romantic photo", "mysterious photo", "party photo",
"nature scene", "city scene", "travel photo", "food photo", "work photo",
"bright photo", "dark photo", "warm colors", "cool colors",
"adventure", "relaxation", "celebration", "reflection", "serenity"
]
# 4. Duygu ve Enerji Aralığı Tanımları
mood_mappings = {
"Mutlu ve Coşkulu": {"valence": [0.7, 1.0], "energy": [0.7, 1.0]},
"Hüzünlü ve Melankolik": {"valence": [0.0, 0.3], "energy": [0.0, 0.4]},
"Sakin ve Huzurlu": {"valence": [0.5, 0.8], "energy": [0.2, 0.6]},
"Enerjik ve Canlı": {"valence": [0.6, 1.0], "energy": [0.8, 1.0]},
"Gergin ve Dramatik": {"valence": [0.2, 0.5], "energy": [0.6, 0.9]},
"Romantik ve Duygusal": {"valence": [0.6, 0.9], "energy": [0.3, 0.7]},
"Gizemli ve Derin": {"valence": [0.3, 0.6], "energy": [0.4, 0.7]},
"Parti ve Eğlence": {"valence": [0.7, 1.0], "energy": [0.8, 1.0]},
"Odaklanma ve Çalışma": {"valence": [0.4, 0.7], "energy": [0.3, 0.6]},
"Seyahat ve Keşif": {"valence": [0.6, 0.9], "energy": [0.6, 0.9]},
}
available_genres = df['genre'].unique().tolist()
available_genres.sort()
# 5. Şarkı Önerme Fonksiyonu
def get_song_recommendations(story_text, uploaded_image, selected_mood, selected_genre, num_recommendations=5):
if df.empty:
return "Veri seti yüklenemediği için öneri yapılamıyor. Lütfen kontrol edin."
# ----- Metin Duygu Analizi -----
text_sentiment_score = 0.5 # Varsayılan nötr
if story_text:
try:
sentiment_result = sentiment_analyzer(story_text)[0]
text_sentiment_score = sentiment_result['score'] if sentiment_result['label'] == 'POSITIVE' else (1 - sentiment_result['score'])
except Exception as e:
print(f"Metin duygu analizi sırasında hata oluştu: {e}. Varsayılan nötr duygu atanıyor.")
# ----- Görsel Analizi -----
image_valence_adjustment = 0
image_energy_adjustment = 0
if uploaded_image is not None:
try:
print("Görsel analizi yapılıyor...")
# Gradio'dan gelen görsel PIL Image objesi olarak gelir.
image_results = image_classifier(images=uploaded_image, candidate_labels=candidate_image_labels)
print(f"Görsel analiz sonuçları: {image_results}")
# Basit bir şekilde görsel sonuçları valence/energy'ye yansıtma
# Daha sofistike bir mapping yapılabilir.
for res in image_results:
label = res['label']
score = res['score']
if score > 0.6: # Yüksek güvenli tahminleri kullan
if "happy photo" in label or "bright photo" in label or "celebration" in label:
image_valence_adjustment += 0.1 * score
image_energy_adjustment += 0.05 * score
elif "sad photo" in label or "dark photo" in label or "reflection" in label:
image_valence_adjustment -= 0.1 * score
image_energy_adjustment -= 0.05 * score
elif "energetic photo" in label or "party photo" in label or "city scene" in label or "adventure" in label:
image_energy_adjustment += 0.1 * score
elif "calm photo" in label or "nature scene" in label or "relaxation" in label or "serenity" in label:
image_energy_adjustment -= 0.05 * score
image_valence_adjustment += 0.03 * score # Hafif pozitiflik
elif "romantic photo" in label:
image_valence_adjustment += 0.05 * score
image_energy_adjustment -= 0.03 * score
except Exception as e:
print(f"Görsel analizi sırasında hata oluştu: {e}. Görsel analizi atlanıyor.")
# ----- Hedef Valence ve Energy Aralığı Belirleme -----
target_valence_range = list(mood_mappings[selected_mood]["valence"])
target_energy_range = list(mood_mappings[selected_mood]["energy"])
# Metin duygu sentimentini valence aralığına dahil edelim.
text_sentiment_adjustment = (text_sentiment_score - 0.5) * 0.4 # -0.2 ile +0.2 arasında ayarlama
target_valence_range[0] = max(0, target_valence_range[0] + text_sentiment_adjustment)
target_valence_range[1] = min(1, target_valence_range[1] + text_sentiment_adjustment)
# Görsel duygu adjustment'ını uygulayalım
target_valence_range[0] = max(0, target_valence_range[0] + image_valence_adjustment)
target_valence_range[1] = min(1, target_valence_range[1] + image_valence_adjustment)
target_energy_range[0] = max(0, target_energy_range[0] + image_energy_adjustment)
target_energy_range[1] = min(1, target_energy_range[1] + image_energy_adjustment)
# Aralıkları 0-1 arasında tut
target_valence_range = [min(1, max(0, tv)) for tv in target_valence_range]
target_energy_range = [min(1, max(0, te)) for te in target_energy_range]
#print(f"Nihai Hedef Valence Aralığı: {target_valence_range}, Nihai Hedef Energy Aralığı: {target_energy_range}")
# ----- Filtreleme ve Puanlama -----
filtered_songs = df[df['genre'] == selected_genre].copy()
if filtered_songs.empty:
return f"'{selected_genre}' türünde şarkı bulunamadı. Lütfen başka bir tür seçin."
filtered_songs['valence_diff'] = filtered_songs['valence'].apply(
lambda x: min(abs(x - target_valence_range[0]), abs(x - target_valence_range[1]))
)
filtered_songs['energy_diff'] = filtered_songs['energy'].apply(
lambda x: min(abs(x - target_energy_range[0]), abs(x - target_energy_range[1]))
)
filtered_songs['fit_score'] = 1 / (filtered_songs['valence_diff'] + filtered_songs['energy_diff'] + 0.01)
recommended_songs = filtered_songs.sort_values(by='fit_score', ascending=False).head(num_recommendations)
if recommended_songs.empty:
return "Seçimlerinize uygun şarkı bulunamadı. Daha geniş kriterler deneyin."
results = []
for index, row in recommended_songs.iterrows():
results.append(f"• {row['name']} - {row['artist']} ({row['genre']})")
return "\n".join(results)
# 6. Gradio Arayüzü Oluştur
print("\nGradio arayüzü başlatılıyor...")
iface = gr.Interface(
fn=get_song_recommendations,
inputs=[
gr.Textbox(lines=3, placeholder="Instagram hikayenizi buraya yazın (örneğin: 'Gün batımında sahilde yürüyorum, huzur veren bir an')", label="Hikaye Metni (İsteğe Bağlı)"),
gr.Image(type="pil", label="Hikaye Görseli (İsteğe Bağlı, JPG/PNG)"), # Yeni görsel girdi
gr.Dropdown(list(mood_mappings.keys()), label="Hikayenin Ruh Hali"),
gr.Dropdown(available_genres, label="Müzik Türü"),
],
outputs=gr.Textbox(label="Önerilen Şarkılar", lines=5),
title="🌟 Akıllı Hikaye Müzik Önerici (Görsel ve Metin Analizli) 🌟",
description="Hikaye metninizi ve/veya görselinizi yükleyerek, ayrıca ruh hali ve müzik türü seçerek Instagram hikayeniz için mükemmel şarkı önerileri alın. Öneriler Kaggle veri seti ve Hugging Face NLP/Görsel analiz ile güçlendirilmiştir.",
allow_flagging="never"
)
iface.launch(share=False)