Es ist ungefähr ein halbes Jahr her, seit ich von TensorFlow nach Pytorch gezogen bin, also werde ich die Grundlagen zusammenfassen. Dieses Mal möchte ich mich auf die folgenden drei Punkte konzentrieren.
Die derzeit verfügbaren vorgefertigten Modelle sind:
Verwenden Sie Folgendes, wenn Sie das trainierte Modell in ImageNet verwenden.
import torchvision
model = torchvision.models.alexnet(pretrained=True)
Wenn Sie nicht "pretrained = True" setzen, werden die trainierten Gewichte in ImageNet nicht geladen. --Bitte beachten Sie, dass der Standardwert "pretrained = False" ist.
Wenn Sie die Struktur des Modells überprüfen möchten, können Sie dies mit print (model)
überprüfen. Das Folgende ist das Ausführungsergebnis.
AlexNet(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Dropout(p=0.5, inplace=False)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Dropout(p=0.5, inplace=False)
(4): Linear(in_features=4096, out_features=4096, bias=True)
(5): ReLU(inplace=True)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
)
Wenn Sie nach Ihren eigenen Daten klassifizieren möchten, ändern Sie dies wie folgt. Nehmen Sie als Beispiel die Klassifizierung in zwei Klassen.
model.classifier[6].out_features = 2
Wenn Sie print (model)
erneut ausführen, können Sie sehen, dass es sich geändert hat.
AlexNet(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Dropout(p=0.5, inplace=False)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Dropout(p=0.5, inplace=False)
(4): Linear(in_features=4096, out_features=4096, bias=True)
(5): ReLU(inplace=True)
(6): Linear(in_features=4096, out_features=2, bias=True)
)
)
Kommen wir nun zum Hauptthema. Dieses Mal werden wir 1D CNN mit Scratch implementieren. Hier ist ein einfaches Beispiel.
import torch
import torch.nn as nn
class Net1D(nn.Module):
def __init__(self):
super(SimpleNet,self).__init__()
self.conv1 = nn.Conv1d(1, 8,kernel_size=3, stride=1)
self.bn1 = nn.BatchNorm1d(8)
self.relu = nn.ReLU()
self.maxpool = nn.MaxPool1d(kernel_size=3, stride=2)
self.conv2 = nn.Conv1d(8, 16,kernel_size=3, stride=1)
self.bn2 = nn.BatchNorm1d(16)
self.conv3 = nn.Conv1d(16,64,kernel_size=3, stride=1)
self.gap = nn.AdaptiveAvgPool1d(1)
self.fc = nn.Linear(64,2)
def forward(self,x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.maxpool(x)
x = self.conv2(x)
x = self.bn2(x)
x = self.relu(x)
x = self.maxpool(x)
x = self.conv3(x)
x = self.gap(x)
x = x.view(x.size(0),-1)
x = self.fc(x)
return x
Wenn Sie sehen möchten, ob dieses Modell funktioniert, versuchen Sie Folgendes:
model = SimpleNet()
in_data = torch.randn(8,1,50)
out_data = model(data)
print(out_size.size()) #torch.Size([8, 2])
Bereiten Sie die entsprechenden Eingabedaten mit torch.randn ()
vor. ← Diese Methode ist praktisch! Es kann auch in 2D angewendet werden!
Die Eingabe lautet "torch.randn (Stapelgröße, Anzahl der Kanäle, Größe des eindimensionalen Arrays)". Die Größe der Ausgabe ist "torch.Size ([8, 2])", was "torch.Size (Stapelgröße, letzte Ausgabe)" bedeutet.
Wenn Sie eine Klassifizierungsaufgabe ausführen möchten, können Sie diese anschließend über softmax ausführen.
Außerdem gibt es eine praktische Bibliothek namens "Fackelzusammenfassung", mit der Sie die Größe der Feature-Map überprüfen können. Verwenden Sie diese also auch. Ich habe vorher einen Artikel geschrieben, also werde ich einen Link posten.
===============================================================
===============================================================
【nn.Conv1d】
nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
parameters | Überblick |
---|---|
in_channels | Anzahl der Eingangskanäle. |
out_channels | Anzahl der Kanäle nach der Faltung. Anzahl der Filter. |
kernel_size | Die Größe des Kernels. |
stride | Wie viel muss der Kernel bewegen? |
padding | Die Größe der Polsterung. Wenn 1 angegeben ist, wird es an beiden Enden eingefügt, sodass es um 2 erhöht wird. Der Standardwert ist 0. |
dilation | Ändern Sie den Abstand zwischen den Filtern. Wird in atrous Conv usw. verwendet. |
groups | Der Standardwert ist 1. Durch Erhöhen der Anzahl werden die Berechnungskosten reduziert. |
bias | Ob Voreingenommenheit einbezogen werden soll. Standard ist True |
padding_mode | Auffüllmodus. Der Standardwert ist 0. |
【nn.BatchNorm1d】
nn.BatchNorm1d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
Es ist in Ordnung, die gleiche Anzahl von "num_features" einzugeben wie den Wert von "out_channels" der vorherigen Ebene.
Ich habe ein einfaches CNN-Beispiel geschrieben. Dieses Mal werden die Anzahl der Filter und die Kernelgröße entsprechend festgelegt. Wenn Sie ein eigenes Netzwerk erstellen, berücksichtigen Sie bei der Entscheidung die Werte.
import torch
import torch.nn as nn
class Net2D(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1 = nn.Conv2d(3,16,kernel_size=3,stride=2)
self.bn1 = nn.BatchNorm2d(16)
self.relu = nn.ReLU()
self.maxpool = nn.MaxPool2d(2)
self.conv2 = nn.Conv2d(16,32,kernel_size=3,stride=2)
self.bn2 = nn.BatchNorm2d(32)
self.conv3 = nn.Conv2d(32,64,kernel_size=3,stride=2)
self.gap = nn.AdaptiveAvgPool2d(1)
self.fc1 = nn.Linear(64,32)
self.fc2 = nn.Linear(32,2)
def forward(self,x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.maxpool(x)
x = self.conv2(x)
x = self.bn2(x)
x = self.relu(x)
x = self.maxpool(x)
x = self.conv3(x)
x = self.gap(x)
x = x.view(x.size(0),-1)
x = self.fc1(x)
x = self.fc2(x)
return x
nn.Module
erben.init
verwendete Ebene.
Ich sehe oft Artikel, die solche mit Parametern in "init" und solche ohne Parameter in "forward" definieren, aber relu usw. werden zum Zeitpunkt von "print (model)" nicht angezeigt, daher habe ich Parameter Sogar so etwas wie kein Relu ist wie diesmal in init
definiert.--forward
bestimmt die Struktur des Modells.
【nn.Conv2d】
nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
parameters | Überblick |
---|---|
in_channels | Anzahl der Eingangskanäle. Im RGB-Bild wird es zu 3. |
out_channels | Anzahl der Kanäle nach der Faltung. Anzahl der Filter. |
kernel_size | Die Größe des Kernels. |
stride | Wie viel muss der Kernel bewegen? |
padding | Die Größe der Polsterung. Wenn 1 angegeben ist, wird es an beiden Enden eingefügt, sodass es um 2 erhöht wird. Der Standardwert ist 0. |
dilation | Ändern Sie den Abstand zwischen den Filtern. Wird in atrous Conv usw. verwendet. |
groups | Der Standardwert ist 1. Durch Erhöhen der Anzahl werden die Berechnungskosten reduziert. |
bias | Ob Voreingenommenheit einbezogen werden soll. Standard ist True |
padding_mode | Auffüllmodus. Der Standardwert ist 0. |
【nn.BatchNorm2d】
nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
Die Chargennormalisierung ermittelt den Mittelwert und die Standardabweichung für jedes Element in der Charge. Beim Falten normalisiert es sich auf die Kanäle im Stapel. Wenn es sich um eine vollständig verbundene Schicht handelt, wird sie zu einer Einheit.
Außerdem gibt es "Layernorm", "Instanznorm", "Gruppennorm" usw. Wenn Sie also interessiert sind, suchen Sie bitte.
【nn.ReLU】
nn.ReLU(inplace=False)
【nn.MaxPool2d】
nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
Verwenden Sie eine Pooling-Ebene, um die Funktionen hervorzuheben.
――Es gibt zwei Hauptmuster. Überprüfen Sie dies unten.
① Wenn die Größe des Pools quadratisch ist
m = nn.MaxPool2d(3, stride=2) #(pool of square window of size=3, stride=2)
② Wenn Sie die Größe des Pools anpassen möchten
m = nn.MaxPool2d((3, 2), stride=(2, 1)) #(pool of non-square window)
【nn.AdaptiveMaxPool2d】
nn.AdaptiveMaxPool2d(output_size, return_indices=False)
Oft als "Global Max Pooling" bezeichnet.
Es wird häufig verwendet, bevor eine Verbindung zu einer vollständig verbundenen Schicht hergestellt wird, da jeder Kanal zu einem einzelnen Wert wird.
Geben Sie die Ausgabegröße eines Kanals in output_size
ein.
Ich denke, dass "output_size = 1" oft verwendet wird.
【nn.Linear】
nn.Linear(in_features, out_features, bias=True)
Geben Sie in_features und out_features an, die verwendet werden sollen. Verwenden Sie diese Option, wenn Sie eine vollständig verbundene Schicht implementieren.
Es ist ungefähr ein halbes Jahr her, seit ich nach Pytorch gezogen bin, und es ist sehr einfach zu bedienen. Ich hoffe, dieser Artikel hilft Ihnen weiter.
Recommended Posts