MCPcopy Index your code
hub / github.com/PrathamLearnsToCode/paper2code / UNet

Class UNet

skills/paper2code/worked/ddpm/src/model.py:219–382  ·  view source on GitHub ↗

§3.3, Appendix B — U-Net noise prediction network ε_θ(x_t, t). "We use a U-Net backbone similar to an unmasked PixelCNN++ with group normalization throughout, and we add one head of self-attention at the 16×16 feature map resolution." The U-Net takes a noisy image x_t and a times

Source from the content-addressed store, hash-verified

217# ---------------------------------------------------------------------------
218
219class UNet(nn.Module):
220 """§3.3, Appendix B — U-Net noise prediction network ε_θ(x_t, t).
221
222 "We use a U-Net backbone similar to an unmasked PixelCNN++ with
223 group normalization throughout, and we add one head of self-attention
224 at the 16×16 feature map resolution."
225
226 The U-Net takes a noisy image x_t and a timestep t, and predicts the
227 noise ε that was added. This is NOT the paper's core contribution —
228 it is the backbone model that enables the diffusion process.
229
230 Architecture (for CIFAR-10 32×32):
231 Down: 32→32→16→8→4 (with skip connections)
232 Middle: bottleneck with attention
233 Up: 4→8→16→32→32 (with skip connections from down path)
234 """
235
236 def __init__(self, config: UNetConfig):
237 super().__init__()
238 self.config = config
239 ch = config.base_channels
240
241 # Time embedding: sinusoidal -> MLP
242 # §3.3 — "Transformer sinusoidal position embedding"
243 time_embed_dim = config.time_embed_dim
244 self.time_embed = nn.Sequential(
245 SinusoidalTimeEmbedding(ch),
246 nn.Linear(ch, time_embed_dim),
247 nn.SiLU(),
248 nn.Linear(time_embed_dim, time_embed_dim),
249 )
250
251 # Initial convolution
252 self.input_conv = nn.Conv2d(config.image_channels, ch, kernel_size=3, padding=1)
253
254 # Downsampling path
255 self.down_blocks = nn.ModuleList()
256 self.down_samples = nn.ModuleList()
257 channels = [ch]
258 current_res = config.image_size
259 in_ch = ch
260
261 for level, mult in enumerate(config.channel_mults):
262 out_ch = ch * mult
263 for _ in range(config.num_res_blocks):
264 layers = [ResidualBlock(in_ch, out_ch, time_embed_dim,
265 config.dropout, config.num_groups)]
266 if current_res in config.attention_resolutions:
267 layers.append(AttentionBlock(out_ch, config.num_groups))
268 self.down_blocks.append(nn.ModuleList(layers))
269 channels.append(out_ch)
270 in_ch = out_ch
271
272 if level < len(config.channel_mults) - 1:
273 self.down_samples.append(Downsample(out_ch))
274 channels.append(out_ch)
275 current_res //= 2
276 else:

Callers 2

trainFunction · 0.90
load_modelFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected