如何将图像(像素)数据训练成libsvm格式以便在Java中用于识别

我想制作一个Java应用程序来识别字符,使用libsvm,但当我开始研究时,我不明白如何将图像数据训练成libsvm可以使用的格式?

最近为了学习,我使用现有数据进行了一次测试:

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

转换后的图像像素(0,1)示例:

0000000000000111100000000000000000000000000011111110000000000000000000000011111111110000000000000000000111111111111110000000000000000001111111011111100000000000000000111111100000111100000000000000001111111000000011100000000000000011111110000000111100000000000000111111100000000111000000000000001111111000000001110000000000000011111100000000011110000000000000111111000000000011100000000000001111110000000000111000000000000001111110000000000111000000000000011111100000000001110000000000000111111000000000011100000000000001111110000000000111000000000000111111100000000011110000000000001111011000000000111100000000000011110000000000011110000000000000011110000000000011110000000000000111100000000001111100000000000001111000000000111110000000000000011110000000011111000000000000000011100000011111100000000000000000111100011111110000000000000000001111111111111100000000000000000001111111111111000000000000000000011111111111100000000000000000000011111111100000000000000000000000011111000000000000000000000000000011000000000000000000 0000000000000011111111100000000000000000000111111111111100000000000000000011111111111111100000000000000000111111111111111000000000000000001111111111111111000000000000001111111111111111100000000000000011111000001111110000000000000000000000000001111100000000000000000000000000011111000000000000000000000000000111110000000000000000000000000011111000000000000000000000000001111110000000000000000000000000011111100000000000000000000000000111111000000000000000000000000011111100000000000000000001111111111111111100000000000000111111111111111111100000000000001111111111111111111000000000000011111111111111111110000000000001111111111111111110000000000000011111111111100000000000000000000111111111111000000000000000000000111111111110000000000000000000000000111110000000000000000000000000001111100000000000000000000000000011111000000000000000000000000001111110000000000000000000000000011111100000000000000000000000001111110000000000000000000000000111111100000000000000000000000000111110000000000000000000000000001111100000000000000000 7

如何将其转换为libsvm (训练、测试数据)格式?


回答:

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

LABEL INDEX0:VALUE0 INDEX1:VALUE1 … INDEXN:VALUEN

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

010011000

将变成

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。你现在所做的,是某种阈值处理,当v > T时设置为1,当v <= T时设置为0,而将这些值映射到实值会为模型提供更多信息。这可以通过简单的压缩v / 255来实现。结果,所有值都在[0,1]区间内,但也包括中间值,如0.25等。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注