基本上,我想使用逻辑回归检测图像中的错误。我希望得到关于我的方法的反馈,如下:
培训:
使用sigmod函数,线性回归方程为:
1/ (1 - e^(xθ))
其中x是输入值,θ(θ)是权重。我使用梯度下降来训练网络。我的代码是:
void LogisticRegression::Train(float **trainingSet,float *labels, int m)
{
float tempThetaValues[m_NumberOfWeights];
for (int iteration = 0; iteration < 10000; ++iteration)
{
// Reset the temp values for theta.
memset(tempThetaValues,0,m_NumberOfWeights*sizeof(float));
float error = 0.0f;
// For each training set in the example
for (int trainingExample = 0; trainingExample < m; ++trainingExample)
{
float * x = trainingSet[trainingExample];
float y = labels[trainingExample];
// Partial derivative of the cost function.
float h = Hypothesis(x) - y;
for (int i =0; i < m_NumberOfWeights; ++i)
{
tempThetaValues[i] += h*x[i];
}
float cost = h-y; //Actual J(theta), Cost(x,y), keeps giving NaN use MSE for now
error += cost*cost;
}
// Update the weights using batch gradient desent.
for (int theta = 0; theta < m_NumberOfWeights; ++theta)
{
m_pWeights[theta] = m_pWeights[theta] - 0.1f*tempThetaValues[theta];
}
printf("Cost on iteration[%d] = %f\n",iteration,error);
}
}
使用以下方法计算sigmoid和假设:
float LogisticRegression::Sigmoid(float z) const
{
return 1.0f/(1.0f+exp(-z));
}
float LogisticRegression::Hypothesis(float *x) const
{
float z = 0.0f;
for (int index = 0; index < m_NumberOfWeights; ++index)
{
z += m_pWeights[index]*x[index];
}
return Sigmoid(z);
}
最终的预测是:
int LogisticRegression::Predict(float *x)
{
return Hypothesis(x) > 0.5f;
}
由于我们使用强度直方图,输入和重量数组是255个元素。我希望将它用在像瘀伤的苹果图片上,并用它来识别擦伤的部分。整个受伤和苹果训练集的(标准化)直方图看起来像这样:
我并不是100%确信单独使用强度会产生我想要的结果,但即便如此,在明显可分离的数据集上使用它也不起作用。为了测试它,我将它标记为完全白色和完全黑色的图像。然后我在下面的小图片上运行它:
即使在此图片上,它也无法将任何段识别为黑色。
使用MSE我看到成本正在向下收敛到它仍然存在的程度,黑白测试它开始时的成本约为250,并且结算为100.苹果chuncks从大约4000开始并在1600点结算。 / p>
我不知道问题出在哪里。
是,该方法听起来但执行方式已经破裂? Logistic回归是用于此任务的错误算法吗?渐变体面不够健壮吗?
答案 0 :(得分:1)
我忘了回答这个问题......基本上问题出在我的直方图中,当生成时没有将memset设置为0.关于使用灰度图像进行逻辑回归是否是一个好解决方案的整体问题,答案是不。 Greyscale没有为良好的分类提供足够的信息。使用所有颜色通道有点好,但我认为我试图解决的问题的复杂性(苹果中的瘀伤)对于简单的逻辑回归本身来说有点多了。您可以在我的博客here上看到结果。