我正在实施Viola Jones算法进行人脸检测。我在算法的AdaBoost学习部分的第一部分遇到了问题。
原始论文陈述
弱分类器选择算法如下进行。对于每个要素,示例都根据要素值进行排序。
我目前正在使用相对较小的2000张正面图像和1000张负面图像。该论文描述了数据集大到10,000。
AdaBoost的主要目的是减少24x24窗口中的功能数量,总计160,000+。该算法适用于这些功能并选择最佳功能。
本文描述了对于每个特征,它计算每个图像的值,然后根据值对它们进行排序。这意味着我需要为每个特征制作一个容器并存储所有样本的值。
我的问题是我的程序在仅评估了10,000个功能(仅占其中的6%)后内存不足。所有容器的总体尺寸最终将达到160,000 * 3000,达到数十亿。如何在不耗尽内存的情况下实现此算法?我已经增加了堆大小,它让我从3%增加到6%,我认为增加它不会更有效。
本文暗示整个算法需要这些排序值,因此我不能在每个特征后丢弃它们。
到目前为止,这是我的代码
public static List<WeakClassifier> train(List<Image> positiveSamples, List<Image> negativeSamples, List<Feature> allFeatures, int T) {
List<WeakClassifier> solution = new LinkedList<WeakClassifier>();
// Initialize Weights for each sample, whether positive or negative
float[] positiveWeights = new float[positiveSamples.size()];
float[] negativeWeights = new float[negativeSamples.size()];
float initialPositiveWeight = 0.5f / positiveWeights.length;
float initialNegativeWeight = 0.5f / negativeWeights.length;
for (int i = 0; i < positiveWeights.length; ++i) {
positiveWeights[i] = initialPositiveWeight;
}
for (int i = 0; i < negativeWeights.length; ++i) {
negativeWeights[i] = initialNegativeWeight;
}
// Each feature's value for each image
List<List<FeatureValue>> featureValues = new LinkedList<List<FeatureValue>>();
// For each feature get the values for each image, and sort them based off the value
for (Feature feature : allFeatures) {
List<FeatureValue> thisFeaturesValues = new LinkedList<FeatureValue>();
int index = 0;
for (Image positive : positiveSamples) {
int value = positive.applyFeature(feature);
thisFeaturesValues.add(new FeatureValue(index, value, true));
++index;
}
index = 0;
for (Image negative : negativeSamples) {
int value = negative.applyFeature(feature);
thisFeaturesValues.add(new FeatureValue(index, value, false));
++index;
}
Collections.sort(thisFeaturesValues);
// Add this feature to the list
featureValues.add(thisFeaturesValues);
++currentFeature;
}
... rest of code
答案 0 :(得分:1)
这应该是选择其中一个弱分类器的伪代码:
normalize the per-example weights // one float per example
for feature j from 1 to 45,396:
// Training a weak classifier based on feature j.
- Extract the feature's response from each training image (1 float per example)
// This threshold selection and error computation is where sorting the examples
// by feature response comes in.
- Choose a threshold to best separate the positive from negative examples
- Record the threshold and weighted error for this weak classifier
choose the best feature j and threshold (lowest error)
update the per-example weights
您无需存储数十亿个功能。只需在每次迭代时即时提取特征响应。您使用的是积分图像,因此提取速度很快。这是主要的内存瓶颈,并不是那么多,每个图像中每个像素只有一个整数...基本上与您所需图像的存储量相同。
即使您只计算了所有图像的所有特征响应并将它们全部保存,因此您不必每次迭代都这样做,但仍然只有:
基本上,即使您 存储所有功能值,也不应该耗尽内存。