web-dev-qa-db-fra.com

PyTorch: prédire un seul exemple

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?

4
blue-sky

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)
6
AveryLiu