Embeds class labels into vector representations. Also handles label dropout for classifier-free guidance.
| 175 | |
| 176 | |
| 177 | class CaptionEmbedder(nn.Module): |
| 178 | """ |
| 179 | Embeds class labels into vector representations. Also handles label dropout for classifier-free guidance. |
| 180 | """ |
| 181 | |
| 182 | def __init__( |
| 183 | self, |
| 184 | in_channels, |
| 185 | hidden_size, |
| 186 | uncond_prob, |
| 187 | act_layer=nn.GELU(approximate="tanh"), |
| 188 | token_num=120, |
| 189 | ): |
| 190 | super().__init__() |
| 191 | self.y_proj = Mlp( |
| 192 | in_features=in_channels, |
| 193 | hidden_features=hidden_size, |
| 194 | out_features=hidden_size, |
| 195 | act_layer=act_layer, |
| 196 | drop=0, |
| 197 | ) |
| 198 | self.register_buffer( |
| 199 | "y_embedding", |
| 200 | nn.Parameter(torch.randn(token_num, in_channels) / in_channels**0.5), |
| 201 | ) |
| 202 | self.uncond_prob = uncond_prob |
| 203 | |
| 204 | def token_drop(self, caption, force_drop_ids=None): |
| 205 | """ |
| 206 | Drops labels to enable classifier-free guidance. |
| 207 | """ |
| 208 | if force_drop_ids is None: |
| 209 | drop_ids = torch.rand(caption.shape[0]).cuda() < self.uncond_prob |
| 210 | else: |
| 211 | drop_ids = force_drop_ids == 1 |
| 212 | caption = torch.where(drop_ids[:, None, None, None], self.y_embedding, caption) |
| 213 | return caption |
| 214 | |
| 215 | def forward(self, caption, train, force_drop_ids=None): |
| 216 | if train: |
| 217 | assert ( |
| 218 | caption.shape[1:] == self.y_embedding.shape |
| 219 | ), f"{caption.shape} is not {self.y_embedding.shape}" |
| 220 | use_dropout = self.uncond_prob > 0 |
| 221 | if (train and use_dropout) or (force_drop_ids is not None): |
| 222 | caption = self.token_drop(caption, force_drop_ids) |
| 223 | caption = self.y_proj(caption) |
| 224 | return caption |
| 225 | |
| 226 | |
| 227 | ################################################################################# |
nothing calls this directly
no outgoing calls
no test coverage detected