Entwickeln und bauen Sie ein Bilderkennungssystem für 40 gängige chinesische Kräutermedizin basierend auf dem leichten MnasNet-Modell

Der Text ist eine Fortsetzung des vorherigen Textes:

„Python entwickelt und baut ein Bilderkennungssystem für 23 gängige chinesische Kräutermedizin basierend auf dem leichten GhostNet-Modell.“

Im vorherigen Artikel wurde hauptsächlich versucht, ein Bilderkennungssystem für chinesische Kräutermedizin zu entwickeln und zu konstruieren, das auf einem leichten CNN-Modell für kleine Chargen und kleine Arten von Datensätzen basiert. Die ursprüngliche Absicht dieses Artikels bestand darin, die Grundlage für eine große Kategorie und große Datenmengen zu schaffen eingestellt, aber es wurde festgestellt, dass die Arten chinesischer Kräutermedizin erreicht wurden Es gibt mehr als tausend Arten, und der Arbeitsaufwand für die Datenerfassung und manuelle Verarbeitung ist enorm, sodass ich keine andere Wahl habe, als ihn vorübergehend beiseite zu legen und auf freie Zeit zu warten bevor Sie weiter investieren. Hier ist ein Crawler zum Erstellen eines Datensatzes von 40 gängigen chinesischen Kräutermedizin zur Entwicklung und zum Aufbau eines Identifikationssystems basierend auf MnasNet. Schauen Sie sich zunächst den Beispieleffekt an:

MnasNet (Mobile Neural Architecture Search Net) ist ein leichtes Faltungs-Neuronales Netzwerkmodell, das auf Neural Architecture Search (NAS) basiert. Finden Sie eine effiziente Netzwerkstruktur, die für mobile Geräte geeignet ist, indem Sie die Suche nach neuronalen Netzwerkarchitekturen automatisieren. Es nutzt Reinforcement-Learning-Algorithmen und Multi-Ziel-Optimierungsstrategien, um nach der besten Netzwerkarchitektur zu suchen. Durch die Suche und Kombination verschiedener Teile des Netzwerks ist MnasNet in der Lage, hohe Leistung und Genauigkeit zu liefern und gleichzeitig eine kleine Modellgröße beizubehalten.

Beim Entwerfen eines Modellsuchalgorithmus gibt es drei wichtigste Punkte:
1. Optimierungsziel: Bestimmt die Leistung und Effizienz des durchsuchten Netzwerk-Frameworks;
2. Suchraum: Bestimmt, aus welchen Grundmodulen das Netzwerk besteht;
3. Optimierungsstrategie: Bestimmt die Konvergenzgeschwindigkeit des Reinforcement Learning.

Konstruktionsprinzip
Das Algorithmuskonstruktionsprinzip des MnasNet-Modells besteht darin, ein effizientes Faltungs-Neuronales Netzwerkmodell zu erstellen, indem schwache Verbindungssuchalgorithmen und automatisierte Netzwerkdesignmethoden verwendet werden. Der Suchraum von MNasNet bezieht sich größtenteils auf MobileNet v2. Durch Verstärkungslernen wurde der MobileNet v2-Algorithmus erhalten, der andere Modellsuchalgorithmen und ihre Referenzen übertrifft. Es ist ersichtlich, dass die Zusammenarbeit von künstlichem Design und Verstärkungslernen eine bessere Richtung sein sollte der Entwicklung. Der in MNasNet vorgeschlagene hierarchische Suchraum kann eine Netzwerkstruktur generieren, die für jeden Netzwerkblock einzigartig ist, was auch bei der Verbesserung der Leistung des Netzwerks sehr hilfreich ist. Dies profitiert jedoch auch von der erheblichen Reduzierung des Suchraums nach der Bezugnahme auf MobileNet v2 zum Entwerfen des Suchraums. Suchschwierigkeit.

Im Suchalgorithmus für schwache Verbindungen verwendet MnasNet eine auf schwachen Verbindungen basierende Suchstrategie, indem es an jeder Position des Netzwerks schwache Verbindungen einführt und dann die Netzwerkstruktur durch selektives Hinzufügen und Löschen von Verbindungen durchsucht. Dieser Ansatz kann den Suchraum erheblich reduzieren und die Sucheffizienz verbessern.

Unter den automatisierten Netzwerkdesignmethoden verwendet MnasNet eine automatisierte Netzwerkdesignmethode, um die Netzwerkstruktur zu optimieren. Diese Methode sucht nach der optimalen Netzwerkstruktur, indem sie eine Reihe möglicher Operationen und Gewichtsräume definiert und Algorithmen für verstärkendes Lernen verwendet. Dieser Ansatz kann die Netzwerkstruktur automatisch erlernen und die Modellgröße und den Rechenressourcenverbrauch reduzieren, während gleichzeitig eine hohe Leistung aufrechterhalten wird.

Vorteile
Hohe Leistung: MnasNet ist in der Lage, leistungsstarke Faltungs-Neuronale Netze zu suchen und zu entwerfen, indem es schwache Verbindungssuchalgorithmen und automatisierte Netzwerkentwurfsmethoden verwendet. Diese Netzwerke haben bei mehreren Bildklassifizierungs- und Objekterkennungsaufgaben eine gute Leistung gezeigt.

Leicht: MnasNet berücksichtigt die Größe des Modells und die Nutzung von Rechenressourcen während des Netzwerkentwurfsprozesses. Durch die Automatisierung von Netzwerkentwurfsmethoden ist MnasNet in der Lage, die Modellgröße und den Rechenaufwand zu reduzieren und so ein geringes Gewicht bei gleichzeitig hoher Leistung zu erreichen.

Skalierbarkeit: Die automatisierte Netzwerkdesignmethode von MnasNet weist eine starke Skalierbarkeit auf. Es kann ein automatisiertes Netzwerkdesign auf der Grundlage unterschiedlicher Aufgaben und Datensätze durchführen und sich an unterschiedliche Einschränkungen der Rechenressourcen und Anforderungen an Anwendungsszenarien anpassen.

Nachteile
Lange Trainingszeit: Da MnasNet eine automatisierte Netzwerkdesignmethode verwendet, muss in einem großen Suchraum gesucht und trainiert werden, sodass die Trainingszeit lang ist.

Langsame Bereitstellung und Inferenz: Aufgrund der relativ komplexen Netzwerkstruktur von MnasNet sind während der Bereitstellung und Inferenz mehr Rechenressourcen erforderlich. Insbesondere auf Geräten mit begrenzten Rechenressourcen kann es Auswirkungen auf die Modellbereitstellung und Echtzeit-Inferenzeffekte haben.

Das MnasNet-Modell erstellt ein leistungsstarkes und leichtes Modell durch schwache Verbindungssuchalgorithmen und automatisierte Netzwerkdesignmethoden. Allerdings ist die Trainingszeit lang und die Bereitstellungs- und Inferenzgeschwindigkeit langsam, und diese Faktoren müssen in praktischen Anwendungen umfassend berücksichtigt werden.

Die Kernimplementierung von MnasNet lautet wie folgt:

class MNASNet(torch.nn.Module):

    def __init__(
        self,
        alpha: float,
        num_classes: int = 1000,
        dropout: float = 0.2
    ) -> None:
        super(MNASNet, self).__init__()
        assert alpha > 0.0
        self.alpha = alpha
        self.num_classes = num_classes
        depths = _get_depths(alpha)
        layers = [
            nn.Conv2d(3, depths[0], 3, padding=1, stride=2, bias=False),
            nn.BatchNorm2d(depths[0], momentum=_BN_MOMENTUM),
            nn.ReLU(inplace=True),
            nn.Conv2d(depths[0], depths[0], 3, padding=1, stride=1,
                      groups=depths[0], bias=False),
            nn.BatchNorm2d(depths[0], momentum=_BN_MOMENTUM),
            nn.ReLU(inplace=True),
            nn.Conv2d(depths[0], depths[1], 1, padding=0, stride=1, bias=False),
            nn.BatchNorm2d(depths[1], momentum=_BN_MOMENTUM),
            _stack(depths[1], depths[2], 3, 2, 3, 3, _BN_MOMENTUM),
            _stack(depths[2], depths[3], 5, 2, 3, 3, _BN_MOMENTUM),
            _stack(depths[3], depths[4], 5, 2, 6, 3, _BN_MOMENTUM),
            _stack(depths[4], depths[5], 3, 1, 6, 2, _BN_MOMENTUM),
            _stack(depths[5], depths[6], 5, 2, 6, 4, _BN_MOMENTUM),
            _stack(depths[6], depths[7], 3, 1, 6, 1, _BN_MOMENTUM),
            nn.Conv2d(depths[7], 1280, 1, padding=0, stride=1, bias=False),
            nn.BatchNorm2d(1280, momentum=_BN_MOMENTUM),
            nn.ReLU(inplace=True),
        ]
        self.layers = nn.Sequential(*layers)
        self.classifier = nn.Sequential(nn.Dropout(p=dropout, inplace=True),
                                        nn.Linear(1280, num_classes))
        self._initialize_weights()

    def forward(self, x: Tensor, need_fea=False) -> Tensor:
        if need_fea:
            features, features_fc = self.forward_features(x, need_fea)
            x = self.classifier(features_fc)
            return features, features_fc, x
        else:
            x = self.forward_features(x)
            x = self.classifier(x)
            return x

    def forward_features(self, x, need_fea=False):
        if need_fea:
            input_size = x.size(2)
            scale = [4, 8, 16, 32]
            features = [None, None, None, None]
            for idx, layer in enumerate(self.layers):
                x = layer(x)
                if input_size // x.size(2) in scale:
                    features[scale.index(input_size // x.size(2))] = x
            return features, x.mean([2, 3])
        else:
            x = self.layers(x)
            x = x.mean([2, 3])
            return x

    def _initialize_weights(self) -> None:
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode="fan_out",
                                        nonlinearity="relu")
                if m.bias is not None:
                    nn.init.zeros_(m.bias)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.ones_(m.weight)
                nn.init.zeros_(m.bias)
            elif isinstance(m, nn.Linear):
                nn.init.kaiming_uniform_(m.weight, mode="fan_out",
                                         nonlinearity="sigmoid")
                nn.init.zeros_(m.bias)

    def cam_layer(self):
        return self.layers[-1]

    def _load_from_state_dict(self, state_dict: Dict, prefix: str, local_metadata: Dict, strict: bool,
                              missing_keys: List[str], unexpected_keys: List[str], error_msgs: List[str]) -> None:
        version = local_metadata.get("version", None)
        assert version in [1, 2]
        if version == 1 and not self.alpha == 1.0:
            depths = _get_depths(self.alpha)
            v1_stem = [
                nn.Conv2d(3, 32, 3, padding=1, stride=2, bias=False),
                nn.BatchNorm2d(32, momentum=_BN_MOMENTUM),
                nn.ReLU(inplace=True),
                nn.Conv2d(32, 32, 3, padding=1, stride=1, groups=32,
                          bias=False),
                nn.BatchNorm2d(32, momentum=_BN_MOMENTUM),
                nn.ReLU(inplace=True),
                nn.Conv2d(32, 16, 1, padding=0, stride=1, bias=False),
                nn.BatchNorm2d(16, momentum=_BN_MOMENTUM),
                _stack(16, depths[2], 3, 2, 3, 3, _BN_MOMENTUM),
            ]
            for idx, layer in enumerate(v1_stem):
                self.layers[idx] = layer
        super(MNASNet, self)._load_from_state_dict(
            state_dict, prefix, local_metadata, strict, missing_keys,
            unexpected_keys, error_msgs)

Der in diesem Artikel vorgeschlagene Datensatz stammt aus einer selbst erstellten Verarbeitung und enthält die folgenden Kategorien, wie unten dargestellt:

三七
人参
佛手片
元胡
厚朴
天南星
天麻
安息香
川芎
巴戟天
当归
木香
朱砂
杜仲
枸杞
桔梗
熊胆
牛黄
玉果
瓜蒌
甘草
生地
白前
白术
白芍
羚羊角
肉苁蓉
苏合香
苦参
茯苓
荜拨
菊花
蔓荆子
贝母
连召
银花
香附
麦冬
黄芪
黄连

Auf dieser Basis werden in Zukunft die Kategorien erweitert.

Das Datenbeispiel sieht so aus:

Die Visualisierung der Datenverteilung sieht folgendermaßen aus:

Der Gesamtverlust des Trainingsprozesses ist wie folgt:

Die Genauigkeitskurve ist wie folgt:

Die Verwirrungsmatrix sieht folgendermaßen aus:

Wir haben für jede Kategorie separate Metriküberprüfungen durchgeführt, wie unten beschrieben:

+--------+-----------+---------+----------+---------+----------+
|  三七  |  0.70968  | 0.73333 | 0.72131  | 0.71376 | 0.73333  |
|  人参  |  0.89286  | 0.86207 | 0.87719  | 0.87409 | 0.86207  |
| 佛手片 |  0.83871  | 0.89655 | 0.86667  | 0.86312 | 0.89655  |
|  元胡  |  0.66667  | 0.68966 | 0.67797  | 0.66954 | 0.68966  |
|  厚朴  |  0.56667  | 0.60714 | 0.58621  | 0.57557 | 0.60714  |
| 天南星 |  0.70588  | 0.82759 | 0.76190  | 0.75528 | 0.82759  |
|  天麻  |  0.80000  | 0.85714 | 0.82759  | 0.82316 | 0.85714  |
| 安息香 |  0.63636  | 0.70000 | 0.66667  | 0.65735 | 0.70000  |
|  川芎  |  0.57576  | 0.67857 | 0.62295  | 0.61280 | 0.67857  |
| 巴戟天 |  0.87097  | 0.93103 | 0.90000  | 0.89734 | 0.93103  |
|  当归  |  0.58974  | 0.79310 | 0.67647  | 0.66688 | 0.79310  |
|  木香  |  0.64286  | 0.64286 | 0.64286  | 0.63399 | 0.64286  |
|  朱砂  |  0.71875  | 0.79310 | 0.75410  | 0.74745 | 0.79310  |
|  杜仲  |  0.77273  | 0.58621 | 0.66667  | 0.65929 | 0.58621  |
|  枸杞  |  0.96552  | 0.96552 | 0.96552  | 0.96463 | 0.96552  |
|  桔梗  |  0.75000  | 0.62069 | 0.67925  | 0.67179 | 0.62069  |
|  熊胆  |  0.61538  | 0.55172 | 0.58182  | 0.57166 | 0.55172  |
|  牛黄  |  0.84848  | 0.96552 | 0.90323  | 0.90057 | 0.96552  |
|  玉果  |  0.76667  | 0.76667 | 0.76667  | 0.76045 | 0.76667  |
|  瓜蒌  |  0.73333  | 0.75862 | 0.74576  | 0.73911 | 0.75862  |
|  甘草  |  0.77778  | 0.72414 | 0.75000  | 0.74380 | 0.72414  |
|  生地  |  0.53846  | 0.50000 | 0.51852  | 0.50702 | 0.50000  |
|  白前  |  0.83333  | 0.86207 | 0.84746  | 0.84346 | 0.86207  |
|  白术  |  0.78571  | 0.75862 | 0.77193  | 0.76617 | 0.75862  |
|  白芍  |  0.86667  | 0.89655 | 0.88136  | 0.87825 | 0.89655  |
| 羚羊角 |  0.76000  | 0.65517 | 0.70370  | 0.69666 | 0.65517  |
| 肉苁蓉 |  0.52174  | 0.42857 | 0.47059  | 0.45876 | 0.42857  |
| 苏合香 |  0.60000  | 0.41379 | 0.48980  | 0.47913 | 0.41379  |
|  苦参  |  0.82759  | 0.82759 | 0.82759  | 0.82315 | 0.82759  |
|  茯苓  |  0.71429  | 0.68966 | 0.70175  | 0.69422 | 0.68966  |
|  荜拨  |  0.96552  | 0.96552 | 0.96552  | 0.96463 | 0.96552  |
|  菊花  |  0.89286  | 0.86207 | 0.87719  | 0.87409 | 0.86207  |
| 蔓荆子 |  0.87879  | 1.00000 | 0.93548  | 0.93371 | 1.00000  |
|  贝母  |  0.87500  | 0.96552 | 0.91803  | 0.91582 | 0.96552  |
|  连召  |  0.91304  | 0.72414 | 0.80769  | 0.80333 | 0.72414  |
|  银花  |  0.87097  | 0.93103 | 0.90000  | 0.89734 | 0.93103  |
|  香附  |  0.57576  | 0.65517 | 0.61290  | 0.60228 | 0.65517  |
|  麦冬  |  1.00000  | 0.96552 | 0.98246  | 0.98201 | 0.96552  |
|  黄芪  |  0.86364  | 0.67857 | 0.76000  | 0.75477 | 0.67857  |
|  黄连  |  0.66667  | 0.62069 | 0.64286  | 0.63400 | 0.62069  |
+--------+-----------+---------+----------+---------+----------+

Die Genauigkeit einiger Kategorien ist nicht hoch, aber insgesamt relativ stabil.

Supongo que te gusta

Origin blog.csdn.net/Together_CZ/article/details/134851066
Recomendado
Clasificación