调整 vlfeat SVM
Tuning vlfeat SVM
我有 6 个 1 个暗淡数据样本作为示例,我正在尝试在其上训练 vlfeat 的 SVM:
data:
[188.00000000;
168.00000000;
191.00000000;
150.00000000;
154.00000000;
124.00000000]
前 3 个样本为阳性,后 3 个样本为阴性。
我得到权重(包括偏差):
w: -0.6220197226 -0.0002974511
问题是所有样本都被预测为负样本,但它们显然是线性可分的。
为了学习,我使用求解器类型 VlSvmSolverSgd 和 lambda 0.01。
如果重要的话,我正在使用 C API。
最小工作示例:
void vlfeat_svm_test()
{
vl_size const numData = 6 ;
vl_size const dimension = 1 ;
//double x[dimension * numData] = {188.0,168.0,191.0,150.0, 154.0, 124.0};
double x[dimension * numData] = {188.0/255,168.0/255,191.0/255,150.0/255, 154.0/255, 124.0/255};
double y[numData] = {1, 1, 1, -1, -1, -1} ;
double lambda = 0.01;
VlSvm *svm = vl_svm_new(VlSvmSolverSgd, x, dimension, numData, y, lambda);
vl_svm_train(svm);
double const * w= vl_svm_get_model(svm);
double bias= vl_svm_get_bias(svm);
for(int k=0;k<numData;++k)
{
double res= 0.0;
for(int i=0;i<dimension;++i)
{
res+= x[k*dimension+i]*w[i];
}
int pred= ((res+bias)>0)?1:-1;
cout<< pred <<endl;
}
cout << "w: ";
for(int i=0;i<dimension;++i)
cout<< w[i] <<" ";
cout<< bias <<endl;
vl_svm_delete(svm);
}
更新:
我还尝试通过除以 255 来缩放输入数据,但没有效果。
更新二:
极低的 lambda= 0.000001 似乎可以解决问题。
发生这种情况是因为 VLFeat 中的 SVM 求解器不直接估计模型和偏差,而是使用向数据添加常量分量的变通方法(如 http://www.vlfeat.org/api/svm-fundamentals.html 中所述)和 return相应的模型权重作为偏差。
因此,偏差项是正则化器的一部分,具有较高偏差的模型在能量方面是 "penalized"。这种效果在您的情况下特别强烈,因为您的数据维度极低:)
因此,您需要选择较小的正则化参数 LAMBDA 值来降低正则化器的重要性。
我有 6 个 1 个暗淡数据样本作为示例,我正在尝试在其上训练 vlfeat 的 SVM:
data:
[188.00000000;
168.00000000;
191.00000000;
150.00000000;
154.00000000;
124.00000000]
前 3 个样本为阳性,后 3 个样本为阴性。
我得到权重(包括偏差):
w: -0.6220197226 -0.0002974511
问题是所有样本都被预测为负样本,但它们显然是线性可分的。
为了学习,我使用求解器类型 VlSvmSolverSgd 和 lambda 0.01。
如果重要的话,我正在使用 C API。
最小工作示例:
void vlfeat_svm_test()
{
vl_size const numData = 6 ;
vl_size const dimension = 1 ;
//double x[dimension * numData] = {188.0,168.0,191.0,150.0, 154.0, 124.0};
double x[dimension * numData] = {188.0/255,168.0/255,191.0/255,150.0/255, 154.0/255, 124.0/255};
double y[numData] = {1, 1, 1, -1, -1, -1} ;
double lambda = 0.01;
VlSvm *svm = vl_svm_new(VlSvmSolverSgd, x, dimension, numData, y, lambda);
vl_svm_train(svm);
double const * w= vl_svm_get_model(svm);
double bias= vl_svm_get_bias(svm);
for(int k=0;k<numData;++k)
{
double res= 0.0;
for(int i=0;i<dimension;++i)
{
res+= x[k*dimension+i]*w[i];
}
int pred= ((res+bias)>0)?1:-1;
cout<< pred <<endl;
}
cout << "w: ";
for(int i=0;i<dimension;++i)
cout<< w[i] <<" ";
cout<< bias <<endl;
vl_svm_delete(svm);
}
更新:
我还尝试通过除以 255 来缩放输入数据,但没有效果。
更新二:
极低的 lambda= 0.000001 似乎可以解决问题。
发生这种情况是因为 VLFeat 中的 SVM 求解器不直接估计模型和偏差,而是使用向数据添加常量分量的变通方法(如 http://www.vlfeat.org/api/svm-fundamentals.html 中所述)和 return相应的模型权重作为偏差。
因此,偏差项是正则化器的一部分,具有较高偏差的模型在能量方面是 "penalized"。这种效果在您的情况下特别强烈,因为您的数据维度极低:) 因此,您需要选择较小的正则化参数 LAMBDA 值来降低正则化器的重要性。