akaxiao commited on
Commit
b469b54
·
verified ·
1 Parent(s): 3b3ab49

Upload 2 files

Browse files
models/Block/Blocks_etop.py ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from functools import partial
4
+ from einops import rearrange
5
+ import torch.nn.functional as F
6
+ #from sageattention import sageattn
7
+ #F.scaled_dot_product_attention = sageattn
8
+
9
+ class Mlp(nn.Module):
10
+ def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):
11
+ super().__init__()
12
+ out_features = out_features or in_features
13
+ hidden_features = hidden_features or in_features
14
+ self.fc1 = nn.Linear(in_features, hidden_features)
15
+ self.act = act_layer()
16
+ self.fc2 = nn.Linear(hidden_features, out_features)
17
+ self.drop = nn.Dropout(drop)
18
+
19
+ def forward(self, x):
20
+ x = self.fc1(x)
21
+ x = self.act(x)
22
+ x = self.drop(x)
23
+ x = self.fc2(x)
24
+ x = self.drop(x)
25
+ return x
26
+
27
+ class Attention(nn.Module):
28
+ def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):
29
+ super().__init__()
30
+ self.num_heads = num_heads
31
+ self.head_dim = dim // num_heads
32
+ # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights
33
+ self.scale = qk_scale or self.head_dim ** -0.5
34
+
35
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
36
+ self.attn_drop = nn.Dropout(attn_drop)
37
+ self.proj = nn.Linear(dim, dim)
38
+ self.proj_drop = nn.Dropout(proj_drop)
39
+
40
+ def forward(self, x):
41
+ B, N, C = x.shape
42
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4)
43
+ q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)
44
+ # x = F.scaled_dot_product_attention(q, k, v).transpose(1, 2).reshape(B, N, 768)
45
+ attn = (q @ k.transpose(-2, -1)) * self.scale
46
+ attn = attn.softmax(dim=-1)
47
+ # a = attn.sum(-1)
48
+ # aa = a.sum(0)
49
+ attn = self.attn_drop(attn)
50
+ x = (attn @ v).transpose(1, 2).reshape(B, N, C)
51
+ x = self.proj(x)
52
+ x = self.proj_drop(x)
53
+ return x, attn
54
+
55
+ class flash_Attention(nn.Module):
56
+ def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.,dropout=0.0):
57
+ super().__init__()
58
+ self.num_heads = num_heads
59
+ self.head_dim = dim // num_heads
60
+ # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights
61
+ self.scale = qk_scale or self.head_dim ** -0.5
62
+
63
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
64
+ self.attn_drop = nn.Dropout(attn_drop)
65
+ self.proj = nn.Linear(dim, dim)
66
+ self.proj_drop = nn.Dropout(proj_drop)
67
+
68
+
69
+ def forward(self, x):
70
+ B, N, C = x.shape
71
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4)
72
+ q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)
73
+ x = F.scaled_dot_product_attention(q, k, v).transpose(1, 2).reshape(B, N, 768)
74
+ x = self.proj(x)
75
+ x = self.proj_drop(x)
76
+ return x, x
77
+
78
+ class FormerAttention(nn.Module):
79
+ def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):
80
+ super().__init__()
81
+ self.num_heads = num_heads
82
+ head_dim = dim // num_heads
83
+ # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights
84
+ self.scale = qk_scale or head_dim ** -0.5
85
+
86
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
87
+ self.attn_drop = nn.Dropout(attn_drop)
88
+ self.proj = nn.Linear(dim, dim)
89
+ self.proj_drop = nn.Dropout(proj_drop)
90
+
91
+ def forward(self, x):
92
+ B, N, C = x.shape
93
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
94
+ q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)
95
+ attn = (q @ k.transpose(-2, -1)) * self.scale
96
+ attn = attn.softmax(dim=-1)
97
+ # a = attn.sum(-1)
98
+ # aa = a.sum(0)
99
+ attn = self.attn_drop(attn)
100
+ x = (attn @ v).transpose(1, 2).reshape(B, N, C)
101
+ x = self.proj(x)
102
+ x = self.proj_drop(x)
103
+ return x ,attn
104
+
105
+
106
+ class AttentionYenhance(nn.Module):
107
+ def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):
108
+ super().__init__()
109
+ self.num_heads = num_heads
110
+ head_dim = dim // num_heads
111
+ # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights
112
+ self.scale = qk_scale or head_dim ** -0.5
113
+
114
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
115
+ self.attn_drop = nn.Dropout(attn_drop)
116
+ self.proj = nn.Linear(dim, dim)
117
+ self.proj_drop = nn.Dropout(proj_drop)
118
+
119
+ self.dynamic_pattern_conv = nn.Sequential(nn.Linear(in_features=head_dim, out_features=int(head_dim/2)),
120
+ nn.ReLU(),
121
+ nn.Linear(in_features=int(head_dim/2), out_features=head_dim),
122
+ nn.Tanh())
123
+ def forward(self, x, x_len=576):
124
+ B, N, C = x.shape
125
+ y_len = N - x_len
126
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
127
+ q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)\
128
+
129
+ ky = k[:,:,x_len:,:].clone()
130
+ ky = (1 + self.dynamic_pattern_conv(ky)) * ky
131
+ k[:,:,x_len:,:] = ky
132
+
133
+ attn = (q @ k.transpose(-2, -1)) * self.scale
134
+ attn = attn.softmax(dim=-1)
135
+ attn = self.attn_drop(attn)
136
+ x = (attn @ v).transpose(1, 2).reshape(B, N, C)
137
+ x = self.proj(x)
138
+ x = self.proj_drop(x)
139
+ return x ,attn
140
+
141
+ class Block(nn.Module):
142
+
143
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,
144
+ drop_path=0., act_layer=nn.GELU, norm_layer=partial(nn.LayerNorm, eps=1e-6)):
145
+ super().__init__()
146
+ self.norm1 = norm_layer(dim)
147
+ self.attn = Attention(
148
+ dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
149
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
150
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
151
+ self.norm2 = norm_layer(dim)
152
+ self.mlp = Mlp(in_features=dim, hidden_features=3072, act_layer=act_layer, drop=drop)
153
+
154
+ def forward(self, x):
155
+ x_1, attn = self.attn(self.norm1(x))
156
+ x = x + self.drop_path(x_1)
157
+ x = x + self.drop_path(self.mlp(self.norm2(x)))
158
+ return x, attn
159
+
160
+ class flash_Block(nn.Module):
161
+
162
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,
163
+ drop_path=0., act_layer=nn.GELU, norm_layer=partial(nn.LayerNorm, eps=1e-6)):
164
+ super().__init__()
165
+ self.norm1 = norm_layer(dim)
166
+ self.attn = flash_Attention(
167
+ dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
168
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
169
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
170
+ self.norm2 = norm_layer(dim)
171
+ self.mlp = Mlp(in_features=dim, hidden_features=3072, act_layer=act_layer, drop=drop)
172
+
173
+ def forward(self, x):
174
+ x_1,_ = self.attn(self.norm1(x))
175
+ x = x + self.drop_path(x_1)
176
+ x = x + self.drop_path(self.mlp(self.norm2(x)))
177
+ return x,0
178
+
179
+ class FormerBlock(nn.Module):
180
+
181
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,
182
+ drop_path=0., act_layer=nn.GELU, norm_layer=partial(nn.LayerNorm, eps=1e-6)):
183
+ super().__init__()
184
+ self.norm1 = norm_layer(dim)
185
+ self.attn = FormerAttention(
186
+ dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
187
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
188
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
189
+ self.norm2 = norm_layer(dim)
190
+ mlp_hidden_dim = int(dim * mlp_ratio)
191
+ self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
192
+
193
+ # self.scale = nn.Parameter(torch.zeros(8, 24, 512), requires_grad=False)
194
+ # self.size = nn.parameter(torch.)
195
+ def forward(self, x):
196
+ x_1,attn = self.attn(self.norm1(x))
197
+ x = x + self.drop_path(x_1)
198
+ x = x + self.drop_path(self.mlp(self.norm2(x)))
199
+ return x, attn
200
+
201
+ ### 输入一个 L * d 的一个尺度特征s。
202
+ ### 输入一个 L_X * d 的一个特征x。
203
+ ### 输入一个 L_Y * d 的一个特征y。
204
+ ###
205
+
206
+ def drop_path(x, drop_prob: float = 0., training: bool = False):
207
+ """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
208
+
209
+ This is the same as the DropConnect impl I created for EfficientNet, etc networks, however,
210
+ the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper...
211
+ See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for
212
+ changing the layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use
213
+ 'survival rate' as the argument.
214
+
215
+ """
216
+ if drop_prob == 0. or not training:
217
+ return x
218
+ keep_prob = 1 - drop_prob
219
+ shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets
220
+ random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device)
221
+ random_tensor.floor_() # binarize
222
+ output = x.div(keep_prob) * random_tensor
223
+ return output
224
+
225
+
226
+ class DropPath(nn.Module):
227
+ """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
228
+ """
229
+ def __init__(self, drop_prob=None):
230
+ super(DropPath, self).__init__()
231
+ self.drop_prob = drop_prob
232
+
233
+ def forward(self, x):
234
+ return drop_path(x, self.drop_prob, self.training)
235
+
236
+
237
+ if __name__ == '__main__':
238
+ x = torch.rand(8,576+48,512)
239
+ model = AttentionYenhance(dim=512)
240
+ output = model(x)
241
+ print(output.shape)
models/CntVit_3layers_scalepos_patchmat_withr_plain.py ADDED
@@ -0,0 +1,345 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from functools import partial
2
+ from pathlib import Path
3
+ import torch
4
+ import torch.nn as nn
5
+ from einops import rearrange, repeat
6
+ from timm.models.vision_transformer import PatchEmbed
7
+ import sys
8
+ import os
9
+ if __name__ == '__main__':
10
+ sys.path.append(os.getcwd())
11
+ from models.models.Block.Blocks_etop import Block,flash_Block
12
+ import torch.nn.functional as F
13
+ from util.pos_embed import get_2d_sincos_pos_embed
14
+ import numpy as np
15
+ from thop import profile
16
+ from thop import clever_format
17
+ from util.img_show import img_save,img_save_color
18
+
19
+ from huggingface_hub import PyTorchModelHubMixin
20
+
21
+ class SupervisedMAELoose(nn.Module, PyTorchModelHubMixin):
22
+ """ CntVit with VisionTransformer backbone
23
+ """
24
+
25
+ def __init__(self, img_size=384, patch_size=16, in_chans=3,
26
+ embed_dim=1024, depth=24, num_heads=16,
27
+ decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,
28
+ mlp_ratio=4., norm_layer=nn.LayerNorm, device = 'cuda:0',test = False,
29
+ norm_pix_loss=False, drop_path_rate = 0.3,
30
+ interaction_indexes = [[0, 2], [3, 5], [6, 8], [9, 11]],with_cffn=True, cffn_ratio=0.25,use_extra_extractor=True,
31
+ blocksize_list=[32,64,128], output_stride_list=[16,32,64],
32
+ mode = 'GlobalAttention' ,decodemode = 'GlobalAttention', similarityfunc = 'PatchConv',similaritymode = 'OutputAdd',gamma = True, xenhance=False,mullayer = True, updown=None):
33
+ super().__init__()
34
+ ## Setting the model
35
+ self.mode = mode
36
+ self.mullayer = mullayer
37
+ self.decodemode = decodemode
38
+ self.similarityfunc = similarityfunc
39
+ self.similaritymode = similaritymode
40
+ self.gamma = gamma
41
+ self.updown = updown
42
+ self.test = test
43
+
44
+ self.embed_dim = embed_dim
45
+ self.decoder_embed_dim = decoder_embed_dim
46
+ ## Setting the model
47
+
48
+ ## Global Setting
49
+ self.patch_size = patch_size
50
+ self.img_size = img_size
51
+ ex_size = 64
52
+ self.norm_pix_loss = norm_pix_loss
53
+ ## Global Setting
54
+
55
+ ## Encoder specifics
56
+ self.scale_embeds = nn.Linear(2, embed_dim, bias=True)
57
+ self.patch_embed_exemplar = PatchEmbed(ex_size, patch_size, in_chans + 1, embed_dim)
58
+ num_patches_exemplar = self.patch_embed_exemplar.num_patches
59
+ self.pos_embed_exemplar = nn.Parameter(torch.zeros(1, num_patches_exemplar, embed_dim), requires_grad=False)
60
+ self.patch_embed = PatchEmbed(img_size, patch_size, in_chans, embed_dim)
61
+ num_patches = self.patch_embed.num_patches
62
+ self.pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim),
63
+ requires_grad=False) # fixed sin-cos embedding
64
+
65
+ self.norm = norm_layer(embed_dim)
66
+ if self.mode == 'GlobalAttention':
67
+ self.blocks = nn.ModuleList([
68
+ flash_Block(embed_dim, num_heads, mlp_ratio, qkv_bias=True, qk_scale=None, norm_layer=norm_layer)
69
+ for i in range(depth-1)])
70
+ self.blocks.append(Block(embed_dim, num_heads, mlp_ratio, qkv_bias=True, qk_scale=None, norm_layer=norm_layer))
71
+ self.v_y = nn.Linear(decoder_embed_dim, decoder_embed_dim, bias=True)
72
+ self.density_proj = nn.Linear(decoder_embed_dim, decoder_embed_dim)
73
+
74
+ self.accm = {}
75
+ self.counter = nn.ModuleDict()
76
+
77
+ for iter, blocksize in enumerate(blocksize_list):
78
+ blocksize, os = blocksize // 16, output_stride_list[iter]//16
79
+ num_patch = self.patch_embed.img_size[0] // 16
80
+ target_size = int((num_patch - blocksize) / os + 1)
81
+ accm_12 = torch.FloatTensor(1, blocksize * blocksize, target_size * target_size).fill_(1)
82
+ accm_12 = F.fold(accm_12, (num_patch, num_patch), kernel_size=blocksize, stride=os)
83
+ accm_12 = 1 / accm_12
84
+ accm_12 /= blocksize ** 2
85
+ self.accm[f'{blocksize * 16}'] = F.unfold(accm_12, kernel_size=blocksize, stride=os).sum(1).view(1, 1, target_size, target_size)
86
+ self.counter[f'{blocksize * 16}'] = nn.Sequential(
87
+ nn.Conv2d(769,512,kernel_size=3,stride=1,padding=1,bias=False),
88
+ nn.GroupNorm(32,512),
89
+ nn.ReLU(inplace=True),
90
+ nn.Conv2d(512,256,kernel_size=3,stride=1,padding=1,bias=False),
91
+ nn.GroupNorm(32,256),
92
+ nn.ReLU(inplace=True),
93
+ nn.AvgPool2d((blocksize, blocksize), stride=os),
94
+ nn.Conv2d(256, 256, kernel_size=1, stride=1),
95
+ nn.GroupNorm(32,256),
96
+ nn.ReLU(inplace=True),
97
+ nn.Conv2d(256, 1, 1)
98
+ )
99
+
100
+ self.initialize_weights()
101
+ for name, p in self.named_parameters():
102
+ print(f'{name}')
103
+
104
+ def initialize_weights(self):
105
+ # initialization
106
+ # initialize (and freeze) pos_embed by sin-cos embedding
107
+ pos_embed = get_2d_sincos_pos_embed(self.pos_embed.shape[-1], int(self.patch_embed.num_patches ** .5),
108
+ cls_token=False)
109
+ self.pos_embed.data.copy_(torch.from_numpy(pos_embed).float().unsqueeze(0))
110
+
111
+ pos_embde_exemplar = get_2d_sincos_pos_embed(self.pos_embed_exemplar.shape[-1],
112
+ int(self.patch_embed_exemplar.num_patches ** .5), cls_token=False)
113
+ self.pos_embed_exemplar.copy_(torch.from_numpy(pos_embde_exemplar).float().unsqueeze(0))
114
+ self.apply(self._init_weights)
115
+
116
+ def _init_weights(self, m):
117
+ if isinstance(m, nn.Linear):
118
+ # we use xavier_uniform following official JAX ViT:
119
+ torch.nn.init.xavier_uniform_(m.weight)
120
+ if isinstance(m, nn.Linear) and m.bias is not None:
121
+ nn.init.constant_(m.bias, 0)
122
+ elif isinstance(m, nn.LayerNorm):
123
+ nn.init.constant_(m.bias, 0)
124
+ nn.init.constant_(m.weight, 1.0)
125
+ elif isinstance(m, nn.Conv2d):
126
+ nn.init.constant_(m.weight, 0.01)
127
+ elif isinstance(m, nn.Linear):
128
+ nn.init.constant_(m.weight, 0.2)
129
+ nn.init.constant_(m.bias, 1)
130
+
131
+
132
+
133
+ def scale_embedding(self, exemplars, scale_infos):
134
+ method = 1
135
+ if method == 0:
136
+ bs, n, c, h, w = exemplars.shape
137
+ scales_batch = []
138
+ for i in range(bs):
139
+ scales = []
140
+ for j in range(n):
141
+ w_scale = torch.linspace(0, scale_infos[i, j, 0], w)
142
+ w_scale = repeat(w_scale, 'w->h w', h=h).unsqueeze(0)
143
+ h_scale = torch.linspace(0, scale_infos[i, j, 1], h)
144
+ h_scale = repeat(h_scale, 'h->h w', w=w).unsqueeze(0)
145
+ scale = torch.cat((w_scale, h_scale), dim=0)
146
+ scales.append(scale)
147
+ scales = torch.stack(scales)
148
+ scales_batch.append(scales)
149
+ scales_batch = torch.stack(scales_batch)
150
+
151
+ if method == 1:
152
+ bs, n, c, h, w = exemplars.shape
153
+ scales_batch = []
154
+ for i in range(bs):
155
+ scales = []
156
+ for j in range(n):
157
+ w_scale = torch.linspace(0, scale_infos[i, j, 0], w)
158
+ w_scale = repeat(w_scale, 'w->h w', h=h).unsqueeze(0)
159
+ h_scale = torch.linspace(0, scale_infos[i, j, 1], h)
160
+ h_scale = repeat(h_scale, 'h->h w', w=w).unsqueeze(0)
161
+ scale = w_scale + h_scale
162
+ scales.append(scale)
163
+ scales = torch.stack(scales)
164
+ scales_batch.append(scales)
165
+ scales_batch = torch.stack(scales_batch)
166
+
167
+ scales_batch = scales_batch.to(exemplars.device)
168
+ exemplars = torch.cat((exemplars, scales_batch), dim=2)
169
+
170
+ return exemplars
171
+
172
+ def forward_encoder(self, x, y, scales=None):
173
+ if self.mode == 'GlobalAttention':
174
+ y_embed = []
175
+ y = rearrange(y,'b n c w h->n b c w h')
176
+ for box in y:
177
+ box = self.patch_embed_exemplar(box)
178
+ box = box + self.pos_embed_exemplar
179
+ y_embed.append(box)
180
+ y_embed = torch.stack(y_embed, dim=0)
181
+ box_num,_,n,d = y_embed.shape
182
+ y = rearrange(y_embed, 'box_num batch n d->batch (box_num n) d')
183
+ x = self.patch_embed(x)
184
+ x = x + self.pos_embed
185
+ _, l, d = x.shape
186
+ attns = []
187
+ x_y = torch.cat((x,y),axis=1)
188
+ for i, blk in enumerate(self.blocks):
189
+ x_y, attn = blk(x_y)
190
+ attns.append(attn)
191
+ x_y = self.norm(x_y) ## 输出�???? [batch * 288 * 768] 仅仅保存了一�????
192
+ x = x_y[:,:l,:]
193
+ for i in range(box_num):
194
+ y[:,i*n:(i+1)*n,:] = x_y[:,l+i*n:l+(i+1)*n,:]
195
+ y = rearrange(y,'batch (box_num n) d->box_num batch n d',box_num = box_num,n=n)
196
+ return x, y, attns
197
+
198
+ def AttentionEnhance_for_fenxi(self, attns, l=24, n=1, layer=0, fig_name='0.jpg'):
199
+ output_dir = '/data/wangzhicheng/Code/CntViT/attention/' + fig_name[0] + '/layer_' + str(layer)
200
+ if output_dir:
201
+ Path(output_dir).mkdir(parents=True, exist_ok=True)
202
+ l_x = int(l * l)
203
+ l_y = int(4 * 4)
204
+ r = self.img_size // self.patch_size
205
+
206
+ # attns = torch.stack(attns) # 8 * batch * heads * (M+l*3) * (M+l*3)
207
+ attns = torch.mean(attns, dim=1)
208
+
209
+ attns_y2y = attns[:, l_x:, l_x:]
210
+ n = 3
211
+ for i in range(n):
212
+ attns_y2yi = attns[:, l_x + i * l_y:l_x + (i + 1) * l_y, l_x + i * l_y:l_x + (i + 1) * l_y]
213
+ attns_y2yi = torch.mean(attns_y2yi, dim=1, keepdim=True)
214
+ attns_y2yi = rearrange(attns_y2yi, 'b l (w h)->b l w h', w=4)
215
+ nameDi = output_dir + '/attnD' + str(i) + '.jpg'
216
+ img_save_color(attns_y2yi[0, 0] * 255 / torch.max(attns_y2yi[0]), pth=nameDi)
217
+
218
+ attns_y2x = attns[:, :l_x, l_x:]
219
+ attns_x2y = attns[:, l_x:, :l_x]
220
+ attns_y2x = rearrange(attns_y2x, 'a b c->a c b')
221
+ patch_attn = attns[:, :l_x, :l_x] ## 576 * 576
222
+ patch_attn = torch.mean(patch_attn, dim=1, keepdim=True)
223
+ patch_attn = rearrange(patch_attn, 'b l (w h)->b l w h', w=r)
224
+ nameA = output_dir + '/attnA.jpg'
225
+ img_save_color(patch_attn[0, 0] * 255 / torch.max(patch_attn[0]), pth=nameA)
226
+
227
+ attns_x2y = rearrange(attns_x2y, 'b (n ly) l->b n ly l', ly=l_y)
228
+ attns_y2x = rearrange(attns_y2x, 'b (n ly) l->b n ly l', ly=l_y)
229
+ attns_x2y = attns_x2y.sum(2)
230
+ attns_y2x = attns_y2x.sum(2)
231
+
232
+ attns_x2y = torch.mean(attns_x2y, dim=1).unsqueeze(-1)
233
+ attns_y2x = torch.mean(attns_y2x, dim=1).unsqueeze(-1)
234
+
235
+ attns_x2y = rearrange(attns_x2y, 'b (w h) c->b c w h', w=r, h=r)
236
+ attns_y2x = rearrange(attns_y2x, 'b (w h) c->b c w h', w=r, h=r)
237
+ nameB = output_dir + '/attnB.jpg'
238
+ nameC = output_dir + '/attnC.jpg'
239
+ img_save_color(attns_x2y[0, 0] * 255 / torch.max(attns_x2y[0]), pth=nameC)
240
+ img_save_color(attns_y2x[0, 0] * 255 / torch.max(attns_y2x[0]), pth=nameB)
241
+ return attns_x2y
242
+
243
+ def AttentionEnhance(self, attns, l=24, n=1):
244
+ l_x = int(l * l)
245
+ l_y = int(4 * 4)
246
+ r = self.img_size // self.patch_size
247
+
248
+ # attns = torch.stack(attns) # 8 * batch * heads * (M+l*3) * (M+l*3)
249
+ attns = torch.mean(attns, dim=1)
250
+
251
+ attns_x2y = attns[:, l_x:, :l_x]
252
+ attns_x2y = rearrange(attns_x2y, 'b (n ly) l->b n ly l', ly=l_y)
253
+ # attns_x2y = rearrange(attns_y2x,'b l (n ly)->b n ly l',ly = l_y)
254
+ attns_x2y = attns_x2y * n.unsqueeze(-1).unsqueeze(-1)
255
+ attns_x2y = attns_x2y.sum(2)
256
+
257
+ attns_x2y = torch.mean(attns_x2y, dim=1).unsqueeze(-1)
258
+ attns_x2y = rearrange(attns_x2y, 'b (w h) c->b c w h', w=r, h=r)
259
+ return attns_x2y
260
+
261
+ def MacherMode(self, x, y, attn:list, scales=None, name='0.jpg', vis=True):
262
+ if self.similaritymode == 'OutputAdd':
263
+ # x = self.decoder_norm(x)
264
+ B, L, D = x.shape
265
+ # y = self.decoder_norm(y)
266
+ n,B,_,D = y.shape
267
+ r2 = (scales[:, :, 0] + scales[:, :, 1]) ** 2
268
+ n = 16 / (r2 * 384)
269
+ # density_feature = rearrange(x, 'b (w h) d->b d w h', w=24)
270
+ density_feature = rearrange(x, 'b (w h) d->b d w h', w=int(self.patch_embed.img_size[0] // 16))
271
+ if name != None:
272
+ for i in range(12):
273
+ density_enhance1 = self.AttentionEnhance_for_fenxi(attn[i], l=int(np.sqrt(L)), n=n, layer=i,
274
+ fig_name=name)
275
+ density_enhance = self.AttentionEnhance(attn[-1], l=int(np.sqrt(L)), n=n)
276
+ # if vis:
277
+ # temp = density_enhance.squeeze(0).squeeze(0).detach().cpu().numpy()
278
+ # attention_map = cv2.normalize(temp , None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
279
+ # attention_map = cv2.applyColorMap((attention_map * 255).astype(np.uint8), cv2.COLORMAP_JET)
280
+ # cv2.imwrite("atten_map.png", attention_map)
281
+ density_feature = torch.cat((density_feature, density_enhance), axis=1)
282
+ return density_feature, density_enhance
283
+
284
+ def Regressor(self, feature, test, size):
285
+ # feature = self.decode_head(feature)
286
+ f={}
287
+ if not test:
288
+ for iter, (level, counter) in enumerate(self.counter.items()):
289
+ f.update({level: counter(feature)})
290
+ f[level] = f[level].squeeze(-3)
291
+ else:
292
+ for iter, (level, counter) in enumerate(self.counter.items()):
293
+ if size.item() < int(level):
294
+ break
295
+ # _, _, h, w = f[level].shape()
296
+ f = self.counter[level](feature)
297
+ self.accm[level] = self.accm[level].to(feature.device)
298
+ f *= self.accm[level]
299
+
300
+ return f
301
+
302
+ def forward(self, samples, size=None, test=True, single=False): ## 输入的是[8, 3, 384, 384]
303
+ imgs = samples[0]
304
+ boxes = samples[1]
305
+ scales = samples[2]
306
+ size = samples[3]
307
+ if len(samples) > 3:
308
+ name = samples[3][0]
309
+ boxes = self.scale_embedding(boxes, scales)
310
+ latent, y_latent, attns1 = self.forward_encoder(imgs, boxes, scales=scales)
311
+ density_feature, atten_map = self.MacherMode(latent, y_latent, attns1, scales, name=None)
312
+ density_map = self.Regressor(density_feature, test, size)
313
+ if single:
314
+ return density_map, atten_map, attns1
315
+ elif not test:
316
+ return density_map
317
+ else:
318
+ return density_map, atten_map
319
+
320
+ def local_count_mutihead_loose(**kwargs):
321
+ model = SupervisedMAELoose(
322
+ patch_size=16, embed_dim=768, num_heads=12,
323
+ decoder_embed_dim=512, decoder_depth=3, decoder_num_heads=16,
324
+ mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6),**kwargs)
325
+ return model
326
+
327
+ config = {
328
+ "embed_dim": 768,
329
+ "depth": 11,
330
+ "num_heads":16,
331
+ "decoder_embed_dim": 512,
332
+ "mlp_ratio": 4,
333
+ "norm_layer":partial(nn.LayerNorm, eps=1e-6),
334
+ "blocksize_list": [32,64,128],
335
+ "output_stride_list": [16,16,16],
336
+ "decodemode": "GlobalAttention",
337
+ "gamma": True,
338
+ "mode": "GlobalAttention",
339
+ "mullayer": False,
340
+ "norm_pix_loss": True,
341
+ "similarityfunc": "PatchConv",
342
+ "similaritymode": "OutputAdd",
343
+ "xenhance": False
344
+ }
345
+ model = SupervisedMAELoose(**config)