EmguCV 中的多层感知器
Multi-Layer Perceptrons in EmguCV
我正在尝试使用 C#(Windows 形式)中的 EmguCV 3.1(OpenCV 库的点 NET 包装器)实现多层感知器 (MLP) 神经网络。为了练习这个库,我决定使用 MLP 实现 OR
操作。
我使用 "Initialize" 方法创建 MLP,并使用 "Train" 方法学习它,如下所示:
private void Initialize()
{
NETWORK.SetActivationFunction(
ANN_MLP.AnnMlpActivationFunction.SigmoidSym);
NETWORK.SetTrainMethod(ANN_MLP.AnnMlpTrainMethod.Backprop);
Matrix<double> layers = new Matrix<double>(new Size(4, 1));
layers[0, 0] = 2;
layers[0, 1] = 2;
layers[0, 2] = 2;
layers[0, 3] = 1;
NETWORK.SetLayerSizes(layers);
}
private void Train()
{
// providing data for input
Matrix<float> input = new Matrix<float>(4, 2);
input[0, 0] = MIN_ACTIVATION_FUNCTION; input[0, 1] = MIN_ACTIVATION_FUNCTION;
input[1, 0] = MIN_ACTIVATION_FUNCTION; input[1, 1] = MAX_ACTIVATION_FUNCTION;
input[2, 0] = MAX_ACTIVATION_FUNCTION; input[2, 1] = MIN_ACTIVATION_FUNCTION;
input[3, 0] = MAX_ACTIVATION_FUNCTION; input[3, 1] = MAX_ACTIVATION_FUNCTION;
//providing data for output
Matrix<float> output = new Matrix<float>(4, 1);
output[0, 0] = MIN_ACTIVATION_FUNCTION;
output[1, 0] = MAX_ACTIVATION_FUNCTION;
output[2, 0] = MAX_ACTIVATION_FUNCTION;
output[3, 0] = MAX_ACTIVATION_FUNCTION;
// mixing input and output for training
TrainData mixedData = new TrainData(
input,
Emgu.CV.ML.MlEnum.DataLayoutType.RowSample,
output);
// stop condition = 1 million iterations
NETWORK.TermCriteria = new MCvTermCriteria(1000000);
// training
NETWORK.Train(mixedData);
}
其中 MIN_ACTIVATION_FUNCTION
和 MAX_ACTIVATION_FUNCTION
分别等于 -1.7159 和 1.7159 (according to OpenCV Documentation)。在 1000000 次迭代之后(如您在停止条件下的代码中所见),我使用 Predict 方法测试我的网络预测,如下所示:
private void Predict()
{
Matrix<float> input = new Matrix<float>(1, 2);
input[0, 0] = MIN_ACTIVATION_FUNCTION;
input[0, 1] = MIN_ACTIVATION_FUNCTION;
Matrix<float> output = new Matrix<float>(1, 1);
NETWORK.Predict(input, output);
MessageBox.Show(output[0, 0].ToString());
//////////////////////////////////////////////
input[0, 0] = MIN_ACTIVATION_FUNCTION;
input[0, 1] = MAX_ACTIVATION_FUNCTION;
NETWORK.Predict(input, output);
MessageBox.Show(output[0, 0].ToString());
//////////////////////////////////////////////
input[0, 0] = MAX_ACTIVATION_FUNCTION;
input[0, 1] = MIN_ACTIVATION_FUNCTION;
NETWORK.Predict(input, output);
MessageBox.Show(output[0, 0].ToString());
////////////////////////////////////////////////
input[0, 0] = MAX_ACTIVATION_FUNCTION;
input[0, 1] = MAX_ACTIVATION_FUNCTION;
NETWORK.Predict(input, output);
MessageBox.Show(output[0, 0].ToString());
}
以下是 NETWORK 预测结果的示例:
-0.00734469
-0.03184918
0.02080269
-0.006674092
我希望是这样的:
-1.7
+1.7
+1.7
+1.7
我的代码有什么问题?
请注意,我也使用 0、1 作为 MIN_ACTIVATION_FUNCTION
和 MAX_ACTIVATION_FUNCTION
值,但我仍然没有任何好的结果。
更新 1:
我编辑我的代码作为第一个答案提到我(甚至我用评论中引用的想法测试我的代码)。现在我在调用 predict
方法时得到 NaN
。
您提供的输出数据似乎有误。使用 output
数组而不是 input
。
我认为您的输出响应应该是二维矩阵(有 2 列)。最后一层应该有 2 个输出神经元,因为你有 2 个 类,例如 (1, 0) is class "True"
和 (0, 1) is class "False"
。还尝试更改网络的体系结构。逻辑运算符 OR
是线性可分的,即它可以使用单个感知器执行。
根据 EmguCV 的新版本(Emgu.CV-3.1.0-r16.12) the problem was a bug in version 3.1.0 Now it is fixed in Emgu.CV-3.1.0-r16.12。通过下载这个版本,我从我的网络得到了正确的响应。
我正在尝试使用 C#(Windows 形式)中的 EmguCV 3.1(OpenCV 库的点 NET 包装器)实现多层感知器 (MLP) 神经网络。为了练习这个库,我决定使用 MLP 实现 OR
操作。
我使用 "Initialize" 方法创建 MLP,并使用 "Train" 方法学习它,如下所示:
private void Initialize()
{
NETWORK.SetActivationFunction(
ANN_MLP.AnnMlpActivationFunction.SigmoidSym);
NETWORK.SetTrainMethod(ANN_MLP.AnnMlpTrainMethod.Backprop);
Matrix<double> layers = new Matrix<double>(new Size(4, 1));
layers[0, 0] = 2;
layers[0, 1] = 2;
layers[0, 2] = 2;
layers[0, 3] = 1;
NETWORK.SetLayerSizes(layers);
}
private void Train()
{
// providing data for input
Matrix<float> input = new Matrix<float>(4, 2);
input[0, 0] = MIN_ACTIVATION_FUNCTION; input[0, 1] = MIN_ACTIVATION_FUNCTION;
input[1, 0] = MIN_ACTIVATION_FUNCTION; input[1, 1] = MAX_ACTIVATION_FUNCTION;
input[2, 0] = MAX_ACTIVATION_FUNCTION; input[2, 1] = MIN_ACTIVATION_FUNCTION;
input[3, 0] = MAX_ACTIVATION_FUNCTION; input[3, 1] = MAX_ACTIVATION_FUNCTION;
//providing data for output
Matrix<float> output = new Matrix<float>(4, 1);
output[0, 0] = MIN_ACTIVATION_FUNCTION;
output[1, 0] = MAX_ACTIVATION_FUNCTION;
output[2, 0] = MAX_ACTIVATION_FUNCTION;
output[3, 0] = MAX_ACTIVATION_FUNCTION;
// mixing input and output for training
TrainData mixedData = new TrainData(
input,
Emgu.CV.ML.MlEnum.DataLayoutType.RowSample,
output);
// stop condition = 1 million iterations
NETWORK.TermCriteria = new MCvTermCriteria(1000000);
// training
NETWORK.Train(mixedData);
}
其中 MIN_ACTIVATION_FUNCTION
和 MAX_ACTIVATION_FUNCTION
分别等于 -1.7159 和 1.7159 (according to OpenCV Documentation)。在 1000000 次迭代之后(如您在停止条件下的代码中所见),我使用 Predict 方法测试我的网络预测,如下所示:
private void Predict()
{
Matrix<float> input = new Matrix<float>(1, 2);
input[0, 0] = MIN_ACTIVATION_FUNCTION;
input[0, 1] = MIN_ACTIVATION_FUNCTION;
Matrix<float> output = new Matrix<float>(1, 1);
NETWORK.Predict(input, output);
MessageBox.Show(output[0, 0].ToString());
//////////////////////////////////////////////
input[0, 0] = MIN_ACTIVATION_FUNCTION;
input[0, 1] = MAX_ACTIVATION_FUNCTION;
NETWORK.Predict(input, output);
MessageBox.Show(output[0, 0].ToString());
//////////////////////////////////////////////
input[0, 0] = MAX_ACTIVATION_FUNCTION;
input[0, 1] = MIN_ACTIVATION_FUNCTION;
NETWORK.Predict(input, output);
MessageBox.Show(output[0, 0].ToString());
////////////////////////////////////////////////
input[0, 0] = MAX_ACTIVATION_FUNCTION;
input[0, 1] = MAX_ACTIVATION_FUNCTION;
NETWORK.Predict(input, output);
MessageBox.Show(output[0, 0].ToString());
}
以下是 NETWORK 预测结果的示例:
-0.00734469
-0.03184918
0.02080269
-0.006674092
我希望是这样的:
-1.7
+1.7
+1.7
+1.7
我的代码有什么问题?
请注意,我也使用 0、1 作为 MIN_ACTIVATION_FUNCTION
和 MAX_ACTIVATION_FUNCTION
值,但我仍然没有任何好的结果。
更新 1:
我编辑我的代码作为第一个答案提到我(甚至我用评论中引用的想法测试我的代码)。现在我在调用 predict
方法时得到 NaN
。
您提供的输出数据似乎有误。使用 output
数组而不是 input
。
我认为您的输出响应应该是二维矩阵(有 2 列)。最后一层应该有 2 个输出神经元,因为你有 2 个 类,例如 (1, 0) is class "True"
和 (0, 1) is class "False"
。还尝试更改网络的体系结构。逻辑运算符 OR
是线性可分的,即它可以使用单个感知器执行。
根据 EmguCV 的新版本(Emgu.CV-3.1.0-r16.12) the problem was a bug in version 3.1.0 Now it is fixed in Emgu.CV-3.1.0-r16.12。通过下载这个版本,我从我的网络得到了正确的响应。