ПрограммированиеФорумОбщее

Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal (18 стр)

Страницы: 117 18 19 2030 Следующая »
#255
(Правка: 12:08) 12:03, 20 июня 2025

Gradius
> В случае обучения рекуррентной сети очень остро встал вопрос - как правильно запитывать сеть обучающими данными?
>
> Тут фигурирует размер батча, который собственно определяет возможность обучению распараллеливаться. А в случае рекуррентной сети батч, бОльший 1 - нарушает причинность данных.
>
> Проще говоря, как распараллелить обучение при размере батча >1, но при этом не потерять причинность данных?

Решил этот вопрос.  Ответ оказался очень даже не тривиальным. Ниже изложены шаги и действия, которые в итоге привели меня к тому, что именно мне и нужно.

1) Первым делом, нашёл норамальную библиотеку, в которой реализована нужная мне архитектура рекуррентного кодека:

https://github.com/shobrook/sequitur

Конкретно: LSTM_AE

Ему нужно несколько N примеров серий TIME векторов размерностью MEL. Тоесть - лист шейпов (TIME,MEL) *N

В моём случае: выбрал TIME=4 (4 смежных фрейма спектрограммы), MEL=80 (размерность одного фрейма).

Обучил сеть и проверил.  Пришлось вытащить функцию train_model(), так как штатная quick_train() не работает с LSTM_AE

Число эпох обучения и обучающий набор сделал небольшими, чтобы посмотреть важное - насколько хорошо или плохо стыкуются между собой фреймы на границах примеров (в данном случае стык будет через TIME=4).

Мои ожидания оправдались:  стык между примерами нарушен:

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

Видны вертикальные полосы - через каждые 4 фрейма.

Значит, данная библиотека не поддерживала сохранение скрытых состояний между набором примеров.

Так и есть: модуль lstm_ae.py в функциях кодирования и декодирования  игнорируется работа со скрытым состоянием:

x, (h_n, c_n) = layer(x)

2) Далее сосредоточился на поиске решения, как сохранять скрытые состояния между наборами.

Нашёл вот что: https://discuss.pytorch.org/t/lstm-how-to-remember-hidden-and-cel… batches/11957

Конкретно здесь:

out, hidden = lstm(inputs, hidden)

В глобальный кортеж тензоров hidden мы должны сохранить следующее состояние.  А в инициализации или в отдельном методе (reset предположим)  этот кортеж тензоров должен обнуляться.

И это всё прекрасно работает в инференсе:  обученную сеть переглючило, так как учёт скрытого состояния был введён ПОСЛЕ обучения:

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

Из рисунка видно, что перыве 4 фрейма слева - идут нормально, а потом постепенно нарастают глюки из-за накопления ошибки.

Придётся переобучить сеть заново.

3)  Как оказалось,  при обучении сети это НЕ работает, так как проблема в градиенте:

RuntimeError: Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.

Решение нашёл здесь: https://stackoverflow.com/questions/48274929/pytorch-runtimeerror… cond-time-but

Конкретно помогло это:

hidden = hidden.detach()

В итоге код по обновлению скрытого состояния вышел таким (в кодере и декодере - аналогично):

            hidden=[(self.A,self.B),(self.C,self.D)]

            x,tmp=layer(x,hidden[t])

            self.A=tmp[0].detach()
            self.B=tmp[1].detach()

Без детача обучение заканчивается ошибкой с текстом выше.

В конечном итоге - удалось добиться бесшовной спектрограммы:

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

Здесь по-прежнему обучение было на скорую руку - с малым числом обучающих выборок и минимум эпох, чтобы проверить.

Ещё раз убедился в том, что готoвых решений - нет и не будет :) Всё приходится изучать и пробовать самостоятельно.

Восстановленная спектрограмма - на обученном рекуррентном автоэнкодере (временная серия 4 фрейма, число полос 80, скрытый вектор размерность 80, общее число обучающих векторов 600 000.  По сути сжатие по времени 4x ):

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

Если присмотреться - видны дефекты - стыки между сериями по 4 фрейма, так как картинка была сделана раньше, чем была введена поддержка сохранения скрытых состояний между примерами/батчами.

#256
(Правка: 2:32) 2:28, 25 июня 2025

Ну что я могу сказать...  Сделал автоэнкодер на базе рекуррентных ячеек, перепробовал все три: RNN, GRU, LSTM.  Лосс минимальный у GRU и LSTM, самая простя ячейка - это RNN, но у неё есть проблемы взрыва и затухания градиента.

Из 4-х смежных фреймов спектрограммы - получаю одно скрытое представление размерностью в 2 раза меньше.  Тоесть:

Вход:  4 фрейма 80-полосной спектрограммы (1 фрейм 16 мс)
Выход: 1 скрытое состояние размерностью 40

Выход квантую NSVQ - 12 бит.  Обучение долгое, из-за того что рекуррентная сеть.

Плюс регуляризация входных фреймов - слоем Time Jitter с вероятностью 0.5

Итого после 10  эпох, спектр выглядит так:

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

Смотрится весьма убого по сравнению с оригиналом, но на слух даёт разборчивую речь, правда голос изменился (что неважно) - он стал сиплым.  А также появился иностранный акцент: что указывает о захвате сетью каких-то более крупных признаков речи, так как обучение шло на образцах англоязычной речи,  а тестирование - на русских высказываниях.

Итого здесь выходит:

4 фрейма по 16 мс  = 64 мс = 12 бит, значит битрейт: (1000/64)*12 = 187,5 бит/c

По сути, рекуррентные сети дали эффективное сжатие по временной оси, что не дают сверточные сети.

Теперь нужно совместить сверточные слои(сжатие по оси частот)  с рекуррентными(сжатие по оси времени) и посмотреть что изменится. 

По идее, это всё позволит отбросить несущественное и оставить только важное, а также вектор меньшей размерности - лучше квантуется векторными квантователями, что уменьшит ошибку определения ближайшего из кодовой книги

#257
(Правка: 5:37) 5:35, 27 июня 2025

1) Впервые столкнулся с таким поведением во время обучения нейросети, когда достаточно 2-х/3-х эпох обучения:

Epoch 1/100, Loss: 0.284877
Epoch 2/100, Loss: 0.261488
Epoch 3/100, Loss: 0.278799
Epoch 4/100, Loss: 0.257852
Epoch 5/100, Loss: 0.264374
Epoch 6/100, Loss: 0.270392
Epoch 7/100, Loss: 0.271651
Epoch 8/100, Loss: 0.274381
Epoch 9/100, Loss: 0.262498
Epoch 10/100, Loss: 0.263773
Epoch 11/100, Loss: 0.266983
Epoch 12/100, Loss: 0.260020
Epoch 13/100, Loss: 0.259852
Epoch 14/100, Loss: 0.266786
Epoch 15/100, Loss: 0.269370
Epoch 16/100, Loss: 0.274770
Epoch 17/100, Loss: 0.278780
Epoch 18/100, Loss: 0.267804
Epoch 19/100, Loss: 0.265802
Epoch 20/100, Loss: 0.263646
Epoch 21/100, Loss: 0.265057
Epoch 22/100, Loss: 0.262379
Epoch 23/100, Loss: 0.256146
Epoch 24/100, Loss: 0.263446
Epoch 25/100, Loss: 0.273561

Обучающая выборка:  9,5 миллионов векторов. Речевые высказывания многих людей обоих полов.

2) Добавление шума uniform во внутренний слой сети при обучении - лучшая регуляризация, насильно заставляющая нейросеть именно обобщать(генерализировать), а не заучивать:

z=self.encoder(x) # z [-1..1]
Alpha=0.95         #5% Noise
noise=uniform_dist.Uniform(-1.0,+1.0).sample([z.shape[0],z.shape[1]])
z=(Alpha*z)+((1.0-Alpha)*noise) #Blend

3) То же добавление шума во входной слой (блендиг в исходные данные) - ведёт к возможности разделять речевые высказывания от тишины и шума

#258
(Правка: 7:23) 6:58, 29 июня 2025

Подборка квантователей на любой вкус и цвет: https://github.com/lucidrains/vector-quantize-pytorch

Пока испытал только FSQ. Работает. https://arxiv.org/pdf/2309.15505

Ниже - результат работы кодека на 5 кбит/c: восстановленная спектрограмма.  Параметры: 1 фрейм = 16 мс, рекуррентный авто-энкодер с тайм-слотом 4 фрейма, скрытое состояние - 80 измерений, квантование скрытого состояния - FSQ : 16 уровней -  4 бита на каждое измерение.

Обучающий набор: 2 400 000 речевых сегментов размером 80x4.  Англоязычная речь, несколько разных голосов обоих полов.  Проверочный набор - высказывания на русском.

При этом я не дополнял датасет примерами со сдвигами на +1/+2/+3 фрейма(как об этом писал ранее, когда экспериментировал со свёрточными сетями) - для улучшения к временной инвариантности. Подразумевалось, что рекуррентная нейросеть должна самостоятельно вывозить временные корреляции между соседними фреймами.

Итого итоговый битрейт: 1000 ms*80 band *4 bits /(4 frames *16 ms) = 5000 бит/c.

На слух - практически нет различий по сравнению с оригинальной спектрограммой.  Озвучка спектрограммы - через MELGAN. 
Чисто субъективно лучше, чем кодек CELP на 4800 бит/c и GSM 9600 бит/c. Не говоря уже о том, что частота семплирования 16 кГц, а не 8 кГц(как принято в телефонии).

Лосс реконструкции: классический MSE - на 20-й эпохе Loss: 0.000414.  Лосс применялся к сегменту спектрограммы размером 80x4 пикселей (80 полос, 4 фрейма по времени). Спектрограмма глобально нормирована в диапазоне [0..1)

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal



P.S.
Вот чем мне нравятся скалярные квантователи, так это тем, что им нужен только STE, без дополнительных лоссов.  И что очень важно: более предсказуемый результат на проверочных/незнакомых данных, так как кодовых книг у скалярных квантователей нет. 
Векторные квантователи на тестовых/незнакомых данных вносят очень большой лосс реконструкции.

P.P.S. Всё больше и больше убеждаюсь, что Torch (и его реализация на Питоне - PyTorch) - очень гибкий и стабильный фреймворк.  Ещё ни разу не было такого, чтобы скачанный с гитхаба сорец на Торче отказался запускаться. 

Ну и  граф вычислений более удачно сделан, чем в Keras/Tensorflow : можно без проблем смешивать обучение с инференсом другой сети, или получать доступ к весам слоёв напрямую.  Чего не скажешь о tensorflow и тем более Keras.

Они там кстати новый фреймворк на базе tensorflow запилили Sonnet:  https://github.com/google-deepmind/sonnet

Проверил его на примере VQ-VAE: работает.  Даже ничего править не пришлось.  Секрет прост: они как-то изнасиловали tensorflow, заставив его современную версию работать по-старому, отбросив все придурошные нововведения, которые только мешали собирать проекты.

#259
23:29, 29 июня 2025

Gradius
> При этом я не дополнял датасет примерами со сдвигами на +1/+2/+3 фрейма(как об этом писал ранее, когда экспериментировал со свёрточными сетями) - для улучшения к временной инвариантности.
Мне кажется, это зря: на халяву увеличить обучающий набор в несколько раз — дорого стоит.

#260
(Правка: 2:22) 2:09, 30 июня 2025

}:+()___ [Smile]
> Мне кажется, это зря: на халяву увеличить обучающий набор в несколько раз — дорого стоит.

Дополнил датасет примерами со сдвигами 1/2/3 - дообучил сеть.  Качество спектрограммы осталось тем же, лосс почти не уменьшился.

———

Сократил битрейт кодека вчетверо: с 5000 бит/c - до 1250 бит/c.  Просто добавил пару линейных слоёв: 80=>20 и 20=>80  без активаций, после- и до- реккурентных ячеек.  Дополнительно сделал стейк из трёх LSTM в кодере и декодере, раньше был только 1 слой.

Применение 2-х стейков/слоёв LSTM вместо одного - уже уменьшает лосс почти в 2 раза при прочих равных условиях.

Лосс после 40 эпох обучения MSE=0.000654

Визуально спектрограмма немного хуже, чем в случае с 5000 бит/c, но на слух терпимо - разборчивость сохраняется (она вообще всегда сохраняется при использовании MELGAN, чего не скажешь о PyWorld).

Чисто субъективно, качество и разборчивость вышла намного превосходящей аналогичные кодеки MELP 2400 бит/c и LPC-10 2400 бит/c.

Проверяю, естественно, на данных, которые не были в обучении.

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal


А это латентное пространство (проекция скрытого состояния последнего слоя LSTM ячейки - на линейный слой ), квантованный выход после кодера - сжатие по времени в 4 раза, число уникальных цветов - 16 (квантование 4 бита на каждое измерение скрытого состояния):

2 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal


Смотрю на это, и собственно не вижу ничего похожего на фонемы - в скрытом пространстве.  Больше похоже на шум - в сегментах где речь.

#261
2:59, 30 июня 2025

Gradius
> Больше похоже на шум
Это, как раз, не удивительно: идеальное сжатие выглядит неотличимо от шума.
Если видно какую-то структуру, то это только значит, что еще остался потенциал для уменьшения битрейта.

#262
(Правка: 6:34) 6:16, 30 июня 2025

}:+()___ [Smile]
> Это, как раз, не удивительно: идеальное сжатие выглядит неотличимо от шума.
> Если видно какую-то структуру, то это только значит, что еще остался потенциал для уменьшения битрейта.

В таком случае векторное квантование в пролёте. Так как из кодовой книги ищутся вектора, ближайшие по минимальной евклидовой дистанции (или по косинусному сходству - для нормированных векторов).  А тут - что ни вектор - так резко отличается от других.

И кстати, неизвестно что выдаст, если взять среднее двух векторов.

Остаётся только скалярное квантование - когда каждое измерение квантуется отдельно.

В случае с кодеком на 1250 бит/c,  скалярное квантование 16 значений на кажое из 20 измерений. Даёт многообразие,  какое давала бы кодовая книга с 16^20 = 1 208 925 819 614 629 174 706 176 значений. Это офигеть как много.

В то же время, обучающая выборка:  всего 2 400 000 записей.

Векторные квантователи на 4096 записей (и даже 65536 записей) - дают очень плохой результат на валидационных данных.  На обучающих данных - результат удовлетворительный.

Из чего я делаю вывод, что сеть при обучении - просто подстраивается под конкретный векторный квантователь и под эти данные.  На валидации будет облом.

Я бы хотел увидеть протяжённости в скрытом пространстве, которые монотонно переходили из одного в другое,  типо фонем/слогов/дифонов/трифонов.  При этом количество их было бы жёстко задано.  При этом обучение шло без ручных меток - сеть должна сама научиться находить и выделять участки речи и кластеризовать их в фонемное или слоговое множество.

А этого нет.  Вместо этого - просто шум:  между соседними сегментами 80x4(64 мс) - в латентном пространстве 20x1 - нет плавности перехода.

Вот для сравнения, вместо скалярного квантования - векторное 16 бит (кодовая книга на 64K записей).

Восстановленный спектр, выглядит намного хуже, чем при скалярном квантовании:

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal


А вот его латентное пространство - снова шум в речевых сегментах:

2 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

Выходит, что на спектре по временной оси всё перетекает плавно, а когда сжали по времени (по 4 фрейма - в 1 сегмент) - получается шум.

Хотя длина фонемы/слога может быть и до 200 мс, что намного больше чем 64 мс (1 сегмент).

В идеале, хотелось бы представления в латентном пространстве - что-то типа такого:

posteriorgram | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal Screenshot 2024-06-03 at 14.03.28 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal
#263
14:59, 5 июля 2025

Возвращаясь к фокальной модуляции: https://arxiv.org/pdf/2203.11926

По результатам уделала аттеншены:

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal
#264
(Правка: 10:54) 10:46, 6 июля 2025

Немаловажно проверять распределение в скрытом пространстве - с целью, чтобы оценить насколько качественно и без зазоров кластеризованы векторы.

Как вариант - t-SNE.  При таком подходе можно представить многомерные вектора, как 2- или 3- мерные и вывести их на плоскость/куб.

Ниже - результат SFVQ квантования скрытого пространства автоэнкодера на 32 значения:

2 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

Более крупнее:

+ Показать

Получились спагетти, что ожидаемо :)

Внутреннее представление (непрерывно):

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

Внутреннее представление (SFVQ квантование на 32 значения):

2 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

P.S. Пытаюсь найти "фонемы" в скрытом пространстве, экспериментируя с лоссами и регуляризациями.

Точнее - вылепить пространство, которе содержало бы подобия фонем, позволяющих дискретизировать участки по времени.

#265
(Правка: 4:28) 4:08, 7 июля 2025

Итак, что мы имеем на сегодняшний день.

1) Модель речевого кодека на 5000/2500/1250/625 бит/c на базе рекуррентных ячеек сети, работающий со спектрограммой и дающий разборчивый и натуральный голос с минимальными искажениями: на спектрограмме и на слух.

2) Модель речевого кодека на 5000/2500 бит/c на базе свёрточных 1D ячеек сети, работающий также со спектрограммой и дающий звук того же качества, что и в п. 1).

Все попытки получить битрейт ещё ниже (200 - 300 бит/c), не меняя стратегии (работа со спектрограммой): редуцирование по оси частот или по оси времени - приводят к одному результату: искажения сильно растут, спектрограмма "разваливается":  звук становится дрожащим и/или сиплым. Разборчивость снижается, но остаётся удовлетворительной.

Поэтому, как писал в предыдущем посте, копаю далее в сторону "вылепливания фонемо-подобных паттернов" в скрытом представлении.

Начал читать про контрастно-предиктированное кодирование (CPC). Основы изложены здесь: https://arxiv.org/pdf/1807.03748

Суть метода - обучить кодер давать репрезентативные представления (не тривиальные, а богатые признаками) входных данных. Это именно то, чего не хватает спектрограммам. Проще говоря, нужна токенизация, "трансформер" своего рода:


1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

При этом не требуется разметки данных, что само по себе очень ценно.

В простейшем случае CPC-сеть состоит из кодера (ячейка свёртки) и авто-регрессора (рекуррентная ячейка).  Сеть выводит представления векторов, которые похожи на смежные вектора и различны с дальними.  В идеале - на основе речевых данных сеть должна вывести элементы языка(алфавит из токенов), что близко к фонемам.

Удалось запустить обучение по методу CPC, пока на WAV-форме.  Под спектрограмму адаптирую позже.

Распределение после кластеризации(квантования) выходит таким:


1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

+ Показать


Визуально вижу "цветок" - более равномерное и упорядоченное покрытие.

Но есть проблемы:

1) При переобучении вектора на выходе настолько контрастируют  друг с другом - что между соседними появляется шум. Надо будет проверить как со спeктрограммой пойдёт обучение.

Может придётся срезать градиент, чтобы не допустить его взрыва, и поиграться с температурой в функции потерь InfoNCE.

2) Более того, CPC метод(также, как и классический метод обучения авто-энкодера) может дать коллапс скрытого пространства (только снижение размерности) при:

а) неправильно подобранных параметрах обучения
б) отстуствии нужной регуляризации
в) неправильной архитектуре сети

3 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

В этом случае решение будет тривиальным.  Слева - вариант колапсирования векторов в близко похожие (случай известен, как - "постоянное кодирование"),  справа - снижение размерности скрытого пространства - вектора после обучения попали на плоскость. А должны быть на всей сфере.

Более детально про коллапс и методы его обхода здесь: https://arxiv.org/pdf/2110.09348v3

#266
5:36, 7 июля 2025

Gradius
> Ниже - результат SFVQ квантования скрытого пространства автоэнкодера на 32 значения
Это же график точек? Как я и говорил ранее, выглядит ужасно: вдоль линий плотность сильно завышена, поперек — явно недостаточна. Либо это артефакт визуализации и точки не вплотную стоят, а разнесены поперек экрана, либо теряешь несколько битов на каждой точке. По идее, качество можно оценить по распределению попарных расстояний, но тут я не специалист.

> Все попытки получить битрейт ещё ниже (200 - 300 бит/c), не меняя стратегии (работа со спектрограммой): редуцирование по оси частот или по оси времени - приводят к одному результату: искажения сильно растут, спектрограмма "разваливается": звук становится дрожащим и/или сиплым.
Математику не обманешь: каждое сообщение имеет свою энтропию, ниже которой сжать нельзя. Можно только выбрать, какую часть данных допустимо выкинуть, с соответствующей потерей информации.

#267
(Правка: 6:57) 6:42, 10 июля 2025

}:+()___ [Smile]
> Это же график точек?

Да.

}:+()___ [Smile]
> Как я и говорил ранее, выглядит ужасно: вдоль линий плотность сильно завышена, поперек — явно недостаточна. Либо это артефакт визуализации и точки не вплотную стоят, а разнесены поперек экрана, либо теряешь несколько битов на каждой точке.

Это из-за архитектуры SFVQ.

}:+()___ [Smile]
> Математику не обманешь: каждое сообщение имеет свою энтропию, ниже которой сжать нельзя. Можно только выбрать, какую часть данных допустимо выкинуть, с соответствующей потерей информации.

Не обязательно сжимать, а потом восстанавливать. Можно пойти по пути извлечения фич, далее на синтезирующей стороне строить по эталонным фонемам полноценную речь.

———

1) Запустил Tacotron: https://github.com/bshall/Tacotron

Это фонетический синтезатор человеческой речи. На вход коды фонем, на выходе Mel-спектрограмма.

Воспроизводить любой читалкой спектра.  Штатная читалка спектра у автора репозитория UniVoc - слишком медленно работает.  MELGAN работает намного быстрее.

Вопрос, который актуален как никогда: возможно ли этот Tacotron переобучить не на языковые фонемы, а на некие фонетические представления, которые даёт энкодер в своём латентном пространстве?

В этом случае можно было бы  передавать не дискретные значения фонемо-подобных элементов, а непрерывные апостериоры со слоя софт-макса кодера.

2)  Обнаружил замечательный факт:  свёртка спектрограммы во времени даёт более качественную восстановленную спектрограмму на выходе. 

Ранее я делал свёртку по частотам. Это приводило к заметному искажению спектрограммы при квантовании - особенно терялись формантные полосы.

Корифеи науки нейросетей в своих трудах пишут, что спектрограмма - это довольно бедное (не репрезентативное) представление в качестве входных данных.  И чтобы из неё сеть извлекла признаки - идут на ухищрение:  размножают частотные каналы, пропуская их через несколько сверток во времени, применяют контрастивно-предиктивное кодирование, добавляют дельты (производные), дополняют ДКП и их дельтами,...  Чтобы хоть как-то увеличить информативность на входе.

Поэтому свёртка по частотам - в моём случае убивало фичность входных данных ещё больше. Что делало разультат векторного квантования просто ужасным.

Лучше использовать WAV-форму вместо спектрограммы, но тогда возрастают сильно требования к памяти и вычислительным ресурсам, что недопустимо в моих целях.

Ниже спектрограмма, полученная с помощью временной свёртки в кодере и рекуррентной ячейке декодера.  Сжатие во времени здесь 4 фрейма (16 мс * 4),  квантование фич - 12 бит.  Квантователь - NSVQ (который  дышит шумом при обучении, обнуляя лоссы квантователя - что очень хорошо).

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

И это уже:  1000*12/64 = 188 бит/c ! :)

Сохранены формантные полосы.  Из минусов: видны вертикальные стыки блоков шириной по 32 полосы - пока не понял, как с этим бороться на уровне нейросети.  Вижу, что проще всего - интерполировать шов, как писал об этом ранее.

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

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal

И тут тоже видны швы :)


Намного лучше, чем вот эта предыдущая попытка, которая получена свёрткой по частотам:

Изображение
#268
(Правка: 3:02) 2:54, 11 июля 2025

Gradius
> Из минусов: видны вертикальные стыки блоков шириной по 32 полосы - пока не понял, как с этим бороться на уровне нейросети.

Стыки возникали, потому что подавал спектрограмму частями, кратными 32.  Отрешейпил тестовую спектрограмму в одну большую часть, получилось без швов:

1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal
1 | Нейросети на базе Keras, Tensorflow, Torch и другие. Теория и практика применения. Pyhton/C++/Pascal


Звучит на слух разборчиво, мягко, без хрипа и дрожания.  С иностранным акцентом: напоминает результат, как в FocalCodec.

Здесь MSE лосс по всей спектрограмме: 0.003592. Причем это результат квантования на 4096 записей(12 бит) из кодовой книги.

В FocalCodec используется 8192 записей(13 бит)

Можно попытаться уменьшить лосс путём более тщательной подборки слоёв кодека, что и собираюсь попробовать.


Gradius
> 2) Обнаружил замечательный факт: свёртка спектрограммы во времени даёт более качественную восстановленную спектрограмму на выходе.
>
> Ранее я делал свёртку по частотам. Это приводило к заметному искажению спектрограммы при квантовании - особенно терялись формантные полосы.

Здесь важно другое:  свёртка и квантование должны быть ортогональны по направлениям.

Раньше направление свертки (частоты) было параллельно квантованию (по частотам).

Только в случае перпендикулярности получается эффективное квантование.  Все нейронные кодеки, которые смотрел, применяют свёртку по времени, а квантование по фичам (частотным банкам).

Но никто из них не делает 1D свертку по частотам и квантование по ним.

#269
(Правка: 13 июля 2025, 1:20) 6:31, 12 июля 2025

Gradius
> Квантователь - NSVQ

1) Обнаружил у данного квантователя недостаток: скорость обучения нейросети происходит намного быстрее, чем обучение векторов кодовой книги квантователя.

В связи с этим, значение лосса при обучении становится намного ниже, чем лосс валидации.
Потому что согласно концепции NSVQ, обучение квантователя никак не влияет на градиент сети в целом (так как происходит компенсация скачка градиента шумом), а вот вектора отливаются запоздало.

В итоге наблюдаю монотонное уменьшение лосса сети при обучении (что правильно),  и скачки лосса валидации - от неприлично высокого, до редко низкого.

При этом, я контроллирую степень  использования записей кодовой книги - те, что сильно редкие (допустим - менее 10% использования) - я выкидываю и перераспределяю заново (это всё может делать функционал NSVQ).

Выходит, что книга не схлопывается (что собственно и нужно), но результат не всегда оптимален и обобщаем.

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

Сейчас пробую другие квантователи (у которых дополнительный лосс).

2)  Обнаружил, что MELGAN даёт звук по качеству хуже, чем Vocos.    Но Vocos не подходит из-за его огромной модели, которая к тому же ест много вычислительных ресурсов.

Нужен спектральный вокодер, но с превосходным качеством звука, по сравнению с MELGAN.

Оценил субъективно, сравнивая на слух одни и те же звуковые данные.  Vocos звучит  намного приятнее MelGAN'а.

3) Удалось подключить к своему кодеку блоки фокальной модуляции.  Про FocalNet я говорил выше.  Хорошо замещает устаревшие Attention.

С примнением ячеек FocalNet сходимость сети ускоряется по сравнению со свёрточными блоками и ячейками ResNet.

Общий лосс сети упал на 28%.

Страницы: 117 18 19 2030 Следующая »
ПрограммированиеФорумОбщее