En suivant l'exemple de:
https://github.com/jcjohnson/pytorch-examples
Ce code s'entraîne avec succès:
# Code in file tensor/two_layer_net_tensor.py
import torch
device = torch.device('cpu')
# device = torch.device('cuda') # Uncomment this to run on GPU
# N is batch size; D_in is input dimension;
# H is hidden dimension; D_out is output dimension.
N, D_in, H, D_out = 64, 1000, 100, 10
# Create random input and output data
x = torch.randn(N, D_in, device=device)
y = torch.randn(N, D_out, device=device)
# Randomly initialize weights
w1 = torch.randn(D_in, H, device=device)
w2 = torch.randn(H, D_out, device=device)
learning_rate = 1e-6
for t in range(500):
# Forward pass: compute predicted y
h = x.mm(w1)
h_relu = h.clamp(min=0)
y_pred = h_relu.mm(w2)
# Compute and print loss; loss is a scalar, and is stored in a PyTorch Tensor
# of shape (); we can get its value as a Python number with loss.item().
loss = (y_pred - y).pow(2).sum()
print(t, loss.item())
# Backprop to compute gradients of w1 and w2 with respect to loss
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.t().mm(grad_y_pred)
grad_h_relu = grad_y_pred.mm(w2.t())
grad_h = grad_h_relu.clone()
grad_h[h < 0] = 0
grad_w1 = x.t().mm(grad_h)
# Update weights using gradient descent
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
Comment puis-je prédire un seul exemple? Jusqu'à présent, mon expérience consiste à utiliser des réseaux à action directe en utilisant simplement numpy
. Après avoir formé un modèle, j'utilise la propagation vers l'avant, mais pour un seul exemple:
numpy
extrait de code où new
est la valeur de sortie que j'essaie de prédire:
new = np.asarray(toclassify)
Z1 = np.dot(weight_layer_1, new.T) + bias_1
sigmoid_activation_1 = sigmoid(Z1)
Z2 = np.dot(weight_layer_2, sigmoid_activation_1) + bias_2
sigmoid_activation_2 = sigmoid(Z2)
sigmoid_activation_2
contient les attributs vectoriels prédits
La façon idiomatique PyTorch est-elle la même? Utiliser la propagation directe pour faire une seule prédiction?
Le code que vous avez publié est une simple démonstration essayant de révéler le mécanisme interne de ces cadres d'apprentissage en profondeur. Ces cadres, y compris PyTorch, Keras, Tensorflow et bien d'autres, gèrent automatiquement le calcul direct, le suivi et l'application de gradients pour vous tant que vous définissez la structure du réseau. Cependant, le code que vous avez montré essaie toujours de faire ces choses manuellement. C'est la raison pour laquelle vous vous sentez lourd lorsque vous prédisez un exemple, car vous le faites toujours à partir de zéro.
En pratique, nous définirons une classe de modèle héritée de torch.nn.Module
et initialiser tous les composants du réseau (comme la couche neuronale, GRU, la couche LSTM, etc.) dans le __init__
, et définissez comment ces composants interagissent avec l'entrée réseau dans la fonction forward
.
Prenons l'exemple de la page que vous avez fournie:
# Code in file nn/two_layer_net_module.py
import torch
class TwoLayerNet(torch.nn.Module):
def __init__(self, D_in, H, D_out):
"""
In the constructor we instantiate two nn.Linear modules and
assign them as
member variables.
"""
super(TwoLayerNet, self).__init__()
self.linear1 = torch.nn.Linear(D_in, H)
self.linear2 = torch.nn.Linear(H, D_out)
def forward(self, x):
"""
In the forward function we accept a Tensor of input data and we must return
a Tensor of output data. We can use Modules defined in the constructor as
well as arbitrary (differentiable) operations on Tensors.
"""
h_relu = self.linear1(x).clamp(min=0)
y_pred = self.linear2(h_relu)
return y_pred
# N is batch size; D_in is input dimension;
# H is hidden dimension; D_out is output dimension.
N, D_in, H, D_out = 64, 1000, 100, 10
# Create random Tensors to hold inputs and outputs
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
# Construct our model by instantiating the class defined above.
model = TwoLayerNet(D_in, H, D_out)
# Construct our loss function and an Optimizer. The call to
model.parameters()
# in the SGD constructor will contain the learnable parameters of the two
# nn.Linear modules which are members of the model.
loss_fn = torch.nn.MSELoss(size_average=False)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)
for t in range(500):
# Forward pass: Compute predicted y by passing x to the model
y_pred = model(x)
# Compute and print loss
loss = loss_fn(y_pred, y)
print(t, loss.item())
# Zero gradients, perform a backward pass, and update the weights.
optimizer.zero_grad()
loss.backward()
optimizer.step()
Le code définit un modèle nommé TwoLayerNet, il initialise deux couches linéaires dans le __init__
et définit en outre comment ces deux linéaires interagissent avec l'entrée x
dans la fonction forward
. Une fois le modèle défini, nous pouvons effectuer une seule opération de rétroaction simplement en appelant l'instance de modèle comme illustré par la fin de l'extrait de code:
y_pred = model(x)