- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 OpenCV SVM 实现来二进制预测图像特征的重要性。因此,我正在根据正面和负面图像特征对其进行训练,并在 {0,1} 中寻找分类。
我遇到的问题是,在训练之后,SVM 总是预测具有更高/更大类别标签的类别。我可以更改训练数据集的标签,但这个问题仍然存在。我仔细检查了生成的标签和训练的 cv::Mat 矩阵,没有发现任何问题。
下面是我的 SVM 类和附带的 SVM 参数
//Populate the SVM parameters
void SVM::setSVMParams()
{
params.svm_type = cv::SVM::C_SVC;
params.kernel_type = cv::SVM::RBF;
params.term_crit = cv::TermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
params_set = true;
}
//Train the SVM with the given data
void SVM::train(cv::Mat train_data, cv::Mat labels)
{
//Set the SVM parameters if they haven't been already
if (!params_set)
{
setSVMParams();
}
svm.train(train_data, labels, cv::Mat(), cv::Mat(), params);
}
//Based on training, predict the class of the given data
float SVM::predict(cv::Mat sample)
{
return svm.predict(sample, false);
}
这里是负责生成训练数据和相应标签的函数
//Creates the appropriate training data and class labels for subsequent SVM training according to supplied D threshold
void Matchings::createSVMTrainingObjects(const float t_D, const float positive_label, const float negative_label, bool print_info)
{
cv::Mat train_data_l((int)matchings_list.size(), 132, CV_32FC1);
cv::Mat labels_l((int)matchings_list.size(), 1, CV_32FC1);
int num_pos = 0;
int num_neg = 0;
for (int i = 0; i < matchings_list.size(); i++)
{
matching_d entry = matchings_list[i];
//Important feature, label 1
if (entry.D > t_D)
{
labels_l.at<float>(i) = positive_label;
num_pos++;
}
//Unimportant feature, label -1
else
{
labels_l.at<float>(i) = negative_label;
num_neg++;
}
int j = 0;
//Copy feature into current row of openCV matrix
train_data_l.at<float>(i, j++) = entry.feature.x;
train_data_l.at<float>(i, j++) = entry.feature.y;
train_data_l.at<float>(i, j++) = entry.feature.scale;
train_data_l.at<float>(i, j++) = entry.feature.angle;
for (int k = 0; k < 128; k++)
{
train_data_l.at<float>(i, j + k) = entry.feature.vec[k];
}
}
std::cout << "For training: #+ves=" << num_pos << ", #-ves=" << num_neg << std::endl;
train_data = train_data_l;
labels = labels_l;
}
最后,这里是实际调用 SVM 预测结果以保留重要图像特征的函数
matchingslist ASIFT::filterFeaturesWithSVM(matchingslist matchings, SVM& svm)
{
matchingslist new_matchings;
for (int i = 0; i < (int)matchings.size(); i++)
{
cv::Mat first = Utility::keypointToMat(matchings[i].first);
cv::Mat second = Utility::keypointToMat(matchings[i].second);
//If both features are of importance, retain them
if (svm.predict(first) == 1.0f && svm.predict(second) == 1.0f)
{
new_matchings.push_back(matchings[i]);
}
else
{
std::cout << "Feature removed" << std::endl;
}
}
return new_matchings;
}
最佳答案
该方法的一个主要问题是您在使用 RBF 时没有设置 SVM 的超参数,因此可能 C=1
和 gamma=1/d
(或 1/mean ||x||^2
),因为这些是大多数 SVM 实现中的默认值。
虽然这些对于构建有效模型至关重要。特别是,如果您的 C
值太低(1
可能是,取决于数据的许多特征),那么 SVM 会构建一个简单的模型总是预测其中一个类。
你应该做什么?您应该检查 C
和 gamma
的多个值。这些参数的含义是什么?
C
(您的1
)是错误分类的权重 - C
越大,SVM 将更加努力地准确学习训练数据,可能以过度拟合为代价。gamma
(您的默认值)是 RBF 核的 2 倍方差的倒数。换句话说 - Gamma 越大,高斯越小,因此 - 你的方法在几何意义上更“局部”。同样 - 大 Gamma 可以帮助您最大限度地减少训练误差(偏差),但会导致更高的测试误差(方差)。正确选择方差偏差之间的权衡是机器学习技术的关键要素。在 RBF SVM 的情况下——你可以通过上面的方法来控制它。和他们一起玩,检查训练集错误和测试集错误,看看发生了什么。如果你的训练集错误很大——增加 C 和/或 Gamma 。一旦你的训练集误差没问题,看看测试集——如果它太大——尝试减少值等等。它通常通过一些内部交叉验证和参数的网格搜索以自动方式完成。
查看关于模型选择和超参数优化的资料。
此外你固定迭代次数
params.term_crit = cv::TermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
而对于 SVM,您永远不应该这样做。让它收敛(或者至少放 100,000 之类的东西),在仅仅 100 步之后,SVM 可能甚至没有接近收敛(因此导致了微不足道的模型)。
关于c++ - OpenCV SVM 总是预测更高类别的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33755408/
我有一个 DIV #page,如果我在顶部添加边距,突然出现一个滚动条,即使该元素不大于主体。我怎样才能去掉滚动条? (参见 Fiddle) 我的 HTML I am a div siz
function getClosestValue(standardArray, targetVal) { standardArray = standardArray.sort(function(a,
我有 318x424 的书籍封面图片,我想做的是指定一张图片,并在其下方添加一个文本链接。初始 src 是 about:blank,这样如果响应式设计不显示框架,它就不会占用用户带宽。 框架的 HTM
我被这个问题困了两天了,还是没搞定。 基本上,我有一个二维数组,其中包含某些数字(在给定范围内)之间的关系: 0 = 顺序无关紧要 1 = 第一个数字(左栏中的数字)应该是第一个 2 = 第二个数字(
只有当我在更高的 API 上进行调试时,我才会强制关闭脚本:16,但是当涉及到 API 时它工作正常:10。这可能是我的项目设置问题吗? 这是对服务器的简单请求,以获取 fragment 中的类别列表
给定下表books id | listorder ----+----------- 3 | 1 2 | 2 1 | 3 4 |
我想要那个密码切换功能,好像TextInputLayout有这个功能,而不是 TextInputEditText .但是正如您在下面的代码中看到的,即使我将高度设置为 wrap_content和 ap
似乎从 读取给出空列表,它主要发生在延迟较高的网络上的主机上。是否有更强大的与远程主机交互的方式? use Net::SSH2; # my $ssh = Net::SSH2->new(); # ..
为了在 Play 商店中发布我的应用程序,我必须将 TargetSdkVersion 从 23 更改为 26。在我更改它之前,该应用程序运行良好!现在应用程序在启动时崩溃。我想通了,问题出在这两行:
我尝试了很多解决方案,但找不到一个。我有 3 个不同的列,其中包含不同类型的文本,我需要它们具有相同的高度。但它们是这样不同的:colums有人可以帮忙吗? 代码: .col-sm-2{
我尝试将一个 div 相对于其具有负顶值的父级定位。这工作正常,现在的问题是这个 div,即使它有一个负的 top 值也会使父 div 更大。 我该怎么做才能让父 div 不那么大? Here's a
这是一个一般性问题,可能适用于任何给定的语言,如 C、C++、Java 等。 我认为无论以何种方式实现它,都不会比使用 2 个循环更高效,后者的效率为 n^2。 for(i=0;i O(1) ),要么
我需要查找所有有订单的家庭。我根本不关心订单的数据,只关心它的存在。 (使用 SQL Server) 这样说是不是更有效率: SELECT HouseholdID, LastName, FirstNa
我有一个 UINavigationController,在屏幕顶部有一个 UINavigationBar,在底部有一个 UIToolbar。我想让工具栏高一点。这是我的代码: CGRect toolb
我正在使用自定义字体。该字体在我的 Windows PC 上完美运行,但在我的 Mac (Yosemite OSX) 上运行不佳。正如您在图片中看到的,Mac 上的字体比 Windows 上的字体稍大
我正在尝试使用 FaSTLane 将我的应用程序作为 alpha 版本部署到 Play 商店,但出现此错误: Google Api 错误:multiApkShadowedActiveApk:任何设备都
我在这里找不到神奇的调味料。看起来 API 不支持它,所以我想我正在寻找一些 CSS 来使 slider 更大。 我得到的是左边的,但我想把它设计成右边的样子?任何 CSS 技巧或以前有人这样做过。
如果我运行这段代码: float a=1.123456789; printf("The float value is %f\n",a); double b=1.123456789876543 prin
我正在尝试使用 strip binary 来剥离我的目标文件。我在 gcc-7 上构建了最新的 binutils,但我的代码库使用 gcc-4.9.2。Binutils 是为 64 位架构构建的,我的
有没有办法让 iPhone 应用的“内容”区域感知到更大的导航栏? 类似这些问题: iOS: Adding a fixed image just below the navigation bar iO
我是一名优秀的程序员,十分优秀!