{"id":380,"date":"2022-03-31T08:51:52","date_gmt":"2022-03-31T08:51:52","guid":{"rendered":"https:\/\/blog.liguanxin.cn\/?p=380"},"modified":"2022-06-30T02:59:21","modified_gmt":"2022-06-30T02:59:21","slug":"sknet%e4%bb%a3%e7%a0%81%e8%a7%a3%e6%9e%90","status":"publish","type":"post","link":"https:\/\/blog.liguanxin.cn\/index.php\/2022\/03\/31\/sknet%e4%bb%a3%e7%a0%81%e8%a7%a3%e6%9e%90\/","title":{"rendered":"\u8bba\u6587\u7b14\u8bb0\u2014\u2014SKNET\u4ee3\u7801\u89e3\u6790"},"content":{"rendered":"<p>sknet\u662f\u4e00\u4e2a\u5377\u79ef\u7ed3\u6784\uff0c\u53ef\u4ee5\u6269\u5927\u5377\u79ef\u7684\u611f\u53d7\u91ce\uff0c\u5e76\u4e14\u80fd\u8ba9\u5377\u79ef\u540c\u65f6\u6355\u83b7\u5230<span class=\"katex-eq\" data-katex-display=\"false\">3*3<\/span>\u548c<span class=\"katex-eq\" data-katex-display=\"false\">5*5<\/span>\u7684\u7279\u5f81\u3002<\/p>\n<h1>\u6574\u4f53\u7ed3\u6784<\/h1>\n<p><img src=\"https:\/\/blog.liguanxin.cn\/wp-content\/uploads\/2022\/03\/\u5fae\u4fe1\u622a\u56fe_20220331163222.png\" alt=\"\" \/><\/p>\n<h1>CODE<\/h1>\n<p><strong>sknet\u7684\u4e3b\u4f53\u5206\u4e3a4\u4e2astage\uff0c\u6bcf\u4e2astage\u7531\u591a\u4e2aSKUnit\u6784\u6210<\/strong><\/p>\n<pre><code class=\"language-python\">class SKNet(nn.Module):\n    def __init__(self, class_num, nums_block_list = [3, 4, 6, 3], strides_list = [1, 2, 2, 2]):\n        super(SKNet, self).__init__()\n        self.basic_conv = nn.Sequential(\n            nn.Conv2d(3, 64, 7, 2, 3, bias=False),\n            nn.BatchNorm2d(64),\n            nn.ReLU(inplace=True),\n        )\n\n        self.maxpool = nn.MaxPool2d(3,2,1)\n\n        self.stage_1 = self._make_layer(64, 128, 256, nums_block=nums_block_list[0], stride=strides_list[0])\n        self.stage_2 = self._make_layer(256, 256, 512, nums_block=nums_block_list[1], stride=strides_list[1])\n        self.stage_3 = self._make_layer(512, 512, 1024, nums_block=nums_block_list[2], stride=strides_list[2])\n        self.stage_4 = self._make_layer(1024, 1024, 2048, nums_block=nums_block_list[3], stride=strides_list[3])\n\n        self.gap = nn.AdaptiveAvgPool2d((1, 1))\n        self.classifier = nn.Linear(2048, class_num)\n\n    # \u6784\u9020\u6bcf\u4e00\u4e2astage\uff0c\u5305\u542b\u591a\u4e2aSKUnit\uff0c\u6bcf\u4e00\u5c42\u6570\u91cf\u901a\u8fc7nums_block_list\u6765\u5b9a\n    def _make_layer(self, in_feats, mid_feats, out_feats, nums_block, stride=1):\n        layers=[SKUnit(in_feats, mid_feats, out_feats, stride=stride)]\n        for _ in range(1,nums_block):\n            layers.append(SKUnit(out_feats, mid_feats, out_feats))\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        fea = self.basic_conv(x)  # \u6d45\u5c42\u7279\u5f81\u63d0\u53d6\n        fea = self.maxpool(fea)  # \u6700\u5927\u6c60\u5316\u5c42\u4f7f\u56fe\u7247\u5c3a\u5bf8\u957f\u5bbd\u5404\u51cf\u5c11\u4e24\u500d\n        # \u5404\u4e2astage\n        fea = self.stage_1(fea)\n        fea = self.stage_2(fea)\n        fea = self.stage_3(fea)\n        fea = self.stage_4(fea)\n        # \u81ea\u9002\u5e94\u5e73\u5747\u6c60\u5316\u5c42\u5bf9\u5404\u4e2achannel\u6c42\u5747\u503c\uff0c\uff0c\u7136\u540esqueeze\u548cclassifier\u4f7f\u5f97fea\u53d8\u6210class_num\u4e2a\u5206\u7c7b\n        fea = self.gap(fea)\n        fea = torch.squeeze(fea)\n        fea = self.classifier(fea)\n        return fea<\/code><\/pre>\n<p><strong>SKUnit\u5355\u5143\uff0c\u8ba9\u5305\u62ecSKConv\u524d\u540e\u7684\u5377\u79ef\u5f52\u4e00\u7b49\u64cd\u4f5c<\/strong><\/p>\n<pre><code class=\"language-python\">class SKUnit(nn.Module):\n    def __init__(self, in_features, mid_features, out_features, M=2, G=32, r=16, stride=1, L=32):\n        super(SKUnit, self).__init__()\n\n        self.conv1 = nn.Sequential(\n            nn.Conv2d(in_features, mid_features, 1, stride=1, bias=False),\n            nn.BatchNorm2d(mid_features),\n            nn.ReLU(inplace=True)\n            )\n\n        self.conv2_sk = SKConv(mid_features, M=M, G=G, r=r, stride=stride, L=L)\n\n        self.conv3 = nn.Sequential(\n            nn.Conv2d(mid_features, out_features, 1, stride=1, bias=False),\n            nn.BatchNorm2d(out_features)\n            )\n        self.shortcut = nn.Sequential()\n        self.relu = nn.ReLU(inplace=True)\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)  # 1*1\u5377\u79ef\uff0cbatchnorm\uff0crelu\u5c42\n        out = self.conv2_sk(out)  # SKConv\u5c42\n        out = self.conv3(out)  # 1*1\u5377\u79ef\uff0cbatchnorm\n\n        return self.relu(out + self.shortcut(residual))<\/code><\/pre>\n<p><strong>\u6700\u6838\u5fc3\u7684SKConv\u5c42\uff0c\u5982\u56fe\u6240\u793a<\/strong><br \/>\n<img src=\"https:\/\/blog.liguanxin.cn\/wp-content\/uploads\/2022\/03\/\u5fae\u4fe1\u622a\u56fe_20220331163222.png\" alt=\"\" \/><\/p>\n<pre><code class=\"language-python\">class SKConv(nn.Module):\n    def __init__(self, features, M=2, G=32, r=16, stride=1 ,L=32):\n        super(SKConv, self).__init__()\n        d = max(int(features\/r), L)\n        self.M = M\n        self.features = features\n        self.convs = nn.ModuleList([])\n        for i in range(M):\n            self.convs.append(nn.Sequential(\n                nn.Conv2d(features, features, kernel_size=3, stride=stride, padding=1+i, dilation=1+i, groups=G, bias=False),\n                nn.BatchNorm2d(features),\n                nn.ReLU(inplace=True)\n            ))\n        self.gap = nn.AdaptiveAvgPool2d((1,1))\n        self.fc = nn.Sequential(nn.Conv2d(features, d, kernel_size=1, stride=1, bias=False),\n                                nn.BatchNorm2d(d),\n                                nn.ReLU(inplace=True))\n        self.fcs = nn.ModuleList([])\n        for i in range(M):\n            self.fcs.append(\n                 nn.Conv2d(d, features, kernel_size=1, stride=1)\n            )\n        self.softmax = nn.Softmax(dim=1)\n\n    def forward(self, x):\n\n        batch_size = x.shape[0]  # \u83b7\u53d6batch_size\n\n        feats = [conv(x) for conv in self.convs]  # \u8ba9x\u5206\u62103*3\u548c5*5\u8fdb\u884c\u5377\u79ef\n        feats = torch.cat(feats, dim=1)  # \u5408\u5e76\u5377\u79ef\u7ed3\u679c\n        feats = feats.view(batch_size, self.M, self.features, feats.shape[2], feats.shape[3]) # reshape\u4e00\u4e0b\u5927\u5c0f\n        # \u63a5\u4e0b\u6765\u8ba1\u7b97\u56fe\u4e2d\u7684U\n        feats_U = torch.sum(feats, dim=1)  # \u4e24\u4e2a\u5206\u652f\u5f97\u5230\u7684\u5377\u79ef\u7ed3\u679c\u76f8\u52a0\n        feats_S = self.gap(feats_U)  # \u81ea\u9002\u5e94\u6c60\u5316\uff0c\u4e5f\u5c31\u662f\u5bf9\u5404\u4e2achanel\u6c42\u5747\u503c\u5f97\u5230\u56fe\u4e2d\u7684S\n        feats_Z = self.fc(feats_S)  # fc\u5c42\u538b\u7f29\u7279\u5f81\u5f97\u5230\u56fe\u4e2d\u7684Z\n\n        attention_vectors = [fc(feats_Z) for fc in self.fcs]  # \u4e0d\u540c\u7684\u5934\u5404\u81ea\u6062\u590d\u7279\u5f81Z\u5230channel\u7684\u5bbd\u5ea6\n        attention_vectors = torch.cat(attention_vectors, dim=1)  # \u8fde\u63a5\u8d77\u6765\u65b9\u4fbf\u540e\u7eed\u64cd\u4f5c\n        attention_vectors = attention_vectors.view(batch_size, self.M, self.features, 1, 1)  # reshape\u8d77\u6765\u65b9\u4fbf\u540e\u7eed\u64cd\u4f5c\n        attention_vectors = self.softmax(attention_vectors)  # softmax\u5f97\u5230\u56fe\u4e2d\u7684a\u548cb\uff08\u5b9e\u9645\u4e0a\u662f\u8054\u5408\u5728\u4e86\u7b2c\u4e8c\u7ef4\uff09\n\n        feats_V = torch.sum(feats*attention_vectors, dim=1)  # \u628asoftmax\u540e\u7684\u5404\u81ea\u81ea\u6ce8\u610f\u529b\u8ddf\u5377\u79ef\u540e\u7684\u7ed3\u679c\u76f8\u4e58\uff0c\u5f97\u5230\u56fe\u4e2dselect\u7684\u7ed3\u679c\uff0c\u7136\u540e\u76f8\u52a0\u5f97\u5230\u6700\u7ec8\u8f93\u51fa\n\n        return feats_V<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>sknet\u662f\u4e00\u4e2a\u5377\u79ef\u7ed3\u6784\uff0c\u53ef\u4ee5\u6269\u5927\u5377\u79ef\u7684\u611f\u53d7\u91ce\uff0c\u5e76\u4e14\u80fd\u8ba9\u5377\u79ef\u540c\u65f6\u6355\u83b7\u5230\u548c\u7684\u7279\u5f81\u3002 \u6574\u4f53\u7ed3\u6784 CODE skne [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[14,11],"_links":{"self":[{"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/posts\/380"}],"collection":[{"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/comments?post=380"}],"version-history":[{"count":0,"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/posts\/380\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/media?parent=380"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/categories?post=380"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.liguanxin.cn\/index.php\/wp-json\/wp\/v2\/tags?post=380"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}