From ea53b86767b0084fbe08a3eef9590d3de74fad0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= <traizetc@cesbio.cnes.fr> Date: Wed, 21 Jun 2017 09:42:51 +0200 Subject: [PATCH] DR is now based on Machine Learning Models, it is now possible to reduce de dimension of the pca model (it has to be changed in PCAModel.txx for now --- app/cbDimensionalityReductionVector.cxx | 20 +++++------ include/AutoencoderModel.h | 29 ++++++++++------ include/AutoencoderModel.txx | 4 +-- include/DimensionalityReductionModelFactory.h | 6 ++-- .../DimensionalityReductionModelFactory.txx | 24 ++++++++------ include/ImageDimensionalityReductionFilter.h | 5 +-- include/PCAModel.h | 33 ++++++++++++------- include/PCAModel.txx | 9 +++-- include/cbLearningApplicationBaseDR.h | 16 ++++----- include/cbLearningApplicationBaseDR.txx | 8 ++--- 10 files changed, 93 insertions(+), 61 deletions(-) diff --git a/app/cbDimensionalityReductionVector.cxx b/app/cbDimensionalityReductionVector.cxx index 90927c56c4..25ac852bd4 100644 --- a/app/cbDimensionalityReductionVector.cxx +++ b/app/cbDimensionalityReductionVector.cxx @@ -27,7 +27,7 @@ #include "itkListSample.h" #include "otbShiftScaleSampleListFilter.h" #include "DimensionalityReductionModelFactory.h" -#include "DimensionalityReductionModel.h" +//#include "DimensionalityReductionModel.h" #include <time.h> namespace otb @@ -57,16 +57,16 @@ class CbDimensionalityReductionVector : public Application /** Filters typedef */ - typedef double ValueType; - typedef DimensionalityReductionModel<ValueType,ValueType> DimensionalityReductionModelType; - typedef DimensionalityReductionModelFactory<ValueType, ValueType> DimensionalityReductionModelFactoryType; - typedef DimensionalityReductionModelType::Pointer ModelPointerType; + typedef double ValueType; + typedef itk::VariableLengthVector<ValueType> InputSampleType; + typedef itk::Statistics::ListSample<InputSampleType> ListSampleType; + typedef MachineLearningModel<itk::VariableLengthVector<ValueType>, itk::VariableLengthVector<ValueType>> DimensionalityReductionModelType; + typedef DimensionalityReductionModelFactory<ValueType,ValueType> DimensionalityReductionModelFactoryType; + typedef DimensionalityReductionModelType::Pointer ModelPointerType; /** Statistics Filters typedef */ - typedef itk::VariableLengthVector<ValueType> MeasurementType; - typedef otb::StatisticsXMLFileReader<MeasurementType> StatisticsReader; - typedef itk::VariableLengthVector<ValueType> InputSampleType; - typedef itk::Statistics::ListSample<InputSampleType> ListSampleType; + typedef itk::VariableLengthVector<ValueType> MeasurementType; + typedef otb::StatisticsXMLFileReader<MeasurementType> StatisticsReader; typedef otb::Statistics::ShiftScaleSampleListFilter<ListSampleType, ListSampleType> ShiftScaleFilterType; ~CbDimensionalityReductionVector() ITK_OVERRIDE { @@ -211,7 +211,7 @@ class CbDimensionalityReductionVector : public Application /** Read the model */ - + std::cout << "create the fact ?" << std::endl; m_Model = DimensionalityReductionModelFactoryType::CreateDimensionalityReductionModel(GetParameterString("model"), DimensionalityReductionModelFactoryType::ReadMode); if (m_Model.IsNull()) diff --git a/include/AutoencoderModel.h b/include/AutoencoderModel.h index 3fd4c44748..e9dd9d2b66 100644 --- a/include/AutoencoderModel.h +++ b/include/AutoencoderModel.h @@ -6,23 +6,31 @@ namespace otb { template <class TInputValue, class AutoencoderType> -class ITK_EXPORT AutoencoderModel: public DimensionalityReductionModel<TInputValue,TInputValue> +class ITK_EXPORT AutoencoderModel: public MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TInputValue>> { public: typedef AutoencoderModel Self; - typedef DimensionalityReductionModel<TInputValue,TInputValue> Superclass; + typedef MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TInputValue>> Superclass; typedef itk::SmartPointer<Self> Pointer; typedef itk::SmartPointer<const Self> ConstPointer; - typedef typename Superclass::InputValueType InputValueType; - typedef typename Superclass::InputSampleType InputSampleType; - typedef typename Superclass::InputListSampleType InputListSampleType; - typedef typename Superclass::TargetValueType TargetValueType; - typedef typename Superclass::TargetSampleType TargetSampleType; - typedef typename Superclass::TargetListSampleType TargetListSampleType; + typedef typename Superclass::InputValueType InputValueType; + typedef typename Superclass::InputSampleType InputSampleType; + typedef typename Superclass::InputListSampleType InputListSampleType; + typedef typename InputListSampleType::Pointer ListSamplePointerType; + typedef typename Superclass::TargetValueType TargetValueType; + typedef typename Superclass::TargetSampleType TargetSampleType; + typedef typename Superclass::TargetListSampleType TargetListSampleType; + + /// Confidence map related typedefs + typedef typename Superclass::ConfidenceValueType ConfidenceValueType; + typedef typename Superclass::ConfidenceSampleType ConfidenceSampleType; + typedef typename Superclass::ConfidenceListSampleType ConfidenceListSampleType; + + itkNewMacro(Self); itkTypeMacro(AutoencoderModel, DimensionalityReductionModel); @@ -59,8 +67,9 @@ protected: AutoencoderModel(); ~AutoencoderModel() ITK_OVERRIDE; - virtual TargetSampleType DoPredict(const InputSampleType& input) const ITK_OVERRIDE; - virtual void DoPredictBatch(const InputListSampleType *, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType *) const ITK_OVERRIDE; + virtual TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType * quality = ITK_NULLPTR) const; + + virtual void DoPredictBatch(const InputListSampleType *, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType *, ConfidenceListSampleType * quality = ITK_NULLPTR) const; private: diff --git a/include/AutoencoderModel.txx b/include/AutoencoderModel.txx index a23adb9ba2..3060d8fb30 100644 --- a/include/AutoencoderModel.txx +++ b/include/AutoencoderModel.txx @@ -171,7 +171,7 @@ void AutoencoderModel<TInputValue,AutoencoderType>::Load(const std::string & fil template <class TInputValue, class AutoencoderType> typename AutoencoderModel<TInputValue,AutoencoderType>::TargetSampleType -AutoencoderModel<TInputValue,AutoencoderType>::DoPredict(const InputSampleType & value) const +AutoencoderModel<TInputValue,AutoencoderType>::DoPredict(const InputSampleType & value, ConfidenceValueType * quality) const { shark::RealVector samples(value.Size()); for(size_t i = 0; i < value.Size();i++) @@ -200,7 +200,7 @@ AutoencoderModel<TInputValue,AutoencoderType>::DoPredict(const InputSampleType & template <class TInputValue, class AutoencoderType> void AutoencoderModel<TInputValue,AutoencoderType> -::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets) const +::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets, ConfidenceListSampleType * quality) const { std::vector<shark::RealVector> features; Shark::ListSampleRangeToSharkVector(input, features,startIndex,size); diff --git a/include/DimensionalityReductionModelFactory.h b/include/DimensionalityReductionModelFactory.h index 791199b5e8..16fa0f416d 100644 --- a/include/DimensionalityReductionModelFactory.h +++ b/include/DimensionalityReductionModelFactory.h @@ -18,9 +18,11 @@ #ifndef DimensionalityReductionModelFactory_h #define DimensionalityReductionModelFactory_h -#include "DimensionalityReductionModel.h" +//#include "DimensionalityReductionModel.h" #include "otbMachineLearningModelFactoryBase.h" +#include "otbMachineLearningModel.h" + namespace otb { /** \class MachineLearningModelFactory @@ -44,7 +46,7 @@ public: itkTypeMacro(DimensionalityReductionModelFactory, itk::Object); /** Convenient typedefs. */ - typedef otb::DimensionalityReductionModel<TInputValue,TOutputValue> DimensionalityReductionModelType; + typedef otb::MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TOutputValue>> DimensionalityReductionModelType; typedef typename DimensionalityReductionModelType::Pointer DimensionalityReductionModelTypePointer; /** Mode in which the files is intended to be used */ diff --git a/include/DimensionalityReductionModelFactory.txx b/include/DimensionalityReductionModelFactory.txx index a546978fb7..ac8f40c680 100644 --- a/include/DimensionalityReductionModelFactory.txx +++ b/include/DimensionalityReductionModelFactory.txx @@ -22,25 +22,25 @@ #include "otbConfigure.h" #include "SOMModelFactory.h" -/* + #ifdef OTB_USE_SHARK #include "AutoencoderModelFactory.h" #include "PCAModelFactory.h" #endif -*/ + #include "itkMutexLockHolder.h" namespace otb { -/* + template <class TInputValue, class TTargetValue> using AutoencoderModelFactory = AutoencoderModelFactoryBase<TInputValue, TTargetValue, shark::Autoencoder<shark::TanhNeuron, shark::LinearNeuron>> ; template <class TInputValue, class TTargetValue> using TiedAutoencoderModelFactory = AutoencoderModelFactoryBase<TInputValue, TTargetValue, shark::TiedAutoencoder< shark::TanhNeuron, shark::LinearNeuron>> ; -*/ + template <class TInputValue, class TTargetValue> using SOM2DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 2> ; @@ -56,7 +56,7 @@ using SOM5DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 5> ; template <class TInputValue, class TOutputValue> -typename DimensionalityReductionModel<TInputValue,TOutputValue>::Pointer +typename MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TOutputValue>>::Pointer DimensionalityReductionModelFactory<TInputValue,TOutputValue> ::CreateDimensionalityReductionModel(const std::string& path, FileModeType mode) { @@ -65,26 +65,30 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue> std::list<DimensionalityReductionModelTypePointer> possibleDimensionalityReductionModel; std::list<LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("DimensionalityReductionModel"); + for(std::list<LightObject::Pointer>::iterator i = allobjects.begin(); i != allobjects.end(); ++i) { - DimensionalityReductionModel<TInputValue,TOutputValue> * io = dynamic_cast<DimensionalityReductionModel<TInputValue,TOutputValue>*>(i->GetPointer()); + MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TOutputValue>> * io = dynamic_cast<MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TOutputValue>>*>(i->GetPointer()); if(io) { possibleDimensionalityReductionModel.push_back(io); } else { + std::cerr << "Error DimensionalityReductionModel Factory did not return an DimensionalityReductionModel: " << (*i)->GetNameOfClass() << std::endl; } } + for(typename std::list<DimensionalityReductionModelTypePointer>::iterator k = possibleDimensionalityReductionModel.begin(); k != possibleDimensionalityReductionModel.end(); ++k) { if( mode == ReadMode ) { + if((*k)->CanReadFile(path)) { return *k; @@ -115,13 +119,13 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue> RegisterFactory(SOM3DModelFactory<TInputValue,TOutputValue>::New()); RegisterFactory(SOM4DModelFactory<TInputValue,TOutputValue>::New()); RegisterFactory(SOM5DModelFactory<TInputValue,TOutputValue>::New()); - /* + #ifdef OTB_USE_SHARK RegisterFactory(PCAModelFactory<TInputValue,TOutputValue>::New()); RegisterFactory(AutoencoderModelFactory<TInputValue,TOutputValue>::New()); RegisterFactory(TiedAutoencoderModelFactory<TInputValue,TOutputValue>::New()); #endif - */ + } template <class TInputValue, class TOutputValue> @@ -182,7 +186,7 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue> itk::ObjectFactoryBase::UnRegisterFactory(som2dFactory); continue; } - /* + #ifdef OTB_USE_SHARK // Autoencoder @@ -211,7 +215,7 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue> continue; } #endif -*/ + } } diff --git a/include/ImageDimensionalityReductionFilter.h b/include/ImageDimensionalityReductionFilter.h index e550b1944d..008c57d2a4 100644 --- a/include/ImageDimensionalityReductionFilter.h +++ b/include/ImageDimensionalityReductionFilter.h @@ -19,7 +19,8 @@ #define ImageDimensionalityReduction_h #include "itkImageToImageFilter.h" -#include "DimensionalityReductionModel.h" +//#include "DimensionalityReductionModel.h" +#include "otbMachineLearningModel.h" #include "otbImage.h" namespace otb @@ -66,7 +67,7 @@ public: typedef typename OutputImageType::RegionType OutputImageRegionType; typedef typename OutputImageType::InternalPixelType LabelType; - typedef DimensionalityReductionModel<ValueType, LabelType> ModelType; + typedef MachineLearningModel<itk::VariableLengthVector<ValueType>, itk::VariableLengthVector<LabelType>> ModelType; typedef typename ModelType::Pointer ModelPointerType; typedef otb::Image<double> ConfidenceImageType; diff --git a/include/PCAModel.h b/include/PCAModel.h index 45693dfc8a..d5557eb169 100644 --- a/include/PCAModel.h +++ b/include/PCAModel.h @@ -7,29 +7,39 @@ namespace otb { template <class TInputValue> -class ITK_EXPORT PCAModel: public DimensionalityReductionModel<TInputValue,TInputValue> +class ITK_EXPORT PCAModel: public MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TInputValue>> { public: typedef PCAModel Self; - typedef DimensionalityReductionModel<TInputValue,TInputValue> Superclass; + typedef MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TInputValue>> Superclass; typedef itk::SmartPointer<Self> Pointer; typedef itk::SmartPointer<const Self> ConstPointer; - typedef typename Superclass::InputValueType InputValueType; - typedef typename Superclass::InputSampleType InputSampleType; - typedef typename Superclass::InputListSampleType InputListSampleType; - typedef typename Superclass::TargetValueType TargetValueType; - typedef typename Superclass::TargetSampleType TargetSampleType; - typedef typename Superclass::TargetListSampleType TargetListSampleType; + typedef typename Superclass::InputValueType InputValueType; + typedef typename Superclass::InputSampleType InputSampleType; + typedef typename Superclass::InputListSampleType InputListSampleType; + typedef typename InputListSampleType::Pointer ListSamplePointerType; + typedef typename Superclass::TargetValueType TargetValueType; + typedef typename Superclass::TargetSampleType TargetSampleType; + typedef typename Superclass::TargetListSampleType TargetListSampleType; + + /// Confidence map related typedefs + typedef typename Superclass::ConfidenceValueType ConfidenceValueType; + typedef typename Superclass::ConfidenceSampleType ConfidenceSampleType; + typedef typename Superclass::ConfidenceListSampleType ConfidenceListSampleType; + + itkNewMacro(Self); itkTypeMacro(PCAModel, DimensionalityReductionModel); unsigned int GetDimension() {return m_Dimension;}; itkSetMacro(Dimension,unsigned int); + itkSetMacro(Do_resize_flag,bool); + bool CanReadFile(const std::string & filename); bool CanWriteFile(const std::string & filename); @@ -44,15 +54,16 @@ protected: PCAModel(); ~PCAModel() ITK_OVERRIDE; - virtual TargetSampleType DoPredict(const InputSampleType& input) const ITK_OVERRIDE; - virtual void DoPredictBatch(const InputListSampleType *, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType *) const ITK_OVERRIDE; + virtual TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType * quality = ITK_NULLPTR) const; + + virtual void DoPredictBatch(const InputListSampleType *, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType *, ConfidenceListSampleType * quality = ITK_NULLPTR) const ITK_OVERRIDE; private: shark::LinearModel<> m_encoder; shark::LinearModel<> m_decoder; shark::PCA m_pca; unsigned int m_Dimension; - + bool m_Do_resize_flag; }; } // end namespace otb diff --git a/include/PCAModel.txx b/include/PCAModel.txx index 8f48040388..9cda11ec90 100644 --- a/include/PCAModel.txx +++ b/include/PCAModel.txx @@ -40,6 +40,7 @@ void PCAModel<TInputValue>::Train() shark::Data<shark::RealVector> inputSamples = shark::createDataFromRange( features ); m_pca.setData(inputSamples); m_pca.encoder(m_encoder, m_Dimension); + std::cout << m_encoder.matrix() << std::endl; m_pca.decoder(m_decoder, m_Dimension); } @@ -94,13 +95,17 @@ void PCAModel<TInputValue>::Load(const std::string & filename, const std::string m_encoder.read(ia); ifs.close(); m_Dimension = m_encoder.outputSize(); + auto eigenvectors = m_encoder.matrix(); + eigenvectors.resize(2,m_encoder.inputSize()); + m_encoder.setStructure(eigenvectors, m_encoder.offset() ); + std::cout << m_encoder.matrix() << std::endl; //this->m_Size = m_NumberOfHiddenNeurons; } template <class TInputValue> typename PCAModel<TInputValue>::TargetSampleType -PCAModel<TInputValue>::DoPredict(const InputSampleType & value) const +PCAModel<TInputValue>::DoPredict(const InputSampleType & value, ConfidenceValueType * quality) const { shark::RealVector samples(value.Size()); for(size_t i = 0; i < value.Size();i++) @@ -126,7 +131,7 @@ PCAModel<TInputValue>::DoPredict(const InputSampleType & value) const template <class TInputValue> void PCAModel<TInputValue> -::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets) const +::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets, ConfidenceListSampleType * quality) const { std::vector<shark::RealVector> features; diff --git a/include/cbLearningApplicationBaseDR.h b/include/cbLearningApplicationBaseDR.h index 71c31f40fe..b3bf030786 100644 --- a/include/cbLearningApplicationBaseDR.h +++ b/include/cbLearningApplicationBaseDR.h @@ -15,12 +15,12 @@ #include "DimensionalityReductionModelFactory.h" #include "SOMModel.h" -/* + #ifdef OTB_USE_SHARK #include "AutoencoderModel.h" #include "PCAModel.h" #endif -*/ + namespace otb { namespace Wrapper @@ -99,7 +99,7 @@ public: typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 5> Map5DType; typedef otb::SOMModel<InputValueType, 5> SOM5DModelType; -/* + #ifdef OTB_USE_SHARK typedef shark::Autoencoder< shark::TanhNeuron, shark::LinearNeuron> AutoencoderType; typedef otb::AutoencoderModel<InputValueType, AutoencoderType> AutoencoderModelType; @@ -109,7 +109,7 @@ public: typedef otb::PCAModel<InputValueType> PCAModelType; #endif - */ + protected: cbLearningApplicationBaseDR(); @@ -136,7 +136,7 @@ private: template <class somchoice> void TrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath); void BeforeTrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath); -/* + #ifdef OTB_USE_SHARK void InitAutoencoderParams(); void InitPCAParams(); @@ -148,7 +148,7 @@ private: void TrainPCA(typename ListSampleType::Pointer trainingListSample, std::string modelPath); -#endif */ +#endif //@} }; @@ -158,11 +158,11 @@ private: #ifndef OTB_MANUAL_INSTANTIATION #include "cbLearningApplicationBaseDR.txx" #include "cbTrainSOM.txx" -/* + #ifdef OTB_USE_SHARK #include "cbTrainAutoencoder.txx" #include "cbTrainPCA.txx" -#endif*/ +#endif #endif #endif diff --git a/include/cbLearningApplicationBaseDR.txx b/include/cbLearningApplicationBaseDR.txx index 2befe3e396..a42ad73857 100644 --- a/include/cbLearningApplicationBaseDR.txx +++ b/include/cbLearningApplicationBaseDR.txx @@ -50,12 +50,12 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> InitSOMParams(); - /* + #ifdef OTB_USE_SHARK InitAutoencoderParams(); InitPCAParams(); #endif - */ + } template <class TInputValue, class TOutputValue> @@ -80,7 +80,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> { BeforeTrainSOM(trainingListSample,modelPath); } - /* + if(modelName == "autoencoder") { #ifdef OTB_USE_SHARK @@ -105,7 +105,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> #else otbAppLogFATAL("Module SharkLearning is not installed. You should consider turning OTB_USE_SHARK on during cmake configuration."); #endif - }*/ + } } } -- GitLab