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

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

18

Полносвязная сеть для классификации звуков.

4 входных признака -> 16 скрытых нейронов -> 8 скрытых нейронов -> 3 класса

"""

def __init__(self):

super().__init__()

self.fc1 = nn.Linear(4, 16) # входной слой -> скрытый слой 1

self.fc2 = nn.Linear(16, 8) # скрытый слой 1 -> скрытый слой 2

self.fc3 = nn.Linear(8, 3) # скрытый слой 2 -> выходной слой (3 класса)

self.relu = nn.ReLU() # функция активации ReLU

self.softmax = nn.Softmax(dim=1) # для получения вероятностей

def forward(self, x):

x = self.relu(self.fc1(x))

x = self.relu(self.fc2(x))

x = self.softmax(self.fc3(x))

return x

# Создаём модель, функцию потерь и оптимизатор

model = SoundClassifier()

criterion = nn.CrossEntropyLoss()

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

print("Модель создана:")

print(model)

print(f"\nКоличество параметров: {sum(p.numel() for p in model.parameters())}")

Наша сеть принимает четыре признака для каждого аудиофрейма: среднюю громкость, частоту пересечений нуля, спектральный центроид и спектральный спад. Частота пересечений нуля показывает, насколько сигнал колеблется — у шума она высокая, у музыки средняя, у речи низкая. Спектральный центроид показывает, где сосредоточена энергия спектра — у шипящих звуков он высокий, у басовых — низкий. Спектральный спад показывает, насколько спектр сконцентрирован — у тональных звуков он низкий, у шумовых — высокий.

Сеть состоит из трёх слоёв. Первый слой принимает четыре признака и выдаёт шестнадцать скрытых представлений. Второй сжимает их до восьми. Третий выдаёт три числа — вероятности для каждого класса: речь, музыка, шум. Функция активации ReLU оставляет положительные значения без изменений и обнуляет отрицательные — это простая нелинейность, которая хорошо работает на практике.

Обучение классификатора

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

python

def generate_synthetic_data(n_samples=500):

"""

Генерирует синтетические данные для демонстрации обучения.

В реальном проекте здесь была бы загрузка реальных аудиофайлов.

"""

np.random.seed(42)

data = []

labels = []

for _ in range(n_samples):

# Класс 0: Речь

data.append([

np.random.normal(0.3, 0.1), # rms: умеренная громкость

np.random.normal(0.15, 0.05), # zcr: низкая частота пересечений нуля

np.random.normal(0.8, 0.2), # centroid: низкий центроид

np.random.normal(0.6, 0.3), # rolloff: умеренный спад

])

labels.append(0)

# Класс 1: Музыка

data.append([

np.random.normal(0.4, 0.15), # rms: средняя громкость

np.random.normal(0.25, 0.08), # zcr: средняя

np.random.normal(1.5, 0.5), # centroid: средний

np.random.normal(2.0, 1.0), # rolloff: выше

])

labels.append(1)

# Класс 2: Шум

data.append([

np.random.normal(0.2, 0.1), # rms: низкая громкость

np.random.normal(0.45, 0.1), # zcr: высокая

np.random.normal(2.5, 1.0), # centroid: высокий

np.random.normal(3.0, 1.5), # rolloff: высокий

])

labels.append(2)

# Перемешиваем

data = np.array(data, dtype=np.float32)

labels = np.array(labels)

shuffle_idx = np.random.permutation(len(data))

return data[shuffle_idx], labels[shuffle_idx]