18+
реклама
18+
Бургер менюБургер меню

Александр Иванов – Python в аудио-спецэффектах. Как работают нейросети изнутри. (страница 7)

18

# Генерируем данные

X, y = generate_synthetic_data(500)

# Разделяем на обучающую и тестовую выборки

split = int(0.8 * len(X))

X_train, X_test = X[:split], X[split:]

y_train, y_test = y[:split], y[split:]

# Преобразуем в тензоры PyTorch

X_train_tensor = torch.tensor(X_train)

y_train_tensor = torch.tensor(y_train, dtype=torch.long)

X_test_tensor = torch.tensor(X_test)

y_test_tensor = torch.tensor(y_test, dtype=torch.long)

print(f"Обучающих примеров: {len(X_train)}")

print(f"Тестовых примеров: {len(X_test)}")

# Обучаем модель

model = SoundClassifier()

criterion = nn.CrossEntropyLoss()

optimizer = optim.Adam(model.parameters(), lr=0.01)

num_epochs = 200

for epoch in range(num_epochs):

# Прямой проход

outputs = model(X_train_tensor)

loss = criterion(outputs, y_train_tensor)

# Обратный проход и оптимизация

optimizer.zero_grad()

loss.backward()

optimizer.step()

if epoch % 40 == 0 or epoch == num_epochs - 1:

# Оцениваем точность на тестовой выборке

with torch.no_grad():

test_outputs = model(X_test_tensor)

_, predicted = torch.max(test_outputs, 1)

accuracy = (predicted == y_test_tensor).float().mean()

print(f"Эпоха {epoch:3d}: Потери = {loss.item():.4f}, Точность = {accuracy:.2%}")

print("\nОбучение завершено!")

Запустите этот код. Вы увидите, как потери уменьшаются от эпохи к эпохе, а точность на тестовой выборке растёт. К концу обучения модель должна достигнуть точности выше девяноста процентов — это означает, что она хорошо научилась отличать три класса звуков друг от друга.

Разберём, что происходит при обучении. criterion = nn.CrossEntropyLoss() — функция потерь, которая измеряет, насколько предсказания модели отличаются от правильных ответов. optimizer = optim.Adam(model.parameters(), lr=0.01) — оптимизатор Adam, который сам подбирает величину шага для каждого параметра. loss.backward() — магия PyTorch: автоматически вычисляет градиенты для всех параметров модели. optimizer.step() — обновляет параметры в направлении уменьшения ошибки.

Применяем модель к реальному звуку

Теперь давайте проверим нашу модель на реальном аудиофайле. Мы загрузим запись, извлечём признаки и посмотрим, какие классы модель предсказывает для разных фреймов.

python

def classify_audio_file(filepath, model, label_names):

"""Классифицирует аудиофайл по фреймам."""

y, sr = librosa.load(filepath, sr=22050, mono=True)

features = extract_features(y, sr)

# Преобразуем в тензор

features_tensor = torch.tensor(features)

# Предсказываем

with torch.no_grad():

outputs = model(features_tensor)

_, predicted = torch.max(outputs, 1)

# Считаем статистику

unique, counts = np.unique(predicted.numpy(), return_counts=True)

total = len(predicted)

print(f"\nАнализ файла: {filepath}")

print(f" Всего фреймов: {total}")

for cls, count in zip(unique, counts):

print(f" {label_names[cls]}: {count} фреймов ({count / total:.1%})")

return predicted.numpy()

# Классифицируем тестовый файл (если есть) или создадим синтетический

label_names = ['Речь', 'Музыка', 'Шум']

# Создадим тестовый сигнал: первые 2 секунды — тон (музыка), затем шум, затем речь из файла

sr = 22050

t = np.linspace(0, 4.0, int(sr * 4.0), endpoint=False)

test_signal = np.zeros_like(t)

# Музыка: синусоида с обертонами

test_signal[:int(1.5 * sr)] = (np.sin(2 * np.pi * 440 * t[:int(1.5 * sr)]) +