stable diffusion中的UNet2DConditionModel代码解读

UNet2DConditionModel总体结构
在这里插入图片描述

stable diffusion 运行unet部分的代码。

noise_pred = self.unet(
    sample=latent_model_input,  #(2,4,64,64) 生成的latent
    timestep=t,  #时刻t
    encoder_hidden_states=prompt_embeds, #(2,77,768) #输入的prompt和negative prompt 生成的embedding
    timestep_cond=timestep_cond,#默认空
    cross_attention_kwargs=self.cross_attention_kwargs, #默认空
    added_cond_kwargs=added_cond_kwargs, #默认空
    return_dict=False,
)[0]

1.time

get_time_embed使用了sinusoidal timestep embeddings,
time_embedding 使用了两个线性层和激活层进行映射,将320转换到1280。
如果还有class_labels,added_cond_kwargs等参数,也转换为embedding,并且相加。

t_emb = self.get_time_embed(sample=sample, timestep=timestep)  #(2,320)
emb = self.time_embedding(t_emb, timestep_cond)  #(2,1280)

2.pre-process

卷积转换,输入latent从(2,4,64,64) 到(2,320,64,64)

sample = self.conv_in(sample)  #(2,320,64,64)
self.conv_in = nn.Conv2d(
            in_channels, block_out_channels[0], kernel_size=conv_in_kernel, padding=conv_in_padding
        )

3.down

down_block 由三个CrossAttnDownBlock2D和一个DownBlock2D组成。输入包括:

  • hidden_states:latent

  • temb:时刻t的embdedding

  • encoder_hidden_states:prompt和negative prompt的embedding

网络结构

CrossAttnDownBlock2D( 
    ResnetBlock2D
### Stable DiffusionUNet 的结构和组成 Stable Diffusion 使用的 U-Net 架构是一种经典的卷积神经网络设计,广泛应用于图像分割和其他计算机视觉任务中。U-Net 结构由编码器(下采样路径)、解码器(上采样路径)以及跳过连接三部分组成[^1]。 #### 编码器部分 编码器负责提取输入图像中的高层次特征。它通常通过一系列卷积层和池化操作来逐步降低空间分辨率并增加通道数。具体来说,在 Stable Diffusion 的 U-Net 实现中,每一级都包含多个卷积层,这些卷积层可能采用残差连接以增强梯度传播效果[^3]。此外,为了进一步提升性能,某些版本还引入了注意力机制,使得模型能够更好地关注重要区域的信息[^4]。 #### 解码器部分 解码器的作用是对经过压缩后的低维表示进行重建,恢复到原始尺寸大小的同时生成目标输出。这一过程主要依赖于转置卷积或者插值方法完成放大操作;与此同时也会加入来自相应层次编码阶段的结果作为辅助信息——即所谓的跳跃链接(Skip Connections),从而保留更多细节特性不被丢失掉[^2]。 #### 跳跃连接 跳跃连接是 U-Net 的核心组成部分之一,它们将编码器不同层级产生的特征图传递给对应的解码器层级。这种设计有助于缓解因多次降采样而导致的空间信息损失问题,并促进浅层与深层之间的交流互动,最终提高整体预测精度。 以下是简化版 Python 表达形式展示了一个典型 U-net 层次关系: ```python class UNetBlock(nn.Module): def __init__(self, in_channels, out_channels): super(UNetBlock, self).__init__() self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) self.relu = nn.ReLU(inplace=True) self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1) def forward(self, x): x = self.conv1(x) x = self.relu(x) x = self.conv2(x) return self.relu(x) def downsample_block(input_channel, output_channel): block = nn.Sequential( nn.MaxPool2d(kernel_size=2), UNetBlock(input_channel, output_channel)) return block def upsample_block(input_channel, concat_channel, output_channel): block = nn.Sequential( nn.Upsample(scale_factor=2, mode='nearest'), UNetBlock(input_channel + concat_channel, output_channel)) return block ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值