neural-network regression deep-learning caffe

neural network - ¿Etiquetas de prueba para regresión caffe, flotador no permitido?



neural-network regression (4)

Además de la respuesta de @ Shai anterior, escribí una capa MultiTaskData que admite etiquetas de tipo float .

Su idea principal es almacenar las etiquetas en el campo float_data de Datum , y MultiTaskDataLayer analizará como etiquetas para cualquier número de tareas de acuerdo con el valor de task_num y label_dimension establecido en net.prototxt . Los archivos relacionados incluyen: caffe.proto , multitask_data_layer.hpp/cpp , io.hpp/cpp .

Puede agregar fácilmente esta capa a su propio café y usarla de esta manera (este es un ejemplo para la tarea de aprendizaje de distribución de etiquetas de expresión facial en la que "exp_label" puede ser vectores de tipo flotante como [0.1, 0.1, 0.5, 0.2, 0.1 ] que representa la distribución de probabilidad de expresiones faciales (clase 5).

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 } }

Estoy haciendo regresión usando caffe, y mis archivos test.txt y train.txt son así:

/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

Mi problema es que parece que caffe no permite etiquetas flotantes como 2.0, cuando uso etiquetas flotantes mientras leo, por ejemplo, el archivo ''test.txt'' caffe solo reconoce

un total de 1 imágenes

Cuál está mal.

Pero cuando, por ejemplo, cambio el 2.0 a 2 en el archivo y las siguientes líneas son iguales, caffe ahora da

un total de 2 imágenes

lo que implica que las etiquetas flotantes son responsables del problema.

¿Alguien puede ayudarme aquí? Para resolver este problema, definitivamente necesito usar etiquetas flotantes para la regresión, entonces, ¿alguien sabe sobre una solución o solución para esto? Gracias por adelantado.

EDITAR Para cualquiera que se enfrente a un problema similar, usar caffe para entrenar a Lenet con datos CSV podría ser de ayuda. Gracias a @Shai.


Cuando se usa la capa de entrada del conjunto de datos de imagen (con el backend lmdb o leveldb ) caffe solo admite una etiqueta entera por imagen de entrada.

Si desea hacer una regresión y usar etiquetas de punto flotante, debe intentar usar la capa de datos HDF5. Ver por ejemplo esta pregunta .

En python puedes usar el paquete h5py para crear archivos 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 vez que tenga todos los archivos h5 y los archivos de prueba correspondientes que los enumeran, puede agregar una capa de entrada HDF5 a su 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 } }

Aclaracion :
Cuando digo "caffe solo admite una etiqueta entera por imagen de entrada" no quiero decir que los contenedores leveldb / lmdb son limitados, me refiero a las herramientas de caffe, específicamente la herramienta convert_imageset .
En una inspección más cercana, parece que caffe almacena datos de tipo Datum en leveldb / lmdb y la propiedad "label" de este tipo se define como un entero (ver caffe.proto ), por lo tanto, cuando se usa la interfaz de caffe para leveldb / lmdb, está restringido a un sola etiqueta int32 por imagen.


Terminé transponiendo, cambiando el orden de los canales y usando entradas sin firmar en lugar de flotantes para obtener resultados. Sugiero leer una imagen desde su archivo HDF5 para asegurarse de que se muestre correctamente.

Primero lea la imagen como ints sin firmar:

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

Luego cambie el orden de los canales de RGB a BGR:

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

Finalmente, cambie de Altura x Ancho x Canales a Canales x Altura x Ancho:

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

¡Simplemente cambiar la forma revuelve su imagen y arruina sus datos!

Para volver a leer la imagen:

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()

Aquí hay un script que escribí que trata con dos etiquetas (dirección y velocidad) para una tarea de auto sin conductor: https://gist.github.com/crizCraig/aa46105d34349543582b177ae79f32f0


La respuesta de Shai ya cubre guardar etiquetas flotantes en formato HDF5. En caso de que se requiera / prefiera LMDB, aquí hay un fragmento sobre cómo crear un LMDB a partir de datos flotantes (adaptado de this comentario de 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()