2017-09-01 1 views
2

Pour les modèles pytorch, j'ai trouvé this tutorial expliquant comment classer une image. J'ai essayé d'appliquer la même procédure pour un modèle de création. Cependant, le modèle échoue pour chaque image que je charge dansLe modèle de création de pytorch génère une mauvaise étiquette pour chaque image d'entrée

code:

# some people need these three lines to make it work 
#from torchvision.models.inception import model_urls 
#name = 'inception_v3_google' 
#model_urls[name] = model_urls[name].replace('https://', 'http://') 

from torch.autograd import Variable 
import torchvision 
import requests 
from torchvision import models, transforms 
from PIL import Image 
import io 
from PIL import Image 

LABELS_URL = 'https://s3.amazonaws.com/outcome-blog/imagenet/labels.json' 

# cat 
IMG_URL1 = 'http://farm2.static.flickr.com/1029/762542019_4f197a0de5.jpg' 

# dog 
IMG_URL2 = 'http://farm3.static.flickr.com/2314/2518519714_98b01968ee.jpg' 

# lion 
IMG_URL3 = 'http://farm1.static.flickr.com/62/218998565_62930f10fc.jpg' 


labels = {int(key):value for (key, value) 
      in requests.get(LABELS_URL).json().items()} 


model = torchvision.models.inception_v3(pretrained=True) 
model.training = False 
model.transform_input = False 



def predict_url_img(url): 
    response = requests.get(url) 
    img_pil = Image.open(io.BytesIO(response.content)) 

    normalize = transforms.Normalize(
     mean=[0.485, 0.456, 0.406], 
     std=[0.229, 0.224, 0.225] 
    ) 
    preprocess = transforms.Compose([ 
     transforms.Scale(256), 
     transforms.CenterCrop(299), 
     transforms.ToTensor(), 
     normalize 
    ]) 

    img_tensor = preprocess(img_pil) 
    img_tensor.unsqueeze_(0) 
    img_variable = Variable(img_tensor) 
    fc_out = model(img_variable) 
    print("prediction:", labels[fc_out.data.numpy().argmax()]) 

predict_url_img(IMG_URL1) 
predict_url_img(IMG_URL2) 
predict_url_img(IMG_URL3) 

En sortie, j'obtenir ceci:

('prédiction:', u "piston, aide-plombier")

('prédiction:', sac u'plastic ')

(' prédiction: », u "plongeur, assistant de plombier")

Répondre

1

J'ai découvert que l'on doit appeler model.eval() avant d'appliquer le modèle. En raison des normalisations par lots et des couches de décrochage, le modèle se comporte différemment pour l'entraînement et les tests.

+0

est ainsi la couche de décrochage, ces deux couches se comporte différemment dans la phase de formation et de test, voir [ici] (http://pytorch.org/docs/master/nn.html#torch.nn.Module.eval) – jdhao

0

J'ai exécuté votre code en ajoutant la ligne model.eval() et a obtenu:

('prediction:', u'Egyptian cat') 
('prediction:', u'groenendael') 
('prediction:', u'lion, king of beasts, Panthera leo') 

Mais si je change le pré-traitement (juste enlever votre normalize opération PyTorch et la mise en model.transform_input = True d'utiliser le pré-traitement par défaut de lancement v3) les résultats légèrement différente:

('prediction:', u'tiger cat') 
('prediction:', u'Border collie') 
('prediction:', u'lion, king of beasts, Panthera leo') 

Je ne suis pas un expert en matière de chat et de chien, mais une recherche rapide sur Google suggère que ces résultats sont plus précis (le chat dans votre image d'entrée semble plus proche d'un chat tigre qu'un chat égyptien et Border collie chiens ressemblent plus semblable à l'entrée que groenendael ainsi). Mon point est que je pense qu'on devrait utiliser inception_v3 pré-traitement par défaut (ce qui est le comportement par défaut sauf si vous changez model.transform_input = False) au lieu de la normalisation classique, mais je n'ai pas trouvé de réponse définitive à ce sujet.

This thread discute de cette question.

Espérons que cela aide quelqu'un.