Fonction torch.nn.Linear de PyTorch
Manuel de référence torch.nn de PyTorch
torch.nn.Linearest un module de PyTorch utilisé pour créer une couche entièrement connectée (également appelée couche linéaire ou transformation affine).
Il s'agit de l'une des couches les plus élémentaires et les plus couramment utilisées dans les réseaux de neurones, chargée de transformer linéairement les caractéristiques d'entrée dans l'espace des caractéristiques de sortie.
Définition de fonction
torch.nn.Linear(in_features, out_features, bias=True)
Description des paramètres :
in_features(int): La dimension des caractéristiques d'entrée, c'est-à-dire le nombre de caractéristiques produites par la couche précédente.out_features(int): La dimension des caractéristiques de sortie, c'est-à-dire le nombre de caractéristiques produites par cette couche.bias(bool) : Indique s'il faut ajouter un terme de biais. La valeur par défaut estTrue. Si défini surFalse, alors cette couche n'apprendra pas de paramètres de biais.
Attributs :
weight(Tensor): La matrice de poids apprenables de forme (out_features, in_features).bias(Tensor): Le vecteur de biais apprenable de forme (out_features,). Sibias=False, alors cet attribut n'existe pas.
Principe mathématique
nn.LinearLa formule de calcul est la suivante :
y = xA^T + b
où :
xest le tenseur d'entrée, de forme (..., in_features)Aest la matrice de poids, de forme (out_features, in_features)best le vecteur de biais, de forme (out_features)yest le tenseur de sortie, de forme (..., out_features)
Le symbole...indique que l'entrée peut être un tenseur de n'importe quelle dimension, et que la transformation linéaire est appliquée à la dernière dimension.
Exemples d'utilisation
Exemple 1 : Utilisation de base
Créer une couche entièrement connectée simple qui associe une entrée de dimension 10 à une sortie de dimension 5 :
Exemple
import torch.nn as nn
# Créer une couche linéaire : entrée à 10 dimensions, sortie à 5 dimensions
linear_layer = nn.Linear(in_features=10, out_features=5, bias=True)
# Afficher les formes du poids et du biais
print("Forme du poids :", linear_layer.weight.shape) # torch.Size([5, 10])
print("Forme du biais :", linear_layer.bias.shape) # torch.Size([5])
# Créer un tenseur d'entrée : batch_size=3, dimension des caractéristiques=10
input_tensor = torch.randn(3, 10)
# Propagation avant
output = linear_layer(input_tensor)
print("Forme de l'entrée :", input_tensor.shape) # torch.Size([3, 10])
print("Forme de la sortie :", output.shape) # torch.Size([3, 5])
print("Données de sortie :\n", output)
Le résultat de sortie est:
权重形状: 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>)
Dans cet exemple, nous avons créé une couche entièrement connectée avec une entrée de 10 et une sortie de 5. La forme du tenseur d'entrée est (3, 10), où 3 est la taille du lot et 10 est la dimension des caractéristiques. La forme du tenseur de sortie est (3, 5).
Exemple 2 : Sans biais
Créer une couche linéaire sans terme de biais :
Exemple
import torch.nn as nn
# Créer une couche linéaire sans biais
linear_no_bias = nn.Linear(in_features=10, out_features=5, bias=False)
# Vérifier si le biais existe
print("Le biais existe :", linear_no_bias.bias is None) # True
# Propagation avant
input_tensor = torch.randn(3, 10)
output = linear_no_bias(input_tensor)
print("Forme de la sortie :", output.shape) # torch.Size([3, 5])
print("Sortie :\n", output)
Le résultat de sortie est:
偏置是否存在: 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>)
Exemple 3 : Entrée multidimensionnelle
nn.LinearIl peut gérer des entrées de dimensions arbitraires et ne transforme que la dernière dimension :
Exemple
import torch.nn as nn
# Créer une couche linéaire
linear = nn.Linear(in_features=10, out_features=5)
# Traiter une entrée 2D (lot, caractéristiques)
input_2d = torch.randn(8, 10)
output_2d = linear(input_2d)
print("entrée 2D -> sortie :", input_2d.shape, "->", output_2d.shape)
# Traiter l'entrée 3D (batch, seq, features)
input_3d = torch.randn(4, 6, 10)
output_3d = linear(input_3d)
print("entrée 3D -> sortie :", input_3d.shape, "->", output_3d.shape)
# Traiter l'entrée 4D (batch, channels, height, width)
input_4d = torch.randn(2, 3, 4, 10)
output_4d = linear(input_4d)
print("entrée 4D -> sortie :", input_4d.shape, "->", output_4d.shape)
Le résultat de sortie est:
二维输入 -> 输出: 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])
Exemple 4 : Utilisation dans un réseau de neurones
Dans un réseau de neurones réel,nn.Linearil est généralement utilisé en combinaison avec d'autres couches :
Exemple
import torch.nn as nn
# Définir un perceptron multicouche (MLP)
class MLP(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(MLP, self).__init__()
# Première couche : entrée -> couche cachée
self.fc1 = nn.Linear(input_dim, hidden_dim)
# Fonction d'activation
self.relu = nn.ReLU()
# Deuxième couche : couche cachée -> sortie
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
# Créer le modèle
model = MLP(input_dim=784, hidden_dim=256, output_dim=10)
# Afficher la structure du modèle
print("Structure du modèle:")
print(model)
# Tester la propagation avant
input_tensor = torch.randn(32, 784) # batch_size=32, 28x28=784
output = model(input_tensor)
print("\nForme de l'entrée :", input_tensor.shape) # torch.Size([32, 784])
print("Forme de la sortie :", output.shape) # torch.Size([32, 10])
Le résultat de sortie est:
模型结构: 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])
Initialisation des poids
Par défaut,nn.Linearutilise la stratégie d'initialisation par défaut de PyTorch.
Vous pouvez également initialiser manuellement les poids :
Exemple
import torch.nn as nn
# Créer une couche linéaire
linear = nn.Linear(10, 5)
# Utiliser l'initialisation Xavier pour les poids
nn.init.xavier_uniform_(linear.weight)
# Initialiser le biais à zéro
nn.init.zeros_(linear.bias)
# Afficher les poids initialisés
print("Poids :\n", linear.weight.data)
print("Biais :", linear.bias.data)
Différence avec nn.functional.linear
PyTorch fournit également une interface fonctionnelletorch.nn.functional.linear:
Exemple
import torch.nn as nn
import torch.nn.functional as F
# Méthode 1 : Utilisation de nn.Module
linear_module = nn.Linear(10, 5)
output1 = linear_module(torch.randn(3, 10))
# Méthode 2 : Utilisation de l'interface fonctionnelle
weight = torch.randn(5, 10)
bias = torch.randn(5)
output2 = F.linear(torch.randn(3, 10), weight, bias)
print("forme de sortie de nn.Module :", output1.shape)
print("forme de sortie de nn.functional :", output2.shape)
La différence entre les deux :
nn.Linearest une classe de module qui sauvegarde les paramètres de poids et de biais, ce qui facilite l'entraînement et la sauvegarde des modèles.F.linearest une fonction qui nécessite de passer manuellement les poids et les biais, souvent utilisée dans des situations sans paramètres apprenables.
Remarque : Bien que les opérations mathématiques des deux soient identiques, lors de la construction de réseaux de neurones, nous utilisons généralement
nn.Linear, car il enregistre automatiquement les paramètres, ce qui facilite leur mise à jour par les optimiseurs.
Questions courantes
Q1 : Comment afficher le nombre de paramètres dans une couche Linear ?
Pour une couche linéaire avec (in_features, out_features) :
- Nombre de paramètres de poids : in_features * out_features
- Nombre de paramètres de biais : out_features (si bias=True)
Exemple
import torch.nn as nn
linear = nn.Linear(100, 50)
print("Nombre total de paramètres :", sum(p.numel() for p in linear.parameters()))
print("Paramètres de poids :", linear.weight.numel())
print("Paramètres de biais :", linear.bias.numel())
Q2 : Comment figer les paramètres d'une couche Linear ?
Si vous souhaitez figer certaines couches afin qu'elles ne participent pas à l'entraînement, vous pouvez définirrequires_grad=False:
Exemple
import torch.nn as nn
linear = nn.Linear(10, 5)
# Geler les poids afin qu'ils ne participent pas au calcul du gradient
linear.weight.requires_grad = False
# Geler le biais
linear.bias.requires_grad = False
# Vérifier
print("Poids requires_grad:", linear.weight.requires_grad)
print("Biais requires_grad:", linear.bias.requires_grad)
Cas d'utilisation
nn.Linearest l'une des couches les plus couramment utilisées dans les réseaux de neurones. Les principaux scénarios d'application incluent :
- Perceptron multicouche (MLP): En tant que couche entièrement connectée, projette les caractéristiques vers un nouvel espace de caractéristiques.
- Classificateur: À la fin des réseaux convolutionnels ou récurrents, utilisez une couche entièrement connectée pour la classification.
- Transformation de caractéristiques: Appliquez une transformation linéaire aux données pour réaliser une réduction ou une augmentation de la dimensionnalité.
- Mécanisme d'attention: Dans Transformer, utilisé pour générer les matrices Q, K, V.
Autres extensions