Etichette di prova per caffe ‘di regressione, galleggiante non permesso?

Sto facendo una regressione usando caffe, e i miei file test.txt e train.txt sono così:

 /home/foo/caffe/data/finetune/flickr/3860781056.jpg 2.0 /home/foo/caffe/data/finetune/flickr/4559004485.jpg 3.6 /home/foo/caffe/data/finetune/flickr/3208038920.jpg 3.2 /home/foo/caffe/data/finetune/flickr/6170430622.jpg 4.0 /home/foo/caffe/data/finetune/flickr/7508671542.jpg 2.7272 

Il mio problema è che sembra che caffe non permetta etichette fluttuanti come la 2.0, quando uso le etichette float durante la lettura, ad esempio il file 'test.txt' riconosce solo caffe

un totale di 1 immagini

che è sbagliato.

Ma quando per esempio cambio il 2.0 a 2 nel file e le linee seguenti sono uguali, ora dà caffe

un totale di 2 immagini

implicando che le etichette float sono responsabili per il problema.

Qualcuno può aiutarmi qui, per risolvere questo problema, ho sicuramente bisogno di usare le etichette float per la regressione, quindi qualcuno sa di un lavoro o di una soluzione per questo? Grazie in anticipo.

MODIFICA Per chiunque si trovi ad affrontare un problema simile, usare caffe per addestrare Lenet con i dati CSV potrebbe essere di aiuto. Grazie a @Shai.

Quando si utilizza il livello di input del set di dati dell’immagine (con back leveldb end lmdb o leveldb ), caffe supporta solo un’etichetta intera per immagine di input.

Se si desidera eseguire la regressione e utilizzare le etichette in virgola mobile, è necessario provare e utilizzare il livello dati HDF5. Vedi ad esempio questa domanda .

In python puoi usare il pacchetto h5py per creare file hdf5.

 import h5py, os import caffe import numpy as np SIZE = 224 # fixed size to all images with open( 'train.txt', 'r' ) as T : lines = T.readlines() # If you do not have enough memory split data into # multiple batches and generate multiple separate h5 files X = np.zeros( (len(lines), 3, SIZE, SIZE), dtype='f4' ) y = np.zeros( (len(lines),1), dtype='f4' ) for i,l in enumerate(lines): sp = l.split(' ') img = caffe.io.load_image( sp[0] ) img = caffe.io.resize( img, (SIZE, SIZE, 3) ) # resize to fixed size # you may apply other input transformations here... # Note that the transformation should take img from size-by-size-by-3 and transpose it to 3-by-size-by-size # for example # transposed_img = img.transpose((2,0,1))[::-1,:,:] # RGB->BGR X[i] = transposed_img y[i] = float(sp[1]) with h5py.File('train.h5','w') as H: H.create_dataset( 'X', data=X ) # note the name X given to the dataset! H.create_dataset( 'y', data=y ) # note the name y given to the dataset! with open('train_h5_list.txt','w') as L: L.write( 'train.h5' ) # list all h5 files you are going to use 

Una volta che hai tutti i file h5 e i file di test corrispondenti che li elencano puoi aggiungere un layer di input HDF5 al tuo train_val.prototxt :

  layer { type: "HDF5Data" top: "X" # same name as given in create_dataset! top: "y" hdf5_data_param { source: "train_h5_list.txt" # do not give the h5 files directly, but the list. batch_size: 32 } include { phase:TRAIN } } 

Chiarimento :
Quando dico “caffe supporta solo un’etichetta intera per immagine di input” non intendo che i contenitori leveldb / lmdb siano limitati, intendevo gli strumenti di caffe, in particolare lo strumento convert_imageset .
Ad un esame più attento, sembra che il caffe memorizzi i dati di tipo Datum in leveldb / lmdb e la proprietà “label” di questo tipo sia definita come intero (vedi caffe.proto ), quindi quando si utilizza l’interfaccia caffe su leveldb / lmdb si è limitati a un etichetta int32 singola per immagine.

La risposta di Shai copre già il salvataggio delle etichette flottanti nel formato HDF5. Nel caso in cui LMDB sia richiesto / preferito, ecco uno snippet su come creare un LMDB dai dati float (adattato da questo commento github):

 import lmdb import caffe def scalars_to_lmdb(scalars, path_dst): db = lmdb.open(path_dst, map_size=int(1e12)) with db.begin(write=True) as in_txn: for idx, x in enumerate(scalars): content_field = np.array([x]) # get shape (1,1,1) content_field = np.expand_dims(content_field, axis=0) content_field = np.expand_dims(content_field, axis=0) content_field = content_field.astype(float) dat = caffe.io.array_to_datum(content_field) in_txn.put('{:0>10d}'.format(idx) dat.SerializeToString()) db.close() 

Ho finito per trasporre, cambiare l’ordine dei canali e usare valori non firmati anziché float per ottenere risultati. Suggerisco di leggere un’immagine dal file HDF5 per assicurarmi che venga visualizzata correttamente.

Prima leggi l’immagine come unsigned ints:

img = np.array(Image.open('images/' + image_name))

Quindi cambia l’ordine dei canali da RGB a BGR:

img = img[:, :, ::-1]

Infine, passa da Altezza x Larghezza x Canali a Canali x Altezza x Larghezza:

img = img.transpose((2, 0, 1))

Semplicemente cambiando la forma si rimescola la tua immagine e si rovinano i tuoi dati!

Per leggere l’immagine:

 with h5py.File(h5_filename, 'r') as hf: images_test = hf.get('images') targets_test = hf.get('targets') for i, img in enumerate(images_test): print(targets_test[i]) from skimage.viewer import ImageViewer viewer = ImageViewer(img.reshape(SIZE, SIZE, 3)) viewer.show() 

Ecco una sceneggiatura che ho scritto che si occupa di due etichette (sterzo e velocità) per un’attività auto-guida: https://gist.github.com/crizCraig/aa46105d34349543582b177ae79f32f0

Oltre alla risposta di @ Shai sopra, ho scritto un layer MultiTaskData che supporta etichette tipizzate float .

L’idea principale è quella di memorizzare le etichette nel campo float_data di Datum e il MultiTaskDataLayer le MultiTaskDataLayer come etichette per qualsiasi numero di attività in base al valore di task_num e label_dimension impostato in net.prototxt . I file correlati includono: caffe.proto , multitask_data_layer.hpp/cpp , io.hpp/cpp .

È ansible aggiungere facilmente questo livello al proprio caffè e utilizzarlo in questo modo (questo è un esempio per l’attività di apprendimento della distribuzione dell’etichetta di espressioni facciali in cui “exp_label” può essere vettori float tipizzati come [0.1, 0.1, 0.5, 0.2, 0.1 ] che rappresenta la distribuzione di probabilità di espressioni facciali (5 classi).):

  name: "xxxNet" layer { name: "xxx" type: "MultiTaskData" top: "data" top: "exp_label" data_param { source: "expression_ld_train_leveldb" batch_size: 60 task_num: 1 label_dimension: 8 } transform_param { scale: 0.00390625 crop_size: 60 mirror: true } include:{ phase: TRAIN } } layer { name: "exp_prob" type: "InnerProduct" bottom: "data" top: "exp_prob" param { lr_mult: 1 decay_mult: 1 } param { lr_mult: 2 decay_mult: 0 } inner_product_param { num_output: 8 weight_filler { type: "xavier" } bias_filler { type: "constant" } } } layer { name: "exp_loss" type: "EuclideanLoss" bottom: "exp_prob" bottom: "exp_label" top: "exp_loss" include:{ phase: TRAIN } }