diff --git a/app/cbDimensionalityReduction.cxx b/app/cbDimensionalityReduction.cxx index abe3875264e729e45d343fc032115e1e913fe0fa..5a019b3989e26dc5210ed11b2776895cac03f78d 100644 --- a/app/cbDimensionalityReduction.cxx +++ b/app/cbDimensionalityReduction.cxx @@ -28,7 +28,6 @@ #include "otbImageToVectorImageCastFilter.h" #include "DimensionalityReductionModelFactory.h" -#include "PCAModel.h" namespace otb { diff --git a/include/AutoencoderModel.txx b/include/AutoencoderModel.txx index 8ae6e58b9dd94c85c1f634fdd1f7a0169af166a9..b0e206532ff2672e5558c1d02b2707539b8def2d 100644 --- a/include/AutoencoderModel.txx +++ b/include/AutoencoderModel.txx @@ -122,18 +122,20 @@ AutoencoderModel<TInputValue,AutoencoderType>::DoPredict(const InputSampleType & shark::RealVector samples(value.Size()); for(size_t i = 0; i < value.Size();i++) { - samples.push_back(value[i]); + samples[i]=value[i]; } - shark::Data<shark::RealVector> data; - data.element(0)=samples; - data = m_net.encode(data); + std::vector<shark::RealVector> features; + features.push_back(samples); + + shark::Data<shark::RealVector> data = shark::createDataFromRange(features); + + data = m_net.encode(data); TargetSampleType target; - - //target.SetSize(m_NumberOfHiddenNeurons); + target.SetSize(m_NumberOfHiddenNeurons); + for(unsigned int a = 0; a < m_NumberOfHiddenNeurons; ++a){ - //target[a]=data.element(0)[a]; - target=data.element(0)[a]; + target[a]=data.element(0)[a]; } return target; } @@ -143,7 +145,7 @@ template <class TInputValue, class AutoencoderType> void AutoencoderModel<TInputValue,AutoencoderType> ::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets, ConfidenceListSampleType * quality) const { - + std::cout << "BATCH" << std::endl; std::vector<shark::RealVector> features; Shark::ListSampleRangeToSharkVector(input, features,startIndex,size); shark::Data<shark::RealVector> data = shark::createDataFromRange(features); diff --git a/include/ImageDimensionalityReductionFilter.txx b/include/ImageDimensionalityReductionFilter.txx index 9d6f8d7085c5afcb2676dda4c6bdf14bd4b340c4..9f5b34cab24f0baea14dbb9618eaa9534a57c0ca 100644 --- a/include/ImageDimensionalityReductionFilter.txx +++ b/include/ImageDimensionalityReductionFilter.txx @@ -40,7 +40,7 @@ ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> this->SetNthOutput(0,TOutputImage::New()); this->SetNthOutput(1,ConfidenceImageType::New()); m_UseConfidenceMap = false; - m_BatchMode = true; + m_BatchMode = false; } template <class TInputImage, class TOutputImage, class TMaskImage> @@ -99,7 +99,7 @@ template <class TInputImage, class TOutputImage, class TMaskImage> void ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> ::ClassicThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) -{/* +{ // Get the input pointers InputImageConstPointerType inputPtr = this->GetInput(); MaskImageConstPointerType inputMaskPtr = this->GetInputMask(); @@ -118,61 +118,14 @@ ImageDimensionalityReductionFilter<TInputImage, TOutputImage, TMaskImage> InputIteratorType inIt(inputPtr, outputRegionForThread); OutputIteratorType outIt(outputPtr, outputRegionForThread); - // Eventually iterate on masks - MaskIteratorType maskIt; - if (inputMaskPtr) - { - maskIt = MaskIteratorType(inputMaskPtr, outputRegionForThread); - maskIt.GoToBegin(); - } - - // setup iterator for confidence map - bool computeConfidenceMap(m_UseConfidenceMap && m_Model->HasConfidenceIndex() && !m_Model->GetRegressionMode()); - ConfidenceMapIteratorType confidenceIt; - if (computeConfidenceMap) - { - confidenceIt = ConfidenceMapIteratorType(confidencePtr,outputRegionForThread); - confidenceIt.GoToBegin(); - } - - bool validPoint = true; - double confidenceIndex = 0.0; - // Walk the part of the image for (inIt.GoToBegin(), outIt.GoToBegin(); !inIt.IsAtEnd() && !outIt.IsAtEnd(); ++inIt, ++outIt) { - // Check pixel validity - if (inputMaskPtr) - { - validPoint = maskIt.Get() > 0; - ++maskIt; - } - // If point is valid - if (validPoint) - { - // Classifify - if (computeConfidenceMap) - { - outIt.Set(m_Model->Predict(inIt.Get(),&confidenceIndex)[0]); - } - else - { - outIt.Set(m_Model->Predict(inIt.Get())[0]); - } - } - else - { - // else, set default value - outIt.Set(m_DefaultLabel); - confidenceIndex = 0.0; - } - if (computeConfidenceMap) - { - confidenceIt.Set(confidenceIndex); - ++confidenceIt; - } + // Classifify + + outIt.Set(m_Model->Predict(inIt.Get())); progress.CompletedPixel(); - }*/ + } } diff --git a/include/PCAModel.h b/include/PCAModel.h index 529d2fa9bb8ecd2ece54d81e061c25c29e02b899..96d0e235c0cddadf90bddd390da83586799b5435 100644 --- a/include/PCAModel.h +++ b/include/PCAModel.h @@ -31,7 +31,7 @@ public: itkTypeMacro(AutoencoderModel, DimensionalityReductionModel); unsigned int GetDimension() {return m_Dimension;}; - //itkGetMacro(Dimension,unsigned int); + itkSetMacro(Dimension,unsigned int); bool CanReadFile(const std::string & filename); bool CanWriteFile(const std::string & filename); diff --git a/include/PCAModel.txx b/include/PCAModel.txx index 329b2558cf77626de248f505844aed3664111f38..c7625e661e8bbae0eb54cd81281b96807d5640d1 100644 --- a/include/PCAModel.txx +++ b/include/PCAModel.txx @@ -1,6 +1,6 @@ -#ifndef AutoencoderModel_txx -#define AutoencoderModel_txx +#ifndef PCAModel_txx +#define PCAModel_txx #include <fstream> #include <shark/Data/Dataset.h> @@ -24,7 +24,7 @@ PCAModel<TInputValue>::PCAModel() template <class TInputValue> -PCAModel<TInputValue,AutoencoderType>::~PCAModel() +PCAModel<TInputValue>::~PCAModel() { } @@ -38,10 +38,10 @@ void PCAModel<TInputValue>::Train() Shark::ListSampleToSharkVector(this->GetInputListSample(), features); shark::Data<shark::RealVector> inputSamples = shark::createDataFromRange( features ); - - m_pca(inputSamples); - pca.encoder(m_encoder, m_Dimension); - pca.decoder(m_decoder, m_Dimension); + //m_pca.train(m_encoder,inputSamples); + m_pca.setData(inputSamples); + m_pca.encoder(m_encoder, m_Dimension); + m_pca.decoder(m_decoder, m_Dimension); } @@ -72,7 +72,8 @@ template <class TInputValue> void PCAModel<TInputValue>::Save(const std::string & filename, const std::string & name) { std::ofstream ofs(filename); - ofs << m_encoder.name() << std::endl; //first line + //ofs << m_encoder.name() << std::endl; //first line + ofs << "pca" << std::endl; //first line boost::archive::polymorphic_text_oarchive oa(ofs); m_encoder.write(oa); ofs.close(); @@ -86,11 +87,12 @@ void PCAModel<TInputValue>::Load(const std::string & filename, const std::string ifs.getline(encoder,256); std::string encoderstr(encoder); - if (autoencoderstr != m_encoder.name()){ + //if (encoderstr != m_encoder.name()){ + if (encoderstr != "pca"){ itkExceptionMacro(<< "Error opening " << filename.c_str() ); } boost::archive::polymorphic_text_iarchive ia(ifs); - m_net.read(ia); + m_encoder.read(ia); ifs.close(); m_Dimension = m_encoder.outputSize(); //this->m_Size = m_NumberOfHiddenNeurons; @@ -104,22 +106,20 @@ PCAModel<TInputValue>::DoPredict(const InputSampleType & value, ConfidenceValueT shark::RealVector samples(value.Size()); for(size_t i = 0; i < value.Size();i++) { - samples.push_back(value[i]); + samples[i]=value[i]; } - shark::Data<shark::RealVector> data; - data.element(0)=samples; - data = m_encoder(data); + std::vector<shark::RealVector> features; + features.push_back(samples); + + shark::Data<shark::RealVector> data = shark::createDataFromRange(features); + + data = m_encoder(data); TargetSampleType target; - - //target.SetSize(m_NumberOfHiddenNeurons); + target.SetSize(m_Dimension); - for(unsigned int a = 0; a < m_NumberOfHiddenNeurons; ++a){ - target[a]=p[a]; - - //target.SetElement(a,p[a]); - - + for(unsigned int a = 0; a < m_Dimension; ++a){ + target[a]=data.element(0)[a]; } return target; } @@ -136,11 +136,12 @@ void PCAModel<TInputValue> TargetSampleType target; data = m_encoder(data); unsigned int id = startIndex; - target.SetSize(m_NumberOfHiddenNeurons); + target.SetSize(m_Dimension); for(const auto& p : data.elements()){ - for(unsigned int a = 0; a < m_NumberOfHiddenNeurons; ++a){ + for(unsigned int a = 0; a < m_Dimension; ++a){ target[a]=p[a]; + //target[a]=1; //target.SetElement(a,p[a]); diff --git a/include/PCAModelFactory.txx b/include/PCAModelFactory.txx index 2a0ff98b44a2f9a352be9eb2018dba75180ffce8..bfaa4f6f624b12d8351defb1bc52ad9a4d37253e 100644 --- a/include/PCAModelFactory.txx +++ b/include/PCAModelFactory.txx @@ -15,15 +15,15 @@ PURPOSE. See the above copyright notices for more information. =========================================================================*/ -#ifndef AutoencoderModelFactory_txx -#define AutoencoderModelFactory_txx +#ifndef PCAFactory_txx +#define PCAFactory_txx -#include "AutoencoderModelFactory.h" +#include "PCAModelFactory.h" #include "itkCreateObjectFunction.h" -#include "AutoencoderModel.h" -#include <shark/Algorithms/Trainers/PCA.h> +#include "PCAModel.h" +//#include <shark/Algorithms/Trainers/PCA.h> #include "itkVersion.h" namespace otb @@ -40,7 +40,7 @@ PCAModelFactory<TInputValue,TOutputValue>::PCAModelFactory() "Shark PCA ML Model", 1, // itk::CreateObjectFunction<AutoencoderModel<TInputValue,TOutputValue> >::New()); - itk::CreateObjectFunction<PCAModel<TInputValue,shark::LinearModel<> > >::New()); + itk::CreateObjectFunction<PCAModel<TInputValue>>::New()); } template <class TInputValue, class TOutputValue> diff --git a/include/cbLearningApplicationBaseDR.h b/include/cbLearningApplicationBaseDR.h index abd8cfc55f801a69747ec1e9f143e6cf36ff6ebd..7a467e242e39ce709d97df95ce30a19f83de3cf4 100644 --- a/include/cbLearningApplicationBaseDR.h +++ b/include/cbLearningApplicationBaseDR.h @@ -91,6 +91,8 @@ public: typedef shark::TiedAutoencoder< shark::TanhNeuron, shark::LinearNeuron> TiedAutoencoderType; typedef otb::AutoencoderModel<InputValueType, TiedAutoencoderType> TiedAutoencoderModelType; + + typedef otb::PCAModel<InputValueType> PCAModelType; #endif protected: @@ -117,8 +119,10 @@ private: #ifdef OTB_USE_SHARK void InitAutoencoderParams(); + void InitPCAParams(); template <class autoencoderchoice> void TrainAutoencoder(typename ListSampleType::Pointer trainingListSample, std::string modelPath); + void TrainPCA(typename ListSampleType::Pointer trainingListSample, std::string modelPath); #endif //@} }; @@ -130,6 +134,7 @@ private: #include "cbLearningApplicationBaseDR.txx" #ifdef OTB_USE_SHARK #include "cbTrainAutoencoder.txx" +#include "cbTrainPCA.txx" #endif #endif diff --git a/include/cbLearningApplicationBaseDR.txx b/include/cbLearningApplicationBaseDR.txx index 344b6eccfc85ee309d8e1a51214b94133fb7a7b4..562b5e395b5599d11e0885cf2d4c73f9096b908a 100644 --- a/include/cbLearningApplicationBaseDR.txx +++ b/include/cbLearningApplicationBaseDR.txx @@ -51,6 +51,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> #ifdef OTB_USE_SHARK InitAutoencoderParams(); + InitPCAParams(); #endif } @@ -114,6 +115,15 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> otbAppLogFATAL("Module SharkLearning is not installed. You should consider turning OTB_USE_SHARK on during cmake configuration."); #endif } + + if(modelName == "pca") + { + #ifdef OTB_USE_SHARK + TrainPCA(trainingListSample,modelPath); + #else + otbAppLogFATAL("Module SharkLearning is not installed. You should consider turning OTB_USE_SHARK on during cmake configuration."); + #endif + } } } diff --git a/include/cbTrainPCA.txx b/include/cbTrainPCA.txx new file mode 100644 index 0000000000000000000000000000000000000000..9c02c566cd83f49c4d011050140acaca3e10cee2 --- /dev/null +++ b/include/cbTrainPCA.txx @@ -0,0 +1,50 @@ + +#ifndef cbTrainPCA_txx +#define cbTrainPCA_txx + +#include "cbLearningApplicationBaseDR.h" + +namespace otb +{ +namespace Wrapper +{ + +template <class TInputValue, class TOutputValue> +void +cbLearningApplicationBaseDR<TInputValue,TOutputValue> +::InitPCAParams() +{ + + + AddChoice("model.pca", "Shark PCA"); + SetParameterDescription("model.pca", + "This group of parameters allows setting Shark PCA parameters. " + ); + + + //Output Dimension + AddParameter(ParameterType_Int, "model.pca.dim", + "Dimension of the output of the pca transformation"); + SetParameterInt("model.pca.dim",10, false); + SetParameterDescription( + "model.pca.dim", + "Dimension of the output of the pca transformation."); + + +} + +template <class TInputValue, class TOutputValue> +void cbLearningApplicationBaseDR<TInputValue,TOutputValue> +::TrainPCA(typename ListSampleType::Pointer trainingListSample,std::string modelPath) +{ + typename PCAModelType::Pointer dimredTrainer = PCAModelType::New(); + dimredTrainer->SetDimension(GetParameterInt("model.pca.dim")); + dimredTrainer->SetInputListSample(trainingListSample); + dimredTrainer->Train(); + dimredTrainer->Save(modelPath); +} + +} //end namespace wrapper +} //end namespace otb + +#endif diff --git a/otb-module.cmake b/otb-module.cmake index 8b1eb2c05c22e88c2a0a938f46b0ec2f2ea87af0..f4a7c8f8cab47d1b8ab0ec5a3a9af4f91e07bdd7 100644 --- a/otb-module.cmake +++ b/otb-module.cmake @@ -8,6 +8,7 @@ otb_module(CbDimensionalityReduction OTBBoost OTBSupervised OTBAppClassification + OTBSOM DESCRIPTION "${DOCUMENTATION}" )