2017-08-03 3 views
0

J'essaie un exemple de calcul de moyenne de base, mais la validation et la perte ne correspondent pas et le réseau ne converge pas si j'augmente le temps d'apprentissage. J'entraîne un réseau avec 2 couches cachées, chacune 500 unités de largeur sur trois entiers de la gamme [0,9] avec un taux d'apprentissage de 1e-1, Adam, taille de lot de 1, et dropout pour 3000 itérations et valider chaque 100 itérations. Si la différence absolue entre l'étiquette et l'hypothèse est inférieure à un seuil, ici je mets le seuil à 1, je considère que c'est correct. Quelqu'un pourrait-il me dire si c'est un problème avec le choix de la fonction de perte, quelque chose qui ne va pas avec Pytorch, ou quelque chose que je fais. Voici quelques parcelles:Fonctions de perte de régression incorrectes

val_diff = 1 
acc_diff = torch.FloatTensor([val_diff]).expand(self.batch_size) 

boucle 100 fois durant la validation:

num_correct += torch.sum(torch.abs(val_h - val_y) < acc_diff) 

Append après chaque phase de validation:

validate.append(num_correct/total_val) 

Voici quelques exemples de la (hypothèse, et les étiquettes):

[...(-0.7043088674545288, 6.0), (-0.15691305696964264, 2.6666667461395264), 
(0.2827358841896057, 3.3333332538604736)] 

J'ai essayé six des fonctions de perte de l'API qui sont généralement utilisés pour la régression:

                                                                                                        torch.nn.L1Loss (size_average = False) enter image description here

                                                                                                                                            torch.nn.L1Loss() enter image description here

                                                                                                          torch.nn.MSELoss (size_average = False) enter image description here

                                                                                                                                      torch.nn.MSELoss() enter image description here

                                                                                          torch.nn.SmoothL1Loss (size_average = False) enter image description here

                                                                                                                              torch.nn.SmoothL1Loss() enter image description here

Merci.

code réseau:

class Feedforward(nn.Module): 
    def __init__(self, topology): 
     super(Feedforward, self).__init__() 
     self.input_dim  = topology['features'] 
     self.num_hidden = topology['hidden_layers'] 
     self.hidden_dim = topology['hidden_dim'] 
     self.output_dim = topology['output_dim'] 
     self.input_layer = nn.Linear(self.input_dim, self.hidden_dim) 
     self.hidden_layer = nn.Linear(self.hidden_dim, self.hidden_dim) 
     self.output_layer = nn.Linear(self.hidden_dim, self.output_dim) 
     self.dropout_layer = nn.Dropout(p=0.2) 


    def forward(self, x): 
     batch_size = x.size()[0] 
     feat_size = x.size()[1] 
     input_size = batch_size * feat_size 

     self.input_layer = nn.Linear(input_size, self.hidden_dim).cuda() 
     hidden = self.input_layer(x.view(1, input_size)).clamp(min=0) 

     for _ in range(self.num_hidden): 
      hidden = self.dropout_layer(F.relu(self.hidden_layer(hidden))) 

     output_size = batch_size * self.output_dim 
     self.output_layer = nn.Linear(self.hidden_dim, output_size).cuda() 
     return self.output_layer(hidden).view(output_size) 

Code de formation:

def train(self): 
    if self.cuda: 
     self.network.cuda() 

    dh  = DataHandler(self.data) 
    # loss_fn = nn.L1Loss(size_average=False) 
    # loss_fn = nn.L1Loss() 
    # loss_fn = nn.SmoothL1Loss(size_average=False) 
    # loss_fn = nn.SmoothL1Loss() 
    # loss_fn = nn.MSELoss(size_average=False) 
    loss_fn = torch.nn.MSELoss() 
    losses = [] 
    validate = [] 
    hypos  = [] 
    labels = [] 
    val_size = 100 
    val_diff = 1 
    total_val = float(val_size * self.batch_size) 

    for i in range(self.iterations): 
     x, y = dh.get_batch(self.batch_size) 
     x = self.tensor_to_Variable(x) 
     y = self.tensor_to_Variable(y) 

     self.optimizer.zero_grad() 
     loss = loss_fn(self.network(x), y) 
     loss.backward() 
     self.optimizer.step() 
+0

Êtes-vous vos gradients après la réduction à zéro la mise à jour votre poids? C'est une erreur commune. En outre, votre taux d'apprentissage semble vraiment élevé. – mexmex

+0

@mexmex ne suis-je pas supposé effacer les gradients locaux à chaque itération? N'est-ce pas le but de optimizer.zero_grad? – Soubriquet

+0

Oui, était juste en train de vérifier que vous faites en fait! Désolé, si ma langue était ambiguë. – mexmex

Répondre

1

On dirait que vous avez mal compris comment les couches dans les œuvres de pytorch, voici quelques conseils:

  • Dans votre forward lorsque vous faites nn.Linear(...) vous définissez nouveau couches au lieu d'utiliser celles que vous avez prédéfinies dans votre réseau __init__. Par conséquent, il ne peut rien apprendre car les poids sont constamment revitalisés.

  • Vous ne devriez pas avoir besoin d'appeler à l'intérieur .cuda()net.forward(...) puisque vous avez déjà copié le réseau sur gpu dans votre train en appelant self.network.cuda()

  • Idéalement l'entrée net.forward(...) doit directement avoir la forme de la première couche si vous n'aurez pas à le modifier. Ici, vous devriez avoir x.size() <=> Linear -- > (Batch_size, Features).

Votre avant devrait examiner de près à ceci:

def forward(self, x): 
    x = F.relu(self.input_layer(x)) 
    x = F.dropout(F.relu(self.hidden_layer(x)),training=self.training) 
    x = self.output_layer(x) 
    return x 
+0

J'ai donc initialisé de nouvelles couches à chaque itération pour accommoder les entrées dynamiques. Est-ce que pytorch gère automatiquement les entrées dynamiques et les lots dynamiques? – Soubriquet

+0

@Soubriquet Que voulez-vous dire par entrées dynamiques et lots dynamiques? Cependant, l'utilisation de nouveaux poids à chaque entrée ne fonctionnera pas. – Cedias

+0

oui, comment voulez-vous dynamiquement par lots – Soubriquet