Я новичок в машинном обучении/нейронных сетях и хочу реализовать вариационный автоэнкодер, который принимает в качестве входных данных одномерные массивы Numpy (форму волны звуковых файлов). Запуск файла не вызывает ошибки, но потери приближаются к 2000 году, и реконструкция выглядит как чистый шум.
Я использовал код от Goffinet et al. (https://doi.org/10.7554/eLife.67855) и попытался переписать его, чтобы он принимал одномерные входные данные, поскольку раньше я работал с их (2-D) Vae. Это код для сети и функции пересылки:
def _build_network(self):
# Encoder
self.conv1 = nn.Conv1d(1, 8, 3,1,padding=1)
self.conv2 = nn.Conv1d(8, 8, 3,2,padding=1)
self.conv3 = nn.Conv1d(8, 16,3,1,padding=1)
self.conv4 = nn.Conv1d(16,16,3,2,padding=1)
self.conv5 = nn.Conv1d(16,24,3,1,padding=1)
self.conv6 = nn.Conv1d(24,24,3,2,padding=1)
self.conv7 = nn.Conv1d(24,32,3,1,padding=1)
self.bn1 = nn.BatchNorm1d(1)
self.bn2 = nn.BatchNorm1d(8)
self.bn3 = nn.BatchNorm1d(8)
self.bn4 = nn.BatchNorm1d(16)
self.bn5 = nn.BatchNorm1d(16)
self.bn6 = nn.BatchNorm1d(24)
self.bn7 = nn.BatchNorm1d(24)
self.fc1 = nn.Linear(1800,1024)
self.fc2 = nn.Linear(1024,256)
self.fc31 = nn.Linear(256,64)
self.fc32 = nn.Linear(256,64)
self.fc33 = nn.Linear(256,64)
self.fc41 = nn.Linear(64,self.z_dim)
self.fc42 = nn.Linear(64,self.z_dim)
self.fc43 = nn.Linear(64,self.z_dim)
# Decoder
self.fc5 = nn.Linear(self.z_dim,64)
self.fc6 = nn.Linear(64,256)
self.fc7 = nn.Linear(256,1024)
self.fc8 = nn.Linear(1024,1800)
self.convt1 = nn.ConvTranspose1d(32,24,3,1,padding=1)
self.convt2 = nn.ConvTranspose1d(24,24,3,2,padding=1,output_padding=1)
self.convt3 = nn.ConvTranspose1d(24,16,3,1,padding=1)
self.convt4 = nn.ConvTranspose1d(16,16,3,2,padding=1,output_padding=1)
self.convt5 = nn.ConvTranspose1d(16,8,3,1,padding=1)
self.convt6 = nn.ConvTranspose1d(8,8,3,2,padding=1,output_padding=1)
self.convt7 = nn.ConvTranspose1d(8,1,3,1,padding=1)
self.bn8 = nn.BatchNorm1d(32)
self.bn9 = nn.BatchNorm1d(24)
self.bn10 = nn.BatchNorm1d(24)
self.bn11 = nn.BatchNorm1d(16)
self.bn12 = nn.BatchNorm1d(16)
self.bn13 = nn.BatchNorm1d(8)
self.bn14 = nn.BatchNorm1d(8)
def encode(self, x):
#print("encoder x:",x.shape)
x = x.unsqueeze(1)
#nn.Flatten(x)
#print("encoder x:",x.shape)
x = F.relu(self.conv1(self.bn1(x)))
x = F.relu(self.conv2(self.bn2(x)))
x = F.relu(self.conv3(self.bn3(x)))
x = F.relu(self.conv4(self.bn4(x)))
x = F.relu(self.conv5(self.bn5(x)))
x = F.relu(self.conv6(self.bn6(x)))
x = F.relu(self.conv7(self.bn7(x)))
#print(" x:",x.shape)
x = x.view(-1, 1800)
#print(" x:",x.shape)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
mu = F.relu(self.fc31(x))
mu = self.fc41(mu)
u = F.relu(self.fc32(x))
u = self.fc42(u).unsqueeze(-1) # Last dimension is rank \Sigma = 1.
d = F.relu(self.fc33(x))
d = torch.exp(self.fc43(d)) # d must be positive.
return mu, u, d
def decode(self, z):
#print(z.shape)
z = F.relu(self.fc5(z))
z = F.relu(self.fc6(z))
z = F.relu(self.fc7(z))
z = F.relu(self.fc8(z))
#print("z shape before view", z.shape)
z = z.view(-1,32,1800)#16,16)
#print("z shape after view", z.shape)
z = F.relu(self.convt1(self.bn8(z)))
z = F.relu(self.convt2(self.bn9(z)))
z = F.relu(self.convt3(self.bn10(z)))
z = F.relu(self.convt4(self.bn11(z)))
z = F.relu(self.convt5(self.bn12(z)))
z = F.relu(self.convt6(self.bn13(z)))
z = self.convt7(self.bn14(z))
#print("z shape end decode", z.shape)
return z.view(-1, 14400)
def forward(self, x, return_latent_rec=False):
#print("forward", x.shape)
mu, u, d = self.encode(x)
#print(mu.shape,u.shape,d.shape)
latent_dist = LowRankMultivariateNormal(mu, u, d)
z = latent_dist.rsample()
#print("z:",z.shape)
x_rec = self.decode(z)
# E_{q(z|x)} p(z)
elbo = -0.5 * (torch.sum(torch.pow(z,2)) + self.z_dim * np.log(2*np.pi))
# E_{q(z|x)} p(x|z)
# pxz_term = -0.5 * X_DIM * (np.log(2*np.pi/self.model_precision))
pxz_term = -0.5 * 14400 * (np.log(2*np.pi/self.model_precision))
#print("x(input)",x.shape)
#print("x_rec(vae)",x_rec.shape)
l2s = torch.sum(torch.pow(x.view(x.shape[0],-1) - x_rec, 2), dim=1)
pxz_term = pxz_term - 0.5 * self.model_precision * torch.sum(l2s)
elbo = elbo + pxz_term
# H[q(z|x)]
elbo = elbo + torch.sum(latent_dist.entropy())
if return_latent_rec:
return -elbo, z.detach().cpu().numpy(), \
x_rec.view(-1, 128, 128).detach().cpu().numpy()
return -elbo
Мой реконструированный график выглядит следующим образом:
введите здесь описание изображения
Есть ли у кого-нибудь идеи, как улучшить мой VAE? Кстати, использовать любой другой способ отображения звука (например, спектрограммы) вместо волновых форм, к сожалению, не вариант.
Я поигрался со скрытым измерением и заметил небольшие улучшения в потерях, но все равно неудовлетворительно (1800 вместо 2000) и реконструкции совсем не улучшились
Я новичок в машинном обучении/нейронных сетях и хочу реализовать вариационный автоэнкодер, который принимает в качестве входных данных одномерные массивы Numpy (форму волны звуковых файлов). Запуск файла не вызывает ошибки, но потери приближаются к 2000 году, и реконструкция выглядит как чистый шум. Я использовал код от Goffinet et al. (https://doi.org/10.7554/eLife.67855) и попытался переписать его, чтобы он принимал одномерные входные данные, поскольку раньше я работал с их (2-D) Vae. Это код для сети и функции пересылки: [code]def _build_network(self): # Encoder self.conv1 = nn.Conv1d(1, 8, 3,1,padding=1) self.conv2 = nn.Conv1d(8, 8, 3,2,padding=1) self.conv3 = nn.Conv1d(8, 16,3,1,padding=1) self.conv4 = nn.Conv1d(16,16,3,2,padding=1) self.conv5 = nn.Conv1d(16,24,3,1,padding=1) self.conv6 = nn.Conv1d(24,24,3,2,padding=1) self.conv7 = nn.Conv1d(24,32,3,1,padding=1) self.bn1 = nn.BatchNorm1d(1) self.bn2 = nn.BatchNorm1d(8) self.bn3 = nn.BatchNorm1d(8) self.bn4 = nn.BatchNorm1d(16) self.bn5 = nn.BatchNorm1d(16) self.bn6 = nn.BatchNorm1d(24) self.bn7 = nn.BatchNorm1d(24) self.fc1 = nn.Linear(1800,1024) self.fc2 = nn.Linear(1024,256) self.fc31 = nn.Linear(256,64) self.fc32 = nn.Linear(256,64) self.fc33 = nn.Linear(256,64) self.fc41 = nn.Linear(64,self.z_dim) self.fc42 = nn.Linear(64,self.z_dim) self.fc43 = nn.Linear(64,self.z_dim) # Decoder self.fc5 = nn.Linear(self.z_dim,64) self.fc6 = nn.Linear(64,256) self.fc7 = nn.Linear(256,1024) self.fc8 = nn.Linear(1024,1800) self.convt1 = nn.ConvTranspose1d(32,24,3,1,padding=1) self.convt2 = nn.ConvTranspose1d(24,24,3,2,padding=1,output_padding=1) self.convt3 = nn.ConvTranspose1d(24,16,3,1,padding=1) self.convt4 = nn.ConvTranspose1d(16,16,3,2,padding=1,output_padding=1) self.convt5 = nn.ConvTranspose1d(16,8,3,1,padding=1) self.convt6 = nn.ConvTranspose1d(8,8,3,2,padding=1,output_padding=1) self.convt7 = nn.ConvTranspose1d(8,1,3,1,padding=1) self.bn8 = nn.BatchNorm1d(32) self.bn9 = nn.BatchNorm1d(24) self.bn10 = nn.BatchNorm1d(24) self.bn11 = nn.BatchNorm1d(16) self.bn12 = nn.BatchNorm1d(16) self.bn13 = nn.BatchNorm1d(8) self.bn14 = nn.BatchNorm1d(8)
def encode(self, x): #print("encoder x:",x.shape) x = x.unsqueeze(1) #nn.Flatten(x) #print("encoder x:",x.shape) x = F.relu(self.conv1(self.bn1(x))) x = F.relu(self.conv2(self.bn2(x))) x = F.relu(self.conv3(self.bn3(x))) x = F.relu(self.conv4(self.bn4(x))) x = F.relu(self.conv5(self.bn5(x))) x = F.relu(self.conv6(self.bn6(x))) x = F.relu(self.conv7(self.bn7(x))) #print(" x:",x.shape) x = x.view(-1, 1800) #print(" x:",x.shape) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) mu = F.relu(self.fc31(x)) mu = self.fc41(mu) u = F.relu(self.fc32(x)) u = self.fc42(u).unsqueeze(-1) # Last dimension is rank \Sigma = 1. d = F.relu(self.fc33(x)) d = torch.exp(self.fc43(d)) # d must be positive. return mu, u, d
def decode(self, z): #print(z.shape) z = F.relu(self.fc5(z)) z = F.relu(self.fc6(z)) z = F.relu(self.fc7(z)) z = F.relu(self.fc8(z)) #print("z shape before view", z.shape) z = z.view(-1,32,1800)#16,16) #print("z shape after view", z.shape) z = F.relu(self.convt1(self.bn8(z))) z = F.relu(self.convt2(self.bn9(z))) z = F.relu(self.convt3(self.bn10(z))) z = F.relu(self.convt4(self.bn11(z))) z = F.relu(self.convt5(self.bn12(z))) z = F.relu(self.convt6(self.bn13(z)))
z = self.convt7(self.bn14(z)) #print("z shape end decode", z.shape) return z.view(-1, 14400)
def forward(self, x, return_latent_rec=False): #print("forward", x.shape) mu, u, d = self.encode(x) #print(mu.shape,u.shape,d.shape) latent_dist = LowRankMultivariateNormal(mu, u, d) z = latent_dist.rsample() #print("z:",z.shape) x_rec = self.decode(z) # E_{q(z|x)} p(z) elbo = -0.5 * (torch.sum(torch.pow(z,2)) + self.z_dim * np.log(2*np.pi)) # E_{q(z|x)} p(x|z) # pxz_term = -0.5 * X_DIM * (np.log(2*np.pi/self.model_precision)) pxz_term = -0.5 * 14400 * (np.log(2*np.pi/self.model_precision)) #print("x(input)",x.shape) #print("x_rec(vae)",x_rec.shape) l2s = torch.sum(torch.pow(x.view(x.shape[0],-1) - x_rec, 2), dim=1) pxz_term = pxz_term - 0.5 * self.model_precision * torch.sum(l2s) elbo = elbo + pxz_term # H[q(z|x)] elbo = elbo + torch.sum(latent_dist.entropy()) if return_latent_rec: return -elbo, z.detach().cpu().numpy(), \ x_rec.view(-1, 128, 128).detach().cpu().numpy() return -elbo [/code] Мой реконструированный график выглядит следующим образом: введите здесь описание изображения Есть ли у кого-нибудь идеи, как улучшить мой VAE? Кстати, использовать любой другой способ отображения звука (например, спектрограммы) вместо волновых форм, к сожалению, не вариант. Я поигрался со скрытым измерением и заметил небольшие улучшения в потерях, но все равно неудовлетворительно (1800 вместо 2000) и реконструкции совсем не улучшились
Я хочу реализовать вариационный автоэнкодер, который принимает в качестве входных данных одномерные массивы Numpy (форму волны звуковых файлов). Запуск файла не вызывает ошибки, но потери приближаются к 2000 году, и реконструкция выглядит как чистый...
I am trying to write a parser. I have the parser class below, but I am struggling to write a generalized ParseMany function with templates. В настоящее время, чтобы разыграть, я использую parser.parse () , который возвращает необязательный с {} для...
Этот вопрос частично унаследован от кривой переоценки предыдущего вопроса, аппроксимирующей формулу дисперсии Шотта для стеклянного материала, так что при наличии только двух значений n_e и V_e регрессия может соответствовать кривой, которая...
Здесь немного интересный вопрос. У меня есть модель автоэнкодера CNN, построенная с использованием тензорного потока, и я пытаюсь обнаружить аномалии с использованием оценки плотности ядра вместе с ошибкой реконструкции. Это отлично работает для...