betway88必威OpenCV 之 神经网络 (一)OpenCV 之 神经网络 (一)

  人工神经网络(ANN)
简称神经网络(NN),能学生物神经系统针对体所作出的相互反应,是出于所有适应性大概单元(称为神经元)组成的大面积并行互连网络

  人工神经网络(ANN)
简称神经网络(NN),能模仿生物神经系统对体所作出的相互反应,是出于具有适应性简易单元(称为神经元)组成的广并行互连网络

1  神经元

1  神经元

1.1  M-P 神经元

  如下图所显示,来自其它神经元的信号,$x_1, x_2, … , x_n
$,传递过来当输入信号,并通过带权重 ($w_1, w_2, … , w_n$) 的连接
(connection) 继续传递,

  然后神经元的总输入值 $\sum w_i x_i$ 与阈值 $\theta$
作比较,最后经过激活函数$\,f\,$产生神经元的出口: $y = f\left(\,\sum
\limits_{i=1}^n {w_i x_i} – \theta \right)$

   betway88必威 1

1.1  M-P 神经元

  如下图所展示,来自其他神经元的信号,$x_1, x_2, … , x_n
$,传递过来当输入信号,并透过带权重 ($w_1, w_2, … , w_n$) 的连接
(connection) 继续传递,

  然后神经元的总输入值 $\sum w_i x_i$ 与阈值 $\theta$
作于,最后经激活函数$\,f\,$产生神经元的输出: $y = f\left(\,\sum
\limits_{i=1}^n {w_i x_i} – \theta \right)$

   betway88必威 2

1.2  激活函数 (activation function)

  理想被,阶跃函数可作为激活函数,将输入值映射为出口值 “0” 和
“1;实际中,常用 Sigmoid 函数发激活函数,
$f(x)=\,\dfrac{1}{1+e^{-x}}$,如下图所示:

  betway88必威 3

  OpenCV 中利用的激活函数是其它一样种植样式,$f(x)=\beta
\,\dfrac{1-e^{-\alpha x}}{1+e^{-\alpha x}}$

  当 α = β = 1
时,$f(x)=\dfrac{1-e^{-x}}{1+e^{x}}$,该函数把可能在比充分范围外浮动之输入值,“挤压”
到 (-1, 1) 的出口范围外

    betway88必威 4  

  具体的安装函数如下,param1 –> α,param2 –> β

// 设置激活函数,目前只支持 ANN_MLP::SIGMOID_SYM
virtual void cv::ml::ANN_MLP::setActivationFunction(int type, double param1 = 0, double param2 = 0); 

 

1.2  激活函数 (activation function)

  理想中,阶跃函数可看作激活函数,将输入值映射为出口值 “0” 和
“1;实际被,常用 Sigmoid 函数发激活函数,
$f(x)=\,\dfrac{1}{1+e^{-x}}$,如下图所示:

  betway88必威 5

  OpenCV 中使的激活函数是别一样种样式,$f(x)=\beta
\,\dfrac{1-e^{-\alpha x}}{1+e^{-\alpha x}}$

  当 α = β = 1
时,$f(x)=\dfrac{1-e^{-x}}{1+e^{x}}$,该函数把可能在比生范围外浮动的输入值,“挤压”
到 (-1, 1) 的输出范围外

    betway88必威 6  

  具体的安装函数如下,param1 –> α,param2 –> β

// 设置激活函数,目前只支持 ANN_MLP::SIGMOID_SYM
virtual void cv::ml::ANN_MLP::setActivationFunction(int type, double param1 = 0, double param2 = 0); 

 

2  神经网络

2  神经网络

2.1  感知机 (perceptron)

 
感知机由个别重合神经元组成,输入层收纳外界输入信号,而输出层尽管如此是一个
M-P 神经元。

 
实际上,感知机可视为一个不过简单易行的“神经网络”,用它只是充分易之贯彻逻辑和、或、非等简便运算。

    betway88必威 7

2.1  感知机 (perceptron)

 
感知机由少数层神经元组成,输入层收受外界输入信号,而输出层则是一个
M-P 神经元。

 
实际上,感知机可视为一个无比简单易行的“神经网络”,用它可是大易之兑现逻辑和、或、非等简便运算。

    betway88必威 8

2.2 层级结构

 
常见的神经网络,可分为三层:输入层、隐含层、输出层。输入层接收外界输入,隐层和输出层负责对信号进行加工,输出层输出最终之结果。

 
以下图为条例:每层神经元与生同样层神经元全互连,而同层神经元之间无连续,也无设有跨层连接,这样的结构称为“多叠前馈神经网络”(multi-layer
feedforward neural networks)

    betway88必威 9

2.2 层级结构

 
常见的神经网络,可分为三重叠:输入层、隐含层、输出层。输入层接收外界输入,隐层和输出层负责对信号进行加工,输出层输出最终之结果。

 
以下图也例:每层神经元与下同样叠神经元全互连,而跟层神经元之间不连续,也非存跨层连接,这样的组织称为“多重叠前馈神经网络”(multi-layer
feedforward neural networks)

    betway88必威 10

2.3  层数设置

   OpenCV 中,设置神经网络层数和神经元个数的函数为
setLayerSizes(InputArray _layer_sizes),则达图对应的 InputArray
可由如下代码来组成

// (a) 3层,输入层神经元个数为 4,隐层的为 6,输出层的为 4
Mat layers_size = (Mat_<int>(1,3) << 4,6,4);

// (b) 4层,输入层神经元个数为 4,第一个隐层的为 6,第二个隐层的为 5,输出层的为 4
Mat layers_size = (Mat_<int>(1,4) << 4,6,5,4);

  
如何安装隐层神经元的个数仍是独未决的问题,实际被大多用“试错法”来调整

 

2.3  层数设置

   OpenCV 中,设置神经网络层数和神经元个数的函数为
setLayerSizes(InputArray _layer_sizes),则高达图对应之 InputArray
可由于如下代码来做

// (a) 3层,输入层神经元个数为 4,隐层的为 6,输出层的为 4
Mat layers_size = (Mat_<int>(1,3) << 4,6,4);

// (b) 4层,输入层神经元个数为 4,第一个隐层的为 6,第二个隐层的为 5,输出层的为 4
Mat layers_size = (Mat_<int>(1,4) << 4,6,5,4);

  
如何设置隐层神经元的个数按照是单未决的题材,实际中多应用“试错法”来调动

 

3  OpenCV 函数

3  OpenCV 函数

1)  创建

static Ptr<ANN_MLP> cv::ml::ANN_MLP::create();  // 创建空模型

1)  创建

static Ptr<ANN_MLP> cv::ml::ANN_MLP::create();  // 创建空模型

2) 设置参数

// 设置神经网络的层数和神经元数量
virtual void cv::ml::ANN_MLP::setLayerSizes(InputArray _layer_sizes);

// 设置激活函数,目前只支持 ANN_MLP::SIGMOID_SYM
virtual void cv::ml::ANN_MLP::setActivationFunction(int type, double param1 = 0, double param2 = 0); 

// 设置训练方法,默认为 ANN_MLP::RPROP,较常用的是 ANN_MLP::BACKPROP
// 若设为 ANN_MLP::BACKPROP,则 param1 对应 setBackpropWeightScale()中的参数,param2 对应 setBackpropMomentumScale() 中的参数
virtual void cv::ml::ANN_MLP::setTrainMethod(int method, double param1 = 0, double param2 = 0);
virtual void cv::ml::ANN_MLP::setBackpropWeightScale(double val); // 默认值为 0.1
virtual void cv::ml::ANN_MLP::setBackpropMomentumScale(double val); // 默认值为 0.1

// 设置迭代终止准则,默认为 TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.01)
virtual void cv::ml::ANN_MLP::setTermCriteria(TermCriteria val);

2) 设置参数

// 设置神经网络的层数和神经元数量
virtual void cv::ml::ANN_MLP::setLayerSizes(InputArray _layer_sizes);

// 设置激活函数,目前只支持 ANN_MLP::SIGMOID_SYM
virtual void cv::ml::ANN_MLP::setActivationFunction(int type, double param1 = 0, double param2 = 0); 

// 设置训练方法,默认为 ANN_MLP::RPROP,较常用的是 ANN_MLP::BACKPROP
// 若设为 ANN_MLP::BACKPROP,则 param1 对应 setBackpropWeightScale()中的参数,param2 对应 setBackpropMomentumScale() 中的参数
virtual void cv::ml::ANN_MLP::setTrainMethod(int method, double param1 = 0, double param2 = 0);
virtual void cv::ml::ANN_MLP::setBackpropWeightScale(double val); // 默认值为 0.1
virtual void cv::ml::ANN_MLP::setBackpropMomentumScale(double val); // 默认值为 0.1

// 设置迭代终止准则,默认为 TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.01)
virtual void cv::ml::ANN_MLP::setTermCriteria(TermCriteria val);

3)  训练

// samples - 训练样本; layout - 训练样本为 “行样本” ROW_SAMPLE 或 “列样本” COL_SAMPLE; response - 对应样本数据的分类结果
virtual bool cv::ml::StatModel::train(InputArray samples,int layout,InputArray responses);  

3)  训练

// samples - 训练样本; layout - 训练样本为 “行样本” ROW_SAMPLE 或 “列样本” COL_SAMPLE; response - 对应样本数据的分类结果
virtual bool cv::ml::StatModel::train(InputArray samples,int layout,InputArray responses);  

4)  预测

// samples,输入的样本书数据;results,输出矩阵,默认不输出;flags,标识,默认为 0
virtual float cv::ml::StatModel::predict(InputArray samples, OutputArray results=noArray(),int flags=0) const;       

 

4)  预测

// samples,输入的样本书数据;results,输出矩阵,默认不输出;flags,标识,默认为 0
virtual float cv::ml::StatModel::predict(InputArray samples, OutputArray results=noArray(),int flags=0) const;       

 

4 代码示例

  下面是 OpenCV 3.3 中,在“支持为量机”的例程上召开的改动,使用 BP
神经网络,实现了跟 SVM 相同的分类功能。

   OpenCV 中的 支持向量机 (Support Vector Machine),可参见另一样首博文
OpenCV 之 支持向量机
(一)

 1 #include "opencv2/core/core.hpp"
 2 #include "opencv2/imgproc/imgproc.hpp"
 3 #include "opencv2/imgcodecs/imgcodecs.hpp"
 4 #include "opencv2/highgui/highgui.hpp"
 5 #include "opencv2/ml/ml.hpp"
 6 
 7 using namespace cv;
 8 
 9 int main()
10 {
11     // 512 x 512 零矩阵
12     int width = 512, height = 512;
13     Mat img = Mat::zeros(height, width, CV_8UC3);
14 
15     // 训练样本
16     float train_data[6][2] = { { 500, 60 },{ 245, 40 },{ 480, 250 },{ 160, 380 },{400, 25},{55, 400} };
17     float labels[6] = {0,0,0,1,0,1};  // 每个样本数据对应的输出
18     Mat train_data_mat(6, 2, CV_32FC1, train_data);
19     Mat labels_mat(6, 1, CV_32FC1, labels);
20 
21     // BP 模型创建和参数设置
22     Ptr<ml::ANN_MLP> bp = ml::ANN_MLP::create();
23 
24     Mat layers_size = (Mat_<int>(1,3) << 2,6,1); // 2维点,1维输出
25     bp->setLayerSizes(layers_size);
26 
27     bp->setTrainMethod(ml::ANN_MLP::BACKPROP,0.1,0.1);
28     bp->setActivationFunction(ml::ANN_MLP::SIGMOID_SYM);
29     bp->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 10000, /*FLT_EPSILON*/1e-6));
30 
31     // 保存训练好的神经网络参数
32     bool trained = bp->train(train_data_mat,ml::ROW_SAMPLE,labels_mat);
33     if (trained) {
34         bp->save("bp_param");
35     }
36 
37     // 创建训练好的神经网络
38 //    Ptr<ml::ANN_MLP> bp = ml::ANN_MLP::load("bp_param");
39 
40     // 显示分类的结果
41     Vec3b green(0, 255, 0), blue(255, 0, 0);
42     for (auto i=0; i<img.rows; ++i) {
43         for (auto j=0; j<img.cols; ++j) {
44             Mat sample_mat = (Mat_<float>(1, 2) << j, i);
45             Mat response_mat;
46             bp->predict(sample_mat,response_mat);
47             float response = response_mat.ptr<float>(0)[0];
48             if (response > 0.5) {
49                 img.at<Vec3b>(i, j) = green;
50             } else if (response < 0.5) {
51                 img.at<Vec3b>(i, j) = blue;
52             }
53         }
54     }
55 
56     // 画出训练样本数据
57     int thickness = -1;
58     int lineType = 8;
59     circle(img, Point(500, 60), 5, Scalar(255, 255, 255), thickness, lineType);
60     circle(img, Point(245, 40), 5, Scalar(255, 255, 255), thickness, lineType);
61     circle(img, Point(480, 250), 5, Scalar(255, 255, 255), thickness, lineType);
62     circle(img, Point(160, 380), 5, Scalar(0, 0, 255), thickness, lineType);
63     circle(img, Point(400, 25), 5, Scalar(255, 255, 255), thickness, lineType);
64     circle(img, Point(55, 400), 5, Scalar(0, 0, 255), thickness, lineType);
65 
66     imwrite("result.png", img);        // 保存训练的结果
67     imshow("BP Simple Example", img);
68 
69     waitKey(0);
70 }

   运行结果如下所示:

  betway88必威 11 

小心:OpenCV 3.0
以上版本,相较之前的版,其中关于机器上的一对做了比较生改,本人为是踩了一部分坑才拿走预期的意义。

 1)  代码 #25,必须在 setActivationFunction()
之前,否则训练后的结果基本上啊 nan

 2)  代码 #46,response_mat
为预测的结果betway88必威。若输出向量为 1 列,则要 #47
所著,可直接取出预测结果;若输出向量为 n 列,则可获平均值或者太酷价值。

      同时,根据平均值或最要命价值,代码 #48 处之阈值也要对应的更改。

    float response = 0;
    for (auto i=0;i<n;++i) {
          response += response_mat.ptr<float>(0)[i];
    }

 3)  代码 #39,若曾训练好神经网络的参数,并以该保存至文件
bp_param 中。

      则可将 #22 ~ #35 全部注掉,再倒注释掉
#38,这样,直接加载训练好的神经网络,便足以使了。

 

4 代码示例

  下面是 OpenCV 3.3 中,在“支持为量机”的例程上做的修改,使用 BP
神经网络,实现了同 SVM 相同之分类功能。

   OpenCV 中之 支持向量机 (Support Vector Machine),可参见另一样首博文
OpenCV 之 支持向量机
(一)

 1 #include "opencv2/core/core.hpp"
 2 #include "opencv2/imgproc/imgproc.hpp"
 3 #include "opencv2/imgcodecs/imgcodecs.hpp"
 4 #include "opencv2/highgui/highgui.hpp"
 5 #include "opencv2/ml/ml.hpp"
 6 
 7 using namespace cv;
 8 
 9 int main()
10 {
11     // 512 x 512 零矩阵
12     int width = 512, height = 512;
13     Mat img = Mat::zeros(height, width, CV_8UC3);
14 
15     // 训练样本
16     float train_data[6][2] = { { 500, 60 },{ 245, 40 },{ 480, 250 },{ 160, 380 },{400, 25},{55, 400} };
17     float labels[6] = {0,0,0,1,0,1};  // 每个样本数据对应的输出
18     Mat train_data_mat(6, 2, CV_32FC1, train_data);
19     Mat labels_mat(6, 1, CV_32FC1, labels);
20 
21     // BP 模型创建和参数设置
22     Ptr<ml::ANN_MLP> bp = ml::ANN_MLP::create();
23 
24     Mat layers_size = (Mat_<int>(1,3) << 2,6,1); // 2维点,1维输出
25     bp->setLayerSizes(layers_size);
26 
27     bp->setTrainMethod(ml::ANN_MLP::BACKPROP,0.1,0.1);
28     bp->setActivationFunction(ml::ANN_MLP::SIGMOID_SYM);
29     bp->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 10000, /*FLT_EPSILON*/1e-6));
30 
31     // 保存训练好的神经网络参数
32     bool trained = bp->train(train_data_mat,ml::ROW_SAMPLE,labels_mat);
33     if (trained) {
34         bp->save("bp_param");
35     }
36 
37     // 创建训练好的神经网络
38 //    Ptr<ml::ANN_MLP> bp = ml::ANN_MLP::load("bp_param");
39 
40     // 显示分类的结果
41     Vec3b green(0, 255, 0), blue(255, 0, 0);
42     for (auto i=0; i<img.rows; ++i) {
43         for (auto j=0; j<img.cols; ++j) {
44             Mat sample_mat = (Mat_<float>(1, 2) << j, i);
45             Mat response_mat;
46             bp->predict(sample_mat,response_mat);
47             float response = response_mat.ptr<float>(0)[0];
48             if (response > 0.5) {
49                 img.at<Vec3b>(i, j) = green;
50             } else if (response < 0.5) {
51                 img.at<Vec3b>(i, j) = blue;
52             }
53         }
54     }
55 
56     // 画出训练样本数据
57     int thickness = -1;
58     int lineType = 8;
59     circle(img, Point(500, 60), 5, Scalar(255, 255, 255), thickness, lineType);
60     circle(img, Point(245, 40), 5, Scalar(255, 255, 255), thickness, lineType);
61     circle(img, Point(480, 250), 5, Scalar(255, 255, 255), thickness, lineType);
62     circle(img, Point(160, 380), 5, Scalar(0, 0, 255), thickness, lineType);
63     circle(img, Point(400, 25), 5, Scalar(255, 255, 255), thickness, lineType);
64     circle(img, Point(55, 400), 5, Scalar(0, 0, 255), thickness, lineType);
65 
66     imwrite("result.png", img);        // 保存训练的结果
67     imshow("BP Simple Example", img);
68 
69     waitKey(0);
70 }

   运行结果如下所示:

  betway88必威 12 

小心:OpenCV 3.0
以上版本,相较之前的本子,其中有关机器上的一部分做了于生改观,本人为是踩了有坑才取预期的机能。

 1)  代码 #25,必须在 setActivationFunction()
之前,否则训练后底结果基本上吧 nan

 2)  代码 #46,response_mat
为预测的结果。若输出向量为 1 列,则要 #47
所显示,可一直取出预测结果;若输出向量为 n 列,则可得平均值或者太老价值。

      同时,根据平均值或太酷价值,代码 #48 处的阈值也如对应的反。

    float response = 0;
    for (auto i=0;i<n;++i) {
          response += response_mat.ptr<float>(0)[i];
    }

 3)  代码 #39,若曾训练好神经网络的参数,并将那保存到文件
bp_param 中。

      则可将 #22 ~ #35 全部注掉,再倒注释掉
#38,这样,直接加载训练好的神经网络,便得以采用了。

 

参考资料

  <机器上> 周志华  第5段

  <统计上道> 李航  第1章

  OpenCV 3.0  Tutorials  — Neural Networks

 
OpenCV进阶的路:神经网络识别车牌字符 
    ☆Ronny丶

 【模式识别】OpenCV中采取神经网络
CvANN_MLP 
     xiaowei_cqu

 

参考资料

  <机器上> 周志华  第5章

  <统计上方式> 李航  第1段

  OpenCV 3.0  Tutorials  — Neural Networks

 
OpenCV进阶的路:神经网络识别车牌字符 
    ☆Ronny丶

 【模式识别】OpenCV中动用神经网络
CvANN_MLP 
     xiaowei_cqu

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注