PyTorch torch.nn.Linear-Funktion
PyTorch torch.nn Referenzhandbuch
torch.nn.Linearist ein Modul in PyTorch, das verwendet wird, um eine vollständig verbundene Schicht (auch lineare Schicht oder affine Transformation genannt) zu erstellen.
Es ist eine der grundlegendsten und am häufigsten verwendeten Schichten in neuronalen Netzen und dafür verantwortlich, Eingabemerkmale linear in den Ausgabemerkmalraum zu transformieren.
Funktionsdefinition
torch.nn.Linear(in_features, out_features, bias=True)
Parameterbeschreibung:
in_features(int): Die Dimension der Eingabemerkmale, d. h. die Anzahl der Merkmale, die von der vorherigen Schicht ausgegeben werden.out_features(int): Die Dimension der Ausgabemerkmale, d. h. die Anzahl der Merkmale, die von dieser Schicht ausgegeben werden.bias(bool): Ob ein Bias-Term hinzugefügt werden soll. Standard istTrue. Wenn eingestellt aufFalse, dann lernt diese Schicht keine Bias-Parameter.
Attribute:
weight(Tensor): Die lernbare Gewichtsmatrix mit Form (out_features, in_features).bias(Tensor): Der lernbare Bias-Vektor mit Form (out_features,). Wennbias=False, dann existiert dieses Attribut nicht.
Mathematisches Prinzip
nn.LinearDie Berechnungsformel lautet wie folgt:
y = xA^T + b
wobei:
xist der Eingabe-Tensor mit der Form (..., in_features)Aist die Gewichtsmatrix mit der Form (out_features, in_features)bist der Bias-Vektor mit der Form (out_features)yist der Ausgabe-Tensor mit der Form (..., out_features)
Das Symbol...gibt an, dass die Eingabe ein Tensor beliebiger Dimension sein kann und die lineare Transformation auf die letzte Dimension angewendet wird.
Anwendungsbeispiele
Beispiel 1: Grundlegende Verwendung
Erstellen Sie eine einfache vollständig verbundene Schicht, die eine 10-dimensionale Eingabe auf eine 5-dimensionale Ausgabe abbildet:
Beispiel
import torch.nn as nn
# Erstellen einer linearen Schicht: Eingabe 10 Dimensionen, Ausgabe 5 Dimensionen
linear_layer = nn.Linear(in_features=10, out_features=5, bias=True)
# Die Formen von Gewicht und Bias ausgeben
print("Gewichtsform:", linear_layer.weight.shape) # torch.Size([5, 10])
print("Bias-Form:", linear_layer.bias.shape) # torch.Size([5])
# Eingabetensor erstellen: batch_size=3, Merkmalsdimension=10
input_tensor = torch.randn(3, 10)
# Vorwärtspropagierung
output = linear_layer(input_tensor)
print("Eingabeform:", input_tensor.shape) # torch.Size([3, 10])
print("Ausgabeform:", output.shape) # torch.Size([3, 5])
print("Ausgabedaten:\n", output)
Das Ausgabeergebnis ist:
权重形状: torch.Size([5, 10])
偏置形状: torch.Size([5])
输入形状: torch.Size([3, 10])
输出形状: torch.Size([3, 5])
输出数据:
tensor([[-0.1838, 0.0607, -0.4879, 0.8981, -0.2098],
[ 0.1513, -0.1873, 0.1866, -0.2448, -0.6012],
[ 0.2915, 0.3053, 0.2532, -0.3372, -0.3968]],
grad_fn=<AddmmBackward0>)
In diesem Beispiel haben wir eine vollständig verbundene Schicht mit Eingabe 10 und Ausgabe 5 erstellt. Die Form des Eingabetensors ist (3, 10), wobei 3 die Batch-Größe und 10 die Merkmalsdimension ist. Die Form des Ausgabetensors ist (3, 5).
Beispiel 2: Ohne Bias
Eine lineare Schicht ohne Bias-Term erstellen:
Beispiel
import torch.nn as nn
# Eine lineare Schicht ohne Bias erstellen
linear_no_bias = nn.Linear(in_features=10, out_features=5, bias=False)
# Prüfen, ob der Bias vorhanden ist
print("Bias vorhanden:", linear_no_bias.bias is None) # True
# Vorwärtspropagierung
input_tensor = torch.randn(3, 10)
output = linear_no_bias(input_tensor)
print("Ausgabeform:", output.shape) # torch.Size([3, 5])
print("Ausgabe:\n", output)
Das Ausgabeergebnis ist:
偏置是否存在: True
输出形状: torch.Size([3, 5])
输出:
tensor([[-0.3312, -0.4113, 0.0257, -0.4876, 0.0780],
[ 0.1513, 0.2459, -0.2983, 0.2456, -0.0727],
[-0.0143, 0.3053, 0.1866, -0.3372, 0.2532]],
grad_fn=<MmBackward>)
Beispiel 3: Mehrdimensionale Eingabe
nn.LinearEs kann Eingaben beliebiger Dimensionen verarbeiten und transformiert nur die letzte Dimension:
Beispiel
import torch.nn as nn
# Eine lineare Schicht erstellen
linear = nn.Linear(in_features=10, out_features=5)
# 2D-Eingabe verarbeiten (Batch, Merkmale)
input_2d = torch.randn(8, 10)
output_2d = linear(input_2d)
print("2D-Eingabe -> Ausgabe:", input_2d.shape, "->", output_2d.shape)
# 3D-Eingabe verarbeiten (Batch, Sequenz, Merkmale)
input_3d = torch.randn(4, 6, 10)
output_3d = linear(input_3d)
print("3D-Eingabe -> Ausgabe:", input_3d.shape, "->", output_3d.shape)
# 4D-Eingabe verarbeiten (Batch, Kanäle, Höhe, Breite)
input_4d = torch.randn(2, 3, 4, 10)
output_4d = linear(input_4d)
print("4D-Eingabe -> Ausgabe:", input_4d.shape, "->", output_4d.shape)
Das Ausgabeergebnis ist:
二维输入 -> 输出: torch.Size([8, 10]) -> torch.Size([8, 5]) 三维输入 -> 输出: torch.Size([4, 6, 10]) -> torch.Size([4, 6, 5]) 四维输入 -> 输出: torch.Size([2, 3, 4, 10]) -> torch.Size([2, 3, 4, 5])
Beispiel 4: Verwendung in einem neuronalen Netz
In einem echten neuronalen Netznn.Linearwird es üblicherweise in Kombination mit anderen Schichten verwendet:
Beispiel
import torch.nn as nn
# Definiere ein mehrschichtiges Perzeptron (MLP)
class MLP(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(MLP, self).__init__()
# Erste Schicht: Eingabe -> verborgene Schicht
self.fc1 = nn.Linear(input_dim, hidden_dim)
# Aktivierungsfunktion
self.relu = nn.ReLU()
# Zweite Schicht: verborgene Schicht -> Ausgabe
self.fc2 = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# Modell erstellen
model = MLP(input_dim=784, hidden_dim=256, output_dim=10)
# Modellstruktur ausgeben
print("Modellstruktur:")
print(model)
# Teste die Vorwärtspropagation
input_tensor = torch.randn(32, 784) # batch_size=32, 28x28=784
output = model(input_tensor)
print("\nEingabeform:", input_tensor.shape) # torch.Size([32, 784])
print("Ausgabeform:", output.shape) # torch.Size([32, 10])
Das Ausgabeergebnis ist:
模型结构: MLP( (fc1): Linear(in_features=784, out_features=256, bias=True) (relu): ReLU() (fc2): Linear(in_features=256, out_features=10, bias=True) ) 输入形状: torch.Size([32, 784]) 输出形状: torch.Size([32, 10])
Gewichtsinitialisierung
Standardmäßig,nn.Linearverwendet die Standardinitialisierungsstrategie von PyTorch.
Sie können die Gewichte auch manuell initialisieren:
Beispiel
import torch.nn as nn
# Eine lineare Schicht erstellen
linear = nn.Linear(10, 5)
# Xavier-Initialisierung für die Gewichte verwenden
nn.init.xavier_uniform_(linear.weight)
# Bias auf null initialisieren
nn.init.zeros_(linear.bias)
# Initialisierte Gewichte anzeigen
print("Gewicht:\n", linear.weight.data)
print("Bias:", linear.bias.data)
Unterschied zu nn.functional.linear
PyTorch bietet auch eine funktionale Schnittstelletorch.nn.functional.linear:
Beispiel
import torch.nn as nn
import torch.nn.functional as F
# Methode 1: Verwendung von nn.Module
linear_module = nn.Linear(10, 5)
output1 = linear_module(torch.randn(3, 10))
# Methode 2: Verwendung der funktionalen Schnittstelle
weight = torch.randn(5, 10)
bias = torch.randn(5)
output2 = F.linear(torch.randn(3, 10), weight, bias)
print("Ausgabeform von nn.Module:", output1.shape)
print("Ausgabeform von nn.functional:", output2.shape)
Der Unterschied zwischen den beiden:
nn.Linearist eine Modulklasse, die Gewichts- und Bias-Parameter speichert und das Trainieren und Speichern von Modellen erleichtert.F.linearist eine Funktion, bei der Gewichte und Bias manuell übergeben werden müssen, die häufig in Situationen ohne lernbare Parameter verwendet wird.
Hinweis: Obwohl die mathematischen Operationen der beiden identisch sind, verwenden wir beim Erstellen neuronaler Netze normalerweise
nn.Linear, weil es Parameter automatisch registriert und es dadurch für Optimierer bequem ist, sie zu aktualisieren.
Häufige Fragen
F1: Wie kann man die Anzahl der Parameter in einer Linear-Schicht anzeigen?
Für eine lineare Schicht mit (in_features, out_features):
- Anzahl der Gewichtsparameter: in_features * out_features
- Anzahl der Bias-Parameter: out_features (wenn bias=True)
Beispiel
import torch.nn as nn
linear = nn.Linear(100, 50)
print("Gesamtzahl der Parameter:", sum(p.numel() for p in linear.parameters()))
print("Gewichtsparameter:", linear.weight.numel())
print("Bias-Parameter:", linear.bias.numel())
F2: Wie friert man die Parameter einer Linear-Schicht ein?
Wenn Sie bestimmte Layer fixieren möchten, damit sie nicht am Training teilnehmen, können Sie setzenrequires_grad=False:
Beispiel
import torch.nn as nn
linear = nn.Linear(10, 5)
# Gewichte einfrieren, damit sie nicht an der Gradientenberechnung teilnehmen
linear.weight.requires_grad = False
# Bias einfrieren
linear.bias.requires_grad = False
# Überprüfen
print("Gewicht requires_grad:", linear.weight.requires_grad)
print("Bias requires_grad:", linear.bias.requires_grad)
Anwendungsfälle
nn.Linearist einer der am häufigsten verwendeten Layer in neuronalen Netzen. Die wichtigsten Anwendungsszenarien umfassen:
- Multi-Layer-Perceptron (MLP): Als vollständig verbundener Layer bildet es Merkmale auf einen neuen Merkmalsraum ab.
- Klassifikator: Am Ende von Faltungs- oder rekurrenten Netzen verwenden Sie einen vollständig verbundenen Layer zur Klassifikation.
- Feature-Transformation: Wenden Sie eine lineare Transformation auf Daten an, um eine Dimensionsreduktion oder -erhöhung zu erreichen.
- Attention-Mechanismus: Im Transformer wird er verwendet, um Q-, K-, V-Matrizen zu erzeugen.
Andere Erweiterungen