#40 Blocks in View

If you try to create a helper method which accepts a block, you will run into a few gotchas. Learn the secrets of blocks in views in this episode.
<% side_section do %>
This is on the side bar.
<% end %>

<% admin_area do %>
<%= link_to "Edit Task", edit_task_path(@task) %>
<% end %>
# application_helper
def side_section(&block)
@side_sections ||= []
@side_sections << capture(&block)
end

def admin_area(&block)
concat('<div class="admin">', block.binding)
block.call
concat("</div>", block.binding)
end

# or...
def admin_area(&block)
if admin?
concat content_tag(:div, capture(&block), :class => 'admin'), block.binding
end
end
### Transformer Blocks 的架构详解 #### 自注意力机制 (Self-Attention) Transformer Blocks 是构成 Vision Transformer 和其他变体(如 Swin Transformer)的核心组件之一。在标准的 Transformer 结构中,每一个 Transformer Block 主要由自注意力机制和多层感知机(MLP)组成[^1]。 自注意力机制允许模型关注输入序列中的不同位置,从而捕捉到更丰富的上下文信息。具体来说,在处理图像数据时,这种机制能够帮助模型理解图片的不同区域之间的关系。 #### 多层感知机 (MLP) 除了自注意力模块外,每个 Transformer Block 还包含一个多层感知机(MLP)。这个 MLP 负责对经过自注意力处理后的特征向量进一步变换,增加模型表达能力的同时也引入了非线性特性。 对于像 Swin Transformer 这样的特定实现方式,则采用了更为复杂的结构来优化性能: - **基于窗口的多头自注意力(W-MSA 将输入划分为固定大小的小窗口,并仅在同一窗口内的 token 对之间执行自注意操作。这样做可以减少计算复杂度并提高局部敏感性[^3]。 - **移位窗口多头自注意力(SW-MSA, Shifted Window-based Multi-head Self Attention)** SW-MSA 在 W-MSA 基础上增加了窗口间的交互。通过周期性地移动这些窗口的位置,使得相邻窗口间也能建立联系,进而增强了全局感受野的效果。 ```python class TransformerBlock(nn.Module): def __init__(self, dim, num_heads=8, window_size=7, shift_size=0, mlp_ratio=4., qkv_bias=True, drop_path=0.): super().__init__() self.norm1 = nn.LayerNorm(dim) self.attn = WindowAttention( dim, window_size=(window_size, window_size), num_heads=num_heads, qkv_bias=qkv_bias) self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() self.norm2 = nn.LayerNorm(dim) mlp_hidden_dim = int(dim * mlp_ratio) self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim) if shift_size > 0: attn_mask = compute_attn_mask(window_size, shift_size) else: attn_mask = None self.register_buffer("attn_mask", attn_mask) def forward(self, x): H, W = self.input_resolution B, L, C = x.shape shortcut = x x = self.norm1(x) x = x.view(B, H, W, C) pad_l = pad_t = 0 pad_r = (self.window_size - W % self.window_size) % self.window_size pad_b = (self.window_size - H % self.window_size) % self.window_size x = F.pad(x, (0, 0, pad_l, pad_r, pad_t, pad_b)) _, Hp, Wp, _ = x.shape if self.shift_size > 0: shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) else: shifted_x = x x_windows = window_partition(shifted_x, self.window_size) x_windows = x_windows.view(-1, self.window_size * self.window_size, C) attn_windows = self.attn(x_windows, mask=self.attn_mask) attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) shifted_x = window_reverse(attn_windows, self.window_size, Hp, Wp) if self.shift_size > 0: x = torch.roll(shifted_x, shifts=(self.shift_size, self.shift_size), dims=(1, 2)) else: x = shifted_x if pad_r > 0 or pad_b > 0: x = x[:, :H, :W, :].contiguous() x = x.view(B, H * W, C) x = shortcut + self.drop_path(x) x = x + self.drop_path(self.mlp(self.norm2(x))) return x ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值