如何训练libsvm格式的图像(像素)数据用于Java识别

时间:2013-07-16 02:02:45

标签: java machine-learning classification svm libsvm

我想让一个Java应用程序通过使用libsvm来识别字符但是当我进入这个时,我不明白如何训练图像数据与libsvm一起使用?

最近要学习它,我用existing data:

进行了测试

我还通过将每个像素转换为32x32来创建基于0,1的训练图像数据,但我不知道它是否可以用于创建libsvm训练数据格式? 以及libsvm测试数据是如何创建的?

转换后的图片像素示例(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

如何获取libsvm (training, testing data)

1 个答案:

答案 0 :(得分:6)

libsvm具有特定的数据格式,每行都是

形式的一个训练/测试向量
  

LABEL INDEX0:VALUE0 INDEX1:VALUE1 ... INDEXN:VALUEN

所以在最“天真”的方法中,你只需通过连接连续的行将矩阵表示转换为行表示,所以像

这样的图像
010
011
000

会变成

010011000

以libsvm格式(假设我们用“5”标记):

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

由于libsvm支持“稀疏”表示,您可以使用“0”来省略值

5 1:1 4:1 5:1 

这是一种手动方式,示例数据位于此处:http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/binary/a1a

最简单的“自动”方式是将您的数据表示为.csv格式(再次 - 将数据转换为行状格式,然后转换为.csv),这是非常标准的方法:

  

LABEL,PIXEL_0,PIXEL_1,...,PIXEL_N

...

然后使用此程序进行转换

/* 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;
}

培训和测试文件都具有完全相同的结构,只需将您的数据以一定比例(3:1或9:1)随机分成文件trainingtesting,但请记住包括平衡每个文件中每个类的训练向量数。

特别是 - 您的数据看起来有点像 MNIST 数据集,如果是这种情况,这已经为libsvm准备了:

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

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

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

如果可以使用您的数据,将图像转换为[0,1]间隔中的实值图像将比二进制数据(丢失大量信息)更有价值。

修改

例如,如果您的图像是8位灰度图像,那么每个像素实际上是0到255之间的数字v。您现在正在做的是一些阈值处理,为{{1设置1 } {0}表示v > T,而将这些值映射到实际值会为模型提供更多信息。可以通过简单压缩v <= T来完成。因此,所有值都在v / 255区间内,但也包含“介于...之间”的值,如[0,1]等。