神经网络为什么无法进行预测?

5
我正在尝试使用OpenCV 2.3中的反向传播算法训练神经网络,但它无法正确预测,即使是在训练数据集上也是如此。有人可以帮我找出问题在哪里吗?
training_feature_matrix - N x 69个浮点值的矩阵
training_age_matrix - N x 4个浮点值的矩阵
test_feature_matrix - M x 69个浮点值的矩阵
test_age_matrix - M x 4个浮点值的矩阵
以上提到的特征矩阵是这样的:[0.123435、0.4542665、0.587545、……68个这样的值+最后一个值“1.0或2.0”,取决于其性别)
以上提到的年龄矩阵是这样的:[1,0,0,0; 1,0,0,0; 0,1,0,0;……] 这里的1表示所属年龄类别(婴儿、儿童、成年人、老年人),与特征矩阵的相应行对应。
以下是代码: 使用上述矩阵作为参数调用'mlp'函数。
cv::Mat mlp(cv::Mat& training_feature_matrix, cv::Mat& training_age_matrix, cv::Mat& test_feature_matrix, cv::Mat& test_age_matrix)
{
cv::Mat layers = cv::Mat(3, 1, CV_32SC1);
layers.row(0)  = cv::Scalar(69);
layers.row(1)  = cv::Scalar(36);
layers.row(2)  = cv::Scalar(4);    //   cout<<layers<<"\n";

CvANN_MLP ann;
CvANN_MLP_TrainParams params;
CvTermCriteria criteria;
criteria.max_iter = 10000;
criteria.epsilon  = 0.001;
criteria.type     = CV_TERMCRIT_ITER + CV_TERMCRIT_EPS;
params.train_method = CvANN_MLP_TrainParams::BACKPROP;
params.bp_dw_scale  = 0.1;
params.bp_moment_scale = 0.1;
params.term_crit  = criteria;

ann.create(layers, CvANN_MLP::SIGMOID_SYM);
ann.train(training_feature_matrix, training_age_matrix, cv::Mat(), cv::Mat(), params);

cv::Mat predicted(test_age_matrix.rows, 4, CV_32SC1);
for(int i = 0; i < test_feature_matrix.rows; i++)
{
  cv::Mat response(1, 4, CV_32F);
  cv::Mat sample = test_feature_matrix.row(i);
  ann.predict(sample, response);
  for (int g = 0; g < 4; g++)
  {
    predicted.at<int>(i,g) = response.at<float>(0,g);
  } 
}
   cout << "\n";
   cout << ann.get_weights(0) << "\n";
   cout << ann.get_layer_sizes() << "\n";
   cout << ann.get_layer_count() << "\n\n";

return predicted;
}

编辑 另外,ann.get_weights(0)和ann.get_layer_sizes()返回的值是垃圾值,但是ann.get_layer_count()返回正确的值3。

谢谢 :)


1
ann.get_weights(0)和ann.get_layer_sizes()返回指针,因此如果像您所做的那样打印它们,它们会看起来像“垃圾”。您的其余代码似乎没问题,您确定数据是好的吗?“它没有正确预测”具体意味着什么? - Bull
@user2151446 我该如何从这些指针中提取值? 预测不正确意味着...我得到的输出预测矩阵是一个浮点数值的矩阵...有正数、负数和大于1的值...它没有意义... 输入数据完全正常...每个都是以OpenCV所需的浮点矩阵形式。 - learner
@user2151446 我能够从ann.get_weights()中提取值,但无法提取ann.get_layer_sizes()的值。我该怎么办? - learner
使用2.3版本有特别的原因吗?你能否尝试一下最新的2.4.6版本? - gpicchiarelli
1
你为什么要将结果粗略地转换成整数?我猜你的结果是一个全是零的矩阵... - Bentoy13
@learner:给层分配3行1列有特定的原因吗?我以为这个矩阵只有一行。 - Fabien R
2个回答

2
很久以前就有人问了这个问题,但是我会分享答案。我遇到了与Sigmoid输出值类似的问题,现在已经解决了。你可以在此处查看我的问题:OpenCV神经网络Sigmoid输出
为了总结错误,它是由于mlp的create函数的默认参数引起的。使用这样的方式:ann.create(layers, CvANN_MLP::SIGMOID_SYM, 1, 1)。

1
反向传播并不总是收敛的。如果 epsilon 或 momentum_scale 值过大,很可能会失控并产生无意义的结果。如果您的动量接近可行的最大值,建议尝试减小它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接