(self, latents: Tensor)
| 22 | self.embedding.weight.data.uniform_(-1 / self.K, 1 / self.K) |
| 23 | |
| 24 | def forward(self, latents: Tensor) -> Tensor: |
| 25 | latents = latents.permute(0, 2, 3, 1).contiguous() # [B x D x H x W] -> [B x H x W x D] |
| 26 | latents_shape = latents.shape |
| 27 | flat_latents = latents.view(-1, self.D) # [BHW x D] |
| 28 | |
| 29 | # TODO 计算隐藏向量和嵌入向量权重之间的L2距离 Compute L2 distance between latents and embedding weights |
| 30 | dist = torch.sum(flat_latents ** 2, dim=1, keepdim=True) + \ |
| 31 | torch.sum(self.embedding.weight ** 2, dim=1) - \ |
| 32 | 2 * torch.matmul(flat_latents, self.embedding.weight.t()) # [BHW x K] |
| 33 | |
| 34 | # TODO 获得最小距离对应的索引 Get the encoding that has the min distance |
| 35 | encoding_inds = torch.argmin(dist, dim=1).unsqueeze(1) # [BHW, 1] |
| 36 | |
| 37 | # TODO 将其索引转换为对应的one-hot编码 Convert to one-hot encodings |
| 38 | device = latents.device |
| 39 | encoding_one_hot = torch.zeros(encoding_inds.size(0), self.K, device=device) |
| 40 | encoding_one_hot.scatter_(1, encoding_inds, 1) # [BHW x K] |
| 41 | |
| 42 | #TODO 获得离散化隐藏向量空间 Quantize the latents |
| 43 | quantized_latents = torch.matmul(encoding_one_hot, self.embedding.weight) # [BHW, D] |
| 44 | quantized_latents = quantized_latents.view(latents_shape) # [B x H x W x D] |
| 45 | |
| 46 | # TODO Compute the VQ Losses |
| 47 | commitment_loss = F.mse_loss(quantized_latents.detach(), latents) |
| 48 | embedding_loss = F.mse_loss(quantized_latents, latents.detach()) |
| 49 | |
| 50 | vq_loss = commitment_loss * self.beta + embedding_loss |
| 51 | |
| 52 | # Add the residue back to the latents |
| 53 | quantized_latents = latents + (quantized_latents - latents).detach() |
| 54 | |
| 55 | return quantized_latents.permute(0, 3, 1, 2).contiguous(), vq_loss # [B x D x H x W] |
| 56 | |
| 57 | class ResidualLayer(nn.Module): |
| 58 |
nothing calls this directly
no outgoing calls
no test coverage detected