| ''' |
| Codes are from: |
| https://github.com/jaxony/unet-pytorch/blob/master/model.py |
| ''' |
|
|
| import torch |
| import torch.nn as nn |
| from diffusers import UNet2DModel |
| import einops |
| class UNetPP(nn.Module): |
| ''' |
| Wrapper for UNet in diffusers |
| ''' |
| def __init__(self, in_channels): |
| super(UNetPP, self).__init__() |
| self.in_channels = in_channels |
| self.unet = UNet2DModel( |
| sample_size=[256, 256*3], |
| in_channels=in_channels, |
| out_channels=32, |
| layers_per_block=2, |
| block_out_channels=(64, 128, 128, 128*2, 128*2, 128*4, 128*4), |
| down_block_types=( |
| "DownBlock2D", |
| "DownBlock2D", |
| "DownBlock2D", |
| "AttnDownBlock2D", |
| "AttnDownBlock2D", |
| "AttnDownBlock2D", |
| "DownBlock2D", |
| ), |
| up_block_types=( |
| "UpBlock2D", |
| "AttnUpBlock2D", |
| "AttnUpBlock2D", |
| "AttnUpBlock2D", |
| "UpBlock2D", |
| "UpBlock2D", |
| "UpBlock2D", |
| ), |
| ) |
| |
| |
| if in_channels > 12: |
| self.learned_plane = torch.nn.parameter.Parameter(torch.zeros([1,in_channels-12,256,256*3])) |
|
|
| def forward(self, x, t=256): |
| learned_plane = self.learned_plane |
| if x.shape[1] < self.in_channels: |
| learned_plane = einops.repeat(learned_plane, '1 C H W -> B C H W', B=x.shape[0]).to(x.device) |
| x = torch.cat([x, learned_plane], dim = 1) |
| return self.unet(x, t).sample |
|
|
|
|