21 #ifndef otbNeuralNetworkMachineLearningModel_hxx
22 #define otbNeuralNetworkMachineLearningModel_hxx
31 template <
class TInputValue,
class TOutputValue>
34 m_ANNModel(cv::ml::ANN_MLP::create()),
36 m_ActivateFunction(
CvANN_MLP::SIGMOID_SYM),
39 m_BackPropDWScale(0.1),
40 m_BackPropMomentScale(0.1),
42 m_RegPropDWMin(FLT_EPSILON),
43 m_TermCriteriaType(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS),
52 template <
class TInputValue,
class TOutputValue>
55 const unsigned int nbLayers = layers.size();
57 itkExceptionMacro(<<
"Number of layers in the Neural Network must be >= 3")
59 m_LayerSizes = layers;
67 template <
class TInputValue,
class TOutputValue>
70 unsigned int nbSamples = 0;
71 if (labels !=
nullptr)
73 nbSamples = labels->Size();
81 typename TargetListSampleType::ConstIterator labelSampleIt = labels->Begin();
84 for (; labelSampleIt != labels->End(); ++labelSampleIt)
87 typename TargetListSampleType::MeasurementVectorType labelSample = labelSampleIt.GetMeasurementVector();
88 classLabel = labelSample[0];
89 if (m_MapOfLabels.count(classLabel) == 0)
91 m_MapOfLabels[classLabel] = -1;
95 unsigned int nbClasses = m_MapOfLabels.size();
97 m_MatrixOfLabels = cv::Mat(1,nbClasses, CV_32FC1);
98 unsigned int itLabel = 0;
99 for (
auto& kv : m_MapOfLabels)
101 classLabel = kv.first;
103 m_MatrixOfLabels.at<
float>(0,itLabel) = classLabel;
108 unsigned int sampleIdx = 0;
109 labelSampleIt = labels->Begin();
110 output.create(nbSamples, nbClasses, CV_32FC1);
111 output.setTo(-m_Beta);
113 for (; labelSampleIt != labels->End(); ++labelSampleIt, ++sampleIdx)
116 typename TargetListSampleType::MeasurementVectorType labelSample = labelSampleIt.GetMeasurementVector();
117 classLabel = labelSample[0];
118 unsigned int indexLabel = m_MapOfLabels[classLabel];
119 output.at<
float>(sampleIdx, indexLabel) = m_Beta;
124 template <
class TInputValue,
class TOutputValue>
128 const unsigned int nbLayers = m_LayerSizes.size();
131 itkExceptionMacro(<<
"Number of layers in the Neural Network must be >= 3")
133 cv::Mat layers = cv::Mat(nbLayers, 1, CV_32SC1);
134 for (
unsigned int i = 0; i < nbLayers; i++)
136 layers.row(i) = m_LayerSizes[i];
139 m_ANNModel->setLayerSizes(layers);
140 m_ANNModel->setActivationFunction(m_ActivateFunction, m_Alpha, m_Beta);
144 template <
class TInputValue,
class TOutputValue>
149 otb::ListSampleToMat<InputListSampleType>(this->GetInputListSample(), samples);
150 this->CreateNetwork();
151 int flags = (this->m_RegressionMode ? 0 : cv::ml::ANN_MLP::NO_OUTPUT_SCALE);
152 m_ANNModel->setTrainMethod(m_TrainMethod);
153 m_ANNModel->setBackpropMomentumScale(m_BackPropMomentScale);
154 m_ANNModel->setBackpropWeightScale(m_BackPropDWScale);
155 m_ANNModel->setRpropDW0(m_RegPropDW0);
157 m_ANNModel->setRpropDWMin(m_RegPropDWMin);
160 m_ANNModel->setTermCriteria(cv::TermCriteria(m_TermCriteriaType, m_MaxIter, m_Epsilon));
161 m_ANNModel->train(cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels), flags);
165 template <
class TInputValue,
class TOutputValue>
169 cv::Mat matOutputANN;
170 if (this->m_RegressionMode)
173 otb::ListSampleToMat<TargetListSampleType>(this->GetTargetListSample(), matOutputANN);
178 LabelsToMat(this->GetTargetListSample(), matOutputANN);
180 this->SetupNetworkAndTrain(matOutputANN);
184 template <
class TInputValue,
class TOutputValue>
193 otb::SampleToMat<InputSampleType>(input, sample);
196 m_ANNModel->predict(sample, response);
198 float currentResponse = 0;
199 float maxResponse = response.at<
float>(0, 0);
201 if (this->m_RegressionMode)
204 target[0] = maxResponse;
209 float secondResponse = -1e10;
211 target[0] = m_MatrixOfLabels.at<TOutputValue>(0);
212 unsigned int nbClasses = m_MatrixOfLabels.size[1];
214 for (
unsigned itLabel = 1; itLabel < nbClasses; ++itLabel)
216 currentResponse = response.at<
float>(0, itLabel);
217 if (currentResponse > maxResponse)
219 secondResponse = maxResponse;
221 maxResponse = currentResponse;
222 target[0] = m_MatrixOfLabels.at<TOutputValue>(itLabel);
226 if (currentResponse > secondResponse)
228 secondResponse = currentResponse;
233 if (quality !=
nullptr)
237 if (proba !=
nullptr && !this->m_ProbaIndex)
238 itkExceptionMacro(
"Probability per class not available for this classifier !");
243 template <
class TInputValue,
class TOutputValue>
246 cv::FileStorage fs(filename, cv::FileStorage::WRITE);
247 fs << (name.empty() ? m_ANNModel->getDefaultName() : cv::String(name)) <<
"{";
248 m_ANNModel->write(fs);
250 if (!m_MatrixOfLabels.empty())
252 fs <<
"class_labels" << m_MatrixOfLabels;
258 template <
class TInputValue,
class TOutputValue>
261 cv::FileStorage fs(filename, cv::FileStorage::READ);
262 cv::FileNode model_node(name.empty() ? fs.getFirstTopLevelNode() : fs[name]);
263 m_ANNModel->read(model_node);
264 model_node[
"class_labels"] >> m_MatrixOfLabels;
268 template <
class TInputValue,
class TOutputValue>
276 std::cerr <<
"Could not read file " << file << std::endl;
283 std::getline(ifs, line);
285 if (line.find(
CV_TYPE_NAME_ML_ANN_MLP) != std::string::npos || line.find(m_ANNModel->getDefaultName()) != std::string::npos)
294 template <
class TInputValue,
class TOutputValue>
300 template <
class TInputValue,
class TOutputValue>
304 Superclass::PrintSelf(os, indent);