OpenCV神经网络ANN代码编译运行与解读(一)

运行环境搭建:参考《VS2013安装OpenCV4.1版本并搭建一个小程序》

  • 基于OpenCV4.1.0中neural_network.cpp的例子代码。
  • 参考了《OpenCV3【神经网络】ANN_MLP》中的部分代码和注释内容。
  • BP神经网络原理可参考《置顶 | 2019书单》中机器学习入门部分:

神经网络算法:(以后向传播神经网络为例:Back Propagation)分为一个输入层(神经元数量与特征向量维度相同),多个隐藏层,一个输出层(如果是分类算法,神经元数量与集合数量相同)。每一层的神经元与相邻层的所有神经元之间都有边相连,每个神经元的输入为:(上层所有神经元值与边的权重乘积求和+本神经元的偏执常量)x激励函数。先将输入标准化到区间[0,1],随机给出每条边的初始权重在取间[-1,1]内和偏置值。然后逐层向下计算出结果。神经网络的训练过程是:给出初始权重和偏执,然后通过训练集,自动的调整每条边权重和每个神经元偏置的过程。正向过程全部算完后,根据误差值(通过loss function,即误差函数或损失函数)和给定的学习率再按照给定算法反向计算一遍可以得出每条边的调整后的权重,和每个节点的调整后的偏置。每一组数据可以多次使用直至输出达到可以接受的氛围,经过大量数据的正向计算和反向调整后,即可得到训练好的权重值和偏置值,即训练好的神经网络。(相邻两层神经元之间的权重可以视为一个矩阵,矩阵的长度和宽度分别是上层神经元和下层神经元的数量,由此整个神经网络的计算可以视为若干个矩阵的乘法。)

#include 
#include
#include
#include
#include 

using namespace std;
using namespace cv;
using namespace cv::ml;

const int SAMPLE_NUMBER = 200;	///样本数目///
const int FEATURE_NUMBER = 500;	///单个样本的特征值数目///

int main()
{
	//create random training data
	///data矩阵是训练数据集///
	Mat_ data(SAMPLE_NUMBER, FEATURE_NUMBER);///训练数据data///
	randn(data, Mat::zeros(1, 1, data.type()), Mat::ones(1, 1, data.type()));//随机生成均值为0,标准差为1的数据data
	imshow("", data);
	waitKey(0);///显示data///

	//half of the samples for each class
	///responses矩阵是有监督训练的分类结果集///
	Mat_ responses(data.rows, 2);///行数代表样本数,2为每个样本对应的标签向量(1,0)或(0,1)///
	for (int i = 0; i < data.rows; ++i)
	{
		if (i < data.rows / 2)///前一半数据标签为(1,0)///
		{
			responses(i, 0) = 1;
			responses(i, 1) = 0;
		}
		else///后一半数据标签为(1,0)///
		{
			responses(i, 0) = 0;
			responses(i, 1) = 1;
		}
	}

	/*
	//example code for just a single response (regression)
	Mat_ responses(data.rows, 1);
	for (int i=0; i layerSizes(1, 3);
	layerSizes(0, 0) = data.cols;
	layerSizes(0, 1) = 20;
	layerSizes(0, 2) = responses.cols;

	Ptr network = ANN_MLP::create();///创建///
	network->setLayerSizes(layerSizes);///设置层数///
	network->setActivationFunction(ANN_MLP::SIGMOID_SYM, 0.1, 0.1);///激活函数:典型S型生长曲线函数///
	network->setTrainMethod(ANN_MLP::BACKPROP, 0.1, 0.1);///训练方法:反向传播算法。Backpropogation///
	Ptr trainData = TrainData::create(data, ROW_SAMPLE, responses);///创建训练数据,ROW_SAMPLE表示data中每行为一个样本///

	network->train(trainData);///训练///
	cout << "========== Train Finish ==========" << endl;

	if (network->isTrained())///是否训练完成///
	{
		printf("Predict one-vector:\n");
		Mat result;
		network->predict(Mat::ones(1, data.cols, data.type()), result);///预测全为1的一个样本,得到结果result///
		cout << result << endl;

		printf("Predict training data:\n");
		for (int i = 0; i < data.rows; ++i)
		{
			network->predict(data.row(i), result);///预测训练样本,得到结果result///
			cout << result << endl;
		}
	}
	cout << "========== Display Finish ==========" << endl;

	network->save("h:\\s.xml");//保存训练好的网络
	cout << "Save trained network ..." << endl;

	Ptr bp = ANN_MLP::load("h:\\s.xml");///创建并加载保存的网络///
	//bp->load();
	cout << "Load trained network ..." << endl;

	///仍然使用训练集进行测试,得到一样的结果,依次可以证明加载保存的神经网络是成功的///
	if (1)///测试加载成功,与训练的网络一致///
	{
		printf("Predict one-vector:\n");
		Mat result;
		bp->predict(Mat::ones(1, data.cols, data.type()), result);
		cout << result << endl;

		printf("Predict training data:\n");
		for (int i = 0; i < data.rows; ++i)
		{
			bp->predict(data.row(i), result);
			cout << result << endl;
		}
	}
	Mat I = Mat::ones(10, 10, data.type());
	cout << endl << I << endl;
	putchar(1);
	return 0;
}

完整工程项目(VS2013)可以从 OpenCV4-ANN神经网络配套工程项目完整代码 下载

另外点击 这里 可以下载一个早期的VS2013+OpenCV2.3.1实现的K近邻算法(KNN)实现的旋钮图片分类工程项目代码。

你可能感兴趣的:(神经网络与AI,openCV,云大物移智)