Я разделил набор данных на обучающий и тестовый наборы в соотношении 80/20. В результате получается 6902 обучающих последовательностей, каждая из которых имеет размеры (100, 107) для ЭЭГ и (100, 80) для мел-спектрограмм.
Архитектура моей модели включает в себя:
- Два пренета (один для кодера и один для декодера) для извлечения признаков из ЭЭГ и мел-спектрограмм, проецируя их во вложения. .
- Постнет для уточнения предсказанных мел-спектрограмм.
Проблема, с которой я столкнулся, заключается в том, что, хотя потери при обучении уменьшаются, модель работает плохо во время вывода. Прогнозы на проверочном наборе очень плохие, а модель также неэффективна на обучающем наборе во время вывода.
Во время вывода я прогнозирую данные следующим образом:
Код: Выделить всё
eeg_val = eeg_val.to(device)
mel_val = mel_val.to(device)
mel_input = torch.zeros([modelArgs.batch_size, 1, 80]).to(device)
pos_eeg = torch.arange(1, eeg_context_length + 1).repeat(modelArgs.batch_size, 1).to(device)
pbar = tqdm(range(config["TR"]["context_length"]), desc=f"Validating...", position=0, leave=False)
with torch.no_grad():
for _ in pbar:
pos_mel = torch.arange(1, mel_input.size(1)+1).repeat(modelArgs.batch_size, 1).to(device)
mel_out, postnet_pred, attn, _, attn_dec = model.forward(eeg_val, mel_input, pos_eeg, pos_mel)
mel_input = torch.cat([mel_input, mel_out[:,-1:,:]], dim=1)
batch_loss = criterion(postnet_pred, mel_val)
- — длина окна, т. е. 100.
Код: Выделить всё
config["TR"]["context_length"]
- и pos_mel используются для создания масок внимания
Код: Выделить всё
pos_eeg
- — выходные данные декодера, postnet_pred — выходные данные postnet
Код: Выделить всё
mel_out
Потери рассчитываются с помощью nn.L1Loss() на выходе декодера и выходе постсети: пакет_лосс = mel_loss + post_mel_loss
Некоторые прогнозы, которые делает модель:
Прогноз модели 1
Прогноз модели 2
Моя модель основана на нейронном синтезе речи с трансформаторной сетью, и я использую следующую реализацию:
Единственное различие между моей настройкой и text2Speech заключается в следующем:
[*]Я использую ЭЭГ вместо текста
[*]У меня нет стоп-токена, поскольку Я прогнозирую для фиксированного временного окна.
[*]Я создаю позиционные внедрения, используя следующий класс вместо модуля nn.Embeddings:
Код: Выделить всё
class PositionalEncoding(nn.Module):
def __init__(self, d_model, dropout=0.1, max_len=200):
super(PositionalEncoding, self).__init__()
self.dropout = nn.Dropout(p=dropout)
self.alpha = nn.Parameter(t.ones(1))
pe = t.zeros(max_len, d_model)
position = t.arange(0, max_len, dtype=t.float).unsqueeze(1)
div_term = t.exp(t.arange(0, d_model, 2).float() * (-np.log(10000.0) / d_model))
pe[:, 0::2] = t.sin(position * div_term)
pe[:, 1::2] = t.cos(position * div_term)
self.register_buffer('pe', pe)
def forward(self, x):
pos = self.pe[:x.shape[1]]
pos = t.stack([pos]*x.shape[0], 0) # [bs x seq_len(x) x n_pos]
x = pos * self.alpha + x
return self.dropout(x)
Вопрос: Что меня больше всего удивляет, так это то, что, несмотря на резко растущие потери и очень хорошие показатели корреляции (между предсказанием и истинной информацией) во время обучения, сеть работает очень плохо на одних и тех же обучающих последовательностях во время вывод -> В чем может быть причина плохой авторегрессионной производительности модели?
Я пробовал разные варианты архитектуры и сдвигал входные данные декодера вправо (как это сделано в оригинальной статье для трансформатора). Изменения в архитектуре на самом деле не привели к улучшению прогнозов, но смещение входов декодера на единицу немного улучшило прогнозы (с корреляции примерно с 0% до менее 20%).
Есть идеи или предложения?
Подробнее здесь: https://stackoverflow.com/questions/786 ... sive-perfo