-
Notifications
You must be signed in to change notification settings - Fork 2k
Error rate for SVM #801
Comments
Hi |
Hi @HadeelHassan, The easiest way to achieve what you want is by adding an extra class in your classification problem to model everything that is not a face (the background). In the same way that you have trained the system for multiple people in your database, add a new category containing only images that do not contain a face. Then, if in the end the SVM says that the class for a given image should be this extra class, you can just conclude it is not a face. Hope it helps, |
@cesarsouza |
@cesarsouza |
interesting... |
@cesarsousa |
Hi @HadeelHassan, Please, may I ask more details about how you are testing this approach? It should really work, at least to some extent. It has been used before in countless other problems and domains. Just to reiterate a little bit: You should be grabing examples of the situation that you are currently testing (not exactly the same data, but the same situation, e.g. similar places, images or videos) that do not contain an human face and add those samples as a separate, but fake, "person" in your dataset of people. This should work as long as you have added enough samples to this "background", or "fake person", category. What has happened after you added those samples? Has the performance decreased? Are "no faces" still being recognized as "faces" in your problem domain? In the worst case, if this do not work for you at all even though you have really tried, you can just use a face detector to filter out faces from no-faces in your images, for example using the HaarObjectDetector class. Hope it helps, |
@cesarsouza |
Oh, now I understand. Well, it might be possible, in practice, to disregard samples that the SVM is not completely confident about. However, here, there are a number of possibilities to achieve what you need. I can suggest two ways:
svm.Method = MulticlassComputeMethod.Voting; Now, you should be able to get probability estimates from the SVMs using svm.Probability(input_image); Using those probabilities, you may be able to filter out samples that the SVMs are not really sure about. For example, if the probability of a given input image is less than 0.5, you may discard it as not belonging from any of the faces in your dataset. However, this may or may not work for your problem, and you might need to find this optimum threshold for your dataset by hand. I would advise trying to build a dataset of faces that do not belong to any person in your dataset like in method 1. You can try to use a face detector to obtain all faces that do not correspond to any of the people currently present in your dataset and use those to try to learn the "fake person" class I had mentioned above. Hope it helps, |
@cesarsouza
Where should i put |
hi, here's what I got with Accord_3.4.0 I hope to get answers from you if my test are higher than yours? thank you |
@blaisexen |
@cesarsouza |
Hi Hadeel, Let's say you used the .Decide function to determine to which class a face belongs. That's how you are doing right now, right? So, after you have called the .Decide function, call also the .Probability function. This should give you a value between 0 and 1 determining how confident the model is that the image you gave to the decide method belongs to any of the classes in your dataset. If this probability is very low, it means that the model is uncertain whether the class is really from the class the Decide method said it should be. This should mean that the image may not be a face from your dataset at all. What you can do is to filter out those images where the model is uncertain and label them as not being faces from your dataset. For example, you can only consider a face to be from your dataset if its probability is higher than 0.9 or (90%). However, there might be lots of trial and error before you can determine an appropriate threshold for your application, and there are also other ways this probability value can be computed. As a start, please make sure that your model has been set to use the Voting decision method using
as this is the easiest way to get the Probability method working. Regards, |
We have the same concept to get the exact recognition we want, can you send a compiled application so I can test here if it's good than mine, or not? |
@ALL, anyway, |
@cesarsouza |
Hi @blaisexen |
@HadeelHassan |
In this case, instead of using the voting method, switch to MultilabelSupportVectorMachine (instead of the MulticlassSupportVectorMachine you were using before), calibrate your machines using ProbabilisticOutputCalibration, set the Method property of the multi-label machine to "SumsToOneWithEmphasisOnWinner" and try again. I will try to give an example below: // Let's say we have the following data to be classified
// into three possible classes. Those are the samples:
//
double[][] inputs =
{
// input output
new double[] { 0, 1, 1, 0 }, // 0
new double[] { 0, 1, 0, 0 }, // 0
new double[] { 0, 0, 1, 0 }, // 0
new double[] { 0, 1, 1, 0 }, // 0
new double[] { 0, 1, 0, 0 }, // 0
new double[] { 1, 0, 0, 1 }, // 1
new double[] { 0, 0, 0, 1 }, // 1
new double[] { 0, 0, 0, 1 }, // 1
new double[] { 1, 0, 1, 1 }, // 2
new double[] { 1, 1, 0, 1 }, // 2
new double[] { 0, 1, 1, 1 }, // 2
new double[] { 1, 1, 1, 1 }, // 2
};
int[] outputs = // those are the class labels
{
0, 0, 0, 0, 0,
1, 1, 1,
2, 2, 2, 2,
};
// Create the multi-class learning algorithm for the machine
var teacher = new MultilabelSupportVectorLearning<Gaussian>() // Note: this is multi-label, not multi-class (keep the same kernel you were using before, do not change to a Gaussian, this is just an example)
{
Learner = (param) => new SequentialMinimalOptimization<Gaussian>() // Configure in the same way you were doing before, you do not really need to use kernel estimation if you were not using before
{
UseKernelEstimation = true
}
};
// Learn the machine
var machine = teacher.Learn(inputs, outputs);
// Create multi-label calibration algorithm for the machine
var calibration = new MultilabelSupportVectorLearning<Gaussian>() // again, use the same kernel you were using before
{
Model = machine, // We will start with an existing machine
// Configure the learning algorithm to use Platt's output calibration
Learner = (param) => new ProbabilisticOutputCalibration<Gaussian>()
{
Model = param.Model // Start with an existing machine
}
};
// Calibrate the machine
calibration.Learn(inputs, outputs);
// Now, set the machine probability method:
machine.Method = MultilabelProbabilityMethod.SumsToOneWithEmphasisOnWinner;
// Get class probabilities for each class & sample
double[][] prob = machine.Probabilities(inputs);
// Check if you can discern faces from non-faces using the probabilities I have not actually tested the code above, so I really hope it works! Also, please read the comments I tried to put carefully, if you have questions please ask! Regards, |
@cesarsouza |
@blaisexen |
@cschiano |
@HadeelHassan
|
@blaisexen Hadeel |
@HadeelHassan, |
private void button18_Click(object sender, EventArgs e)
this cod was working because it was multiclass no multilablel , the predict variable was int so i was make matching easily |
try to change code from
to
|
@blaisexen |
is that the issue?
is that actually the error, or some things you want? because I think we have the same way we want! |
@blaisexen |
@HadeelHassan |
@blaisexen |
@HadeelHassan I have also a question that is connected from your project too, thank you for the time |
Hi @blaisexen, @HadeelHassan, Sorry, I have not yet read all the replies, but I just wanted to let you know that, since this is a multi-label support vector machine, it should be able to output a set of boolean labels for each class in your classification problem. So for example, if you have 26 classes, the output of the decide function will be a bool[] array of size 26, where if the value of the boolean at position You can convert a multi-label classifier into a multi-class one using the .ToMulticlass() method of the multi-label SVM. For example, if you have a multi-label svm named ksvm after calling: ksvm = calibration.Learn(facevalues.ToArray(), faceclassnums.ToArray()); you can convert it back to a multi-class classifier using
after this, you should be able to use Decide and Probability as normal as you had been doing before with multi-class SVMs. Regards, |
@ceasarsouza |
@cesarsouza |
@HadeelHassan |
Hi @HadeelHassan, @blaisexen, Yes, the performance should be similar, but the probabilty estimates should be better than before. You might be able to use this improved probability to detect whether something was really a face or not by checking whether it is very low (lower than some threshold you might need to find manually). Regards, |
@HadeelHassan, |
please tell me if this application of image recognition is better than what you have there! this is a cards or card image recognition, for testing... I hope you can test it! thank you |
What would you like to submit? (put an 'x' inside the bracket that applies)
Issue description
If you would like to submit an issue, please include a sample of the code you are trying to execute, as well as any data you might be using in your experiment, such as data tables, images, anything that might be necessary to reproduce the problem.
Note: If you would like to support the development for this feature or resolution of this bug, consider adding a bounty to it later in https://www.bountysource.com/teams/accord-net/issues
The text was updated successfully, but these errors were encountered: