├── Resnet.py ├── adv_denoise_model └── convert.py ├── architectures.py ├── dev.csv ├── image.jpg ├── main.py ├── my_loader.py └── readme.md /Resnet.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copy form https://github.com/TransEmbedBA/TREMBA/blob/master/imagenet_model/Resnet.py 3 | """ 4 | 5 | import torch.nn as nn 6 | import torch 7 | import math 8 | 9 | def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1): 10 | """3x3 convolution with padding""" 11 | return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, 12 | padding=dilation, groups=groups, bias=False, dilation=dilation) 13 | 14 | 15 | def conv1x1(in_planes, out_planes, stride=1): 16 | """1x1 convolution""" 17 | return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False) 18 | 19 | 20 | class BasicBlock(nn.Module): 21 | expansion = 1 22 | 23 | def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, 24 | base_width=64, dilation=1, norm_layer=None): 25 | super(BasicBlock, self).__init__() 26 | if norm_layer is None: 27 | norm_layer = nn.BatchNorm2d 28 | if groups != 1 or base_width != 64: 29 | raise ValueError('BasicBlock only supports groups=1 and base_width=64') 30 | if dilation > 1: 31 | raise NotImplementedError("Dilation > 1 not supported in BasicBlock") 32 | # Both self.conv1 and self.downsample layers downsample the input when stride != 1 33 | self.conv1 = conv3x3(inplanes, planes, stride) 34 | self.bn1 = norm_layer(planes) 35 | self.relu = nn.ReLU(inplace=True) 36 | self.conv2 = conv3x3(planes, planes) 37 | self.bn2 = norm_layer(planes) 38 | self.downsample = downsample 39 | self.stride = stride 40 | 41 | def forward(self, x): 42 | identity = x 43 | 44 | out = self.conv1(x) 45 | out = self.bn1(out) 46 | out = self.relu(out) 47 | 48 | out = self.conv2(out) 49 | out = self.bn2(out) 50 | 51 | if self.downsample is not None: 52 | identity = self.downsample(x) 53 | 54 | out += identity 55 | out = self.relu(out) 56 | 57 | return out 58 | 59 | 60 | class Bottleneck(nn.Module): 61 | expansion = 4 62 | 63 | def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, 64 | base_width=64, dilation=1, norm_layer=None): 65 | super(Bottleneck, self).__init__() 66 | if norm_layer is None: 67 | norm_layer = nn.BatchNorm2d 68 | width = int(planes * (base_width / 64.)) * groups 69 | # Both self.conv2 and self.downsample layers downsample the input when stride != 1 70 | self.conv1 = conv1x1(inplanes, width) 71 | self.bn1 = norm_layer(width) 72 | self.conv2 = conv3x3(width, width, stride, groups, dilation) 73 | self.bn2 = norm_layer(width) 74 | self.conv3 = conv1x1(width, planes * self.expansion) 75 | self.bn3 = norm_layer(planes * self.expansion) 76 | self.relu = nn.ReLU(inplace=True) 77 | self.downsample = downsample 78 | self.stride = stride 79 | 80 | def forward(self, x): 81 | identity = x 82 | 83 | out = self.conv1(x) 84 | out = self.bn1(out) 85 | out = self.relu(out) 86 | 87 | out = self.conv2(out) 88 | out = self.bn2(out) 89 | out = self.relu(out) 90 | 91 | out = self.conv3(out) 92 | out = self.bn3(out) 93 | 94 | if self.downsample is not None: 95 | identity = self.downsample(x) 96 | 97 | out += identity 98 | out = self.relu(out) 99 | 100 | return out 101 | 102 | class Denoise(nn.Module): 103 | 104 | def __init__(self, channel, embed=True, softmax=True): 105 | super().__init__() 106 | self.embed = embed 107 | self.softmax = softmax 108 | self.channel = channel 109 | 110 | if self.embed: 111 | self.conv_theta = nn.Conv2d(channel, channel//2, kernel_size=1, stride=1, padding=0, bias=False) 112 | self.conv_phi = nn.Conv2d(channel, channel//2, kernel_size=1, stride=1, padding=0, bias=False) 113 | self.conv = nn.Conv2d(channel, channel, kernel_size=1, stride=1, padding=0, bias=False) 114 | self.bn = nn.BatchNorm2d(channel) 115 | 116 | def forward(self, x): 117 | if self.embed: 118 | theta = self.conv_theta(x) 119 | phi = self.conv_phi(x) 120 | else: 121 | theta = x 122 | phi = x 123 | n_in, H, W = list(x.size())[1:] 124 | if n_in > H*W or self.softmax: 125 | f = torch.einsum('niab,nicd->nabcd', (theta,phi)) 126 | if self.softmax: 127 | shape = f.size() 128 | f = f.view(-1, shape[2]*shape[3], shape[2]*shape[3]) 129 | f = f / math.sqrt(self.channel/2) 130 | f = nn.functional.softmax(f, dim=-1) 131 | f = f.view(shape) 132 | f = torch.einsum('nabcd,nicd->niab', (f, x)) 133 | else: 134 | f = torch.einsum('nihw,njhw->nij', (phi, x)) 135 | f = torch.einsum('nij,nihw->njhw', (f, theta)) 136 | if not self.softmax: 137 | f = f / (H*W) 138 | 139 | y = self.bn(self.conv(f)) 140 | return x + y 141 | 142 | 143 | class DenoiseBottleneck(nn.Module): 144 | expansion = 4 145 | 146 | def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, 147 | base_width=64, dilation=1, norm_layer=None): 148 | super(DenoiseBottleneck, self).__init__() 149 | if norm_layer is None: 150 | norm_layer = nn.BatchNorm2d 151 | width = int(planes * (base_width / 64.)) * groups 152 | # Both self.conv2 and self.downsample layers downsample the input when stride != 1 153 | self.conv1 = conv1x1(inplanes, width) 154 | self.bn1 = norm_layer(width) 155 | self.conv2 = conv3x3(width, width, stride, groups, dilation) 156 | self.bn2 = norm_layer(width) 157 | self.conv3 = conv1x1(width, planes * self.expansion) 158 | self.bn3 = norm_layer(planes * self.expansion) 159 | self.relu = nn.ReLU(inplace=True) 160 | self.downsample = downsample 161 | self.stride = stride 162 | self.denoise = Denoise(planes * self.expansion, False, False) 163 | 164 | def forward(self, x): 165 | identity = x 166 | 167 | out = self.conv1(x) 168 | out = self.bn1(out) 169 | out = self.relu(out) 170 | 171 | out = self.conv2(out) 172 | out = self.bn2(out) 173 | out = self.relu(out) 174 | 175 | out = self.conv3(out) 176 | out = self.bn3(out) 177 | 178 | if self.downsample is not None: 179 | identity = self.downsample(x) 180 | 181 | out += identity 182 | out = self.relu(out) 183 | out = self.denoise(out) 184 | 185 | return out 186 | 187 | class ResNet(nn.Module): 188 | 189 | def __init__(self, block, layers, num_classes=1000, zero_init_residual=False, 190 | groups=1, width_per_group=64, replace_stride_with_dilation=None, 191 | norm_layer=None, denoise=False): 192 | super(ResNet, self).__init__() 193 | if norm_layer is None: 194 | norm_layer = nn.BatchNorm2d 195 | self._norm_layer = norm_layer 196 | self.denoise = denoise 197 | self.inplanes = 64 198 | self.dilation = 1 199 | if replace_stride_with_dilation is None: 200 | # each element in the tuple indicates if we should replace 201 | # the 2x2 stride with a dilated convolution instead 202 | replace_stride_with_dilation = [False, False, False] 203 | if len(replace_stride_with_dilation) != 3: 204 | raise ValueError("replace_stride_with_dilation should be None " 205 | "or a 3-element tuple, got {}".format(replace_stride_with_dilation)) 206 | self.groups = groups 207 | self.base_width = width_per_group 208 | self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3, 209 | bias=False) 210 | self.bn1 = norm_layer(self.inplanes) 211 | self.relu = nn.ReLU(inplace=True) 212 | self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) 213 | self.layer1 = self._make_layer(block, 64, layers[0]) 214 | self.layer2 = self._make_layer(block, 128, layers[1], stride=2, 215 | dilate=replace_stride_with_dilation[0]) 216 | self.layer3 = self._make_layer(block, 256, layers[2], stride=2, 217 | dilate=replace_stride_with_dilation[1]) 218 | self.layer4 = self._make_layer(block, 512, layers[3], stride=2, 219 | dilate=replace_stride_with_dilation[2]) 220 | self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) 221 | self.fc = nn.Linear(512 * block.expansion, num_classes) 222 | 223 | for m in self.modules(): 224 | if isinstance(m, nn.Conv2d): 225 | nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') 226 | elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)): 227 | nn.init.constant_(m.weight, 1) 228 | nn.init.constant_(m.bias, 0) 229 | 230 | # Zero-initialize the last BN in each residual branch, 231 | # so that the residual branch starts with zeros, and each residual block behaves like an identity. 232 | # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677 233 | if zero_init_residual: 234 | for m in self.modules(): 235 | if isinstance(m, Bottleneck): 236 | nn.init.constant_(m.bn3.weight, 0) 237 | elif isinstance(m, BasicBlock): 238 | nn.init.constant_(m.bn2.weight, 0) 239 | 240 | def _make_layer(self, block, planes, blocks, stride=1, dilate=False): 241 | norm_layer = self._norm_layer 242 | downsample = None 243 | previous_dilation = self.dilation 244 | if dilate: 245 | self.dilation *= stride 246 | stride = 1 247 | if stride != 1 or self.inplanes != planes * block.expansion: 248 | downsample = nn.Sequential( 249 | conv1x1(self.inplanes, planes * block.expansion, stride), 250 | norm_layer(planes * block.expansion), 251 | ) 252 | 253 | layers = [] 254 | layers.append(block(self.inplanes, planes, stride, downsample, self.groups, 255 | self.base_width, previous_dilation, norm_layer)) 256 | self.inplanes = planes * block.expansion 257 | for _ in range(1, blocks): 258 | layers.append(block(self.inplanes, planes, groups=self.groups, 259 | base_width=self.base_width, dilation=self.dilation, 260 | norm_layer=norm_layer)) 261 | if self.denoise: 262 | layers.append(Denoise(self.inplanes)) 263 | return nn.Sequential(*layers) 264 | 265 | def forward(self, x): 266 | x = self.conv1(x) 267 | x = self.bn1(x) 268 | x = self.relu(x) 269 | x = self.maxpool(x) 270 | 271 | x = self.layer1(x) 272 | x = self.layer2(x) 273 | x = self.layer3(x) 274 | x = self.layer4(x) 275 | 276 | x = self.avgpool(x) 277 | x = x.view(x.size(0), -1) 278 | x = self.fc(x) 279 | 280 | return x 281 | 282 | def resnet152(): 283 | model = ResNet(Bottleneck, [3, 8, 36, 3]) 284 | 285 | return model 286 | 287 | def resnet152_denoise(): 288 | model = ResNet(Bottleneck, [3, 8, 36, 3], denoise=True) 289 | 290 | return model 291 | 292 | def resnet101_denoise(): 293 | model = ResNet(DenoiseBottleneck, [3, 4, 23, 3], denoise=False, width_per_group=8, groups=32) 294 | 295 | return model -------------------------------------------------------------------------------- /adv_denoise_model/convert.py: -------------------------------------------------------------------------------- 1 | """ 2 | modified from https://drive.google.com/drive/folders/1KQSe91znWWwaUPG1TSpqUyfyw0o0VgMV by Tianyuan Zhang 3 | """ 4 | 5 | import torch 6 | import torchvision 7 | import numpy as np 8 | import os 9 | 10 | def get_layer_name(name:str): 11 | ''' 12 | :param name: e.g. group0/block1/conv2/W 13 | :return: e.g. layer1 14 | ''' 15 | name_fields = name.split('/') 16 | 17 | layer_name = 'layer' + str((int(name_fields[0][-1])+1)) 18 | 19 | return layer_name 20 | 21 | def get_block_name(name:str): 22 | ''' 23 | :param name: e.g. group0/block1/conv2/W 24 | :return: e.g. block1 25 | ''' 26 | name_fields = name.split('/') 27 | block_name = name_fields[1][5:] 28 | 29 | return block_name 30 | 31 | def parse_conv_name(name:str): 32 | ''' 33 | :param name: e.g. group0/block1/conv2/W 34 | :return: e.g. conv2.weights 35 | ''' 36 | name_fields = name.split('/') 37 | conv_name = name_fields[-2] 38 | 39 | if conv_name == 'convshortcut': 40 | conv_name = 'downsample.0' 41 | 42 | conv_weight_name = conv_name + '.weight' 43 | return conv_weight_name 44 | 45 | def parser_bn_name(name:str): 46 | ''' 47 | :param name: e.g. group2/block23/conv3/bn/beta 48 | :return: e.g. False, bn3.bias 49 | ''' 50 | is_buffer = False 51 | 52 | name_fields = name.split('/') 53 | conv_name = name_fields[2] 54 | 55 | if conv_name == 'convshortcut': 56 | bn_name = 'downsample.1' 57 | else: 58 | bn_name = 'bn' + conv_name[-1] 59 | 60 | if name.find('EMA') is not -1: 61 | # Buffer 62 | is_buffer = True 63 | if name_fields[-2] == 'variance': 64 | bn_name = bn_name + '.running_var' 65 | else: 66 | bn_name = bn_name + '.running_mean' 67 | else: 68 | if name_fields[-1] == 'gamma': 69 | bn_name = bn_name + '.weight' 70 | if name_fields[-1] == 'beta': 71 | bn_name = bn_name + '.bias' 72 | 73 | return is_buffer, bn_name 74 | 75 | def parser_fc_name(name:str): 76 | fc_name = 'fc' 77 | if name[-1] == 'b': 78 | fc_name = fc_name + '.bias' 79 | else: 80 | fc_name = fc_name + '.weight' 81 | return fc_name 82 | 83 | def parse_weight_dict(dic): 84 | ''' 85 | change the tensorflow type of parameter dict to that of pytorch versrion 86 | ''' 87 | torch_weight_dic = {} 88 | torch_buffer_dic = {} 89 | for key in dic.keys(): 90 | if key.find('linear') is not -1: 91 | fc_name = parser_fc_name(key) 92 | torch_weight_dic[fc_name] = dic[key] 93 | 94 | continue 95 | if key[:5] == 'conv0': 96 | if key == 'conv0/W': 97 | torch_weight_dic['conv1.weight'] = dic[key] 98 | else: 99 | new_key = 'conv1/bn1' + key[8:] 100 | fake_key = '0/0/' + new_key 101 | is_buffer, bn_name = parser_bn_name(fake_key) 102 | 103 | if is_buffer: 104 | torch_buffer_dic[bn_name] = dic[key] 105 | else: 106 | torch_weight_dic[bn_name] = dic[key] 107 | 108 | continue 109 | 110 | 111 | layer_name = get_layer_name(key) 112 | block_name = get_block_name(key) 113 | is_buffer = False 114 | 115 | if key.find('W') is not -1 and key.find('conv') is not -1: 116 | name = parse_conv_name(key) 117 | else: 118 | is_buffer, name = parser_bn_name(key) 119 | 120 | print('layer: {} --- block: {} --- name: {} '.format(layer_name, block_name, name)) 121 | name = layer_name + '.' + block_name + '.' + name 122 | 123 | if is_buffer: 124 | torch_buffer_dic[name] = dic[key] 125 | else: 126 | torch_weight_dic[name] = dic[key] 127 | 128 | return torch_weight_dic, torch_buffer_dic 129 | 130 | 131 | if __name__ == '__main__': 132 | dic = np.load('./adv_denoise_model/R152.npz') 133 | 134 | # current code does load BN statistics. 135 | torch_weight_dic, torch_buffer_dic = parse_weight_dict(dic) 136 | net = torchvision.models.resnet152() 137 | 138 | # check the weights 139 | num_param = 0 140 | for name, param in net.named_parameters(): 141 | num_param += 1 142 | tf_param = torch_weight_dic[name] 143 | 144 | if name.find('conv') is not -1 or name.find('downsample.0') is not -1: 145 | tf_param = tf_param.transpose(3,2,0, 1) 146 | pass 147 | 148 | elif name.find('fc') is not -1 and name.find('weight') is not -1: 149 | tf_param = tf_param.transpose() 150 | pass 151 | 152 | tf_param = torch.tensor(tf_param, dtype = param.dtype) 153 | torch_weight_dic[name] = tf_param 154 | print(name, 'weight shape:{} - {}, is the shape right:{}'.format(param.shape, tf_param.shape, param.shape == tf_param.shape)) 155 | if not param.shape == tf_param.shape: 156 | print('wrong!, two kinds of shapes not match') 157 | 158 | # chceck the number of weights. 159 | print(len(torch_weight_dic), num_param) 160 | 161 | # transform numpy to torch.tensor 162 | for name, param in torch_buffer_dic.items(): 163 | torch_buffer_dic[name] = torch.tensor(torch_buffer_dic[name]) 164 | 165 | # combine the buffer part and weight part 166 | weights_and_buffer = dict(torch_weight_dic, **torch_buffer_dic) 167 | net.load_state_dict(weights_and_buffer, strict=False) 168 | torch.save(net.state_dict(), './adv_denoise_model/res152-adv.checkpoint') 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /architectures.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | from torchvision import transforms 6 | 7 | from Resnet import resnet152_denoise, resnet101_denoise 8 | 9 | def get_normalize_layer() -> torch.nn.Module: 10 | return NormalizeLayer() 11 | 12 | class NormalizeLayer(nn.Module): 13 | def __init__(self): 14 | super(NormalizeLayer, self).__init__() 15 | 16 | def forward(self, input: torch.tensor): 17 | # RGB to BGR 18 | permute_RGBtoBGR = [2, 1, 0] 19 | input = input[:, permute_RGBtoBGR, :, :] 20 | # normalize 21 | out = (input / 0.5) - 1 22 | return out 23 | 24 | def get_architecture(denoise = True, model_name = "resnet152") -> torch.nn.Module: 25 | """ 26 | load adversarially pre-trianed model by facebook https://github.com/facebookresearch/ImageNet-Adversarial-Training 27 | the checkpoint is converted from tensorflow to pytorch 28 | """ 29 | if model_name == "Resnet101-DenoiseAll": 30 | model = resnet101_denoise() 31 | model.load_state_dict(torch.load("./adv_denoise_model/Adv_Denoise_Resnext101.pytorch")) 32 | model.avgpool = nn.AdaptiveAvgPool2d((1, 1)) 33 | return nn.Sequential(get_normalize_layer(), model) 34 | 35 | if denoise: 36 | model = resnet152_denoise() 37 | model.load_state_dict(torch.load("./adv_denoise_model/Adv_Denoise_Resnet152.pytorch")) 38 | model.avgpool = nn.AdaptiveAvgPool2d((1, 1)) 39 | else: 40 | model = torchvision.models.resnet152(False) 41 | model.load_state_dict(torch.load("./adv_denoise_model/res152-adv.checkpoint")) 42 | model.avgpool = nn.AdaptiveAvgPool2d((1, 1)) 43 | 44 | normalize_layer = get_normalize_layer() 45 | return torch.nn.Sequential(normalize_layer, model) -------------------------------------------------------------------------------- /dev.csv: -------------------------------------------------------------------------------- 1 | ImageId,TrueLabel,TargetClass 2 | 0c7ac4a8c9dfa802.png,306,779 3 | 4fc263d35a3ad3ee.png,244,123 4 | cc13c2bc5cdd1f44.png,560,741 5 | df58f94361c6d105.png,610,13 6 | 6cae4a23623d142b.png,583,440 7 | d02adcb9140880a1.png,916,783 8 | 71080285ad6cb4e9.png,456,478 9 | 137ab6ca314e9e35.png,620,556 10 | 4b384c8247b56c0a.png,542,925 11 | 62ebd5f7ce015380.png,631,692 12 | f24817d66024dfb6.png,742,740 13 | 3e7b01ba495f15f9.png,708,410 14 | 1a264165276e3c85.png,855,759 15 | bc9a5e01c02e759e.png,923,18 16 | 01bdc0cfe670f708.png,472,541 17 | 493694833dc23399.png,538,835 18 | 7529b42e71769777.png,477,618 19 | d204464fcf15ad99.png,300,269 20 | 7fd7ce3eb2bf9944.png,100,113 21 | 67967c9db11151e0.png,252,820 22 | fa2a7d600b62174e.png,521,572 23 | cd2d2889ef7ac51c.png,924,607 24 | 03f90f7138f761e8.png,664,490 25 | 9cf861a657c27cec.png,583,897 26 | 05817a675e7506d1.png,673,754 27 | e1c702ed9842dd1c.png,693,757 28 | 150249123e81930d.png,923,485 29 | 890fdaf4e1892e00.png,313,692 30 | 9a1c67f467b9beea.png,303,90 31 | 3a7d9bd310202e93.png,790,660 32 | 56e9d5f63cfc507e.png,441,624 33 | 602f2c3749d6021e.png,747,106 34 | 8f5eda0b6a910b43.png,950,918 35 | 741fc1a3fc08731d.png,793,400 36 | d77af00930283f4b.png,901,649 37 | 97151fe7a0a6e2e3.png,734,228 38 | d72f34526e12fd83.png,442,325 39 | 957529a2abaa0581.png,883,648 40 | 3228a465697fb2cf.png,840,922 41 | 1733cbc68a2ae05d.png,556,892 42 | 8a82ddd7ab76efbb.png,511,908 43 | e95ef0aeeab7b496.png,889,860 44 | 8555611998ea426a.png,991,497 45 | 1cc2caf8e5db27c3.png,431,607 46 | a00c8d22e63497c4.png,431,892 47 | 4f553b721705d008.png,397,3 48 | 2153d9869fb5a9ef.png,645,942 49 | 7506caf0a49c3951.png,79,724 50 | 1d4133f5bc7af193.png,141,911 51 | fd26c4733822dfcc.png,363,451 52 | 60f5900a00d94b25.png,706,558 53 | b76e552d4b3ec0c3.png,992,191 54 | 3dc0e8f854bdc9b3.png,604,921 55 | 2e9b377877f64b3d.png,499,706 56 | 2842a69bf5b14526.png,880,757 57 | a74f197288b10a0d.png,808,748 58 | 7a85f42383ec2f81.png,709,802 59 | 55e85d7b58024966.png,968,615 60 | d6d192c5786f29f5.png,473,830 61 | 3692f6967c632fee.png,806,569 62 | fae551840c1690fa.png,720,424 63 | 8020698d79dc39f2.png,855,954 64 | 694e7617a4878041.png,884,720 65 | fa5484e61e455eb2.png,477,769 66 | e6e677a28e3bd6d7.png,604,160 67 | 01f824264783f58d.png,968,678 68 | 4e1bdcb677f21fb4.png,874,779 69 | f54616f2af588fd8.png,673,113 70 | f20911d36a287dce.png,781,492 71 | 81a7637c67f4f777.png,490,836 72 | 65c1808390bd18c5.png,686,587 73 | 556d8b457b94c285.png,747,378 74 | 38546e7d7136c2ab.png,600,114 75 | 9876fe92d003c9d4.png,913,357 76 | 8df3dc0c3fef1824.png,951,843 77 | 938ada2f2bfa2b68.png,844,918 78 | 61131df39f19a4a0.png,615,867 79 | 06a0e36c443746b5.png,354,232 80 | f9937696f421f4e4.png,85,491 81 | c98a8640dcfaa5e0.png,747,847 82 | d34c51d7523e9c0f.png,647,655 83 | 66aa56675136bbab.png,470,607 84 | 411c5d79017077f4.png,82,677 85 | 84640859ee739095.png,720,580 86 | 3e1e47f5af2a3f16.png,294,357 87 | 7a291389e67a8a07.png,417,637 88 | afa0f88aaab03427.png,545,3 89 | 4d1237ccbd9a5b4b.png,815,423 90 | 6841e385fe79177f.png,830,833 91 | b48febf2b989205b.png,760,635 92 | 39f82c728c956125.png,638,762 93 | 823f8eae0df2d5c1.png,95,570 94 | 6d6078c60e59e9f4.png,985,797 95 | 1f71668ab3dbe81b.png,709,967 96 | 70b3b833463d20b9.png,864,857 97 | 8800cff23fade16a.png,532,314 98 | af2ac1705dc19a5f.png,384,99 99 | 87937b805302f958.png,418,873 100 | f33087679c5e7799.png,443,588 101 | e8d5809ee6888f8f.png,717,641 102 | fe94909a2fad4ffe.png,547,965 103 | 00c3cd597f1ee96f.png,138,96 104 | a5949b0719d3ea77.png,981,473 105 | 979757e16b67ac7e.png,323,798 106 | 60ab0fb53634bc3c.png,766,552 107 | 4063377442ea93d3.png,596,814 108 | 8f07c92f0af97807.png,806,108 109 | d67b326ef48bb7b7.png,874,546 110 | 1f7c25207bc3e303.png,476,979 111 | 70d812d368e3e828.png,456,202 112 | e19a59ad09d18497.png,443,915 113 | a33af1b9f8b8a81b.png,880,667 114 | e5cf220f8144c192.png,706,441 115 | 9455bd672cb9e4bd.png,522,582 116 | 9c509bfb75167fb0.png,641,748 117 | 37e7dc99bf2704c7.png,664,610 118 | f2bfa7a95e787fe1.png,721,218 119 | 0f9d8c86a9f38020.png,760,118 120 | ce05236afebb173d.png,536,510 121 | 1a7425e8f990e04a.png,608,676 122 | 1ba816dc6937b62d.png,860,768 123 | a92e49d8bbdc2aae.png,533,564 124 | 0e0f1fd2ed183781.png,114,988 125 | 565c67fd230f18cc.png,555,854 126 | b8596bba57a73794.png,352,41 127 | 9f55ac35ce9703e5.png,9,194 128 | 55323ce1ff485412.png,386,571 129 | 526f322d78bd5b44.png,571,288 130 | 229fbe790098d2e5.png,481,576 131 | e0c0f412d78571dc.png,734,409 132 | d12aad0d18252b40.png,325,39 133 | 3201d10ec4dca056.png,739,605 134 | 12cf4de43c70273e.png,815,833 135 | 56dbd7d814ef5c58.png,254,277 136 | e91abe0f1a7a30f4.png,752,495 137 | 641d03527848417f.png,341,450 138 | 088560551b91ceb0.png,983,797 139 | 5d6c4759c26bae8c.png,547,746 140 | 9db1070b1b9f03d2.png,324,870 141 | d6d42f8a1f6b4460.png,666,374 142 | 517dc655edeaf344.png,430,920 143 | 212476b1b58a0cfe.png,512,697 144 | da4f4d6944d93ae0.png,735,779 145 | 1461ed9402248ddc.png,514,725 146 | f0dcd519b5499d48.png,664,231 147 | cfab8f880da31ad8.png,541,308 148 | 0be391239ccba0f2.png,719,996 149 | 8d68931ba23fdeb7.png,842,800 150 | 6bff4ecb94f1f84e.png,859,866 151 | 96fcb76927274db6.png,472,316 152 | 55b85f4336d9603a.png,880,30 153 | a90d9627e2145090.png,426,722 154 | f4bde5facfdca0c6.png,788,194 155 | 803450d936b35ebb.png,934,258 156 | fff35cdcce3cde43.png,913,409 157 | b58e8d136aff5a50.png,625,565 158 | 5c2d823a4d30e3d5.png,718,894 159 | 73728c249317ccb9.png,848,145 160 | 0b1d45bd9ab1064e.png,561,563 161 | 4b52fd42977215b9.png,901,627 162 | 5dbfff56258cf9e6.png,318,385 163 | c47ca11294a9aefe.png,547,119 164 | 44fa09bc5f8e69a5.png,304,990 165 | 70db5a1689f89129.png,434,472 166 | d531a31add433f46.png,764,769 167 | 4d0c0f35a0c00bdc.png,680,432 168 | 33197fa6ae88508a.png,848,30 169 | 78059d1afd7b9fea.png,58,248 170 | e8c99e0220ab46d2.png,591,535 171 | c755f3b0f89028fc.png,566,827 172 | 784232355d49601b.png,327,161 173 | e99ceff3e420ef95.png,831,768 174 | 23955512cd0e1191.png,476,742 175 | d6eac6858474111c.png,323,250 176 | 8d90c523b27410a7.png,321,563 177 | 5cf72b48fdf5e419.png,630,744 178 | 228fec6cab5f560d.png,974,931 179 | e7b61bec5e4ca40e.png,324,674 180 | c7d0c73d636300f5.png,830,801 181 | 61ed2594a0524631.png,472,996 182 | 89f48bcf97aa6600.png,418,70 183 | 9fe19d5c6dab83a3.png,455,805 184 | e648427e38e80ff8.png,888,617 185 | e758de2cbb3d10a0.png,305,905 186 | 38287d2e5a4a9a57.png,960,798 187 | c6e0d2ab3bbf4a3e.png,706,838 188 | 4cccb215bd60b3c3.png,33,341 189 | 1cbae41091a750dc.png,473,814 190 | de40907c1e2c5515.png,629,486 191 | 35c344ca0584ba14.png,688,831 192 | c335ce88293384f2.png,735,629 193 | daa6404780b1af27.png,638,999 194 | 446b24f903b488fc.png,144,839 195 | d7ffed8f21024a14.png,752,922 196 | 7d599306068f4594.png,717,514 197 | 0d6463e9a7ef6185.png,771,786 198 | af543b5f19ed1b1d.png,40,391 199 | c5c9d17672ff88ce.png,458,266 200 | 80177288cda51d95.png,641,605 201 | 5b60477a29c7ef81.png,416,700 202 | 19d43f8204d3183d.png,985,378 203 | 2b741c5c635a7295.png,108,634 204 | ab8329c28d8538c3.png,469,13 205 | d0029b3675b792ae.png,790,902 206 | 69854b68476d5068.png,893,733 207 | 4bdb561770b52424.png,147,184 208 | a92ab9e5fb9c5d64.png,629,457 209 | 8c6edf1ddfb61102.png,889,123 210 | c135b139d293f7f2.png,347,491 211 | 7d2e9b03ec1b630b.png,401,535 212 | 29fe8d653950a631.png,80,542 213 | d4c817db6be62b71.png,95,164 214 | 1e77361718213a43.png,440,435 215 | 6711e27733cfd050.png,718,733 216 | df874264566c58a9.png,742,152 217 | abd121ef53a69ef8.png,240,335 218 | 5021e7da00bf43b2.png,480,937 219 | ebdfdcba5dc3b72a.png,868,600 220 | 68274b8293271807.png,834,579 221 | a84ead15406596ce.png,480,937 222 | 5d1df4748743d42e.png,964,322 223 | 6e840c209f5733d5.png,442,750 224 | 46b657df12fd7c26.png,284,724 225 | 5c8bcfa0dbb246ab.png,818,581 226 | afb0233b2e0545c4.png,581,959 227 | 1bb5f1337dfb1edd.png,641,293 228 | 64ed3f0e8a2dc320.png,653,410 229 | d25df1a8259d3fdf.png,161,833 230 | 184a160b32ff4c72.png,518,717 231 | 4f722cab5573a5fb.png,885,392 232 | f4902a569fa12171.png,950,992 233 | eae13c52554a7783.png,781,848 234 | b1e69e9c3d740f4c.png,4,833 235 | 2efe4916e679e875.png,866,926 236 | 49b1adfeb8ffcabd.png,932,671 237 | 83896b9fb7e9c2f8.png,537,547 238 | f9f36f7774d73820.png,305,723 239 | dad40e355e4e8e96.png,655,848 240 | 064e1cc405062c85.png,108,135 241 | 18d5f99fe237a306.png,815,77 242 | d0c6c29954f0380b.png,431,96 243 | c777da68bec01dcd.png,487,584 244 | 444109f3ccfacc7b.png,336,221 245 | b722c809657aecee.png,777,640 246 | 97025d82ec9860dc.png,676,574 247 | 23f39187c0d00e30.png,972,658 248 | 515c6586db87bbd8.png,874,218 249 | 42e9b41ce96dbf0a.png,851,647 250 | 19b5bea9a7608a92.png,778,435 251 | 1a94dc47fdd84a95.png,870,830 252 | e22a1c8dab22f256.png,311,11 253 | d959fd91192d5717.png,629,596 254 | 8749fd2540a0cb01.png,833,448 255 | 8e9e976fc98e3cfa.png,666,740 256 | 330b9cb3cd80c88b.png,534,431 257 | 74b2e35cda75fe27.png,629,466 258 | f5a2cf5c66d313fa.png,977,656 259 | 5ceb9f2e8405b0de.png,412,64 260 | 114c98c078c5aab0.png,50,108 261 | d741b583a123562b.png,321,792 262 | fdedd06cdf58084e.png,982,428 263 | 911aebf30626ce02.png,875,731 264 | 55599050147071cc.png,473,962 265 | 7f3c20f487834846.png,408,883 266 | 8c8bc30a62a1ee23.png,304,2 267 | e96d52f9fbe3ca0b.png,631,435 268 | ac295a63ac9d2cd7.png,693,864 269 | 5d23b04cc45bc37b.png,518,737 270 | cbcb7444cc827812.png,763,786 271 | 5ec826683757ffae.png,23,369 272 | b9310b9080c06e4f.png,867,269 273 | 4f9f0b75f5b04524.png,58,897 274 | 5c4eec952ca114a1.png,348,525 275 | 7f045354f4577c16.png,558,970 276 | 9c0e25e2f72438e8.png,512,506 277 | adcf48b42266309d.png,505,589 278 | 3b67bec3793efcb4.png,822,746 279 | 67a08d685abf7fb6.png,739,710 280 | 22a313cc9fc2b4f1.png,310,940 281 | 0d85e0103989c850.png,324,722 282 | c3cf76709c87255b.png,676,224 283 | 74355a8c878b6814.png,875,622 284 | d6887e8d19a06139.png,563,45 285 | 0d65cb9d26de4d37.png,571,336 286 | 3df888fc3b1df464.png,955,383 287 | 5ab3f1edd2f0cb06.png,387,116 288 | 51b390bb124a6d9d.png,968,422 289 | 6ad1230d612d7eb7.png,438,680 290 | 76a5715019fe11c7.png,821,768 291 | 207fd3b5def218d1.png,991,279 292 | ad43e858c614db4d.png,968,71 293 | b3ba6f0352a29b2d.png,752,563 294 | 73ee2cc19ef92e50.png,982,686 295 | 84a5f6ee2af29208.png,321,513 296 | 58420b727fcab02b.png,138,168 297 | 0e0299d6352a3fb8.png,539,4 298 | 2ee4c1b2b9bcc6c8.png,763,785 299 | 24312de5c34473c0.png,874,820 300 | bb748281da5e8681.png,348,694 301 | b0bb1ea9bcc45800.png,845,456 302 | b6c6a5b7829fbc9b.png,473,506 303 | 014f0024918a7b6f.png,10,885 304 | 7e4c41563370bed1.png,719,945 305 | d05076189b7fd185.png,708,765 306 | 232c22314e21f764.png,115,904 307 | 2c54b60a2851b8ed.png,657,577 308 | c96c3eab644075d3.png,348,300 309 | 54666421b4a6998f.png,920,759 310 | 4e34df87968bd882.png,339,379 311 | 96e77c20bf94ecb1.png,818,518 312 | c9302f3b2b0452e4.png,884,892 313 | 0af0a5dfee6b84ff.png,484,808 314 | 592c7424f13b2d29.png,604,517 315 | f5b0ed0fbb3b5f74.png,567,645 316 | 70a2529a6b2c0d46.png,580,550 317 | 000b7d55b6184b08.png,389,963 318 | 8a02b6196885c394.png,760,447 319 | 582663fe666aac9c.png,923,928 320 | 83d35591dfff99ac.png,581,857 321 | 3dfbdd066af9ca1e.png,821,5 322 | 59204d6bb0c234eb.png,418,703 323 | d740663eeccdcecd.png,438,762 324 | 01dd15caa1b2c7b4.png,304,551 325 | b97f4b95ae696316.png,518,399 326 | c42c88890b5fc86d.png,671,112 327 | d158837db31ed892.png,519,804 328 | 4a1a40a116088962.png,598,624 329 | ba4508962af69d90.png,673,827 330 | 7069a117c92d27a4.png,546,186 331 | 72f96c6dc5df2de8.png,885,784 332 | 6609c25b3314b5b3.png,512,878 333 | 52d8515abbfaa8ac.png,230,634 334 | a7f9b28e30d19d85.png,662,699 335 | b2a7e558f1a3ff16.png,620,536 336 | 1a95932427129cda.png,657,465 337 | d4579363596fbf21.png,833,889 338 | f7dd570a0cfe1dcc.png,669,55 339 | 2d23b1dab7e3e9c0.png,511,971 340 | 6b27728f0f816dc6.png,638,874 341 | 9b4cab2ffb0c0754.png,975,963 342 | 33adbc27fdcadd65.png,924,716 343 | eb53098ebcf05e64.png,564,601 344 | 8c609b06a60af060.png,499,291 345 | 4c8a4414419ab0bb.png,662,848 346 | 093402dc35f59027.png,734,113 347 | 8bb7d10e97694eb5.png,143,393 348 | 820ae900a943d605.png,888,701 349 | 8859efd46fab37ff.png,923,599 350 | dde9f0aadcb02874.png,981,640 351 | 13810fcac72f12ba.png,876,72 352 | b1bf532ce2c4c3a1.png,875,557 353 | 5b85f98e0105d135.png,570,933 354 | 53c478ffc8ddb967.png,320,613 355 | 92c3f5e99d8ac862.png,664,362 356 | fae45093bad0961a.png,529,528 357 | 0db0952967f6faa6.png,816,552 358 | 868af4a2e614f5ac.png,718,467 359 | 8e3324c208eb9a3b.png,822,741 360 | 5ff168f7d006f69c.png,683,106 361 | 3e9496f7652e1968.png,469,834 362 | 2f7d5ff922af55c4.png,481,633 363 | 412311ea17528b7c.png,764,440 364 | 00312c7e7196baf4.png,327,220 365 | 51d1c77f80467b59.png,977,538 366 | b0e0e06e647b478f.png,484,915 367 | c609f86fa706bb9e.png,113,889 368 | 7d833ac8ab852bd2.png,52,151 369 | 6ab876a15af539c4.png,984,611 370 | 71d368782c72e313.png,913,487 371 | 65b8c8b065069802.png,666,379 372 | b0619a61cf135f5e.png,985,420 373 | aa07ba1587ec047e.png,469,900 374 | 749ed3502293d019.png,475,578 375 | 791c3d333052ca64.png,964,908 376 | 90e9a43bfb6a68b7.png,867,476 377 | 8c5b5bc0f39e2e06.png,898,253 378 | cc43200264a62126.png,981,590 379 | be95f5be87f6fadd.png,459,603 380 | ed3cb7f5154ae02d.png,980,747 381 | 8400742ba78ac009.png,971,671 382 | 1dfbeffd999f280e.png,582,569 383 | eb8ce5ba5c47e344.png,669,893 384 | f5dffe28fc19b6e7.png,918,730 385 | 8094d4088a08cf09.png,441,615 386 | 631b6820e91a9e3e.png,13,303 387 | c0e0c11350b8740e.png,319,698 388 | c663670c06c06ea4.png,909,903 389 | 49591319edeb6b3a.png,309,416 390 | cc8d850717026796.png,662,791 391 | ab3fef142d031784.png,657,737 392 | 9d55997552acf0de.png,260,199 393 | c135337ca7a575ae.png,348,178 394 | 1e33aa336b89dcff.png,539,588 395 | 39a483e9a23716ed.png,676,646 396 | 5191cfba868056a5.png,971,793 397 | 4572c8986c28343b.png,437,535 398 | 7700d0ba053dc4bd.png,937,292 399 | eab9755117160864.png,611,510 400 | 7d2a7bca22967f29.png,735,600 401 | 8e89734ed940e222.png,657,794 402 | 506b87b78daa499c.png,821,244 403 | 28652355cd12a1e7.png,308,63 404 | abe9504895f6e8dd.png,566,607 405 | dd984311bff04342.png,118,524 406 | f7947af6545be760.png,418,722 407 | 01244097ca8ffdfa.png,91,563 408 | 3cf4bb0637d0f182.png,862,52 409 | 1d5361e858fe8462.png,499,523 410 | 6a50fbe8723a6a4a.png,563,597 411 | 001b5e6f1b89fd3b.png,577,909 412 | 25eef91443ded954.png,437,728 413 | ed3f9b6a081a4802.png,818,210 414 | 5c847b72d1e1713f.png,556,522 415 | 707bce947d54bcd8.png,947,941 416 | 43fa89c17e628c06.png,133,885 417 | 5fc906f27c8975d2.png,979,367 418 | 2fc17ec1fad5d947.png,874,929 419 | 7b8413ef241118df.png,548,485 420 | 2e854fca826e54b3.png,858,596 421 | f0add7f552d2d895.png,650,543 422 | 9d4674c86096e4bd.png,662,614 423 | 82b6f0bc71f5d0af.png,563,578 424 | 7453471febf1db6f.png,595,90 425 | 648231d9393250fd.png,548,650 426 | 864fffaf7a83b3f4.png,581,373 427 | c179282bd977c6e0.png,672,105 428 | 40a7f086461190f3.png,493,841 429 | 839aa3d166b020cf.png,14,211 430 | 38bdd950c1d08be6.png,133,891 431 | 2d95297e468bdf9b.png,866,526 432 | 8868879c2acd5d9e.png,322,130 433 | 9534108b0e8dceb1.png,647,822 434 | fbc6b98b13c768e2.png,459,566 435 | 7c3b0d93654b39cd.png,708,428 436 | 43694caa12d5f823.png,979,757 437 | daa43d65c3b18a84.png,822,54 438 | a8c3363bbcc7015c.png,739,840 439 | 93a0857ff81c25ce.png,548,959 440 | b11fa0f292c0178f.png,702,901 441 | 1dc0533f87996962.png,566,853 442 | 589319c64adf5fce.png,699,588 443 | 7e73c7adc520e406.png,133,86 444 | ebb4dad78cfd67a9.png,738,730 445 | 11afa51200515f9a.png,826,567 446 | 9f6fe669276f04cf.png,920,697 447 | 9ee13ecd8d6727c0.png,498,554 448 | d1a723656dc08b5e.png,822,814 449 | b89dbfcc49dcf156.png,889,467 450 | 5a0e21d54b9c4954.png,328,146 451 | 4b8517e927f32962.png,866,271 452 | 81804435ad51df95.png,437,241 453 | e4941a341ace171a.png,709,298 454 | 77c72d0a01e1af70.png,428,836 455 | 32c0e4647ce5a812.png,327,743 456 | 54153d17b11b495c.png,657,551 457 | fb1efda0b27d5289.png,848,203 458 | 721804d1d3a60206.png,909,34 459 | dcb6b32cd80f2b1f.png,556,832 460 | 49c27b439d39a00c.png,490,418 461 | 3f40eba168e5d385.png,515,936 462 | 6c9f8901246faff2.png,629,689 463 | a64ae1acd9d09a87.png,131,83 464 | 05f7c084329ff0c6.png,973,910 465 | ac2a8a4777dbe746.png,896,46 466 | 3d75d9676ad6361c.png,151,517 467 | 686ea4ec999364ff.png,459,554 468 | f63d58b5af16091f.png,716,420 469 | d3aa8ee50458c020.png,431,874 470 | 2891f4aa2279d369.png,471,405 471 | 348ac56def3ccd35.png,916,533 472 | d46216d31908163e.png,896,785 473 | a8dd9ba15f7b817b.png,806,740 474 | 5224fec9ba33b50d.png,604,532 475 | 4a1a488e8a975f7c.png,920,833 476 | d7c1d1632cf0acc7.png,404,873 477 | ea65c0ff71e7ceb3.png,404,737 478 | 200285e90078210b.png,442,741 479 | cec46dbd1fa3473a.png,898,246 480 | 6314b953a2f66e36.png,311,774 481 | 1f3f949ccbc81c93.png,304,666 482 | 04546cc5e537d7cd.png,426,649 483 | 73064ceb466612d5.png,719,673 484 | ae78688b32986638.png,913,879 485 | 48762c2cd2ed47e1.png,755,308 486 | b217644382dcd864.png,512,708 487 | 629138193e021cdf.png,885,739 488 | 90dfd75887f3e67b.png,986,45 489 | 5d6b9cadb6f9e1cd.png,896,746 490 | a033832d9ff8913b.png,101,357 491 | 313ff0037b86260a.png,498,610 492 | b19e2df06dbcccd9.png,673,816 493 | 0e83f990a04ed67d.png,822,52 494 | e9811aebe8bed6e5.png,336,410 495 | 380053c506e32105.png,780,514 496 | 668bc83a884d24f9.png,3,391 497 | be9a3bea2989a0b4.png,718,677 498 | b74c05ecff5f99d8.png,407,568 499 | 7a51c260ca0e83e7.png,548,748 500 | e89d48768917f563.png,459,308 501 | 080bec22a6b1d37d.png,760,818 502 | e37b556e8889d2ec.png,752,618 503 | 67dd47336dc89421.png,818,949 504 | c3e9a84e039df3ce.png,469,765 505 | 0134ba03294509a1.png,982,355 506 | 7d253f78ef6f029a.png,683,92 507 | fecd59b8de8ae6f7.png,820,793 508 | 24159caf9c5e92be.png,708,743 509 | 7ca714cdcd5d36d9.png,780,106 510 | fafbad0b3093a886.png,672,315 511 | 45315ea51da415ab.png,356,189 512 | 5f3ea3c6b683fb57.png,773,62 513 | ccbcaf10176e78e0.png,923,858 514 | c25da85d5d62b000.png,404,219 515 | beb3e55c385feb12.png,815,881 516 | ed3573d0c197fbaf.png,848,190 517 | 95d1a6be6786190f.png,891,983 518 | c8abefc975e94b10.png,875,675 519 | 024f73e53c3c1f1d.png,580,638 520 | 35d67f3f70aeef92.png,980,582 521 | d47c9aabecda0e12.png,986,199 522 | d97c1f3f1c211d1a.png,979,467 523 | a28beac14b9037da.png,405,351 524 | 44aa69f642b86628.png,880,549 525 | 6cc289dc7a8fce86.png,158,1000 526 | a92babc0a6436d3b.png,760,655 527 | 9fbeb797de1e1639.png,763,511 528 | 5a8d5bc9bf40e832.png,519,634 529 | aa4e1cf9cb6e7801.png,896,840 530 | 200735f93ea764f2.png,309,285 531 | 5d53f9bc389e98ad.png,265,468 532 | 5b974695c09ad165.png,991,393 533 | becf3b004177ded6.png,986,457 534 | 4f04ca75d7aafc0a.png,840,633 535 | 8764eecf6e898c7f.png,484,711 536 | c5f5e09f4f5fd41a.png,404,421 537 | 0e9bdc3ab80b1a71.png,367,335 538 | c17d39b1eba4cc03.png,669,732 539 | 01fa4be27dd11b5d.png,451,829 540 | 490df9e021386d29.png,405,351 541 | 08fbf75e60a6efb7.png,484,666 542 | fc583c08026e3d74.png,881,588 543 | db6c6671a6924eba.png,407,412 544 | 5a6439b10c1f6761.png,320,871 545 | 218e02b6cfa0466e.png,699,217 546 | 3f8bf287f20333eb.png,973,713 547 | be5543dc68f0b970.png,780,636 548 | a4f718e554dd18dd.png,976,95 549 | 38c6124f40b8d845.png,896,19 550 | 2c9398f44d099e0f.png,522,482 551 | d2d6ae6e0b8a0c31.png,986,601 552 | fccfc3563cd562e1.png,977,656 553 | 6217866896fbe2b7.png,699,867 554 | 21554e755b9706d2.png,342,76 555 | 87a2147620d5e1cb.png,780,290 556 | af3736cca01a2d28.png,318,766 557 | 5adb3d985cf217a9.png,405,875 558 | 1cfa5381359bff9f.png,422,852 559 | cd40b0e46c9da574.png,662,739 560 | e9ecdf28dc1d5a85.png,609,192 561 | 821aae58dc96b4b2.png,341,575 562 | 715335d5ddfca1f2.png,481,915 563 | 1be47d60e0156bbb.png,650,912 564 | 2ba52bcf59097dc8.png,971,850 565 | 3617bfc5d06bc196.png,885,554 566 | 143c74a57326fd40.png,422,423 567 | d051e0bd46125123.png,669,776 568 | 84af93c72781b7f0.png,438,782 569 | 3e8bf1eee7083f6e.png,631,683 570 | 5528f7330399485f.png,74,212 571 | 635ea505879178ed.png,539,923 572 | bb03be3702584eeb.png,672,624 573 | 8c975de17f3247d1.png,650,526 574 | 8d86fae18afef4e0.png,38,79 575 | 619a9d0eb2acdd82.png,885,843 576 | 9ab953cce5c7f879.png,443,367 577 | a414ccf5c51454e0.png,830,866 578 | 26aa2e6ee43387e7.png,913,741 579 | 6afe58efa85756dc.png,929,849 580 | 0ceee9a38409e30c.png,484,712 581 | 57e62606f02d0251.png,548,646 582 | 91d18b353d5b3be2.png,931,26 583 | 21b0803c965f76ef.png,920,977 584 | 3d6e530955c60759.png,512,892 585 | 0aebe24fc257286e.png,561,315 586 | 3c970c84b598f2d9.png,780,597 587 | c6166621198a3de4.png,986,747 588 | 134bfd93a04b88b2.png,581,962 589 | 4227a6e105cc0588.png,971,141 590 | 90ab38bb74020d5a.png,647,141 591 | e5f15610a22098bb.png,672,575 592 | 4cd90a6459ce9571.png,719,622 593 | cc283b8f7f46fbf0.png,574,962 594 | 5dd8e133e66ecd3a.png,142,346 595 | 8805b0b20d808c49.png,704,927 596 | 448a738f6dcba07e.png,563,416 597 | e5948d6294eb8ca3.png,887,676 598 | ce4a0aa202981fa8.png,9,738 599 | 3a93a4dc2c8c866a.png,25,470 600 | d8e10d91ca06f8a5.png,418,568 601 | 59d085fdb8a522d8.png,960,28 602 | 516301f7fd74072e.png,885,537 603 | f7f85c56122216e0.png,524,352 604 | b31309b3aea0b4d8.png,542,686 605 | 0398af20cdc80e17.png,971,998 606 | f041df267ce93962.png,975,48 607 | 8ff2f242d37fd0e9.png,834,544 608 | 7b1e8dddc4d3dd95.png,143,287 609 | 71e8af9d2a1988bc.png,780,532 610 | 6cb14870eaa6c645.png,341,759 611 | 29a22db782d2fd6a.png,529,833 612 | bd0610feded7ec1b.png,763,709 613 | 0f2e8e58a991472b.png,120,697 614 | 8c5c46d627350cb2.png,780,59 615 | f6449244abe058a0.png,920,549 616 | 4758e82e4d0eae1e.png,792,546 617 | 55ed9483245c673c.png,780,931 618 | bf571602729dc613.png,23,975 619 | 1e4d8f729c80305c.png,472,425 620 | eaa88f936210e51d.png,398,953 621 | 4b1c01b84f5167a6.png,719,501 622 | 986e14bd6ae80609.png,418,307 623 | 3c99b1263f54b352.png,704,342 624 | d9b46861ab203acc.png,499,957 625 | d173abdca8d08e00.png,611,473 626 | f0920019f77fc2f8.png,563,706 627 | 9552c19d7e2bca89.png,948,490 628 | f9877ce2f6a0b7d3.png,524,907 629 | 6367ac8abbfbee7f.png,975,460 630 | d9e987a5da26eabf.png,669,654 631 | 55d4770499efeaa4.png,304,328 632 | 54f7c8c5af370662.png,854,904 633 | f21635f78f294334.png,147,468 634 | b67c95a6acb2f02b.png,782,995 635 | 37f1e5313e0e0954.png,995,582 636 | e523da536c95ebd8.png,336,68 637 | 17655256e9e840db.png,484,841 638 | e3fb28cd64b13ed5.png,595,759 639 | 409746e2fff0e9e5.png,431,355 640 | ff83ee5de635fda6.png,822,417 641 | d6a884049122f404.png,309,284 642 | 32581cf019042e32.png,986,883 643 | 51fd398284ce6523.png,982,634 644 | b5350cf7e4c962d3.png,975,830 645 | 11bd90ea5ca8f6f1.png,673,440 646 | 244633b53f8cbef5.png,875,284 647 | 5948fbd35229358b.png,418,258 648 | aca4f156b3f7a62e.png,310,227 649 | dd059db2ad7c2bbe.png,718,685 650 | 397aa21ee684462f.png,16,273 651 | c4f8b575d5929648.png,355,856 652 | 50179d5916b65cd4.png,806,809 653 | 38951edc87604648.png,448,273 654 | 5e781d29d1d9ec33.png,441,640 655 | d3966ff1b248339d.png,752,690 656 | 80dcecc8754e64d2.png,336,286 657 | 3ecbd108c7a4a59a.png,405,801 658 | a4d9f51a15d63047.png,709,231 659 | 245d9fddf4882422.png,558,949 660 | 6ee2a3e9f33a690f.png,980,669 661 | 9fcf2c59ff0ff9b6.png,975,483 662 | aca0f7bb5634215e.png,448,139 663 | f5bd6bd67c9f31b9.png,490,327 664 | 8c25acb3c180ab09.png,600,659 665 | 1dfc1acdb562105b.png,22,166 666 | fbdde8cbc678bea7.png,934,83 667 | 2f3ef912ac6b0250.png,986,70 668 | beeecacedee95b9b.png,404,190 669 | 17305ce8e6a2b746.png,889,776 670 | 61e2fbffc6975c45.png,95,755 671 | d273531739675b8a.png,577,971 672 | 800bbac9e2e5974d.png,470,582 673 | f00bd297dae41dfd.png,629,751 674 | e597fa21734e89c4.png,341,933 675 | a959719b8ad773bb.png,830,236 676 | d32f8fed46bda042.png,664,556 677 | 3a18c30e8585b650.png,524,970 678 | 3f3fdf6909d02648.png,688,871 679 | abed3321f9001b33.png,806,763 680 | 951bce0c4f695dc1.png,780,488 681 | db3f8c29f1206c6d.png,780,757 682 | e3deab462fb7c09b.png,896,629 683 | 7b9c901d0f735717.png,426,628 684 | a73d3d29520b1712.png,699,907 685 | 33d792783c22d45f.png,324,879 686 | 90aff731f3c23326.png,558,593 687 | 2ae7111d7768957e.png,976,227 688 | e6bea491b7b39c9d.png,923,25 689 | 824e1d499f83a4e9.png,458,557 690 | d40343ec11465b3c.png,875,231 691 | a37df1410c95fcb1.png,437,299 692 | 1bba4ef457be4add.png,22,459 693 | 9066202fcefbca71.png,874,906 694 | 3b9abecfb8ac2c2c.png,561,855 695 | f126713ff16704b1.png,519,111 696 | 43692809404c2d2d.png,780,784 697 | 1d43c97815370034.png,780,680 698 | 1b8bbe97386a4b63.png,975,539 699 | 7b5bb3821e924e98.png,780,750 700 | 95d22c402431c2db.png,558,958 701 | 71522fb58f7879ee.png,629,526 702 | bb4ef961035d26ec.png,815,728 703 | f29cfc6cff019a05.png,699,550 704 | 3a6fdb1fd754242b.png,986,614 705 | c4aa9d77cb1b4927.png,854,557 706 | 02851c38dfce98b0.png,986,931 707 | 509c3200ab099636.png,820,790 708 | 70dd1a97d4663a72.png,519,489 709 | d1d5ad9f7db05c65.png,625,617 710 | 69720b5bb72880f7.png,146,492 711 | b521cfe682e3c26a.png,706,479 712 | 4595c561ddece482.png,629,645 713 | 97c72b4e6148bdd6.png,972,564 714 | e67ab4ba4bb4dea9.png,922,786 715 | 7f84a1fe9c7d2ae8.png,476,591 716 | 05fe1ace8eecf93e.png,808,481 717 | 62f1ea06dd035411.png,558,136 718 | 9f7aef192b8fa8b3.png,477,639 719 | 5ae100fdc51dfe53.png,746,454 720 | f62f390eb1097576.png,515,379 721 | 0cde76c81018cc8a.png,472,779 722 | 09d9e27638cfd149.png,702,758 723 | 9137f22576f67221.png,779,311 724 | 51d545471e30a2e7.png,702,510 725 | ed42252ca0c0fca5.png,542,439 726 | ae87647541e29397.png,336,356 727 | 888207991e7d9a62.png,341,280 728 | 7000bf5f979d6820.png,718,722 729 | e46f32ee2a471099.png,617,952 730 | ca615289147a0fea.png,411,158 731 | c871806d605af637.png,909,767 732 | e8f105fba60a0633.png,139,519 733 | 49891ab8d826b5e2.png,780,919 734 | defcc0e67346fb39.png,982,247 735 | d089896392c68f10.png,928,796 736 | 7c6571d95eb491fc.png,978,596 737 | aed5042a1020173c.png,404,828 738 | 4a20523c00280ebd.png,404,613 739 | 15553549d8ba09db.png,986,442 740 | 32014e1dcbcd9667.png,547,401 741 | 7941287d96e2a97d.png,821,651 742 | 4e600c516b012ccb.png,108,997 743 | 960c2fbb9393dac1.png,699,58 744 | f7613103a3f7f606.png,490,360 745 | 9efa722b7b18ecab.png,519,446 746 | 41c70c3afeb54d03.png,820,474 747 | 0e5b6760664ca045.png,618,154 748 | d173ff3d2e9a8e40.png,80,624 749 | 16299d503aca0747.png,709,71 750 | 41394f0da7ac8b12.png,313,90 751 | d5692729bde701c6.png,459,784 752 | 1b7c237e43a63caf.png,404,672 753 | 269c7e4cf57800d5.png,921,757 754 | 69d411b3b5646afa.png,582,817 755 | c0c524882c16f45e.png,985,77 756 | 11f5bfa0348cf73b.png,942,802 757 | 84eaa7c8e6f876fc.png,960,543 758 | 178f5890f92a92a0.png,490,931 759 | ce99a0896f6c9277.png,964,316 760 | e37fa47b70126729.png,889,788 761 | bf962faabe206781.png,561,282 762 | 18ce1a3099ee3dac.png,629,600 763 | 568bc38f3ca1e354.png,680,849 764 | 790dee2e3edd6ad1.png,972,673 765 | 0c4219f2a19b5dc3.png,459,236 766 | 1755ddf241af4505.png,484,546 767 | a8656992ebce4856.png,976,894 768 | 0cb005f7eeccb80a.png,868,370 769 | 9948070c7eb241cb.png,459,371 770 | 09e2a86d93e696c2.png,548,363 771 | 60bad371625ab964.png,702,493 772 | e1d0a5989d08d8d9.png,976,49 773 | 89723de59bcd729f.png,820,496 774 | 4d4036763558c2b3.png,896,785 775 | 33e2a1137737fe19.png,848,708 776 | 109d5ba3faba5681.png,437,30 777 | b301910b6e183645.png,747,507 778 | adb7ebb0c1aa25d1.png,618,762 779 | 081f36a3036c82e9.png,405,632 780 | 0b428b3c371c490f.png,324,339 781 | 44ede47181b3ed7c.png,407,675 782 | 4d2279fbb77d5cf4.png,324,464 783 | 5e2795e93d116422.png,405,830 784 | 3d8d44a02f73c91c.png,688,900 785 | 953c5a4e009dee96.png,402,725 786 | 1b2127870b62dae3.png,780,437 787 | 29285c4a579d8c3c.png,418,48 788 | cf648fe7d2176bdc.png,986,397 789 | 97445f57c27f2d47.png,977,796 790 | c712cc9afaa22a99.png,519,538 791 | acd617ee5f3f23a0.png,98,392 792 | 4fc0d5234680582e.png,780,23 793 | e4bd6dffe8b8001f.png,848,662 794 | 9a7ccdb8130eea74.png,426,563 795 | 1a554d01773b4b91.png,780,397 796 | a8cfdf9c34e0a2d9.png,688,44 797 | 0e75ebd66b9ab3cc.png,550,573 798 | c0a4e548b5cbd6e1.png,821,751 799 | 6eb88bb1279e92f9.png,718,897 800 | fc912e8f19f4e1c9.png,320,158 801 | 5f995220f250d08d.png,735,517 802 | deee1f1106038ed0.png,723,569 803 | 2a4185153f0f76fc.png,662,118 804 | 718ef5a99da31acb.png,979,337 805 | 37c329eff6e5207a.png,459,991 806 | 76d4df36ca6fd78b.png,986,825 807 | f27a10945fe9ff4b.png,979,953 808 | 771a3735ff67b691.png,971,492 809 | 06227762bad2b330.png,515,66 810 | f63051413723905d.png,392,936 811 | d46ebcc62af2acb9.png,303,89 812 | 27a61180fabb7637.png,582,874 813 | 099f98003eacf5a8.png,780,717 814 | df852fb48bede2a9.png,966,647 815 | 6319d8a3f0340262.png,309,300 816 | a600298956469f9f.png,706,630 817 | ea9f35646c8e9570.png,820,978 818 | cda835d476e0c303.png,780,717 819 | ad422df43e2a757e.png,405,711 820 | 6cbe797e65839c6e.png,404,584 821 | e0e32cf5266cd521.png,672,5 822 | 29596c93e9d20f40.png,561,721 823 | e79ae44ee3c2a62b.png,780,663 824 | 8d84bc4e09806502.png,896,858 825 | 5f2138e8a283fea8.png,321,844 826 | 4f31358268225536.png,734,614 827 | 456f0845b4eae10c.png,973,945 828 | f7e21aa5b89dc479.png,611,48 829 | 42d97cc2d5f30194.png,897,746 830 | 3417481b4e7b29c8.png,131,221 831 | d5a9b43c6257b3ac.png,311,138 832 | d4c06c1da1658af6.png,558,607 833 | 61716ea3da29278d.png,70,956 834 | 7608022af9de0911.png,437,945 835 | b0e0d37759ce4e3a.png,948,435 836 | 6d818e8669f3ac61.png,434,139 837 | 926c676a37c8d8ca.png,975,138 838 | 13f692e45aad3439.png,534,879 839 | 23de0d55027dc7a3.png,739,627 840 | e4b30712d50cef1d.png,133,148 841 | 71b36f834c4fe9ad.png,411,21 842 | 2def3fa0f5a6ba73.png,861,411 843 | 1864b9416370c851.png,604,656 844 | 50ebcb625858518c.png,752,839 845 | 5d587eaa33f6efec.png,986,521 846 | 0a0e6bfebdf57cbd.png,881,533 847 | 0a002669d7bdc690.png,519,513 848 | 56f3542e14bacdff.png,323,40 849 | c3c7e3994bc34b59.png,645,316 850 | c1e470254bb87522.png,683,224 851 | 0cb2feb744266fd0.png,719,561 852 | 1b735d0ca8fa4658.png,426,576 853 | 6ef50fd6d78ac91a.png,830,902 854 | 76a2bbf100fcadde.png,995,586 855 | 3aa1b2978bded6a7.png,986,521 856 | 11c4b54a964ff082.png,309,371 857 | acb0d1c3621f8800.png,940,633 858 | 551d323118fb54d3.png,896,746 859 | 8f08f1f32cca10a5.png,875,969 860 | d0eaf6fd93c44abe.png,109,68 861 | 8e08a9b7438577a5.png,629,808 862 | 47207907c465be67.png,718,630 863 | 6dfb92193c305bf8.png,569,988 864 | f3332771b727a5ee.png,760,669 865 | 2fc2878b88ad6b2b.png,556,439 866 | b98022eec66378e7.png,760,210 867 | a40071ec26435025.png,985,831 868 | 9b5e40255d8797f1.png,806,969 869 | 746cdec58e3555ba.png,556,682 870 | 15cc30a72f8f9e95.png,986,813 871 | 6a2c70c10ec98aa9.png,725,705 872 | b92c426bcdf4e43d.png,309,759 873 | ac81b69c57b36643.png,577,816 874 | 993357c62f7de85b.png,756,685 875 | 7bbe4f3334281c71.png,519,772 876 | 7eda6af195a61a91.png,405,976 877 | ab1b0fdece18272a.png,971,143 878 | d00e37994716353a.png,976,692 879 | 96c9b394d26a0e07.png,426,837 880 | 7f6d8a15cec61bc8.png,144,423 881 | 96c07d57f5ab319a.png,302,469 882 | 21155a5258a45a27.png,364,493 883 | 5821b43dd6cffda0.png,979,504 884 | a12f6199b2c667d5.png,848,729 885 | 2cd4f0f862b967ed.png,570,543 886 | 2da87918bc750711.png,808,442 887 | ac6e0c07c374d5d3.png,816,831 888 | d57b6311f42ceb01.png,780,491 889 | fe1e574cec7ca19f.png,88,163 890 | 9eafc3680ef735a3.png,93,812 891 | 9011236561e23d43.png,405,472 892 | 22011cb97c752dac.png,422,778 893 | ee6009e30c777a0c.png,975,354 894 | b7fa44c32caaffb3.png,763,713 895 | 7813339c05a069fe.png,985,263 896 | 222d963ec296ba85.png,982,715 897 | 5d93f75020b4f99b.png,699,632 898 | 5e88f291092f01f2.png,120,622 899 | a68e035407c80913.png,868,673 900 | 0bdc3c04749c45d0.png,725,66 901 | f410f7e55ab34cd9.png,744,730 902 | f0e41c05fd793215.png,975,728 903 | 8f7fcccbd5d77137.png,825,788 904 | afab65c0134e89b7.png,986,229 905 | b53c546e0c820bb3.png,913,728 906 | 74cbbe6557010b90.png,294,311 907 | bc3c605c14599dc9.png,980,40 908 | 0760df7b9f52457d.png,822,575 909 | 4a43182fa48efb7b.png,806,778 910 | ef1846af3e7a330b.png,95,89 911 | 50bcbeb838c1a63f.png,725,91 912 | 0e96ff091098f82a.png,920,894 913 | c596ed9fb2fee4ce.png,499,764 914 | 8a45a1ea4a1a65cf.png,561,892 915 | ee0ca63700e017cf.png,469,685 916 | c39e14b985d2504a.png,495,979 917 | 20c7fdb3317a5432.png,866,804 918 | e6076758f0c3c5f8.png,826,508 919 | 26dab12c8c3812b8.png,405,151 920 | b33c0003b4b57bab.png,480,44 921 | 1386bd0426854bf7.png,611,367 922 | 070fdf97b04a48b3.png,115,324 923 | 123d524ff1fabfd8.png,629,601 924 | 7853d8c5bcddf639.png,458,486 925 | 19106fcec4aa5edc.png,669,820 926 | eadcb6de5c696016.png,108,520 927 | 2c68c6ae26e649e7.png,780,948 928 | 173b3f63e7674dcc.png,459,517 929 | 6001cc9decf254ff.png,806,247 930 | 2cf1890535bdfe45.png,341,569 931 | 5205a1f46cba0dbe.png,971,989 932 | 63fa27eea73b1428.png,896,860 933 | 820e369be4f64c37.png,477,121 934 | c790f093bea813b3.png,519,693 935 | 29a1066827fcfaca.png,450,360 936 | 9be422211168e7d4.png,311,372 937 | 4461c08e0e8ccad3.png,780,680 938 | 40fa67f6e533a165.png,144,780 939 | 8a8d7bb089dd305d.png,964,394 940 | 8aba9f1a3dac78f3.png,108,424 941 | 444c1d7cdc1fa734.png,971,883 942 | 31132b257261e655.png,459,148 943 | 2413f3c22fc92bc7.png,948,616 944 | dd6a8febc0c953ef.png,644,45 945 | 1c8d37176aa05ac9.png,481,710 946 | e6ce7bdc752558f7.png,512,249 947 | e373c220d13963c4.png,704,535 948 | c6b127ac8de0db8d.png,719,513 949 | c63383968413f24b.png,780,872 950 | 52deba153ed4e0d2.png,780,39 951 | ecdab98dacbe3d58.png,519,952 952 | 31d7acb588ab6203.png,859,345 953 | 486d49986d58de99.png,940,329 954 | 3cb4532bf414a515.png,821,402 955 | c8b54d9146aaa440.png,709,10 956 | 22fadd66bd941d49.png,909,998 957 | d676a27058888617.png,980,905 958 | 431f6f8fbf02b996.png,780,483 959 | 325789b40f7da9e0.png,854,573 960 | 30d3d719e61e2072.png,322,524 961 | ca899ebaaa192e76.png,512,154 962 | ba5ce414717dcdf4.png,780,136 963 | 4d05d6759e6bbea0.png,875,333 964 | e03b970bb8b75246.png,650,306 965 | 2ca9a74e9461a362.png,975,884 966 | 6cabb8f2ed6a5e48.png,895,791 967 | 14f62659ed234e96.png,780,130 968 | 75a87ac21ad2e102.png,563,105 969 | 799da227df8b4e77.png,85,967 970 | 64970b901ef0209e.png,873,95 971 | 3c416fd66e2f7fa3.png,896,713 972 | b64acf4eab440b2e.png,760,251 973 | 8ae56aa3aaf970ca.png,666,166 974 | 99c649f1364eb2ea.png,696,559 975 | 759e53c9e3f518f8.png,777,510 976 | b1eea5e72b0bb211.png,908,515 977 | 01dadd6b781ef538.png,702,698 978 | cd7adb9c241f3645.png,558,353 979 | ae6d7204c6a7bf9f.png,979,962 980 | 43a8ba622aeb8907.png,490,846 981 | 45ad724c3815c7b8.png,848,524 982 | bff44e5ba0d28c5d.png,407,465 983 | c24ccdbf81172891.png,986,504 984 | f54aeb5092ed5267.png,147,643 985 | dc0efd47be5140b1.png,347,115 986 | 38426929a2c14bc3.png,618,132 987 | 2ec28ff082dd9ddc.png,986,199 988 | 755cad2db75470e8.png,806,161 989 | c31bf2a561660a48.png,108,649 990 | d4ae0b51e0c5c161.png,405,976 991 | eff76dc3f74bdc0f.png,975,753 992 | 92cbae0f539f4693.png,638,328 993 | a4855965f0ee1892.png,548,481 994 | f8f8ac0b8c70545c.png,108,84 995 | fb3c12256f23989b.png,810,513 996 | 279c74d94797c6ae.png,971,825 997 | 309a61f58932f9d3.png,324,68 998 | d709b3b07426a833.png,923,43 999 | 82996d5a78866f57.png,563,569 1000 | 8f64cebadc25455f.png,42,114 1001 | bf9772a06e6bd842.png,920,786 1002 | e02d997b35e0b442.png,704,835 1003 | a84245835f36d314.png,875,702 1004 | e67bc976a1e69a81.png,484,456 1005 | 3835f34272b005a8.png,484,108 1006 | d56b109bb8dd4006.png,437,897 1007 | b81e7b2bd2324839.png,752,951 1008 | af5a6a757ef0acb0.png,629,591 1009 | 949b6656c77fc44c.png,548,361 1010 | 6862ec8595dc6c56.png,976,652 1011 | 9f340eca7b32bd1e.png,821,402 1012 | 5568d5c80c28f3a9.png,875,545 1013 | ff403c29ed79f115.png,896,827 1014 | 00c290a290534440.png,973,267 1015 | 1edabd3f528a988f.png,88,298 1016 | 0bf52174bd593307.png,975,269 1017 | a518ced9fc09eeb3.png,975,99 1018 | cf9d921917a6554c.png,850,515 1019 | e5098db03fc02a79.png,100,493 1020 | 4313065196ceb86a.png,780,919 1021 | d330fefbebf1068f.png,986,817 1022 | be9aaa2b5a32fe9b.png,405,374 1023 | 91dafb69f1245da0.png,294,151 1024 | 84e91c0b8ca02f79.png,405,556 1025 | 74e357a88ff94a07.png,978,544 1026 | 5f9d13820921fb77.png,100,846 1027 | e17b93ee3cbe1f0c.png,438,582 1028 | c17e418fda3eb851.png,519,263 1029 | e165dcbeb553716f.png,2,727 1030 | 8f3505c8e6454794.png,459,787 1031 | 49dcebfc5f06cf7b.png,405,393 1032 | 4b74dc92cf2e80d0.png,108,532 1033 | 01c0e6fbf97538ea.png,755,222 1034 | 0791499bcccabe52.png,699,431 1035 | 01b2592eec61252d.png,977,557 1036 | 30e85d1e2c85669f.png,926,754 1037 | 7cf5d1811b244ea3.png,512,696 1038 | dc4ba9edda1e2a75.png,407,637 1039 | 9b716a09c14f9b79.png,512,547 1040 | 55e190b917b6f461.png,537,921 1041 | 722d7c82f9e52277.png,404,351 1042 | 34622e0ecc448248.png,820,801 1043 | 08d4d6367652408d.png,610,590 1044 | bdb95712664d9e5f.png,405,732 1045 | ca31395e1a54ce30.png,657,867 1046 | 2188f85066df06cf.png,133,238 1047 | a23d4cb3e070d9df.png,512,627 1048 | d4381dfea17fcfa1.png,976,812 1049 | 865c22c59f23a382.png,967,501 1050 | 00d3094857416925.png,821,691 1051 | 7b2da05adcfd033f.png,556,834 1052 | f8f90b6a2ff3a5ca.png,672,452 1053 | 13992d45aea1ac78.png,308,574 1054 | 86ff221686395d10.png,548,359 1055 | d24ff49949d9ac44.png,821,736 1056 | 7c286d90b45671b7.png,760,284 1057 | cbd9875f2249282e.png,548,422 1058 | 307a646d5907399b.png,718,275 1059 | e1a7288ef3c4fcd7.png,914,176 1060 | 16975e74dfbd7402.png,975,292 1061 | 57d1361e30f54c93.png,431,682 1062 | fe2e27a42f7ddd98.png,980,265 1063 | 3bedd25b5a1dad51.png,982,242 1064 | 26b01f31089459d0.png,980,499 1065 | 48e691c7cc9bbabc.png,147,473 1066 | 87c012e12f39ff79.png,407,786 1067 | cc6261571a779f34.png,610,571 1068 | cbad7143016a1593.png,820,97 1069 | 703a0b79ba9ffb4c.png,459,943 1070 | 4ae1e87e1855a760.png,662,460 1071 | ffd75e49a6c6cb04.png,638,946 1072 | 0cda86f27b9c06d3.png,875,746 1073 | fcf19e03aa2008e4.png,512,685 1074 | 0ffa4e0eef72f7ed.png,982,538 1075 | a74536baf84ffa47.png,655,320 1076 | cbcaa587c96b599b.png,777,430 1077 | eb3f60c3e0eb5675.png,405,442 1078 | 415fd08b8c01f727.png,662,831 1079 | d8da85f009866249.png,459,398 1080 | 79a6c5c8b04a7108.png,407,607 1081 | 53953db800a896ff.png,548,297 1082 | ce2facd2fb6d0cbe.png,305,606 1083 | e1eb18e3c44ac514.png,875,608 1084 | bbdd9f5816a28b00.png,548,923 1085 | 27b9e505c9a5b3ba.png,769,64 1086 | cccd3907158215eb.png,920,110 1087 | 6b536636db03368a.png,441,808 1088 | bedcd9af3d03feab.png,780,879 1089 | 4b116f872dd54eed.png,36,697 1090 | 3c1b3819c671f1c7.png,404,819 1091 | 3d2abcbe53ac654b.png,889,313 1092 | e0b447f9a4252571.png,132,324 1093 | 761e179b569cbb65.png,976,85 1094 | c93a9fa0ccd5444b.png,204,322 1095 | 037152a42a3d1e8c.png,627,730 1096 | 1d56331cc332d8c0.png,752,873 1097 | 366caad06763b53d.png,840,497 1098 | 174cbab4303eb662.png,896,660 1099 | ec1c634bfdffe570.png,570,912 1100 | 0bb78770d50d0b08.png,923,833 1101 | 4686fea497a61d5c.png,792,620 1102 | c0cda0f5a54343b7.png,512,593 1103 | 9c858a860598df4c.png,437,745 1104 | 7f22cad03f98680c.png,548,199 1105 | 8919aa6ab76b8a13.png,706,874 1106 | a8cfe84bfbb905b1.png,405,136 1107 | 777c15a9f1bb7a0a.png,706,149 1108 | 86a083993a32fc75.png,539,631 1109 | 39215655c9a7178e.png,875,587 1110 | e14b7963298b695b.png,270,422 1111 | 8c1296e3fc73bb1a.png,361,386 1112 | 77dcba158e450113.png,760,871 1113 | e6557602770210ec.png,821,853 1114 | c54d9d576a077722.png,874,758 1115 | ddb9bf0eb25bf2b0.png,889,512 1116 | e64dc418e4347581.png,405,774 1117 | 42e193ecfc2e3441.png,971,600 1118 | cab419eb5d18f714.png,404,70 1119 | 74a81b0154ea464c.png,822,570 1120 | e38f625efd714dd6.png,982,1000 1121 | ac1b0876bbe8e9a4.png,426,250 1122 | ff8746649ab3f934.png,407,795 1123 | 5775f0a2539557b5.png,920,801 1124 | 00e0c970bacdb5a6.png,672,513 1125 | d74d464c3bb94dab.png,672,812 1126 | 6269269e08fda904.png,704,590 1127 | 196eeedde559e5a9.png,664,511 1128 | e855ba5abd770ab3.png,349,375 1129 | 903e6d1d34d4c358.png,961,213 1130 | 0557707195f0c04c.png,427,498 1131 | cfdfa6e881689ffd.png,672,858 1132 | 37ba2e92645e5fdf.png,821,354 1133 | 89e7fbd80e0de870.png,747,772 1134 | 5034d259fe9dd9e7.png,536,709 1135 | 2ed100c942fe2248.png,604,90 1136 | fe91741b82eba4ec.png,348,893 1137 | d46bda0f98ffd223.png,888,933 1138 | 5d4d94f48ccd34cd.png,441,849 1139 | c5f061dcfb483a11.png,848,243 1140 | 57cb2d0d4e60115f.png,977,998 1141 | 4fd4885be5338a57.png,666,824 1142 | d226233e9e80c844.png,667,782 1143 | d8c4089a3576443d.png,672,313 1144 | 7857c2b2999b6b0d.png,672,556 1145 | dbd5f5702c93d034.png,884,279 1146 | ffea2ed2fcef0dd0.png,699,461 1147 | 081806d391df2390.png,719,678 1148 | 7c01e0d1a303d2f3.png,441,829 1149 | 017907ab47d2a23b.png,835,457 1150 | 030299994195bfce.png,108,742 1151 | 2faf3ea634f1c11c.png,986,104 1152 | 1ab396f9a7dabcc6.png,752,489 1153 | 0037457099831038.png,820,803 1154 | 31c99affa0ec993e.png,976,238 1155 | fa6bae54bd5d8b13.png,806,609 1156 | f12d9fb74d93ac1b.png,148,414 1157 | 89fba1b9f530ae70.png,896,856 1158 | 5c89f0eb592da419.png,93,797 1159 | ca6ad83e69143e79.png,806,284 1160 | e1db6c0ddd408559.png,976,656 1161 | 0a5db53c7286f8ab.png,980,777 1162 | 3ff325032a8ab559.png,405,599 1163 | 8e7f94eeded8fede.png,512,868 1164 | 1cdd7d5724781f3e.png,818,566 1165 | 36ad1ff75147f53e.png,484,847 1166 | de9cd631e3f1bb3b.png,443,855 1167 | b4da4e4c923c953c.png,548,662 1168 | a6cca368f8e25813.png,821,626 1169 | 85ec66858f670b92.png,782,521 1170 | 8ef712565196f839.png,662,272 1171 | 31a2c1b6d289e197.png,487,897 1172 | 5b892db51a31a5c0.png,752,106 1173 | 4561d75e1eb2008d.png,709,92 1174 | 8172f0fdfb6fb9b8.png,59,326 1175 | a95f9e82901ab8c9.png,971,445 1176 | d1626847eb98b247.png,297,667 1177 | c68023eba7275883.png,304,235 1178 | fa61b6c9d4988957.png,821,704 1179 | d21a0c974022fa0f.png,739,788 1180 | 07e44b6351ae7c0e.png,821,765 1181 | 7f7856afe236ce4f.png,426,798 1182 | 09540b63dc9894c5.png,448,500 1183 | 83d5a14d9ffa8eb1.png,976,626 1184 | ffce60210764e242.png,986,536 1185 | d441eb660d2c9b7a.png,978,256 1186 | 8b2f06597a576599.png,793,749 1187 | 27018a94efb8a53d.png,489,700 1188 | 27e0d2d2a445edb5.png,980,871 1189 | 438eeddd57911cdd.png,973,649 1190 | 0b3e55f4f58ece40.png,600,882 1191 | aaa4f3f9d6d61aa9.png,442,583 1192 | 34cd73dae4d33894.png,20,237 1193 | 71683b3b80fcf92a.png,826,943 1194 | 66c0d373c70f8015.png,508,580 1195 | 81dfe18c7dd3deaf.png,563,158 1196 | 6c45e7530872effb.png,976,352 1197 | 0804141fc80a512b.png,752,790 1198 | 4edf885a00cd08b6.png,895,450 1199 | 39efdad3eeaf6fb8.png,743,477 1200 | ab1da57dc73af11f.png,704,87 1201 | d603622bdc1d91fc.png,408,599 1202 | a4c9ad41dbba56e0.png,664,426 1203 | ccebf4596e8cbda3.png,875,645 1204 | 4721d7e8bd28c774.png,498,849 1205 | 225a3247d50b337e.png,405,679 1206 | 9e4d03d077a5b514.png,913,130 1207 | a40a92752aa6ea98.png,401,880 1208 | 87991155b1d3f344.png,918,632 1209 | 843f9eff05e7fbcc.png,672,812 1210 | e43946ff747a33b3.png,918,565 1211 | af47658929e9e020.png,815,797 1212 | f7d7f686b5d95aae.png,923,716 1213 | 1ed36bcbf5dcaad2.png,874,925 1214 | 646d3915eba3dd7c.png,669,930 1215 | cdb921ec7f0ca0bf.png,512,240 1216 | 6b138f3aa500019c.png,566,786 1217 | aad61bf6c5001828.png,672,568 1218 | -------------------------------------------------------------------------------- /image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Equationliu/Attack-ImageNet/c3ef6226947f5112f91aa328a39bc1704d471ff5/image.jpg -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision 3 | import torch.nn as nn 4 | import torch.optim as optim 5 | import torch.nn.functional as F 6 | from torch.autograd import Variable 7 | from torchvision import transforms 8 | from torch.utils.data.dataset import Dataset 9 | 10 | import os 11 | import argparse 12 | import numpy as np 13 | import pandas as pd 14 | from PIL import Image 15 | import time 16 | 17 | from architectures import get_architecture 18 | from my_loader import MyCustomDataset 19 | 20 | parser = argparse.ArgumentParser(description='PyTorch Ensemble Attack') 21 | parser.add_argument('--batch_size', type=int, default=1, metavar='N', 22 | help='batch size for attack (default: 1)') 23 | parser.add_argument('--epsilon', default = 0.125,type = float, 24 | help='perturbation, (default: 0.125)') 25 | parser.add_argument('--num_steps', default=40,type=int, 26 | help='perturb number of steps, (default: 20)') 27 | parser.add_argument('--step_size', default = 0.031, type=float, help='perturb size') 28 | parser.add_argument('--beta', default = 5.0, type=float, help='trade-off between target and non-target loss, (default: 5)') 29 | parser.add_argument('--img_path', default = "./../../images/", type=str, help='path of the images') 30 | parser.add_argument('--csv_path', default = "dev.csv", type=str, help='path of the csv') 31 | parser.add_argument('--random', default = 1, type=int) 32 | args = parser.parse_args() 33 | 34 | device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') 35 | 36 | def Average_logits(model_list, img): 37 | out = torch.zeros(len(model_list), 1000).cuda() 38 | item = 0 39 | for model in model_list: 40 | out[item, :] = model(img) 41 | item += 1 42 | return torch.mean(out, dim = 0, keepdim = True) 43 | 44 | def PGD_ms_attack(model_list, x_nature, y, target, step_size, epsilon, perturb_steps, beta, img_name, random): 45 | if random: 46 | random_noise = torch.FloatTensor(*x_nature.shape).uniform_(-epsilon, epsilon).cuda() 47 | X_pgd = Variable(x_nature.data + random_noise, requires_grad=True) 48 | else: 49 | X_pgd = Variable(x_nature.data, requires_grad=True) 50 | 51 | decay_1 = int(perturb_steps / 2) 52 | decay_2 = int(perturb_steps * 3 / 4) 53 | lr = step_size 54 | 55 | for step in range(perturb_steps): 56 | opt = optim.SGD([X_pgd], lr=1e-3) 57 | opt.zero_grad() 58 | with torch.enable_grad(): 59 | h, w = X_pgd.shape[-2:] 60 | out = Average_logits(model_list, X_pgd) 61 | loss = F.cross_entropy(out, y) - beta * F.cross_entropy(out, target) 62 | for idx, scale in enumerate((0.74, 1.25)): 63 | # resizes 64 | size = tuple([int(s * scale) for s in (h, w)]) 65 | x_resize = F.interpolate(X_pgd, size=size, mode="bilinear", align_corners=True) 66 | out = Average_logits(model_list, x_resize) 67 | loss += F.cross_entropy(out, y) - beta * F.cross_entropy(out, target) 68 | # print("Step: {}, Loss: {}".format(step, loss.data)) 69 | loss.backward() 70 | eta = lr * X_pgd.grad.data.sign() 71 | X_pgd = Variable(X_pgd.data + eta, requires_grad=True) 72 | eta = torch.clamp(X_pgd.data - x_nature.data, -epsilon, epsilon) 73 | X_pgd = Variable(x_nature.data + eta, requires_grad=True) 74 | X_pgd = Variable(torch.clamp(X_pgd, 0, 1), requires_grad=True) 75 | 76 | if (step + 1) >= decay_1: 77 | lr = 0.5 * step_size 78 | decay_1 = perturb_steps + 1 79 | 80 | if (step + 1) >= decay_2: 81 | lr = 0.25 * step_size 82 | decay_2 = perturb_steps + 1 83 | 84 | return X_pgd.data 85 | 86 | if __name__ == "__main__": 87 | 88 | resnet152 = get_architecture(denoise=False).cuda() 89 | resnet152.eval() 90 | 91 | resnet152_denoise = get_architecture(denoise=True).cuda() 92 | resnet152_denoise.eval() 93 | 94 | resnet101_denoise = get_architecture(denoise=True, model_name="Resnet101-DenoiseAll").cuda() 95 | resnet101_denoise.eval() 96 | 97 | model_list = [resnet152, resnet152_denoise, resnet101_denoise] 98 | 99 | loader = MyCustomDataset(csv_path=args.csv_path, img_path=args.img_path) 100 | 101 | attack_loader = torch.utils.data.DataLoader(dataset=loader, 102 | batch_size=args.batch_size, 103 | shuffle=False, 104 | sampler=torch.utils.data.SequentialSampler(loader)) 105 | 106 | record = True 107 | for (img, label, target, img_name) in attack_loader: 108 | img, label, target = img.to(device), label.to(device), target.to(device) 109 | 110 | save_dir = "images_main_attack/" 111 | if not os.path.isdir(save_dir): 112 | os.makedirs(save_dir) 113 | 114 | if os.path.exists(save_dir + img_name[0]): 115 | continue 116 | 117 | if record: 118 | start = time.clock() 119 | 120 | x_adv = PGD_ms_attack(model_list=model_list, 121 | x_nature=img, 122 | y=label, 123 | target=target, 124 | step_size=args.step_size, 125 | epsilon=args.epsilon, 126 | perturb_steps=args.num_steps, 127 | beta=args.beta, 128 | img_name=img_name[0], 129 | random=args.random) 130 | 131 | if record: 132 | end = time.clock() 133 | print(end-start) 134 | record = False 135 | 136 | img_adv = transforms.ToPILImage()(x_adv[0, :, :, :].cpu()).convert('RGB') 137 | img_adv.save(os.path.join(save_dir, img_name[0])) -------------------------------------------------------------------------------- /my_loader.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | from PIL import Image 4 | from torch.utils.data.dataset import Dataset 5 | from torchvision import transforms 6 | 7 | class MyCustomDataset(Dataset): 8 | def __init__(self, csv_path, img_path = "./../images/"): 9 | # Preprocess 10 | self.to_tensor = transforms.ToTensor() 11 | 12 | self.data_info = pd.read_csv(csv_path, header=0) 13 | self.image_name = np.asarray(self.data_info.iloc[:, 0]) 14 | self.label = np.asarray(self.data_info.iloc[:, 1]) - 1 15 | self.target_label = np.asarray(self.data_info.iloc[:, 2]) - 1 16 | self.data_len = len(self.data_info.index) 17 | self.img_path = img_path 18 | 19 | def __getitem__(self, index): 20 | single_image_name = self.image_name[index] 21 | img_as_img = Image.open(self.img_path + single_image_name) 22 | 23 | img_as_tensor = self.to_tensor(img_as_img) 24 | 25 | single_image_label = self.label[index] 26 | single_image_target_label = self.target_label[index] 27 | single_image_name = self.image_name[index] 28 | 29 | return (img_as_tensor, single_image_label, single_image_target_label, single_image_name) 30 | 31 | def __len__(self): 32 | return self.data_len -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Attack-ImageNet 2 | 3 | No.3 solution of Tianchi ImageNet Adversarial Attack Challenge. Team member: @[Equation](https://github.com/Equationliu), @[LayneH](https://github.com/LayneH) 4 | 5 | We use PGD (with learning rate decay) to attack the defense model. 6 | 7 | Tricks: 8 | 9 | 1. Trade-off between non-targeted loss and targeted loss. 10 | 2. Ensemble multi-scale, flip loss. 11 | 3. Ensemble multi pre-trained (adversarial training) model by averaging their logits. 12 | 13 | Part of the attacked images: 14 | 15 | ![](image.jpg) 16 | 17 | ## Environment 18 | 19 | python=3.6.9, pytorch=0.4.1, numpy=1.16.4, pandas=0.25.0 20 | 21 | ## Prepare 22 | 23 | The origin tensorflow models are from [Facebook:ImageNet-Adversarial-Training](https://github.com/facebookresearch/ImageNet-Adversarial-Training/blob/master/INSTRUCTIONS.md) [1]. Corresponding pytorch models can be download from [Google Drive](https://drive.google.com/open?id=1qH9zxDQMk43paLl3MpVmhuKLrDbjwjcj) or [BaiduPan](https://pan.baidu.com/s/1xmlycV7N7HjqDdezsV1aGg) , then extract them to folder `adv_denoise_model`. 24 | > The denoise pytorch models are directly got from [TREMBA](https://github.com/TransEmbedBA/TREMBA) [2]. 25 | 26 | ## Run 27 | 28 | You just need to run: 29 | 30 | ```bash 31 | CUDA_VISIBLE_DEVICES=0 python main.py --img_path YOUR-IMAGE-PATH 32 | ``` 33 | ## Reference 34 | 35 | [1] Xie, Cihang, et al. "Feature denoising for improving adversarial robustness." Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2019. 36 | 37 | [2] Huang Z, Zhang T. Black-Box Adversarial Attack with Transferable Model-based Embedding[J]. arXiv preprint arXiv:1911.07140, 2019. 38 | --------------------------------------------------------------------------------