5

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

最近为了学习它,我用现有的数据做了一个测试:

我还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)

4

1 回答 1

6

libsvm具有特定的数据格式,每一行都是一个训练/测试向量,形式为

标签 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),这是一种非常标准的方法:

标签,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 位灰度图像,那么每个像素实际上是v0 到 255 之间的数字。您现在正在做的是一些阈值处理,将 1 设置为 1v > T并将 0 设置为v <= T,同时将这些值映射到实际值将为模型提供更多信息。可以通过简单的挤压来完成v / 255。结果,所有值都在[0,1]区间内,但也有“介于”之间的值,例如0.25等。

于 2013-08-14T06:04:11.563 回答