Commit 039141fc authored by Cédric Traizet's avatar Cédric Traizet
Browse files

serialization of som models done, added som maps of dimension 4 and 5

No related merge requests found
Showing with 143 additions and 132 deletions
+143 -132
...@@ -48,6 +48,12 @@ using SOM2DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 2> ; ...@@ -48,6 +48,12 @@ using SOM2DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 2> ;
template <class TInputValue, class TTargetValue> template <class TInputValue, class TTargetValue>
using SOM3DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 3> ; using SOM3DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 3> ;
template <class TInputValue, class TTargetValue>
using SOM4DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 4> ;
template <class TInputValue, class TTargetValue>
using SOM5DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 5> ;
template <class TInputValue, class TOutputValue> template <class TInputValue, class TOutputValue>
typename DimensionalityReductionModel<TInputValue,TOutputValue>::Pointer typename DimensionalityReductionModel<TInputValue,TOutputValue>::Pointer
DimensionalityReductionModelFactory<TInputValue,TOutputValue> DimensionalityReductionModelFactory<TInputValue,TOutputValue>
...@@ -104,9 +110,10 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue> ...@@ -104,9 +110,10 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
RegisterFactory(SOM3DModelFactory<TInputValue,TOutputValue>::New());
RegisterFactory(SOM2DModelFactory<TInputValue,TOutputValue>::New()); RegisterFactory(SOM2DModelFactory<TInputValue,TOutputValue>::New());
RegisterFactory(SOM3DModelFactory<TInputValue,TOutputValue>::New());
RegisterFactory(SOM4DModelFactory<TInputValue,TOutputValue>::New());
RegisterFactory(SOM5DModelFactory<TInputValue,TOutputValue>::New());
#ifdef OTB_USE_SHARK #ifdef OTB_USE_SHARK
RegisterFactory(PCAModelFactory<TInputValue,TOutputValue>::New()); RegisterFactory(PCAModelFactory<TInputValue,TOutputValue>::New());
...@@ -142,6 +149,23 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue> ...@@ -142,6 +149,23 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
{ {
// SOM // SOM
SOM5DModelFactory<TInputValue,TOutputValue> *som5dFactory =
dynamic_cast<SOM5DModelFactory<TInputValue,TOutputValue> *>(*itFac);
if (som5dFactory)
{
itk::ObjectFactoryBase::UnRegisterFactory(som5dFactory);
continue;
}
SOM4DModelFactory<TInputValue,TOutputValue> *som4dFactory =
dynamic_cast<SOM4DModelFactory<TInputValue,TOutputValue> *>(*itFac);
if (som4dFactory)
{
itk::ObjectFactoryBase::UnRegisterFactory(som4dFactory);
continue;
}
SOM3DModelFactory<TInputValue,TOutputValue> *som3dFactory = SOM3DModelFactory<TInputValue,TOutputValue> *som3dFactory =
dynamic_cast<SOM3DModelFactory<TInputValue,TOutputValue> *>(*itFac); dynamic_cast<SOM3DModelFactory<TInputValue,TOutputValue> *>(*itFac);
if (som3dFactory) if (som3dFactory)
......
...@@ -54,6 +54,7 @@ void SOMModel<TInputValue, MapDimension>::Train() ...@@ -54,6 +54,7 @@ void SOMModel<TInputValue, MapDimension>::Train()
} }
template <class TInputValue, unsigned int MapDimension> template <class TInputValue, unsigned int MapDimension>
bool SOMModel<TInputValue, MapDimension>::CanReadFile(const std::string & filename) bool SOMModel<TInputValue, MapDimension>::CanReadFile(const std::string & filename)
{ {
...@@ -75,11 +76,27 @@ bool SOMModel<TInputValue, MapDimension>::CanWriteFile(const std::string & filen ...@@ -75,11 +76,27 @@ bool SOMModel<TInputValue, MapDimension>::CanWriteFile(const std::string & filen
return true; return true;
} }
template<typename T>
std::ostream& binary_write(std::ostream& stream, const T& value){
return stream.write(reinterpret_cast<const char*>(&value), sizeof(T));
}
std::ostream& binary_write_string(std::ofstream& stream, const std::string& value){
return stream.write(value.c_str(), value.length());
}
template<typename T>
std::istream & binary_read(std::istream& stream, T& value){
return stream.read(reinterpret_cast<char*>(&value), sizeof(T));
}
template <class TInputValue, unsigned int MapDimension> template <class TInputValue, unsigned int MapDimension>
void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, const std::string & name) void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, const std::string & name)
{ {
std::cout << m_SOMMap->GetNumberOfComponentsPerPixel() << std::endl;
//Ecriture //Ecriture
auto kwl = m_SOMMap->GetImageKeywordlist(); auto kwl = m_SOMMap->GetImageKeywordlist();
kwl.AddKey("MachineLearningModelType", "SOM"+std::to_string(MapDimension)); kwl.AddKey("MachineLearningModelType", "SOM"+std::to_string(MapDimension));
...@@ -92,22 +109,21 @@ void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, con ...@@ -92,22 +109,21 @@ void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, con
// test text // test text
itk::ImageRegionConstIterator<MapType> inputIterator(m_SOMMap,m_SOMMap->GetLargestPossibleRegion()); itk::ImageRegionConstIterator<MapType> inputIterator(m_SOMMap,m_SOMMap->GetLargestPossibleRegion());
std::ofstream ofs(filename+"2"); inputIterator.GoToBegin();
ofs << "SOM" << std::endl; std::ofstream ofs(filename+"2", std::ios::binary);
ofs << MapDimension << std::endl; binary_write_string(ofs,"som");
binary_write(ofs,static_cast<int>(MapDimension));
SizeType size = m_SOMMap->GetLargestPossibleRegion().GetSize() ; SizeType size = m_SOMMap->GetLargestPossibleRegion().GetSize() ;
//ofs << m_SOMMap->GetLargestPossibleRegion().GetSize() << std::endl;
for (size_t i=0;i<MapDimension;i++){ for (size_t i=0;i<MapDimension;i++){
ofs << size[i] << " " ; binary_write(ofs,size[i]);
} }
ofs << std::endl;
ofs << inputIterator.Get().GetNumberOfElements() << std::endl;; binary_write(ofs,inputIterator.Get().GetNumberOfElements());
while(!inputIterator.IsAtEnd()){ while(!inputIterator.IsAtEnd()){
InputSampleType vect = inputIterator.Get(); InputSampleType vect = inputIterator.Get();
for (size_t i=0;i<vect.GetNumberOfElements();i++){ for (size_t i=0;i<vect.GetNumberOfElements();i++){
ofs << vect[i] << " " ; binary_write(ofs,vect[i]);
} }
++inputIterator; ++inputIterator;
} }
ofs.close(); ofs.close();
...@@ -117,113 +133,58 @@ void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, con ...@@ -117,113 +133,58 @@ void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, con
template <class TInputValue, unsigned int MapDimension> template <class TInputValue, unsigned int MapDimension>
void SOMModel<TInputValue, MapDimension>::Load(const std::string & filename, const std::string & name) void SOMModel<TInputValue, MapDimension>::Load(const std::string & filename, const std::string & name)
{ {
/*
auto reader = otb::ImageFileReader<MapType>::New();
reader->SetFileName(filename);
reader->Update();
if (reader->GetOutput()->GetImageKeywordlist().GetMetadataByKey("MachineLearningModelType") != "SOM"+std::to_string(MapDimension)){
itkExceptionMacro(<< "Error opening " << filename.c_str() );
}
m_SOMMap = reader->GetOutput();
*/
// test text
std::ifstream ifs(filename+"2", std::ios::binary);
/** Read the model key (should be som) */
char s[]=" ";
for (int i=0; i<3; i++){
binary_read(ifs,s[i]);
}
std::string modelType(s);
/** Read the dimension of the map (should be equal to MapDimension) */
std::ifstream ifs(filename+"2"); int dimension;
std::string model_type_str; binary_read(ifs,dimension);
std::string dimension_str;
std::string size_str;
std::string number_of_elements_str;
std::getline(ifs,model_type_str); if (modelType != "som" || dimension != MapDimension){
std::getline(ifs,dimension_str);
if (model_type_str+dimension_str != "SOM"+std::to_string(MapDimension)){
itkExceptionMacro(<< "Error opening " << filename.c_str() ); itkExceptionMacro(<< "Error opening " << filename.c_str() );
} }
std::cout << "bug-1?" << std::endl;
SizeType size; SizeType size;
itk::Point<double, MapDimension> origin;
SpacingType spacing;
itk::Index< MapDimension > index; itk::Index< MapDimension > index;
for (int i=0 ; i<MapDimension; i++) for (int i=0 ; i<MapDimension; i++)
{ {
std::getline(ifs,size_str , ' '); binary_read(ifs,size[i]);
size[i] = stof(size_str);
origin[i] = 0;
spacing[i]=0;
index[i]=0; index[i]=0;
} }
unsigned int numberOfElements;
binary_read(ifs,numberOfElements);
std::getline(ifs,number_of_elements_str);
std::getline(ifs,number_of_elements_str);
std::cout << "bug0?" << number_of_elements_str << std::endl;
auto number_of_elements = stof(number_of_elements_str);
//typedef itk::Image< unsigned char, 3 > ImageType;
//typename MapType::Pointer image = MapType::New();
m_SOMMap = MapType::New(); m_SOMMap = MapType::New();
typename MapType::RegionType region; typename MapType::RegionType region;
region.SetSize( size ); region.SetSize( size );
m_SOMMap->SetNumberOfComponentsPerPixel(number_of_elements); m_SOMMap->SetNumberOfComponentsPerPixel(numberOfElements);
region.SetIndex( index ); region.SetIndex( index );
m_SOMMap->SetRegions( region ); m_SOMMap->SetRegions( region );
m_SOMMap->Allocate(); m_SOMMap->Allocate();
std::cout << m_SOMMap << std::endl;
/*
std::cout << "bug1?" << number_of_elements << std::endl;
itk::ImageRegion<MapDimension> outputRegion;
std::cout << "bugoriggin?" << origin << std::endl;
m_SOMMap->SetNumberOfComponentsPerPixel(number_of_elements);
outputRegion.SetIndex(index);
std::cout << "setindex?" << index << std::endl;
outputRegion.SetSize(size);
std::cout << origin << size << std::endl;
m_SOMMap->SetLargestPossibleRegion(outputRegion);
std::cout << "setRegion" << origin << std::endl;
m_SOMMap->Allocate();
std::cout << "bug2?" << std::endl;
*/
itk::ImageRegionIterator<MapType> outputIterator(m_SOMMap,region); itk::ImageRegionIterator<MapType> outputIterator(m_SOMMap,region);
outputIterator.GoToBegin();
std::string value; std::string value;
size_t j=0;
while(!outputIterator.IsAtEnd()){ while(!outputIterator.IsAtEnd()){
std::cout << j << std::endl; InputSampleType vect(numberOfElements);
std::getline(ifs,value, ' '); for (int i=0 ; i<numberOfElements; i++)
itk::VariableLengthVector<float> vect(number_of_elements);
for (int i=0 ; i<number_of_elements; i++)
{ {
std::getline(ifs,value , ' '); binary_read(ifs,vect[i]);
//std::cout << value << " ";
std::cout << stof(value) << " ";
vect[i]=std::stof(value);
} }
std::cout << vect << std::endl;
outputIterator.Set(vect); outputIterator.Set(vect);
++outputIterator; ++outputIterator;
j++;
std::cout << j << "end" << std::endl;
//std::cout << value << std::endl;
//std::string line;
//std::getline(ifs, line);
} }
std::cout << j << std::endl;
ifs.close(); ifs.close();
std::cout << "model type " << model_type_str << std::endl;
std::cout << "dimension " << dimension_str << std::endl;
std::cout << "size " << size_str << std::endl;
} }
...@@ -236,8 +197,6 @@ SOMModel<TInputValue, MapDimension>::DoPredict(const InputSampleType & value) co ...@@ -236,8 +197,6 @@ SOMModel<TInputValue, MapDimension>::DoPredict(const InputSampleType & value) co
target.SetSize(dimension); target.SetSize(dimension);
auto winner =m_SOMMap->GetWinner(value); auto winner =m_SOMMap->GetWinner(value);
// std::cout << winner << std::endl;
for (int i=0; i< dimension ;i++) { for (int i=0; i< dimension ;i++) {
target[i] = winner.GetElement(i); target[i] = winner.GetElement(i);
} }
......
...@@ -86,12 +86,19 @@ public: ...@@ -86,12 +86,19 @@ public:
typedef typename ModelType::InputListSampleType ListSampleType; typedef typename ModelType::InputListSampleType ListSampleType;
// Dimensionality reduction models // Dimensionality reduction models
typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 2> Map2DType;
typedef otb::SOMModel<InputValueType, 2> SOM2DModelType;
typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 3> Map3DType; typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 3> Map3DType;
typedef otb::SOMModel<InputValueType, 3> SOM3DModelType; typedef otb::SOMModel<InputValueType, 3> SOM3DModelType;
typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 2> Map2DType; typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 4> Map4DType;
typedef otb::SOMModel<InputValueType, 2> SOM2DModelType; typedef otb::SOMModel<InputValueType, 4> SOM4DModelType;
typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 5> Map5DType;
typedef otb::SOMModel<InputValueType, 5> SOM5DModelType;
#ifdef OTB_USE_SHARK #ifdef OTB_USE_SHARK
typedef shark::Autoencoder< shark::TanhNeuron, shark::LinearNeuron> AutoencoderType; typedef shark::Autoencoder< shark::TanhNeuron, shark::LinearNeuron> AutoencoderType;
...@@ -134,6 +141,7 @@ private: ...@@ -134,6 +141,7 @@ private:
void TrainPCA(typename ListSampleType::Pointer trainingListSample, std::string modelPath); void TrainPCA(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
template <class somchoice> template <class somchoice>
void TrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath); void TrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
void BeforeTrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
#endif #endif
//@} //@}
}; };
......
...@@ -44,9 +44,10 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> ...@@ -44,9 +44,10 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
{ {
AddDocTag(Tags::Learning); AddDocTag(Tags::Learning);
// main choice parameter that will contain all machine learning options // main choice parameter that will contain all dimensionality reduction options
AddParameter(ParameterType_Choice, "model", "moddel to use for the training"); AddParameter(ParameterType_Choice, "model", "moddel to use for the training");
SetParameterDescription("model", "Choice of the dimensionality reduction model to use for the training."); SetParameterDescription("model", "Choice of the dimensionality reduction model to use for the training.");
InitSOMParams(); InitSOMParams();
#ifdef OTB_USE_SHARK #ifdef OTB_USE_SHARK
...@@ -60,32 +61,7 @@ template <class TInputValue, class TOutputValue> ...@@ -60,32 +61,7 @@ template <class TInputValue, class TOutputValue>
void void
cbLearningApplicationBaseDR<TInputValue,TOutputValue> cbLearningApplicationBaseDR<TInputValue,TOutputValue>
::Reduce(typename ListSampleType::Pointer validationListSample,std::string modelPath) ::Reduce(typename ListSampleType::Pointer validationListSample,std::string modelPath)
{/* {
// Setup fake reporter
RGBAPixelConverter<int,int>::Pointer dummyFilter =
RGBAPixelConverter<int,int>::New();
dummyFilter->SetProgress(0.0f);
this->AddProcess(dummyFilter,"Classify...");
dummyFilter->InvokeEvent(itk::StartEvent());
// load a machine learning model from file and predict the input sample list
ModelPointerType model = ModelFactoryType::CreateMachineLearningModel(modelPath,
ModelFactoryType::ReadMode);
if (model.IsNull())
{
otbAppLogFATAL(<< "Error when loading model " << modelPath);
}
model->Load(modelPath);
model->SetRegressionMode(this->m_RegressionFlag);
model->SetInputListSample(validationListSample);
model->SetTargetListSample(predictedList);
model->PredictAll();
// update reporter
dummyFilter->UpdateProgress(1.0f);
dummyFilter->InvokeEvent(itk::EndEvent());*/
} }
template <class TInputValue, class TOutputValue> template <class TInputValue, class TOutputValue>
...@@ -95,20 +71,15 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> ...@@ -95,20 +71,15 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
std::string modelPath) std::string modelPath)
{ {
// get the name of the chosen machine learning model // get the name of the chosen machine learning model
const std::string modelName = GetParameterString("model"); const std::string modelName = GetParameterString("model");
// call specific train function // call specific train function
if(modelName == "som") if(modelName == "som")
{ {
TrainSOM<SOM2DModelType >(trainingListSample,modelPath); BeforeTrainSOM(trainingListSample,modelPath);
} }
if(modelName == "som3d")
{
TrainSOM<SOM3DModelType >(trainingListSample,modelPath);
}
if(modelName == "autoencoder") if(modelName == "autoencoder")
{ {
#ifdef OTB_USE_SHARK #ifdef OTB_USE_SHARK
......
...@@ -24,6 +24,20 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> ...@@ -24,6 +24,20 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
"This group of parameters allows setting SOM parameters. " "This group of parameters allows setting SOM parameters. "
); );
AddChoice("model.som4d", "OTB SOM");
SetParameterDescription("model.som4d",
"This group of parameters allows setting SOM parameters. "
);
AddChoice("model.som5d", "OTB SOM");
SetParameterDescription("model.som5d",
"This group of parameters allows setting SOM parameters. "
);
AddParameter(ParameterType_Int, "model.som.dim","Dimension of the map");
SetParameterDescription("model.som.dim","Dimension of the SOM map.");
AddParameter(ParameterType_StringList , "model.som.s", "Size"); AddParameter(ParameterType_StringList , "model.som.s", "Size");
SetParameterDescription("model.som.s", "Size of the SOM map"); SetParameterDescription("model.som.s", "Size of the SOM map");
MandatoryOff("model.som.s"); MandatoryOff("model.som.s");
...@@ -63,7 +77,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> ...@@ -63,7 +77,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
AddParameter(ParameterType_Float, "model.som.iv", "InitialValue"); AddParameter(ParameterType_Float, "model.som.iv", "InitialValue");
SetParameterDescription("model.som.iv", "Maximum initial neuron weight"); SetParameterDescription("model.som.iv", "Maximum initial neuron weight");
MandatoryOff("model.som.iv"); MandatoryOff("model.som.iv");
;
SetDefaultParameterInt("model.som.sx", 32); SetDefaultParameterInt("model.som.sx", 32);
SetDefaultParameterInt("model.som.sy", 32); SetDefaultParameterInt("model.som.sy", 32);
SetDefaultParameterInt("model.som.nx", 10); SetDefaultParameterInt("model.som.nx", 10);
...@@ -76,6 +90,41 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue> ...@@ -76,6 +90,41 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
} }
template <class TInputValue, class TOutputValue>
void
cbLearningApplicationBaseDR<TInputValue,TOutputValue>
::BeforeTrainSOM(typename ListSampleType::Pointer trainingListSample,
std::string modelPath)
{
int SomDim = GetParameterInt("model.som.dim");
std::cout << SomDim << std::endl;
if(SomDim == 2)
{
TrainSOM<SOM2DModelType >(trainingListSample,modelPath);
}
if(SomDim == 3)
{
TrainSOM<SOM3DModelType >(trainingListSample,modelPath);
}
if(SomDim == 4)
{
TrainSOM<SOM4DModelType >(trainingListSample,modelPath);
}
if(SomDim == 5)
{
TrainSOM<SOM5DModelType >(trainingListSample,modelPath);
}
if(SomDim > 5 || SomDim < 2)
{
std::cerr << "invalid dimension" << std::endl;
}
}
template <class TInputValue, class TOutputValue> template <class TInputValue, class TOutputValue>
template <typename somchoice> template <typename somchoice>
void cbLearningApplicationBaseDR<TInputValue,TOutputValue> void cbLearningApplicationBaseDR<TInputValue,TOutputValue>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment