2013-07-16 27 views
5

Voglio fare un'applicazione Java per riconoscere i caratteri usando libsvm ma quando ci riesco, non capisco come posso addestrare i dati dell'immagine usare con libsvm?Come addestrare i dati dell'immagine (pixel) in formato libsvm da utilizzare per il riconoscimento con Java

Recentemente per imparare, ho fatto un test con existing data:

Ho anche creare 32x32 basati i dati delle immagini di formazione per convertire ogni pixel per 0,1, ma non so se si potrebbe utilizzare per creare il formato dei dati formazione libsvm ? E anche come sono stati creati i dati di test di libsvm?

Esempio di pixel di immagine convertiti (0,1):

00000000000001111000000000000000 
00000000000011111110000000000000 
00000000001111111111000000000000 
00000001111111111111100000000000 
00000001111111011111100000000000 
00000011111110000011110000000000 
00000011111110000000111000000000 
00000011111110000000111100000000 
00000011111110000000011100000000 
00000011111110000000011100000000 
00000011111100000000011110000000 
00000011111100000000001110000000 
00000011111100000000001110000000 
00000001111110000000000111000000 
00000001111110000000000111000000 
00000001111110000000000111000000 
00000001111110000000000111000000 
00000011111110000000001111000000 
00000011110110000000001111000000 
00000011110000000000011110000000 
00000001111000000000001111000000 
00000001111000000000011111000000 
00000001111000000000111110000000 
00000001111000000001111100000000 
00000000111000000111111000000000 
00000000111100011111110000000000 
00000000111111111111110000000000 
00000000011111111111110000000000 
00000000011111111111100000000000 
00000000001111111110000000000000 
00000000000111110000000000000000 
00000000000011000000000000000000 
0 
00000000000001111111110000000000 
00000000001111111111111000000000 
00000000011111111111111100000000 
00000000011111111111111100000000 
00000000011111111111111110000000 
00000001111111111111111100000000 
00000000111110000011111100000000 
00000000000000000001111100000000 
00000000000000000001111100000000 
00000000000000000001111100000000 
00000000000000000011111000000000 
00000000000000000111111000000000 
00000000000000000111111000000000 
00000000000000000111111000000000 
00000000000000001111110000000000 
00000000011111111111111111000000 
00000000111111111111111111100000 
00000000111111111111111111100000 
00000000111111111111111111100000 
00000001111111111111111110000000 
00000001111111111110000000000000 
00000001111111111110000000000000 
00000000111111111110000000000000 
00000000000011111000000000000000 
00000000000011111000000000000000 
00000000000011111000000000000000 
00000000000111111000000000000000 
00000000000111111000000000000000 
00000000001111110000000000000000 
00000000011111110000000000000000 
00000000001111100000000000000000 
00000000001111100000000000000000 
7 

Come arrivare per libsvm (training, testing data)?

risposta

6

libsvm ha un formato di dati specifico, ogni linea è una formazione/test vettore in forma di

ETICHETTA Indice0: value0 INDEX1: VALUE1 ... INDEXN: valoreN

così nel metodo più "naive", semplicemente convertire rappresentazione matriciale alla rappresentazione fila concatenando righe consequtive, così come immagine

010 
011 
000 

sarebbe diventato

010011000 

e nel formato libsvm (supponendo etichettiamo con "5"):

5 0:0 1:1 2:0 3:0 4:1 5:1 6:0 7:0 8:0 9:0 

come supporto libsvm "sparse" la rappresentazione, è possibile ommit valori con "0 di"

5 1:1 4:1 5:1 

questo è un modo manuale, i dati di esempio si trova qui: http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/binary/a1a

Il modo più semplice "automatico" è quello di rappresentare i dati in un formato .csv (ancora una volta - convertire i dati in formato di riga simile, poi al .csv), che è il metodo abbastanza standard:

ETICHETTA, PIXEL_0, PIXEL_1, ..., PIXEL_N

...

e quindi utilizzare questo programma per la conversione

/* convert cvs data to libsvm/svm-light format */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

char buf[10000000]; 
float feature[100000]; 

int main(int argc, char **argv) 
{ 
    FILE *fp; 

    if(argc!=2) { fprintf(stderr,"Usage %s filename\n",argv[0]); } 
    if((fp=fopen(argv[1],"r"))==NULL) 
    { 
     fprintf(stderr,"Can't open input file %s\n",argv[1]); 
    } 

    while(fscanf(fp,"%[^\n]\n",buf)==1) 
    { 
     int i=0,j; 
     char *p=strtok(buf,","); 

     feature[i++]=atof(p); 

     while((p=strtok(NULL,","))) 
      feature[i++]=atof(p); 

     //  --i; 
     /* 
     if ((int) feature[i]==1) 
      printf("-1 "); 
     else 
      printf("+1 "); 
     */ 
     //  printf("%f ", feature[1]); 
     printf("%d ", (int) feature[0]); 
     for(j=1;j<i;j++) 
      printf(" %d:%f",j,feature[j]); 


     printf("\n"); 
    } 
    return 0; 
} 

entrambi i file di test di formazione e hanno esattamente la stessa struttura , dividi semplicemente i tuoi dati in una proporzione (3: 1 o 9: 1) a caso nei file training e testing, ma ricorda di includere un numero bilanciato di vettori di addestramento per ogni classe in ogni file.

In particolare - i dati sembra un po 'come MNIST set di dati, se si tratta di un caso, questo è già predisposta per libsvm:

http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass.html

formazione MNIST: http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/mnist.scale.bz2

test MNIST : http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/mnist.scale.t.bz2

Se possibile con i tuoi dati, convertire le tue immagini in valori reali nell'intervallo [0,1] val sarebbe più prezioso dei dati binari (che perde molte informazioni).

EDIT

Per fare un esempio, se l'immagine è un'immagine 8bit in scala di grigi, ogni pixel è in realtà un numero v tra 0 e 255. Quello che state facendo ora, è un po 'della soglia, impostazione 1 per v > T e 0 per v <= T, mentre la mappatura di questi valori su valori reali fornirebbe ulteriori informazioni al modello. Può essere fatto semplicemente schiacciando v/255. Di conseguenza, tutti i valori sono nell'intervallo [0,1], ma hanno anche valori "intermedi" come 0.25 ecc.

+0

Quale dovrebbe essere il metodo per "convertire le immagini in valori reali in [0,1] " & Come? – Osify

+0

Aggiornamento della risposta, voglio semplicemente dire di non mappare v -> {0,1} ma piuttosto dell'intero intervallo [0,1], ad esempio - dividendo i valori dei pixel originali (0-255 in caso di immagine a 8 bit) di il 255. – lejlot

+0

Grazie, ci proverò in giro per vedere se sarebbe OK per libsvm – Osify