diff --git a/include/AutoencoderModel.h b/include/AutoencoderModel.h
index e9dd9d2b66e143dd91e94b735ca3df3cbd474bbf..939f592610212021c1164b9ac3716c4d9fd0d4b1 100644
--- a/include/AutoencoderModel.h
+++ b/include/AutoencoderModel.h
@@ -1,7 +1,8 @@
 #ifndef AutoencoderModel_h
 #define AutoencoderModel_h
 
-#include "DimensionalityReductionModel.h"
+#include "otbMachineLearningModelTraits.h"
+#include "otbMachineLearningModel.h"
 
 namespace otb
 {
diff --git a/include/DimensionalityReductionModel.h b/include/DimensionalityReductionModel.h
deleted file mode 100644
index c5026551ee884f0789dcd89dd232e74587949b83..0000000000000000000000000000000000000000
--- a/include/DimensionalityReductionModel.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*=========================================================================
-
-  Program:   ORFEO Toolbox
-  Language:  C++
-  Date:      $Date$
-  Version:   $Revision$
-
-
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
-
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef DimensionalityReductionModel_h
-#define DimensionalityReductionModel_h
-
-#include "itkObject.h"
-#include "itkVariableLengthVector.h"
-#include "itkListSample.h"
-
-namespace otb
-{
-
-/** \class DimensionalityReductionModel
- * \brief DimensionalityReductionModel is the base class for all dimensionality Reduction objects (PCA, autoencoders and SOM) implemented in the dimensionality Reduction framework of the OTB.
- *
- * DimensionalityReductionModel is an abstract object that specifies behavior and
- * interface of dimensionality reduction algorithms (PCA, autoencoders and SOM) in the generic dimensionality Reduction framework of the OTB.
- * The main generic virtual methods specifically implemented in each model
- * derived from the DimensionalityReductionModel class are two learning-related methods:
- * Train() and Save(), and three dimensionality reduction related methods: Load(),
- * DoPredict() and optionnaly DoPredictBatch().
- *
- * Thus, each classifier derived from the MachineLearningModel class
- * computes its corresponding model with Train() and exports it with
- * the help of the Save() method.
- *
- * It is also possible to reduce the dimensionality of any input sample composed of several
- * features (or any number of bands in the case of a pixel extracted
- * from a multi-band image) with the help of the Predict() method which
- * needs a previous loading of the classification model with the Load() method.
- *
- * \sa DimensionalityReductionModelFactory
- * \sa SOMModel
- * \sa PCAModel
- * \sa AutoencderModel
- * \sa ImageDimensionalityReductionFilter
- *
- * \ingroup cbDimensionalityReduction
- */
-template <class TInputValue, class TTargetValue>
-class ITK_EXPORT DimensionalityReductionModel
-  : public itk::Object
-{
-public:
-  /**\name Standard ITK typedefs */
-  //@{
-  typedef DimensionalityReductionModel                  Self;
-  typedef itk::Object                                   Superclass;
-  typedef itk::SmartPointer<Self>                       Pointer;
-  typedef itk::SmartPointer<const Self>                 ConstPointer;
-  //@}
-
-  /**\name Input related typedefs */
-  //@{
-  typedef TInputValue                                   InputValueType;
-  typedef itk::VariableLengthVector<InputValueType>     InputSampleType;
-  typedef itk::Statistics::ListSample<InputSampleType>  InputListSampleType;
-  //@}
-
-  /**\name Target related typedefs */
-  //@{
-  typedef TTargetValue                                  TargetValueType;
-  typedef itk::VariableLengthVector<TargetValueType>    TargetSampleType;
-  typedef itk::Statistics::ListSample<TargetSampleType> TargetListSampleType;
-  //@}
-
-  /**\name Standard macros */
-  //@{
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(DimensionalityReductionModel, itk::Object);
-  //@}
-
-  /** Train the machine learning model */
-  virtual void Train() =0;
-
-  /** Predict a single sample
-    * \param input The sample
-    * \param quality A pointer to the quality variable were to store
-    * quality value, or NULL
-    * \return The predicted label
-     */
-  TargetSampleType Predict(const InputSampleType& input) const;
-
-
-
-  /** Predict a batch of samples (InputListSampleType)
-    * \param input The batch of sample to predict
-    * \param quality A pointer to the list were to store
-    * quality value, or NULL
-    * \return The predicted labels
-    * Note that this method will be multi-threaded if OTB is built
-    * with OpenMP.
-     */
-  typename TargetListSampleType::Pointer PredictBatch(const InputListSampleType * input) const;
-  
-  /** Get the size of the output after dimensionality reduction */
-  virtual unsigned int GetDimension() = 0;
-
-  /**\name Dimensionality Reduction model file manipulation */
-  //@{
-  /** Save the model to file */
-  virtual void Save(const std::string & filename, const std::string & name="") = 0;
-
-  /** Load the model from file */
-  virtual void Load(const std::string & filename, const std::string & name="") = 0;
-  //@}
-
-  /**\name Classification model file compatibility tests */
-  //@{
-  /** Is the input model file readable and compatible with the corresponding model ? */
-  virtual bool CanReadFile(const std::string &) = 0;
-
-  /** Is the input model file writable and compatible with the corresponding model ? */
-  virtual bool CanWriteFile(const std::string &)  = 0;
-  //@}
-
-  /**\name Input list of samples accessors */
-  //@{
-  itkSetObjectMacro(InputListSample,InputListSampleType);
-  itkGetObjectMacro(InputListSample,InputListSampleType);
-  itkGetConstObjectMacro(InputListSample,InputListSampleType);
-  //@}
-
-
- 
-
-protected:
-  /** Constructor */
-  DimensionalityReductionModel();
-
-  /** Destructor */
-  ~DimensionalityReductionModel() ITK_OVERRIDE;
- 
-  /** PrintSelf method */
-  void PrintSelf(std::ostream& os, itk::Indent indent) const ITK_OVERRIDE;
-
-  /** Input list sample */
-  typename InputListSampleType::Pointer m_InputListSample;
-
-  /** Is DoPredictBatch multi-threaded ? */
-  bool m_IsDoPredictBatchMultiThreaded;
-  
-private:
-  /**  Actual implementation of BatchPredicition
-    *  Default implementation will call DoPredict iteratively 
-    *  \param input The input batch
-    *  \param startIndex Index of the first sample to reduce
-    *  \param size Number of samples to reduce
-    *  \param target Pointer to the list of reduced samples
-    * 
-    * Override me if internal implementation allows for batch
-    * prediction.
-    * 
-    * Also set m_IsDoPredictBatchMultiThreaded to true if internal
-    * implementation allows for parallel batch prediction.
-    */
-  virtual void DoPredictBatch(const InputListSampleType * input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * target) const;
-
-  /** Actual implementation of single sample reduction
-   *  \param input sample to reduce
-   *  \return The reduced sample
-   */ 
-  virtual TargetSampleType DoPredict(const InputSampleType& input) const = 0;  
- 
-  DimensionalityReductionModel(const Self &); //purposely not implemented
-  void operator =(const Self&); //purposely not implemented
-};
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "DimensionalityReductionModel.txx"
-#endif
-
-#endif
diff --git a/include/DimensionalityReductionModel.txx b/include/DimensionalityReductionModel.txx
deleted file mode 100644
index 5f49754f8c6f0304c50672e9b5f53b593e8b1f50..0000000000000000000000000000000000000000
--- a/include/DimensionalityReductionModel.txx
+++ /dev/null
@@ -1,143 +0,0 @@
-/*=========================================================================
-
-  Program:   ORFEO Toolbox
-  Language:  C++
-  Date:      $Date$
-  Version:   $Revision$
-
-
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
-
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef DimensionalityReductionModel_txx
-#define DimensionalityReductionModel_txx
-
-#ifdef _OPENMP
- # include <omp.h>
-#endif
-
-#include "DimensionalityReductionModel.h"
-
-#include "itkMultiThreader.h"
-
-namespace otb
-{
-
-template <class TInputValue, class TOutputValue>
-DimensionalityReductionModel<TInputValue,TOutputValue>
-::DimensionalityReductionModel()
-{ this->m_IsDoPredictBatchMultiThreaded=false;}
-
-
-template <class TInputValue, class TOutputValue>
-DimensionalityReductionModel<TInputValue,TOutputValue>
-::~DimensionalityReductionModel()
-{}
-
-
-
-template <class TInputValue, class TOutputValue>
-typename DimensionalityReductionModel<TInputValue,TOutputValue>
-::TargetSampleType
-DimensionalityReductionModel<TInputValue,TOutputValue>
-::Predict(const InputSampleType& input) const
-{
-  // Call protected specialization entry point
-  return this->DoPredict(input);
-}
-
-
-template <class TInputValue, class TOutputValue>
-typename DimensionalityReductionModel<TInputValue,TOutputValue>
-::TargetListSampleType::Pointer
-DimensionalityReductionModel<TInputValue,TOutputValue>
-::PredictBatch(const InputListSampleType * input) const
-{
-  typename TargetListSampleType::Pointer targets = TargetListSampleType::New();
-  targets->Resize(input->Size());
-  
-  
-  if(m_IsDoPredictBatchMultiThreaded)
-    {
-    // Simply calls DoPredictBatch
-    this->DoPredictBatch(input,0,input->Size(),targets);
-    return targets;
-    }
-  else
-    {
-    
-    #ifdef _OPENMP
-    // OpenMP threading here
-    unsigned int nb_threads(0), threadId(0), nb_batches(0);
-    
-    #pragma omp parallel shared(nb_threads,nb_batches) private(threadId)
-    {
-    // Get number of threads configured with ITK
-    omp_set_num_threads(itk::MultiThreader::GetGlobalDefaultNumberOfThreads());
-    nb_threads = omp_get_num_threads();
-    threadId = omp_get_thread_num();
-    nb_batches = std::min(nb_threads,(unsigned int)input->Size());
-    // Ensure that we do not spawn unncessary threads
-    if(threadId<nb_batches)
-      {
-      unsigned int batch_size = ((unsigned int)input->Size()/nb_batches);
-      unsigned int batch_start = threadId*batch_size;
-      if(threadId == nb_threads-1)
-        {
-        batch_size+=input->Size()%nb_batches;
-        }
-    
-      this->DoPredictBatch(input,batch_start,batch_size,targets);
-      }
-    }
-    #else
-    this->DoPredictBatch(input,0,input->Size(),targets);
-    #endif
-    return targets;
-    }
-}
-
-
-
-template <class TInputValue, class TOutputValue>
-void
-DimensionalityReductionModel<TInputValue,TOutputValue>
-::DoPredictBatch(const InputListSampleType * input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets) const
-{
-  assert(input != ITK_NULLPTR);
-  assert(targets != ITK_NULLPTR);
-  
-  assert(input->Size()==targets->Size()&&"Input sample list and target label list do not have the same size.");
-  assert(((quality==ITK_NULLPTR)||(quality->Size()==input->Size()))&&"Quality samples list is not null and does not have the same size as input samples list");
-
-  if(startIndex+size>input->Size())
-    {
-    itkExceptionMacro(<<"requested range ["<<startIndex<<", "<<startIndex+size<<"[ partially outside input sample list range.[0,"<<input->Size()<<"[");
-    }
-
-  
-  for(unsigned int id = startIndex;id<startIndex+size;++id)
-    {
-    const TargetSampleType target = this->DoPredict(input->GetMeasurementVector(id));
-    targets->SetMeasurementVector(id,target);
-    }
-    
-}
-
-template <class TInputValue, class TOutputValue>
-void
-DimensionalityReductionModel<TInputValue,TOutputValue>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  // Call superclass implementation
-  Superclass::PrintSelf(os,indent);
-}
-}
-
-#endif
diff --git a/include/PCAModel.h b/include/PCAModel.h
index d5557eb16994f1b9f8a45ca4c8c242d68a024d12..f26f2233a3118b819e712a1c3a1eeaacbb94f903 100644
--- a/include/PCAModel.h
+++ b/include/PCAModel.h
@@ -1,7 +1,9 @@
 #ifndef PCAModel_h
 #define PCAModel_h
 
-#include "DimensionalityReductionModel.h"
+#include "otbMachineLearningModelTraits.h"
+#include "otbMachineLearningModel.h"
+
 #include <shark/Algorithms/Trainers/PCA.h>
 
 namespace otb