When I try to train the network to output values to be 1, it gives me an error saying that "OpenCV Error: One of arguments' values is out of range (Some of new output training vector components run exceed the original range too much)".
My code is listed below. Near the end of the code I assign the value of 0.9 and it works. When I switch those values to 1.0, it fails. Thanks for any help you can provide.ee
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
using namespace cv;
using namespace ml;
using namespace std;
void add_noise(Mat &mat, float scale)
{
for (int j = 0; j < mat.rows; j++)
{
for (int i = 0; i < mat.cols; i++)
{
float noise = static_cast<float>(rand() % 256);
noise /= 255.0f;
mat.at<float>(j, i) = (mat.at<float>(j, i) + noise*scale) / (1.0f + scale);
if (mat.at<float>(j, i) < 0)
mat.at<float>(j, i) = 0;
else if (mat.at<float>(j, i) > 1)
mat.at<float>(j, i) = 1;
}
}
}
int main(void)
{
const int image_width = 64;
const int image_height = 64;
Mat dove = imread("dove.png", IMREAD_GRAYSCALE);
Mat flowers = imread("flowers.png", IMREAD_GRAYSCALE);
Mat peacock = imread("peacock.png", IMREAD_GRAYSCALE);
Mat statue = imread("statue.png", IMREAD_GRAYSCALE);
dove = dove.reshape(0, 1);
flowers = flowers.reshape(0, 1);
peacock = peacock.reshape(0, 1);
statue = statue.reshape(0, 1);
Mat flt_dove(dove.rows, dove.cols, CV_32FC1);
for (int j = 0; j < dove.rows; j++)
for (int i = 0; i < dove.cols; i++)
flt_dove.at<float>(j, i) = dove.at<unsigned char>(j, i) / 255.0f;
Mat flt_flowers(flowers.rows, flowers.cols, CV_32FC1);
for (int j = 0; j < flowers.rows; j++)
for (int i = 0; i < flowers.cols; i++)
flt_flowers.at<float>(j, i) = flowers.at<unsigned char>(j, i) / 255.0f;
Mat flt_peacock(peacock.rows, peacock.cols, CV_32FC1);
for (int j = 0; j < peacock.rows; j++)
for (int i = 0; i < peacock.cols; i++)
flt_peacock.at<float>(j, i) = peacock.at<unsigned char>(j, i) / 255.0f;
Mat flt_statue = Mat(statue.rows, statue.cols, CV_32FC1);
for (int j = 0; j < statue.rows; j++)
for (int i = 0; i < statue.cols; i++)
flt_statue.at<float>(j, i) = statue.at<unsigned char>(j, i) / 255.0f;
const int num_input_neurons = dove.cols;
const int num_output_neurons = 2;
const int num_hidden_neurons = static_cast<int>(sqrtf(image_width*image_height*num_output_neurons));
Mat output_training_data = Mat(1, 2, CV_32F).clone();
Ptr<ANN_MLP> mlp = ANN_MLP::create();
mlp->setBackpropMomentumScale(0.1);
Mat layersSize = Mat(3, 1, CV_16U);
layersSize.row(0) = Scalar(num_input_neurons);
layersSize.row(1) = Scalar(num_hidden_neurons);
layersSize.row(2) = Scalar(num_output_neurons);
mlp->setLayerSizes(layersSize);
mlp->setActivationFunction(ANN_MLP::ActivationFunctions::SIGMOID_SYM);
TermCriteria termCrit = TermCriteria(TermCriteria::Type::COUNT + TermCriteria::Type::EPS, 1, 0.000001);
mlp->setTermCriteria(termCrit);
mlp->setTrainMethod(ANN_MLP::TrainingMethods::BACKPROP);
output_training_data.at<float>(0, 0) = 0;
output_training_data.at<float>(0, 1) = 0;
Ptr<TrainData> trainingData = TrainData::create(flt_dove, SampleTypes::ROW_SAMPLE, output_training_data);
mlp->train(trainingData);
for (int i = 0; i < 1000; i++)
{
if (i % 100 == 0)
cout << i << endl;
Mat flt_dove_noise = flt_dove.clone();
Mat flt_flowers_noise = flt_flowers.clone();
Mat flt_peacock_noise = flt_peacock.clone();
Mat flt_statue_noise = flt_statue.clone();
add_noise(flt_dove_noise, 0.1f);
add_noise(flt_flowers_noise, 0.1f);
add_noise(flt_peacock_noise, 0.1f);
add_noise(flt_statue_noise, 0.1f);
output_training_data.at<float>(0, 0) = 0;
output_training_data.at<float>(0, 1) = 0;
trainingData = TrainData::create(flt_dove_noise, SampleTypes::ROW_SAMPLE, output_training_data);
mlp->train(trainingData, ANN_MLP::TrainFlags::UPDATE_WEIGHTS);
output_training_data.at<float>(0, 0) = 0;
output_training_data.at<float>(0, 1) = 0.9f;
trainingData = TrainData::create(flt_flowers_noise, SampleTypes::ROW_SAMPLE, output_training_data);
mlp->train(trainingData, ANN_MLP::TrainFlags::UPDATE_WEIGHTS);
output_training_data.at<float>(0, 0) = 0.9f;
output_training_data.at<float>(0, 1) = 0;
trainingData = TrainData::create(flt_peacock_noise, SampleTypes::ROW_SAMPLE, output_training_data);
mlp->train(trainingData, ANN_MLP::TrainFlags::UPDATE_WEIGHTS);
output_training_data.at<float>(0, 0) = 0.9f;
output_training_data.at<float>(0, 1) = 0.9f;
trainingData = TrainData::create(flt_statue_noise, SampleTypes::ROW_SAMPLE, output_training_data);
mlp->train(trainingData, ANN_MLP::TrainFlags::UPDATE_WEIGHTS);
}
return 0;
}