This matches the implementation in Denoising Diffusion Probabilistic Models: Create sinusoidal timestep embeddings. :param timesteps: a 1-D Tensor of N indices, one per batch element. These may be fractional. :param embedding_dim: the dimension of the output. :par
(
timesteps: torch.Tensor,
embedding_dim: int,
flip_sin_to_cos: bool = False,
downscale_freq_shift: float = 1,
scale: float = 1,
max_period: int = 10000,
)
| 101 | |
| 102 | |
| 103 | def get_timestep_embedding( |
| 104 | timesteps: torch.Tensor, |
| 105 | embedding_dim: int, |
| 106 | flip_sin_to_cos: bool = False, |
| 107 | downscale_freq_shift: float = 1, |
| 108 | scale: float = 1, |
| 109 | max_period: int = 10000, |
| 110 | ): |
| 111 | """ |
| 112 | This matches the implementation in Denoising Diffusion Probabilistic Models: Create sinusoidal timestep embeddings. |
| 113 | |
| 114 | :param timesteps: a 1-D Tensor of N indices, one per batch element. |
| 115 | These may be fractional. |
| 116 | :param embedding_dim: the dimension of the output. :param max_period: controls the minimum frequency of the |
| 117 | embeddings. :return: an [N x dim] Tensor of positional embeddings. |
| 118 | """ |
| 119 | assert len(timesteps.shape) == 1, "Timesteps should be a 1d-array" |
| 120 | |
| 121 | half_dim = embedding_dim // 2 |
| 122 | exponent = -math.log(max_period) * torch.arange( |
| 123 | start=0, end=half_dim, dtype=torch.float32, device=timesteps.device |
| 124 | ) |
| 125 | exponent = exponent / (half_dim - downscale_freq_shift) |
| 126 | |
| 127 | emb = torch.exp(exponent) |
| 128 | emb = timesteps[:, None].float() * emb[None, :] |
| 129 | |
| 130 | # scale embeddings |
| 131 | emb = scale * emb |
| 132 | |
| 133 | # concat sine and cosine embeddings |
| 134 | emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=-1) |
| 135 | |
| 136 | # flip sine and cosine embeddings |
| 137 | if flip_sin_to_cos: |
| 138 | emb = torch.cat([emb[:, half_dim:], emb[:, :half_dim]], dim=-1) |
| 139 | |
| 140 | # zero pad |
| 141 | if embedding_dim % 2 == 1: |
| 142 | emb = torch.nn.functional.pad(emb, (0, 1, 0, 0)) |
| 143 | return emb |
| 144 | |
| 145 | |
| 146 | class Timesteps(nn.Module): |