用于图像故障检测的逻辑回归
Logistic regression for fault detection in an image
基本上,我想使用逻辑回归检测图像中的错误。我希望得到对我的方法的反馈,如下所示:
训练:
- 截取图像的一小部分,标记为 "bad" 和 "good"
- 对它们进行灰度化,然后将它们分解成一系列 5*5 像素的片段
- 计算每个片段的像素强度直方图
- 将直方图连同标签传递给逻辑回归 class 进行训练
- 将整个图像分成 5*5 段并为每个段预测 "good"/"bad"。
使用 sigmod 函数得到的线性回归方程为:
1/ (1 - e^(xθ))
其中 x 是输入值,theta (θ) 是权重。我使用梯度下降来训练网络。我的代码是:
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 个元素。我的希望是将它用在诸如有瘀伤的苹果图片之类的东西上,并用它来识别被擦伤的部分。整个 brused 和 apple 训练集的(归一化)直方图看起来像这样:
对于苹果的 "good" 个部分 (y=0):
对于苹果的 "bad" 个部分 (y=1):
我不是 100% 相信单独使用 intensites 会产生我想要的结果,但即便如此,在明显可分离的数据集上使用它也不起作用。为了测试它,我给它传递了一个带标签的全白和全黑图像。然后我就运行把它放在下面的小图上:
即使在这张图片上,它也无法将 任何 片段识别为黑色。
使用 MSE,我看到成本正在向下收敛到一个点,它仍然存在,对于黑白测试,它从大约成本 250 开始并稳定在 100。苹果块从大约 4000 开始并稳定在 1600 .
我不知道问题出在哪里。
是否方法合理但执行失败?逻辑回归是用于此任务的错误算法吗?梯度体面不够健壮吗?
我忘了回答这个问题...基本上问题出在我的直方图中,生成时没有将 memset 设置为 0。至于灰度图像的逻辑回归是否是一个好的解决方案的整体问题,答案是不。灰度只是没有提供足够的信息来进行良好的分类。使用所有颜色通道要好一些,但我认为我试图解决的问题(苹果上的瘀伤)的复杂性对于简单的逻辑回归本身来说有点过分。你可以在我的博客上看到结果 here.
基本上,我想使用逻辑回归检测图像中的错误。我希望得到对我的方法的反馈,如下所示:
训练:
- 截取图像的一小部分,标记为 "bad" 和 "good"
- 对它们进行灰度化,然后将它们分解成一系列 5*5 像素的片段
- 计算每个片段的像素强度直方图
- 将直方图连同标签传递给逻辑回归 class 进行训练
- 将整个图像分成 5*5 段并为每个段预测 "good"/"bad"。
使用 sigmod 函数得到的线性回归方程为:
1/ (1 - e^(xθ))
其中 x 是输入值,theta (θ) 是权重。我使用梯度下降来训练网络。我的代码是:
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 个元素。我的希望是将它用在诸如有瘀伤的苹果图片之类的东西上,并用它来识别被擦伤的部分。整个 brused 和 apple 训练集的(归一化)直方图看起来像这样:
对于苹果的 "good" 个部分 (y=0):
对于苹果的 "bad" 个部分 (y=1):
我不是 100% 相信单独使用 intensites 会产生我想要的结果,但即便如此,在明显可分离的数据集上使用它也不起作用。为了测试它,我给它传递了一个带标签的全白和全黑图像。然后我就运行把它放在下面的小图上:
即使在这张图片上,它也无法将 任何 片段识别为黑色。
使用 MSE,我看到成本正在向下收敛到一个点,它仍然存在,对于黑白测试,它从大约成本 250 开始并稳定在 100。苹果块从大约 4000 开始并稳定在 1600 .
我不知道问题出在哪里。
是否方法合理但执行失败?逻辑回归是用于此任务的错误算法吗?梯度体面不够健壮吗?
我忘了回答这个问题...基本上问题出在我的直方图中,生成时没有将 memset 设置为 0。至于灰度图像的逻辑回归是否是一个好的解决方案的整体问题,答案是不。灰度只是没有提供足够的信息来进行良好的分类。使用所有颜色通道要好一些,但我认为我试图解决的问题(苹果上的瘀伤)的复杂性对于简单的逻辑回归本身来说有点过分。你可以在我的博客上看到结果 here.