(
self,
ch: int,
out_ch: int,
ch_mult: list[int],
num_res_blocks: int,
in_channels: int,
resolution: int,
z_channels: int,
)
| 182 | |
| 183 | class Decoder(nn.Module): |
| 184 | def __init__( |
| 185 | self, |
| 186 | ch: int, |
| 187 | out_ch: int, |
| 188 | ch_mult: list[int], |
| 189 | num_res_blocks: int, |
| 190 | in_channels: int, |
| 191 | resolution: int, |
| 192 | z_channels: int, |
| 193 | ): |
| 194 | super().__init__() |
| 195 | self.ch = ch |
| 196 | self.num_resolutions = len(ch_mult) |
| 197 | self.num_res_blocks = num_res_blocks |
| 198 | self.resolution = resolution |
| 199 | self.in_channels = in_channels |
| 200 | self.ffactor = 2 ** (self.num_resolutions - 1) |
| 201 | |
| 202 | # compute in_ch_mult, block_in and curr_res at lowest res |
| 203 | block_in = ch * ch_mult[self.num_resolutions - 1] |
| 204 | curr_res = resolution // 2 ** (self.num_resolutions - 1) |
| 205 | self.z_shape = (1, z_channels, curr_res, curr_res) |
| 206 | |
| 207 | # z to block_in |
| 208 | self.conv_in = nn.Conv2d(z_channels, block_in, kernel_size=3, stride=1, padding=1) |
| 209 | |
| 210 | # middle |
| 211 | self.mid = nn.Module() |
| 212 | self.mid.block_1 = ResnetBlock(in_channels=block_in, out_channels=block_in) |
| 213 | self.mid.attn_1 = AttnBlock(block_in) |
| 214 | self.mid.block_2 = ResnetBlock(in_channels=block_in, out_channels=block_in) |
| 215 | |
| 216 | # upsampling |
| 217 | self.up = nn.ModuleList() |
| 218 | for i_level in reversed(range(self.num_resolutions)): |
| 219 | block = nn.ModuleList() |
| 220 | attn = nn.ModuleList() |
| 221 | block_out = ch * ch_mult[i_level] |
| 222 | for _ in range(self.num_res_blocks + 1): |
| 223 | block.append(ResnetBlock(in_channels=block_in, out_channels=block_out)) |
| 224 | block_in = block_out |
| 225 | up = nn.Module() |
| 226 | up.block = block |
| 227 | up.attn = attn |
| 228 | if i_level != 0: |
| 229 | up.upsample = Upsample(block_in) |
| 230 | curr_res = curr_res * 2 |
| 231 | self.up.insert(0, up) # prepend to get consistent order |
| 232 | |
| 233 | # end |
| 234 | self.norm_out = nn.GroupNorm(num_groups=32, num_channels=block_in, eps=1e-6, affine=True) |
| 235 | self.conv_out = nn.Conv2d(block_in, out_ch, kernel_size=3, stride=1, padding=1) |
| 236 | |
| 237 | def forward(self, z: Tensor) -> Tensor: |
| 238 | # z to block_in |
nothing calls this directly
no test coverage detected