invertierte Reststruktur

  Die invertierte Reststruktur (Inverted Residual) ist ein häufig verwendetes Entwurfsmodul in leichten Faltungs-Neuronalen Netzen, das darauf abzielt, die Effizienz und Leistung des Modells zu verbessern. Es wurde erstmals von MobileNetV2 eingeführt und wurde in nachfolgenden Netzwerken, einschließlich MobileNetV3 usw., häufig verwendet. Die Kernidee der invertierten Reststruktur besteht darin, die traditionelle Reststruktur (Residual Block) abzuwandeln, um sie an die Eigenschaften leichter Netzwerke anzupassen.
  In der herkömmlichen Reststruktur durchläuft die Eingabe-Feature-Map eine Reihe von Faltungsoperationen und wird zur ursprünglichen Eingabe hinzugefügt, um die Ausgabe zu erhalten. In der umgekehrten Reststruktur führen wir zunächst eine leichte Erweiterungsfaltung für die Eingabe-Feature-Map durch, führen dann eine in der Tiefe trennbare Faltung durch und verwenden schließlich eine Punktfaltung. (Punktweise Faltung) reduziert die Anzahl der Kanäle zurück und fügt sie schließlich hinzu Originaleingabe-Feature-Map, um die Ausgabe zu erhalten.
  Die Hauptinnovationen der invertierten Reststruktur liegen in zwei Aspekten:
  Leichte Erweiterungsfaltung (Expand Convolution): In der invertierten Reststruktur wird zunächst eine Faltungsoperation mit einer kleinen Anzahl von Ausgabekanälen verwendet, um die Anzahl der Kanäle des Eingabemerkmals zu erweitern Karte. . Der Zweck dieser erweiterten Faltung besteht darin, mehr Merkmalsausdrücke für die anschließende tiefentrennbare Faltung einzuführen, um Informationen zu extrahieren.
  Tiefenweise trennbare Faltung: Nach der erweiterten Faltung wird die tiefenweise trennbare Faltung zur Merkmalsextraktion verwendet. Die in der Tiefe trennbare Faltung unterteilt die Faltungsoperation in zwei Schritte: die Tiefenfaltung und die Punktfaltung. Die Tiefenfaltung reduziert den Rechenaufwand, indem Faltungsoperationen für jeden Kanal separat ausgeführt werden. Punktfaltung wird verwendet, um die Anzahl der Kanäle zu reduzieren und eine nichtlineare Transformation einzuführen.
  Die Bedeutung dieses Designs besteht darin, dass die invertierte Reststruktur den Rechenaufwand auf ein niedriges Niveau reduziert, indem nach der Kanalerweiterung eine tiefentrennbare Faltung durchgeführt wird, wodurch eine effiziente Merkmalsextraktion in leichtgewichtigen Netzwerken erreicht wird. Darüber hinaus kann durch Hinzufügen einer Punktfaltung nach der Kanaldilatationsfaltung auch eine nichtlineare Transformation eingeführt werden, um die Ausdrucksfähigkeit des Netzwerks zu verbessern.
  Hier ist ein detaillierteres PyTorch-Codebeispiel:

import torch
import torch.nn as nn
from torchsummary import summary

# 3、倒残差结构
class ConvBNReLU(nn.Sequential):
    def __init__(self, in_channel, out_channel, kernel_size=3, stride=1, groups=1):
        padding = (kernel_size - 1) // 2
        super(ConvBNReLU, self).__init__(
            nn.Conv2d(in_channel, out_channel, kernel_size, stride, padding, groups=groups, bias=False),
            nn.BatchNorm2d(out_channel),
            nn.ReLU(inplace=True)
        )


class InvertedResidual(nn.Module):
    def __init__(self, in_channel, out_channel, stride, expand_ratio):
        super(InvertedResidual, self).__init__()
        hidden_channel = in_channel * expand_ratio#expand_ratio:扩展因子
        self.use_shortcut = stride == 1 and in_channel == out_channel
        layers = []
        if expand_ratio != 1:
            layers.append(ConvBNReLU(in_channel, hidden_channel, kernel_size=1))#hxwxk-->hxwx(tk)
        layers.extend([#layers.extend() 是 Python 中的列表方法,用于在一个列表的末尾一次性添加另一个可迭代对象中的所有元素到该列表中。
                ConvBNReLU(hidden_channel, hidden_channel, kernel_size=stride, groups=hidden_channel),#hxwx(tk)-->(h/s)x(w/s)x(tk)
                nn.Conv2d(hidden_channel, out_channel, kernel_size=1, bias=False),#(h/s)x(w/s)x(tk)-->(h/s)x(w/s)xk'
                nn.BatchNorm2d(out_channel)
            ])

        self.conv = nn.Sequential(*layers)

    def forward(self, x):
        if self.use_shortcut:
            x = x + self.conv(x)
            return x
        else:
            x = self.conv(x)
            return x


if __name__ == '__main__':
    model=InvertedResidual(3,64,1,6)
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    model.to(device)
    input_tensor=torch.randn(1,3,224,224).to(device)
    input_tensor1 = (3, 224, 224)
    output_tensor=model(input_tensor)
    print(output_tensor.shape)

    print("InvertedResidual:")
    summary(model, input_tensor1)

  Der obige Code zeigt im Detail, wie man mit PyTorch ein MobileNetV2-Modell mit einer invertierten Reststruktur erstellt. Sie können es entsprechend Ihren tatsächlichen Bedürfnissen anpassen und erweitern.

Ich denke du magst

Origin blog.csdn.net/qq_50993557/article/details/132418439
Empfohlen
Rangfolge