# ------------------------------------------------------------------------------
# Copyright (c) Microsoft
# Licensed under the MIT License.
# Create by Bin Xiao (Bin.Xiao@microsoft.com)
# Modified by Tianheng Cheng(tianhengcheng@gmail.com), Yang Zhao
# ------------------------------------------------------------------------------

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import logging

import torch
import torch.nn as nn
import torch.nn.functional as F


BatchNorm2d = nn.BatchNorm2d
BN_MOMENTUM = 0.01
logger = logging.getLogger(__name__)


def conv3x3_dw(in_planes, out_planes, stride=1):
    '3x3 depthwise convolution with padding'
    return nn.Sequential(
        nn.Conv2d(in_planes, in_planes, kernel_size=3, stride=stride, padding=1, groups=in_planes, bias=False),
        BatchNorm2d(in_planes, momentum=BN_MOMENTUM),
        nn.ReLU(inplace=True),
        nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=1, padding=0, bias=False),
        BatchNorm2d(out_planes, momentum=BN_MOMENTUM),
        nn.ReLU(inplace=True)
    )


class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3_dw(inplanes, planes, stride)
        self.conv2 = conv3x3_dw(planes, planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.conv2(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual

        return out


class Bottleneck(nn.Module):
    expansion = 4

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
        self.bn1 = BatchNorm2d(planes, momentum=BN_MOMENTUM)
        self.conv2 = conv3x3_dw(planes, planes, stride)
        self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False)
        self.bn3 = BatchNorm2d(planes * self.expansion, momentum=BN_MOMENTUM)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

# ...  (其余代码与之前相同,只需要替换卷积部分)

在这个修改后的代码中,我们定义了一个新的卷积函数conv3x3_dw,它实现了深度可分离卷积。然后,我们将原代码中所有使用conv3x3的地方都替换成了conv3x3_dw

通过这样的修改,我们就可以使用深度可分离卷积来优化HighResolutionNet模型,在保持模型性能的同时,显著减少模型的参数量和计算量。

深度可分离卷积优化的HighResolutionNet人脸关键点检测

原文地址: https://www.cveoy.top/t/topic/fZwl 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录