    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    @author: Axel Brando Guillaumes

## Resolució d'un problema més complex i millora: la Food-101¶

## Creació fitxers train.txt, val.txt i cat.txt¶

Creem els fitxers que contrindran la ruta al fitxer de test (val.txt) el d'entrenament (train.txt) i les categories (cat.txt)

In []:

    import os
    from os import listdir
    from os.path import isdir,isfile, join

    limit = 0 #Pel finetunning actualment a 150 imatges

    fwriteT = open('/Food-101/train.txt','w')
    fwriteV = open('/Food-101/val.txt','w')
    fwriteC = open('/Food-101/cat.txt','w')
    data_path = '/Food-101/images'
    label = 0 #ID de la categoria

    cat = listdir(data_path)
    cat.sort()

    for c in cat:
        if isdir(join(data_path,c)):
            limit = 1
            for f in listdir(join(data_path,c)):
                if not isdir(f):
                    if limit%10:
                        fwriteT.write("%s %d\n" % (join(c+'/',f),label))
                        limit += 1
                    else:
                        limit = 1
                        fwriteV.write("%s %d\n" % (join(c+'/',f),label))

            fwriteC.write("%s %d\n" % (c,label))
            label +=1
    fwriteT.close()
    fwriteC.close()
    fwriteV.close()

## Creació Food-101-crop-50x50¶

Per tal de generar una base de imatges que ens permeti treballar amb ella sense tenir de realitzar càlculs que comportin un gran volum computacional, realitzarem un crop de 50x50 del centre de les imatges i treballarem d'ara fins que no es digui el contrari amb aquesta BD

In []:

    from PIL import Image
    import os
    from os import listdir
    from os.path import isdir,isfile, join
    # size is width/height
    width = 50
    height = 50
    #Path on estan les imatges
    data_path = 'Food-101/images'
    newpath = 'Food-101-crop50/images'

    cat = listdir(data_path)
    cat.sort()

    for c in cat:
        if isdir(join(data_path,c)):
            if not os.path.exists(join(newpath,c)):
                os.makedirs(join(newpath,c))
            for f in listdir(join(data_path,c)):
                if not isdir(f) and f.endswith('.jpg'):
                    #Carreguem la imatge
                    img = Image.open(join(data_path,c)+'/'+f)
                    (w,h) = img.size
                    if w > 50 and h > 50:
                        top = (h/2)-25
                        left = (w/2)-25
                        box = (left, top, left+width, top+height)
                        try:
                            area = img.crop(box)
                        except IOError:
                            print "IOError: File = "+f+", left = "+str(left)+", top = "+str(top)+", width = "+str(width)+", height = "+str(height)
                    else:
                        area = img
                        print "Imatge més petita, File = "+f
                    area.save(join(newpath,c)+'/'+f, 'jpeg')

Ara executariem els scripts \(create\_imagenet.sh\) per crear els fitxers lmbd, \(make\_imagenet\_mean.sh\) per crear la mitja dels fitxers d'entrenament i \(train\_caffenet.sh\) per entrenar la xarxa neuronal i generar la .caffemodel

Seguidament, podríem fer una prova per visualitzar la mitja que hem generat amb el següent codi:

In [9]:

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline

    # Make sure that caffe is on the python path:
    caffe_root = '/home/axel/Desktop/caffe-master/'  # this file is expected to be in {caffe_root}/examples
    import sys
    sys.path.insert(0, caffe_root + 'python')
    #sys.path.insert(0,'/usr/local/lib/python2.7/dist-packages')

    import caffe
    from caffe.proto import caffe_pb2
    from caffe import io

    #Convertim el binaryproto mean en un numpy 'arr' mitjançant el blob
    blob = caffe.proto.caffe_pb2.BlobProto()
    data = open('/media/9C64D17064D14DA0/TFG/food-101/imagenet_mean.binaryproto' , 'rb' ).read()
    blob.ParseFromString(data)
    arr = np.array( caffe.io.blobproto_to_array(blob) )
    out = arr[0]

    #Imprimim el nombre de dimensions
    print out.shape

    fig = plt.figure()
    ax = fig.add_subplot(111)
    #Optenim la matriu de convolució del tercer canal
    cax = ax.matshow(out[0,:,:])
    plt.title('Matriu de confusio del classificador')
    fig.colorbar(cax)
    plt.show()

    fig = plt.figure()
    ax = fig.add_subplot(111)
    #Optenim la matriu de convolució del tercer canal
    cax = ax.matshow(out[1,:,:])
    plt.title('Matriu de confusio del classificador')
    fig.colorbar(cax)
    plt.show()

    fig = plt.figure()
    ax = fig.add_subplot(111)
    #Optenim la matriu de convolució del tercer canal
    cax = ax.matshow(out[2,:,:])
    plt.title('Matriu de confusio del classificador')
    fig.colorbar(cax)
    plt.show()

    (3, 256, 256)

Hem de pensar que tota la informació es troba al centre, per tant, té sentit aquesta representació ja que observem que es destaca la part central on es troba el plat. A cada canal destaca una part diferent però totes separen la part central dels laterals.

## Visualització resultats Food101 450k¶

Ara visualitzarem els resultats de la xarxa neuronal entrenada amb una arquitectura de la ImageNet amb \(450.000\) iteracions.

Primer carreguem la xarxa neuronal amb

In [13]:

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline

    # Make sure that caffe is on the python path:
    caffe_root = '/home/axel/Desktop/caffe-master/'  # this file is expected to be in {caffe_root}/examples
    import sys
    sys.path.insert(0, caffe_root + 'python')
    #sys.path.insert(0,'/usr/local/lib/python2.7/dist-packages')

    import caffe

    # Set the right path to your model definition file, pretrained model weights,
    # and the image you would like to classify. S'HA DE CREAR!!!
    MODEL_FILE = '/home/axel/Desktop/Food-101/deploy.prototxt'
    PRETRAINED = '/media/9C64D17064D14DA0/TFG/Food-101-Santi/train_scripts_iter_450000.caffemodel'

    net = caffe.Classifier(MODEL_FILE, PRETRAINED, channel_swap=(2,1,0), raw_scale=255, image_dims=(227, 227))
    net.set_phase_test()
    net.set_mode_cpu()

Anem a visualitzar un plat de sashimi que correspon a la classe \(86\) consultant el fitxer \(cat.txt\).

In [14]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/sashimi/2006.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[14]:

    <matplotlib.image.AxesImage at 0x7f0e122cd5d0>

In [15]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 86

Veiem que efectivament la classificació ha estat correcte i que la opció dista molt de les altres. Per tant, en aquest cas, el classificador ho fa bé.

Torna a passsar el mateix pel cas del tiramisu (classe \(98\)) que la classificació torna ser bona:

In [17]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/tiramisu/1890089.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[17]:

    <matplotlib.image.AxesImage at 0x7f0e11e31550>

In [18]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 98

## Test resultats¶

Si volguéssim realitzar un test global i que cada \(50\) iteracions ens anés informant de la situació podríem implementar un codi com el següent:

In []:

    import datetime

    freadVal = open('Food-101/val.txt','r')
    IMAGE_FILE = ''
    hit = 0
    tries = 0
    for files in freadVal.readlines():
        IMAGE_FILE = 'Food-101/images/'+str(files.split()[0])
        input_image = caffe.io.load_image(IMAGE_FILE)
        prediction = net.predict([input_image],oversample=False)
        if str(prediction[0].argmax()) == files.split()[1]:
            hit +=1
        tries += 1
        #print str(datetime.datetime.now().time())+" - Accuracy: "+str(hit)+" of "+str(tries)
        if not tries%50:
            print str(datetime.datetime.now().time())+" - Accuracy: "+str(hit)+" of "+str(tries)
    freadVal.close()
    print str(datetime.datetime.now().time())+" - Final Accuracy: "+str(hit*100/float(tries))+" %"

Ara bé, si ens interessa realitzar un test de: donat un valor \(n\), saber quin és el ràtio si és considera un encert estar en les \(n\) posicions primeres, aleshores el codi seria:

In []:

    import datetime

    freadVal = open('Food-101/val.txt','r')
    IMAGE_FILE = ''
    #Verify the last N hits
    Nhits = 5

    hit = [0]*Nhits
    tries = 0
    bol = True

    #Per cada fitxer
    for files in freadVal.readlines():
        #Agafem la seva ruta
        IMAGE_FILE = 'Food-101/images/'+str(files.split()[0])
        #Carreguem la imatge i les n channels posteriors
        input_image = caffe.io.load_image(IMAGE_FILE)
        #predim la possible class
        prediction = net.predict([input_image],oversample=False)

        #Contabilitzem els hits

        #Copiem contingut
        lPredict = prediction[0]
        #Ordenem aquesta segona dnarray i la invertim perquè el màxim estigui
        # al principi
        lPredict = np.sort(lPredict)[::-1]
        #Per cada N hits comprovem si coincideix
        # amb el valor de la classe buscada amb la N-essima posició
        for i in xrange(Nhits):
            if lPredict[i] == prediction[0][int(files.split()[1])]:
                hit[i] +=1
                bol = False
                break
        #Debug per veure errors
        if (bol):
            print "\t Imatge "+str(files.split()[0])+" diu "+str(prediction[0].argmax())+" era "+str(files.split()[1])
        bol = True

        tries += 1
        #Cada 100 iteracions fem un print de la situació
        if not tries%50:
            print str(datetime.datetime.now().time())
            for i in xrange(Nhits):
                print "\t Accuracy at "+str(i+1)+" hits: "+str(sum(hit[:(i+1)]))+" of "+str(tries)
    freadVal.close()
    print str(datetime.datetime.now().time())
    for i in xrange(Nhits):
        print "\t Final Accuracy at "+str(i+1)+" hits: "+str(sum(hit[:(i+1)])*100/float(tries))+" %"

## Visualització resultats Food101 Fine-Tuning 60k mitjançant ImageNet¶

Ara realitzarem la visualització dels resultats mitjançant el model de la xarxa neuronal entrenada amb el Fine-Tuning usant la ImageNet.

In [50]:

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline

    # Make sure that caffe is on the python path:
    caffe_root = '/home/axel/Desktop/caffe-master/'  # this file is expected to be in {caffe_root}/examples
    import sys
    sys.path.insert(0, caffe_root + 'python')
    #sys.path.insert(0,'/usr/local/lib/python2.7/dist-packages')

    import caffe

    # Set the right path to your model definition file, pretrained model weights,
    # and the image you would like to classify. S'HA DE CREAR!!!
    MODEL_FILE = '/home/axel/Desktop/Food-101/deploy.prototxt'
    PRETRAINED = '/media/9C64D17064D14DA0/TFG/Food-101-Finetunning/BU/finetuning/train_scripts_iter_60000.caffemodel'

    net = caffe.Classifier(MODEL_FILE, PRETRAINED, channel_swap=(2,1,0), raw_scale=255, image_dims=(227, 227))
    net.set_phase_test()
    net.set_mode_cpu()

In [39]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/sashimi/2006.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[39]:

    <matplotlib.image.AxesImage at 0x7f0e1168f610>

In [22]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 86

Realment, podem dir que impressiona els resultats. Per exemple, fixem-nos en la següent imatges on podem observar que el menjar realment no és la part important de la fotografia, tot i això, la classificació és clara i accertada ja que la classe \(55\) és el \(hot\_dog\):

Nota: Tot i això, aquesta imatge estava dins del conjunt d'aprenentatge, per tant, no es pot considerar una gran classificació.

In [23]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/hot_dog/3105076.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[23]:

    <matplotlib.image.AxesImage at 0x7f0e11f82810>

In [24]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 55

Però considerem un exemple que no estigui al conjunt d'aprenentatge i que sigui realment poc classificable:

In [40]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/pizza/1407753.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[40]:

    <matplotlib.image.AxesImage at 0x7f0e115c3a10>

Aquests nois estan menjant pizza (classe \(76\)), però el classificador això com ho detectarà?

In [41]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 32

El classificador no ho detecta i ni esperem que ho faci. Classificar això està molt lluny de l'objectiu de classificar el menjar. Per curiositat, la classe \(32\) és \(dumplings\) (https://en.wikipedia.org/wiki/Dumpling)

Presentem dos exemples però que sí que falla. El \(apple\_pie\) és la classe \(0\). El resultat és:

In [25]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/apple_pie/1047447.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[25]:

    <matplotlib.image.AxesImage at 0x7f0e11cc6210>

In [26]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 70

On la classe \(70\) és el plat \(pad\_thai\), un plat que destaca per tenir tons grogossos com la següent imatge:

In [32]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/pad_thai/198098.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[32]:

    <matplotlib.image.AxesImage at 0x7f0e11944050>

Passem a un segón exemple on la nostre xarxa Fine-Tuning 60k falla:

In [33]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/apple_pie/1005649.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[33]:

    <matplotlib.image.AxesImage at 0x7f0e118ef490>

In [34]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 60

La classe \(60\) correspon a \(lobster\_bisque\) blanc pels voltants i groc pel mig. No té perquè ser tan simple el motiu, però sí que si mirem com són les fotogràfies d'aquest fals positiu de classe veiem una similitud entre la imatge anterior i les d'aquesta nova classe. Com a exemple:

In [35]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/lobster_bisque/1789658.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[35]:

    <matplotlib.image.AxesImage at 0x7f0e11a9e0d0>

Ara observarem un cas que funciona tot i ser un cas que a bones a primeres un podria pensar que seria lógic que no accertés classificant:

In [51]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/lasagna/1053418.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[51]:

    <matplotlib.image.AxesImage at 0x7f0e1125dad0>

In [52]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 59

## Test global de la Food-101 Fine-Tuning 60k amb la ImageNet¶

Anem a comprovar què passa si contemplem els \(5\) encerts primers quina ràtio conseguim.

In []:

    import datetime

    freadVal = open('/media/9C64D17064D14DA0/TFG/food-101/valComplet.txt','r')
    IMAGE_FILE = ''
    #Verify the last N hits
    Nhits = 5

    hit = [0]*Nhits
    tries = 0
    bol = True

    #Per cada fitxer
    for files in freadVal.readlines():
        #Agafem la seva ruta
        IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/'+str(files.split()[0])
        #Carreguem la imatge i les n channels posteriors
        input_image = caffe.io.load_image(IMAGE_FILE)
        #predim la possible class
        prediction = net.predict([input_image],oversample=False)

        #Contabilitzem els hits

        #Copiem contingut
        lPredict = prediction[0]
        #Ordenem aquesta segona dnarray i la invertim perquè el màxim estigui
        # al principi
        lPredict = np.sort(lPredict)[::-1]
        #Per cada N hits comprovem si coincideix
        # amb el valor de la classe buscada amb la N-essima posició
        for i in xrange(Nhits):
            if lPredict[i] == prediction[0][int(files.split()[1])]:
                hit[i] +=1
                bol = False
                break
        #Debug per veure errors
        if (bol):
            print "\t Imatge "+str(files.split()[0])+" diu "+str(prediction[0].argmax())+" era "+str(files.split()[1])
        bol = True

        tries += 1
        #Cada 100 iteracions fem un print de la situació
        if not tries%50:
            print str(datetime.datetime.now().time())
            for i in xrange(Nhits):
                print "\t Accuracy at "+str(i+1)+" hits: "+str(sum(hit[:(i+1)]))+" of "+str(tries)
    freadVal.close()
    print str(datetime.datetime.now().time())
    for i in xrange(Nhits):
        print "\t Final Accuracy at "+str(i+1)+" hits: "+str(sum(hit[:(i+1)])*100/float(tries))+" %"

La sortida per aquesta execució anterior és:

     Final Accuracy at 1 hits: 45.9100812042 %
     Final Accuracy at 2 hits: 57.4965339671 %
     Final Accuracy at 3 hits: 64.0621905328 %
     Final Accuracy at 4 hits: 68.4690037631 %
     Final Accuracy at 5 hits: 71.7765894236 %

## Visualització resultats Food101 Fine-Tuning 200k mitjançant VeryDeep¶

En aquest cas, la majoria de processos es faran inviables de dur a terme sense GPU perquè només el test d'una imatge ja tardarà més d'un minut si no tenim GPU. És per això que el marge fora d'un ordinador d'aquestes característiques per tractar amb un model d'aquestes dimensions és molt limitat. La majoria de execucions doncs s'han dut a terme amb el mode GPU activat en l'ordinador adequat per aquest càlculs.

In []:

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline

    # Make sure that caffe is on the python path:
    caffe_root = '/usr/local/caffe2/caffe/'  # this file is expected to be in {caffe_root}/examples
    import sys
    sys.path.insert(0, caffe_root + 'python')
    #sys.path.insert(0,'/usr/local/lib/python2.7/dist-packages')

    import caffe

    # Set the right path to your model definition file, pretrained model weights,
    # and the image you would like to classify.
    MODEL_FILE = '/home/jvitria/caffe_data/data/deploy.prototxt'
    PRETRAINED = '/home/ssegui/caffe_data/train_scripts/verydeep/snapshot_iter_200000.caffemodel'

    net = caffe.Classifier(MODEL_FILE, PRETRAINED, channel_swap=(2,1,0), raw_scale=255, image_dims=(227, 227))
    net.set_phase_test()
    net.set_mode_gpu() #Activem el mode GPU

El fitxer solver ha estat configurat de la següent manera:

In [7]:

    %cat '/home/jvitria/caffe_data/train_scripts/verydeep/solver.prototxt'

    net: "train_val.prototxt"
    test_iter: 1000
    test_interval: 1000
    base_lr: 0.0001
    lr_policy: "step"
    gamma: 0.1
    stepsize: 80000
    display: 20
    max_iter: 400000
    momentum: 0.9
    weight_decay: 0.0005
    snapshot: 10000
    snapshot_prefix: "/home/ssegui/caffe_data/train_scripts/verydeep/snapshot"
    solver_mode: GPU

## Test global mitjançant GPU de la Food-101 Fine-Tuning VeryDeep¶

In [15]:

    # Alguns imports sobren
    import os
    from os import listdir
    from os.path import isdir,isfile, join

    f = open('/home/jvitria/caffe_data/data/outputTESTFinal73-20.txt','w')

    import datetime

    freadVal = open('/home/jvitria/caffe_data/data/valComplet.txt','r')
    IMAGE_FILE = ''
    #Verify the last N hits
    Nhits = 20

    hit = [0]*Nhits
    tries = 0
    bol = True

    #Per cada fitxer
    for files in freadVal.readlines():
        #Agafem la seva ruta
        IMAGE_FILE = '/home/jvitria/caffe_data/data/food-101/images/'+str(files.split()[0])
        #Carreguem la imatge i les n channels posteriors
        input_image = caffe.io.load_image(IMAGE_FILE)
        #predim la possible class
        prediction = net.predict([input_image],oversample=False)

        #Contabilitzem els hits

        #Copiem contingut
        lPredict = prediction[0]
        #Ordenem aquesta segona dnarray i la invertim perquè el màxim estigui
        # al principi
        lPredict = np.sort(lPredict)[::-1]
        #Per cada N hits comprovem si coincideix
        # amb el valor de la classe buscada amb la N-essima posició
        for i in xrange(Nhits):
            if lPredict[i] == prediction[0][int(files.split()[1])]:
                hit[i] +=1
                bol = False
                break
        #Debug per veure errors
        if (bol):
            f.write("\n\t Imatge "+str(files.split()[0])+" diu "+str(prediction[0].argmax())+" era "+str(files.split()[1]))
        bol = True

        tries += 1
        #Cada 100 iteracions fem un print de la situació
        if not tries%100:
            for i in xrange(Nhits):
                f.write("\n\t Accuracy firsts "+str(i+1)+" hits: "+str(sum(hit[:(i+1)]))+" of "+str(tries))
                #print "\t Accuracy firsts "+str(i+1)+" hits: "+str(sum(hit[:(i+1)]))+" of "+str(tries)
            print str(datetime.datetime.now().time())
    freadVal.close()
    f.write("\n"+str(datetime.datetime.now().time()))
    print str(datetime.datetime.now().time())
    for i in xrange(Nhits):
        f.write("\n\t Final Accuracy firsts "+str(i+1)+" hits: "+str(sum(hit[:(i+1)])*100/float(tries))+" %")
        print "\t Final Accuracy firsts "+str(i+1)+" hits: "+str(sum(hit[:(i+1)])*100/float(tries))+" %"
    f.close()

    18:32:48.161873
    18:33:09.829562
    18:33:31.478339
    18:33:53.065730
    18:34:15.926634
    18:34:39.009617
    18:35:01.619559
    18:35:24.827457
    18:35:48.135284
    18:36:11.357099
    18:36:34.384483
    18:36:57.313868
    18:37:20.231987
    18:37:43.151452
    18:38:06.047752
    18:38:29.511240
    18:38:52.123235
    18:39:16.561295
    18:39:39.550056
    18:40:02.455684
    18:40:25.773393
    18:40:48.490968
    18:41:11.552121
    18:41:34.664269
    18:41:57.745685
    18:42:20.900855
    18:42:43.971930
    18:43:07.042440
    18:43:30.164733
    18:43:53.286259
    18:44:16.417055
    18:44:39.479600
    18:45:02.646195
    18:45:25.407060
    18:45:48.588763
    18:46:11.520173
    18:46:34.459036
    18:46:57.623232
    18:47:20.412330
    18:47:43.053704
    18:48:05.704477
    18:48:28.247565
    18:48:50.827186
    18:49:13.578703
    18:49:36.685801
    18:49:59.131244
    18:50:21.910562
    18:50:44.659444
    18:51:07.400651
    18:51:30.310234
    18:51:53.312315
    18:52:16.964051
    18:52:39.810515
    18:53:02.427116
    18:53:25.524382
    18:53:48.399508
    18:54:11.266117
    18:54:34.278667
    18:54:56.482048
    18:55:19.660350
    18:55:42.677623
    18:56:05.438151
    18:56:29.220964
    18:56:52.800179
    18:57:16.427631
    18:57:40.198914
    18:58:03.880984
    18:58:27.552841
    18:58:51.211086
    18:59:14.906642
    18:59:38.643070
    19:00:02.336558
    19:00:25.995413
    19:00:49.723467
    19:01:13.366265
    19:01:36.880282
    19:02:00.552707
    19:02:24.258226
    19:02:47.953179
    19:03:11.604462
    19:03:35.303832
    19:03:58.647432
    19:04:22.168534
    19:04:45.769613
    19:05:09.440857
    19:05:33.198067
    19:05:56.847006
    19:06:20.470603
    19:06:43.915176
    19:07:07.467586
    19:07:30.987588
    19:07:54.533249
    19:08:18.078573
    19:08:42.071259
    19:09:05.304119
    19:09:28.058444
    19:09:50.706915
    19:10:13.384236
    19:10:36.130469
    19:10:58.877647
    19:11:21.099231
    	 Final Accuracy firsts 1 hits: 68.0332739156 %
    	 Final Accuracy firsts 2 hits: 78.0352545058 %
    	 Final Accuracy firsts 3 hits: 82.788671024 %
    	 Final Accuracy firsts 4 hits: 85.6110120816 %
    	 Final Accuracy firsts 5 hits: 87.5816993464 %
    	 Final Accuracy firsts 6 hits: 89.027530204 %
    	 Final Accuracy firsts 7 hits: 90.1663695781 %
    	 Final Accuracy firsts 8 hits: 91.0972469796 %
    	 Final Accuracy firsts 9 hits: 92.0083184789 %
    	 Final Accuracy firsts 10 hits: 92.6223014458 %
    	 Final Accuracy firsts 11 hits: 93.2263814617 %
    	 Final Accuracy firsts 12 hits: 93.6918201624 %
    	 Final Accuracy firsts 13 hits: 94.1968706675 %
    	 Final Accuracy firsts 14 hits: 94.6524064171 %
    	 Final Accuracy firsts 15 hits: 95.0386215092 %
    	 Final Accuracy firsts 16 hits: 95.4347395524 %
    	 Final Accuracy firsts 17 hits: 95.8011487423 %
    	 Final Accuracy firsts 18 hits: 96.0487225193 %
    	 Final Accuracy firsts 19 hits: 96.2071697366 %
    	 Final Accuracy firsts 20 hits: 96.4250346603 %

## Visualitació resultats Food-101 Fine-Tuning VeryDeep¶

Observem el poc temps que tarda l'execució quan realitzem el procés mitjançant GPU

In [12]:

    import datetime
    print str(datetime.datetime.now().time())
    IMAGE_FILE = '/home/jvitria/caffe_data/data/food-101/images/nachos/103312.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    prediction = net.predict([input_image],oversample=False)
    print str(datetime.datetime.now().time())

    17:35:52.387343
    17:35:52.808245

La classe dels \(nachos\) és la número \(66\) i efectivament encerta:

In [36]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/nachos/103312.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[36]:

    <matplotlib.image.AxesImage at 0x7f0e117562d0>

In [13]:

    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 66

Provem la classificació impossible a veure com ha variat el resultat i veiem que la resposta és la classse \(74\) que correspon al ànec Peking.

In [44]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/pizza/1407753.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[44]:

    <matplotlib.image.AxesImage at 0x7f0e11506610>

In [45]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 74

Ara anem a observar un exemple no tan exagerat plantejat anteriorment. Veiem però ara fallarà. Això vol dir que el nostre sistema nou classifica pitxor que l'anterior? Per aquest cas, sí. Però, possiblement, el sistema actual classifiqui millor molts altres tipus de plat que són més "característics" de cada una de les classes ja que, en global, la ràtio d'encert s'ha incrementat del 55% al 74%.

In [47]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/lasagna/1053418.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[47]:

    <matplotlib.image.AxesImage at 0x7f0e113fa410>

In [48]:

    prediction = net.predict([input_image])  # predict takes any number of images, and formats them for the Caffe net automatically
    print 'prediction shape:', prediction[0].shape
    plt.plot(prediction[0])
    print 'predicted class:', prediction[0].argmax()

    prediction shape: (101,)
    predicted class: 28

Observem que la segon opció millor és justament la classe \(59\) que correspon a la \(lasagna\). Per tant, té sentit fer allò de donar \(n\) opcions vàlides!

Veiem que la classe que es dispara és la de \(croque\_madame\) (classe \(28\)) on un exemple seria:

In [49]:

    IMAGE_FILE = '/media/9C64D17064D14DA0/TFG/food-101/images/croque_madame/112800.jpg'
    input_image = caffe.io.load_image(IMAGE_FILE)
    plt.imshow(input_image)

Out[49]:

    <matplotlib.image.AxesImage at 0x7f0e114a1fd0>

## Comparació increment ACCURACY i decrement LOSS function¶

### Cas Fine-Tuning ImageNet¶

In [53]:

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    regression=0
    loss,res=[],[]
    with open('Food-101/Food-101-Fine-Tuning-BVLC/Consola.log') as f:
        for line in f:
            index= line.find('accuracy = ')
            if(index>0):
                if(regression):
                    index2= line.find('(*')
                    res.append(float(line[index+11:index2]))
                else:
                    res.append(100.0*float(line[index+11:]))
            index= line.find(', loss = ')
            if(index>0):
                loss.append(float(line[index+9:]))

    fig= plt.figure(figsize=(16,3))
    axes1= fig.add_subplot(1, 2, 1)
    axes2= fig.add_subplot(1, 2, 2)
    #Pintarem les dades recollides, vermella la LOSS, verda l'ACC
    axes1.plot(loss,color='r'),axes2.plot(res,color='g')
    axes1.set_ylim([min(loss),max(loss[1:])]),axes2.set_ylim([0,100]),axes2.set_xlim([0,60])
    axes1.set_title('LOSS'),axes1.set_xlabel('Num Iteracions x 100'),axes1.set_ylabel('Loss')
    axes1.yaxis.grid(),axes1.xaxis.grid()
    axes2.set_title('% ENCERT'),axes2.set_xlabel('Num Iteracions x 1000'),axes2.set_ylabel('% Accuracy')
    axes2.yaxis.grid(),axes2.xaxis.grid()
    fig.show()
    print max(res)

    55.414

    /home/axel/anaconda/lib/python2.7/site-packages/matplotlib/figure.py:371: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure
      "matplotlib is currently using a non-GUI backend, "

### Cas Fine-Tuning VeryDeep¶

In [54]:

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    regression=0
    loss,res=[],[]
    with open('Food-101/Food-101-Fine-Tuning-VD/Consola.log') as f:
        for line in f:
            index= line.find('accuracy = ')
            if(index>0):
                if(regression):
                    index2= line.find('(*')
                    res.append(float(line[index+11:index2]))
                else:
                    res.append(100.0*float(line[index+11:]))
            index= line.find(', loss = ')
            if(index>0):
                loss.append(float(line[index+9:]))

    fig= plt.figure(figsize=(16,3))
    axes1= fig.add_subplot(1, 2, 1)
    axes2= fig.add_subplot(1, 2, 2)
    #Pintarem les dades recollides, vermella la LOSS, verda l'ACC
    axes1.plot(loss,color='r'),axes2.plot(res,color='g')
    axes1.set_ylim([min(loss),max(loss[1:])]),axes1.set_xlim([0,10000]),axes2.set_ylim([0,100]),axes2.set_xlim([0,200])
    axes1.set_title('LOSS'),axes1.set_xlabel('Num Iteracions x 20'),axes1.set_ylabel('Loss')
    axes1.yaxis.grid(),axes1.xaxis.grid()
    axes2.set_title('% ENCERT'),axes2.set_xlabel('Num Iteracions x 1000'),axes2.set_ylabel('% Accuracy')
    axes2.yaxis.grid(),axes2.xaxis.grid()
    fig.show()
    print max(res)

    74.6834

Concluim doncs veient el resultat que buscàvem. Hem superat l'estat-de-l'art públic que hi havia sobre aquest \(dataset\) des d'un 55.41% a un 74.68%