2016-04-28 37 views
5

Ho un problema con una classificazione delle immagini nel caffè. Uso il modello imagenet (dal tutorial di caffe) per la classificazione dei dati che ho creato, ma ottengo sempre lo stesso risultato di classificazione (stessa classe, ad esempio classe 3). Questo è il modo di procedere:La classificazione delle immagini in Caffe restituisce sempre la stessa classe

io uso caffe per finestre e Python come interfaccia

(1) I raccogliere i dati. Le mie immagini di esempio (formazione & test) sono immagini che hanno una dimensione di 5x5x3 (RGB) uint8, quindi i suoi valori di pixel arrivano da 0-255.
(2) li ridimensiono alla dimensione richiesta dall'imagenet: 256x256x3. Pertanto utilizzo la funzione di ridimensionamento in MATLAB (interpolazione più vicina).
(3) Creo un LevelDB e un image_mean.
(4) Allinea la mia rete (3000 iterazioni). Gli unici parametri IVariazione la definizione IMAGEnet è il percorso dell'immagine media e la LevelDBs.The risultati ottengo:

I0428 12:38:04.350100 3236 solver.cpp:245]  Train net output #0: loss = 1.91102 (* 1 = 1.91102 loss) 
I0428 12:38:04.350100 3236 sgd_solver.cpp:106] Iteration 2900, lr = 0.0001 
I0428 12:38:30.353361 3236 solver.cpp:229] Iteration 2920, loss = 2.18008 
I0428 12:38:30.353361 3236 solver.cpp:245]  Train net output #0: loss = 2.18008 (* 1 = 2.18008 loss) 
I0428 12:38:30.353361 3236 sgd_solver.cpp:106] Iteration 2920, lr = 0.0001 
I0428 12:38:56.351630 3236 solver.cpp:229] Iteration 2940, loss = 1.90925 
I0428 12:38:56.351630 3236 solver.cpp:245]  Train net output #0: loss = 1.90925 (* 1 = 1.90925 loss) 
I0428 12:38:56.351630 3236 sgd_solver.cpp:106] Iteration 2940, lr = 0.0001 
I0428 12:39:22.341891 3236 solver.cpp:229] Iteration 2960, loss = 1.98917 
I0428 12:39:22.341891 3236 solver.cpp:245]  Train net output #0: loss = 1.98917 (* 1 = 1.98917 loss) 
I0428 12:39:22.341891 3236 sgd_solver.cpp:106] Iteration 2960, lr = 0.0001 
I0428 12:39:48.334151 3236 solver.cpp:229] Iteration 2980, loss = 2.45919 
I0428 12:39:48.334151 3236 solver.cpp:245]  Train net output #0: loss = 2.45919 (* 1 = 2.45919 loss) 
I0428 12:39:48.334151 3236 sgd_solver.cpp:106] Iteration 2980, lr = 0.0001 
I0428 12:40:13.040398 3236 solver.cpp:456] Snapshotting to binary proto file Z:/DeepLearning/S1S2/Stockholm/models_iter_3000.caffemodel 
I0428 12:40:15.080418 3236 sgd_solver.cpp:273] Snapshotting solver state to binary proto file Z:/DeepLearning/S1S2/Stockholm/models_iter_3000.solverstate 
I0428 12:40:15.820426 3236 solver.cpp:318] Iteration 3000, loss = 2.08741 
I0428 12:40:15.820426 3236 solver.cpp:338] Iteration 3000, Testing net (#0) 
I0428 12:41:50.398375 3236 solver.cpp:406]  Test net output #0: accuracy = 0.11914 
I0428 12:41:50.398375 3236 solver.cpp:406]  Test net output #1: loss = 2.71476 (* 1 = 2.71476 loss) 
I0428 12:41:50.398375 3236 solver.cpp:323] Optimization Done. 
I0428 12:41:50.398375 3236 caffe.cpp:222] Optimization Done. 

(5) corro seguente codice in Python per classificare una singola immagine:

# set up Python environment: numpy for numerical routines, and matplotlib for plotting 
import numpy as np 
import matplotlib.pyplot as plt 
# display plots in this notebook 


# set display defaults 
plt.rcParams['figure.figsize'] = (10, 10)  # large images 
plt.rcParams['image.interpolation'] = 'nearest' # don't interpolate: show square pixels 
plt.rcParams['image.cmap'] = 'gray' # use grayscale output rather than a (potentially misleading) color heatmap 

# The caffe module needs to be on the Python path; 
# we'll add it here explicitly. 
import sys 
caffe_root = '../' # this file should be run from {caffe_root}/examples (otherwise change this line) 
sys.path.insert(0, caffe_root + 'python') 

import caffe 
# If you get "No module named _caffe", either you have not built pycaffe or you have the wrong path. 


caffe.set_mode_cpu() 

model_def = 'C:/Caffe/caffe-windows-master/models/bvlc_reference_caffenet/deploy.prototxt' 
model_weights = 'Z:/DeepLearning/S1S2/Stockholm/models_iter_3000.caffemodel' 

net = caffe.Net(model_def,  # defines the structure of the model 
       model_weights, # contains the trained weights 
       caffe.TEST)  # use test mode (e.g., don't perform dropout) 

#load mean image file and convert it to a .npy file-------------------------------- 
blob = caffe.proto.caffe_pb2.BlobProto() 
data = open('Z:/DeepLearning/S1S2/Stockholm/S1S2train256.binaryproto',"rb").read() 
blob.ParseFromString(data) 
nparray = caffe.io.blobproto_to_array(blob) 
f = file('Z:/DeepLearning/PythonCalssification/imgmean.npy',"wb") 
np.save(f,nparray) 

f.close() 


# load the mean ImageNet image (as distributed with Caffe) for subtraction 
mu1 = np.load('Z:/DeepLearning/PythonCalssification/imgmean.npy') 
mu1 = mu1.squeeze() 
mu = mu1.mean(1).mean(1) # average over pixels to obtain the mean (BGR) pixel values 
print 'mean-subtracted values:', zip('BGR', mu) 
print 'mean shape: ',mu1.shape 
print 'data shape: ',net.blobs['data'].data.shape 

# create transformer for the input called 'data' 
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) 

# set the size of the input (we can skip this if we're happy 

transformer.set_transpose('data', (2,0,1)) # move image channels to outermost dimension 
transformer.set_mean('data', mu)   # subtract the dataset-mean value in each channel 
transformer.set_raw_scale('data', 255)  # rescale from [0, 1] to [0, 255] 
transformer.set_channel_swap('data', (2,1,0)) # swap channels from RGB to BGR 

# set the size of the input (we can skip this if we're happy 
# with the default; we can also change it later, e.g., for different batch sizes) 
net.blobs['data'].reshape(50,  # batch size 
          3,   # 3-channel (BGR) images 
          227, 227) # image size is 227x227 

#load image 
image = caffe.io.load_image('Z:/DeepLearning/PythonCalssification/380.tiff') 
transformed_image = transformer.preprocess('data', image) 
#plt.imshow(image) 

# copy the image data into the memory allocated for the net 
net.blobs['data'].data[...] = transformed_image 

### perform classification 
output = net.forward() 

output_prob = output['prob'][0] # the output probability vector for the first image in the batch 

print 'predicted class is:', output_prob.argmax() 

Non importa quale immagine di input io utilizzo, ottengo sempre la classe "3" come risultato della classificazione. Ecco un'immagine di esempio I treno/classificazione:
enter image description here
Sarei molto felice se qualcuno ha un'idea di cosa c'è che non va? Grazie in anticipo!

+0

Quanti dati stai utilizzando? Quante classi ed esempi per classe? –

risposta

2

Se si ottiene sempre la stessa classe, significa che NN non è stato adeguatamente formato.

  • Assicurarsi che il set di allenamento sia bilanciato. Quando un classificatore predice sempre la stessa classe, spesso perché una classe è sovra rappresentata secondo le altre. Ad esempio, supponiamo che tu abbia due classi, la prima rappresentata da 95 istanze e la seconda da 5. Se il classificatore classifica tutto come appartenente alla prima classe, allora ha già ragione al 95%.
  • Una cosa ovvia è che è necessario normalizzare gli ingressi image/255.0 - 0.5, centrerà l'input e diminuirà la deviazione standard.
  • Dopo, assicurarsi di avere almeno 4 volte più dati nel set di allenamento in cui si hanno pesi in NN.
  • Ultimo ma non meno importante, assicurarsi che il set di allenamento sia correttamente mischiato.
+0

Proverò a seguire passo passo i tuoi suggerimenti: 1) Ho 8 classi. Sono rappresentati da seguenti dimensioni dei campioni: Classe 1: 918 classe 2: 897 classe 3: 922 classe 4: 799 classe 5:69 classe 6: 277 classe 7: 718 classe 8: 691 –

+0

2) Per quanto mi riguarda, Imagenet richiede una normalizzazione dell'immagine che utilizza la media immagine/pixel. Pertanto i seguenti passaggi sono eseguiti nel codice Python sopra: transformer.set_transpose ('data', (2,0,1)) # sposta i canali immagine nella dimensione più esterna transformer.set_mean ('data', mu) # sottrarre il valore medio del set di dati in ogni trasformatore del canale .set_raw_scale ('data', 255) # riscalata da [0, 1] a [0, 255] transformer.set_channel_swap ('data', (2,1,0)) # scambia canali da RGB a BGR. –

+0

In questa procedura viene sottratta la media dell'immagine, l'immagine viene ridimensionata a 0-255, i canali vengono commutati poiché vengono caricati nell'ordine inverso, infine, l'operazione di trasposizione viene eseguita (non sono sicuro al 100% perché questo sia necessario però) –