confidence of prediction in SVM in OpenCv3.0.0 - c++

i'm using aprogram to classify road singns, and i want get confidence of prediction between 0-1.
Well, I tried to calculate the confidence and compare it with probabilities, but it was not work, because there's images representing (for exp 60 Km / h), and have a rates below than 0.9, and another (also representing 60 Km / h) have a higher rate to 0.9.
but the same thing is repeated with unrecognized traffic sing : there's images that does not represent a traffic sing, and which have a rate less than 0.9, and others which have a rate higher than 0 9.
i tried this
decision = svmob.predict(testData, true);
confidence = 1.0 / (1.0 + exp(-decision));
that i found here but it does'n work in OpenCv3.0.
can you help me please.
than I tried this:
int classObject = decision.at<float>(currentFile) < 0.0 ? 1 : -1;
float confidence = classObject == -1 ? (1.0 / (1.0 + exp(-decision.at<float>(currentFile)))) : (1.0 - (1.0 / (1.0 + exp(-decision.at<float>(currentFile)))));
if(confidence<0.9)
printf("le panneau n'est pas reconnu");
else
printf("decision = %f, response = %f\n",
decision.at<float>(0), response);
I want to know ho to do it, please?

in opencv3.0 we should use the interface predict(p, noArray(), cv::ml::StatModel::RAW_OUTPUT). Its' effect is equal to predict(p, true) in opencv2.4
Opencv documention explain the interface:C++: float StatModel::predict(InputArray samples, OutputArray results=noArray(), int flags=0 ) const
Parameters:
samples – The input samples, floating-point matrix
results – The optional output matrix of results.
flags – The optional flags, model-dependent. Some models, such as Boost, SVM recognize StatModel::RAW_OUTPUT flag, which makes the method return the raw results (the sum), not the class label.

Related

Accuracy warnings in scipy.special

I am running an MCMC sampler which requires the calculation of the hypergeometric function at each step using scipy.special.hyp2f1().
At certain points on my grid (which I do not care about) the solutions to the hypergeometric function are quite unstable and SciPy prints the warning:
Warning! You should check the accuracy
This is rather annoying, and over 1000s of samples may well slow down my routine.
I have tried using special.errprint(0) with no luck, as well as disabling all warnings in Python using both the warnings module and the -W ignore flag.
The offending function (called from another file) is below
from numpy import pi, hypot, real, imag
import scipy.special as special
def deflection_angle(p, (x1, x2)):
# Find the normalisation constant
norm = (p.f * p.m * (p.r0 ** (t - 2.0)) / pi) ** (1.0 / t)
# Define the complex plane
z = x1 + 1j * x2
# Define the radial coordinates
r = hypot(x1, x2)
# Truncate the radial coordinates
r_ = r * (r < p.r0).astype('float') + p.r0 * (r >= p.r0).astype('float')
# Calculate the radial part
radial = (norm ** 2 / (p.f * z)) * ((norm / r_) ** (t - 2))
# Calculate the angular part
h1, h2, h3 = 0.5, 1.0 - t / 2.0, 2.0 - t / 2.0
h4 = ((1 - p.f ** 2) / p.f ** 2) * (r_ / z) ** 2
special.errprint(0)
angular = special.hyp2f1(h1, h2, h3, h4)
# Assemble the deflection angle
alpha = (- radial * angular).conjugate()
# Separate real and imaginary parts
return real(alpha), imag(alpha)`
Unfortunately, hyp2f1 is notoriously hard to compute over some non-trivial areas of the parameter space. Many implementations would dilently produce inaccurate or wildly wrong results. Scipy.special tries hard to at least monitor convergence. An alternative could be to usr arbitrary precision implementations, e.g. mpmath. But these would certainly be quite a bit slower, so MCMC users beware.
EDIT: Ok, this seems to be scipy version dependent. I tried #wrwrwr's example on scipy 0.13.3, and it reproduces what you see: "Warning! You should check the accuracy" is printed regardless of the errprint status. However, doing the same with the dev version, I get
In [12]: errprint(True)
Out[12]: 0
In [13]: hyp2f1(0.5, 2/3., 1.5, 0.09j+0.75j)
/home/br/virtualenvs/scipy_py27/bin/ipython:1: SpecialFunctionWarning: scipy.special/chyp2f1: loss of precision
#!/home/br/virtualenvs/scipy_py27/bin/python
Out[13]: (0.93934867949609357+0.15593972567482395j)
In [14]: errprint(False)
Out[14]: 1
In [15]: hyp2f1(0.5, 2/3., 1.5, 0.09j+0.75j)
Out[15]: (0.93934867949609357+0.15593972567482395j)
So, apparently it got fixed at some point between 2013 and now. You might want to upgrade your scipy version.

In Graphics, when do I need to account for Gamma?

So I've got some code that's intended to generate a Linear Gradient between two input colors:
struct color {
float r, g, b, a;
}
color produce_gradient(const color & c1, const color & c2, float ratio) {
color output_color;
output_color.r = c1.r + (c2.r - c1.r) * ratio;
output_color.g = c1.g + (c2.g - c1.g) * ratio;
output_color.b = c1.b + (c2.b - c1.b) * ratio;
output_color.a = c1.a + (c2.a - c1.a) * ratio;
return output_color;
}
I've also written (semantically identical) code into my shaders as well.
The problem is that using this kind of code produces "dark bands" in the middle where the colors meet, due to the quirks of how brightness translates between a computer screen and the raw data used to represent those pixels.
So the questions I have are:
Do I need to correct for gamma in the host function, the device function, both, or neither?
What's the best way to correct the function to properly handle gamma? Does the code I'm providing below convert the colors in a way that is appropriate?
Code:
color produce_gradient(const color & c1, const color & c2, float ratio) {
color output_color;
output_color.r = pow(pow(c1.r,2.2) + (pow(c2.r,2.2) - pow(c1.r,2.2)) * ratio, 1/2.2);
output_color.g = pow(pow(c1.g,2.2) + (pow(c2.g,2.2) - pow(c1.g,2.2)) * ratio, 1/2.2);
output_color.b = pow(pow(c1.b,2.2) + (pow(c2.b,2.2) - pow(c1.b,2.2)) * ratio, 1/2.2);
output_color.a = pow(pow(c1.a,2.2) + (pow(c2.a,2.2) - pow(c1.a,2.2)) * ratio, 1/2.2);
return output_color;
}
EDIT: For reference, here's a post that is related to this issue, for the purposes of explaining what the "bug" looks like in practice: https://graphicdesign.stackexchange.com/questions/64890/in-gimp-how-do-i-get-the-smudge-blur-tools-to-work-properly
I think there is a flaw in your code.
first i would make sure that 0 <= ratio <=1
second i would use the formula c1.x * (1-ratio) + c2.x *ratio
the way you have set up your calculations at the moment allow for negative results, which would explain the dark spots.
There is no pat answer for when you have to worry about gamma.
You generally want to work in linear color space when mixing, blending, computing lighting, etc.
If your inputs are not in linear space (e.g., that are gamma corrected or are in some color space like sRGB), then you generally want to convert them at once to linear. You haven't told us whether your inputs are in linear RGB.
When you're done, you want to ensure your linear values are corrected for the color space of the output device, whether that's a simple gamma or other color space transform. Again, there's no pat answer here, because you have to know if that conversion is being done for you implicitly at a lower level in the stack or if it's your responsibility.
That said, a lot of code gets away with cheating. They'll take their inputs in sRGB and apply alpha blending or fades as though they're in linear RGB and then output the results as is (probably with clamping). Sometimes that's a reasonable trade off.
your problem lies entirely in the field of perceptual color implementation.
to take care of perceptual lightness aberrations you can use one of the many algorithms found online
one such algorithm is Luma
float luma(color c){
return 0.30 * c.r + 0.59 * c.g + 0.11 * c.b;
}
at this point I would like to point out that the standard method would be to apply all algorithms in the perceptual color space, then convert to rgb color space for display.
colorRGB --(convert)--> colorPerceptual --(input)--> f (colorPerceptual) --(output)--> colorPerceptual' --(convert)--> colorRGB
but if you want to adjust for lightness only (perceptual chromatic aberrations will not be fixed), you can do it efficiently in the following manner
//define color of unit lightness. based on Luma algorithm
color unit_l(1/0.3/3, 1/0.59/3, 1/0.11/3);
color produce_gradient(const color & c1, const color & c2, float ratio) {
color output_color;
output_color.r = c1.r + (c2.r - c1.r) * ratio;
output_color.g = c1.g + (c2.g - c1.g) * ratio;
output_color.b = c1.b + (c2.b - c1.b) * ratio;
output_color.a = c1.a + (c2.a - c1.a) * ratio;
float target_lightness = luma(c1) + (luma(c2) - luma(c1)) * ratio; //linearly interpolate perceptual lightness
float delta_lightness = target_lightness - luma(output_color); //calculate required lightness change magnitude
//adjust lightness
output_color.g += unit_l.r * delta_lightness;
output_color.b += unit_l.g * delta_lightness;
output_color.a += unit_l.b * delta_lightness;
//at this point luma(output_color) approximately equals target_lightness which takes care of the perceptual lightness aberrations
return output_color;
}
Your second code example is perfectly correct, except that the alpha channel is generally not gamma corrected so you shouldn't use pow on it. For efficiency's sake it would be better to do the gamma correction once for each channel, instead of doubling up.
The general rule is that you must do gamma in both directions whenever you're adding or subtracting values. If you're only multiplying or dividing, it makes no difference: pow(pow(x, 2.2) * pow(y, 2.2), 1/2.2) is mathematically equivalent to x * y.
Sometimes you might find that you get better results by working in uncorrected space. For example if you're resizing an image, you should do gamma correction if you're downsizing but not if you're upsizing. I forget where I read this, but I verified it myself - the artifacts from upsizing were much less objectionable if you used gamma corrected pixel values vs. linear ones.

How can I get resistance from temperature?

I have a value in temperature and I want to get a resistance value from this temperature.
I use Steinhart-Hart method but this equation always returns 7,39 regardless of temperatures and coefficients.
My second implementation based on steinhart method (see below) doesn't work with negative coefficients.
Do you know what's the problem with my code ?
double WSensor::temperatureToResistance(double _temp)
{
double Temp = _temp + 273.15;
double X = ((this->therm->getA() - (1 / Temp)) / this->therm->getC());
double Y = this->therm->getB() / this->therm->getC();
double argExpo = pow(-(X / 2) + pow((X*X) / 4 + (Y*Y*Y) / 27, 1.0 / 2.), 1.0 / 3.0) - pow((-(X / 2) - pow((X*X) / 4 + (Y*Y*Y) / 27, 1.0 / 2.0)) * (-1), 1.0 / 3.0);
return exp(argExpo);
}
After 3 days of work, I know why this equation does not work on arduino : overflowing.
Some parts of the equation create float too large for this board model (Arduino Uno).
One of the solutions is to rephrase the equation to prevent bigger results. But this solution takes too much time and need good mathematical skills, that's why I decided to move the equation in an external API.

Gradient descent algorithm won't converge

I'm trying to write out a bit of code for the gradient descent algorithm explained in the Stanford Machine Learning lecture (lecture 2 at around 25:00). Below is the implementation I used at first, and I think it's properly copied over from the lecture, but it doesn't converge when I add large numbers (>8) to the training set.
I'm inputting a number X, and the point (X,X) is added to the training set, so at the moment, I'm only trying to get it to converge to y=ax+b where a=1=theta\[1\] and b=0=theta\[0\].
The training set is the array x and y, where (x[i],y[i]) is a point.
void train()
{
double delta;
for (int i = 0; i < x.size(); i++)
{
delta = y[i]-hypothesis(x[i]);
theta[1] += alpha*delta*x[i];
theta[0] += alpha*delta*1;
}
}
void C_Approx::display()
{
std::cout<<theta[1]<<"x + "<<theta[0]<<" \t "<<"f(x)="<<hypothesis(1)<<std::endl;
}
some of the results I'm getting:
I input a number, it runs train() a few times, then display()
1
0.33616x + 0.33616 f(x)=0.67232
1
0.482408x + 0.482408 f(x)=0.964816
1
0.499381x + 0.499381 f(x)=0.998762
1
0.499993x + 0.499993 f(x)=0.999986
1
0.5x + 0.5 f(x)=1
An example of it diverging after it passed 8:
1
0.33616x + 0.33616 f(x)=0.67232
2
0.705508x + 0.509914 f(x)=1.21542
3
0.850024x + 0.449928 f(x)=1.29995
4
0.936062x + 0.330346 f(x)=1.26641
5
0.951346x + 0.231295 f(x)=1.18264
6
0.992876x + 0.137739 f(x)=1.13062
7
0.932206x + 0.127372 f(x)=1.05958
8
1.00077x + 0.000493063 f(x)=1.00126
9
-0.689325x + -0.0714712 f(x)=-0.760797
10
4.10321e+08x + 4.365e+07 f(x)=4.53971e+08
11
1.79968e+22x + 1.61125e+21 f(x)=1.9608e+22
12
-3.9452e+41x + -3.26957e+40 f(x)=-4.27216e+41
I tried the solution proposed here of scaling the step and ended up with similar results.
What am I doing wrong?
Your implementation is good. Generally, stochastic gradient descent might diverge when α is too large. What you would do with a large dataset is take a reasonably sized random sample, find α that gives you the best results, and then use it for the rest.
I have experienced the same problem (albeit in Java) because my learning rate was too big.
For short, I was using α = 0.001 and I had to push it to 0.000001 to see actual convergence.
Of course these values are linked to your dataset.
When your cost function increases or cycles up and down, you usually have too large a value for alpha. What alpha are you using?
Start out with an alpha = 0.001 and see if that converges? If not try various alphas (0.003, 0.01, 0.03, 0.1, 0.3, 1) and find one that converges quickly.
Scaling the data (normalization) won't help you with only 1 feature (your theta[1]) as normalization only applies to 2+ features (multivariate linear regression).
Also bear in mind that for a small number of features you can use the Normal Equation to get the correct answer.
use backtracking line search to guaranty convergence. It is very simple to implement. See Stephen Boyd, Convex Optimization for reference. You can choose some standard alpha, beta values for backtracking line search, for example 0.3 and 0.8.
If I understand you correctly, your training set only has a non-zero gradient at the edge of a line? Unless you start at the line (actually start exactly at one of your training points) you won't find the line. You are always at a local minimum.
It's not clean from your description what problem you're solving.
Also it's very dangerous to post links to external resources - you can be blocked in stackoverflow.
In any case - gradient descend method and (subgradient descend too) with fixed step size (ML community call it learning rate) should not necesseray converge.
p.s.
Machine Learning community is not interesting in "convergence condition" and "convergence to what" - they are interested in create "something" which pass cross-validation with good result.
If you're curious about optimization - start to look in convex optimization. Unfortunately it's hard to find job on it, but it append clean vision into what happens in various math optimization things.
Here is source code which demonstrate it for simple quadratic objective:
#!/usr/bin/env python
# Gradiend descend method (without stepping) is not converged for convex
# objective
alpha = 0.1
#k = 10.0 # jumping around minimum
k = 20.0 # diverge
#k = 0.001 # algorithm converged but gap to the optimal is big
def f(x): return k*x*x
def g(x): return 2*k*x
x0 = 12
xNext = x0
i = 0
threshold = 0.01
while True:
i += 1
xNext = xNext + alpha*(-1)*(g(xNext))
obj = (xNext)
print "Iteration: %i, Iterate: %f, Objective: %f, Optimality Gap: %f" % (i, xNext, obj, obj - f(0.0))
if (abs(g(xNext)) < threshold):
break
if i > 50:
break
print "\nYou launched application with x0=%f,threshold=%f" % (x0, threshold)

Computing FOVX (openGL)

When working with openGL perspectives I am not quite sure how to compute the fovx from the fovy. I read different things in different places and in I don't get the right behavior by using either method that I found. So can someone please tell me, given the fovy of the camera and the aspect ratio, how to I calculate the fovx of the camera? If any other data is needed that is fine just let me know what I need. Thank you so much in advance!
Correct:
fieldOfViewX = 2 * atan(tan(fieldOfViewY * 0.5) * aspect)
Wrong, especially for large aspects, see #gman's comments below:
Aspect ratio === width/height
fovy ~= "height"
==> fovx = fovy * aspect
Test:
Fovy = 60 degs
Aspect = 4:3 ~= 1.33
Fovx = 60*1.33 = 80
80/60 = 4:3 (fovs match, yay)
For "reasonable" fovs/aspects, simple method is "reasonably" near the truth, but if you have extreme aspects you will get fovx > 180 degrees, which you don't want.
Here is a good link:
http://wiki.panotools.org/Field_of_View
Note that the aspect ratio is not the same thing as the field of view ratio, and the proper relationship given on this page should be used for relating field of view angles.
Java:
double d = (viewportHeight * 0.5) / Math.tan(Math.toRadians(fovY * 0.5));
fovX = (float) (2 * Math.toDegrees(Math.atan((viewportWidth * 0.5) / d)));
Have you looked at the formulas here?:
http://en.wikipedia.org/wiki/Angle_of_view