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

parent de38d430
......@@ -48,6 +48,12 @@ using SOM2DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 2> ;
template <class TInputValue, class TTargetValue>
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>
typename DimensionalityReductionModel<TInputValue,TOutputValue>::Pointer
DimensionalityReductionModelFactory<TInputValue,TOutputValue>
......@@ -104,9 +110,10 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
RegisterFactory(SOM3DModelFactory<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
RegisterFactory(PCAModelFactory<TInputValue,TOutputValue>::New());
......@@ -142,6 +149,23 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
{
// 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 =
dynamic_cast<SOM3DModelFactory<TInputValue,TOutputValue> *>(*itFac);
if (som3dFactory)
......
......@@ -54,6 +54,7 @@ void SOMModel<TInputValue, MapDimension>::Train()
}
template <class TInputValue, unsigned int MapDimension>
bool SOMModel<TInputValue, MapDimension>::CanReadFile(const std::string & filename)
{
......@@ -75,11 +76,27 @@ bool SOMModel<TInputValue, MapDimension>::CanWriteFile(const std::string & filen
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>
void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, const std::string & name)
{
std::cout << m_SOMMap->GetNumberOfComponentsPerPixel() << std::endl;
//Ecriture
auto kwl = m_SOMMap->GetImageKeywordlist();
kwl.AddKey("MachineLearningModelType", "SOM"+std::to_string(MapDimension));
......@@ -92,22 +109,21 @@ void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, con
// test text
itk::ImageRegionConstIterator<MapType> inputIterator(m_SOMMap,m_SOMMap->GetLargestPossibleRegion());
std::ofstream ofs(filename+"2");
ofs << "SOM" << std::endl;
ofs << MapDimension << std::endl;
inputIterator.GoToBegin();
std::ofstream ofs(filename+"2", std::ios::binary);
binary_write_string(ofs,"som");
binary_write(ofs,static_cast<int>(MapDimension));
SizeType size = m_SOMMap->GetLargestPossibleRegion().GetSize() ;
//ofs << m_SOMMap->GetLargestPossibleRegion().GetSize() << std::endl;
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()){
InputSampleType vect = inputIterator.Get();
for (size_t i=0;i<vect.GetNumberOfElements();i++){
ofs << vect[i] << " " ;
binary_write(ofs,vect[i]);
}
++inputIterator;
}
ofs.close();
......@@ -117,113 +133,58 @@ void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, con
template <class TInputValue, unsigned int MapDimension>
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");
std::string model_type_str;
std::string dimension_str;
std::string size_str;
std::string number_of_elements_str;
int dimension;
binary_read(ifs,dimension);
std::getline(ifs,model_type_str);
std::getline(ifs,dimension_str);
if (model_type_str+dimension_str != "SOM"+std::to_string(MapDimension)){
if (modelType != "som" || dimension != MapDimension){
itkExceptionMacro(<< "Error opening " << filename.c_str() );
}
std::cout << "bug-1?" << std::endl;
SizeType size;
itk::Point<double, MapDimension> origin;
SpacingType spacing;
itk::Index< MapDimension > index;
for (int i=0 ; i<MapDimension; i++)
{
std::getline(ifs,size_str , ' ');
size[i] = stof(size_str);
origin[i] = 0;
spacing[i]=0;
binary_read(ifs,size[i]);
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();
typename MapType::RegionType region;
region.SetSize( size );
m_SOMMap->SetNumberOfComponentsPerPixel(number_of_elements);
m_SOMMap->SetNumberOfComponentsPerPixel(numberOfElements);
region.SetIndex( index );
m_SOMMap->SetRegions( region );
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);
outputIterator.GoToBegin();
std::string value;
size_t j=0;
while(!outputIterator.IsAtEnd()){
std::cout << j << std::endl;
std::getline(ifs,value, ' ');
itk::VariableLengthVector<float> vect(number_of_elements);
for (int i=0 ; i<number_of_elements; i++)
InputSampleType vect(numberOfElements);
for (int i=0 ; i<numberOfElements; i++)
{
std::getline(ifs,value , ' ');
//std::cout << value << " ";
std::cout << stof(value) << " ";
vect[i]=std::stof(value);
binary_read(ifs,vect[i]);
}
std::cout << vect << std::endl;
outputIterator.Set(vect);
++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();
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
target.SetSize(dimension);
auto winner =m_SOMMap->GetWinner(value);
// std::cout << winner << std::endl;
for (int i=0; i< dimension ;i++) {
target[i] = winner.GetElement(i);
}
......
......@@ -86,12 +86,19 @@ public:
typedef typename ModelType::InputListSampleType ListSampleType;
// 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 otb::SOMModel<InputValueType, 3> SOM3DModelType;
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>>, 4> Map4DType;
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
typedef shark::Autoencoder< shark::TanhNeuron, shark::LinearNeuron> AutoencoderType;
......@@ -134,6 +141,7 @@ private:
void TrainPCA(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
template <class somchoice>
void TrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
void BeforeTrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
#endif
//@}
};
......
......@@ -44,9 +44,10 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
{
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");
SetParameterDescription("model", "Choice of the dimensionality reduction model to use for the training.");
InitSOMParams();
#ifdef OTB_USE_SHARK
......@@ -60,32 +61,7 @@ template <class TInputValue, class TOutputValue>
void
cbLearningApplicationBaseDR<TInputValue,TOutputValue>
::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>
......@@ -95,20 +71,15 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
std::string modelPath)
{
// get the name of the chosen machine learning model
const std::string modelName = GetParameterString("model");
// call specific train function
// get the name of the chosen machine learning model
const std::string modelName = GetParameterString("model");
// call specific train function
if(modelName == "som")
{
TrainSOM<SOM2DModelType >(trainingListSample,modelPath);
}
if(modelName == "som3d")
{
TrainSOM<SOM3DModelType >(trainingListSample,modelPath);
}
{
BeforeTrainSOM(trainingListSample,modelPath);
}
if(modelName == "autoencoder")
{
#ifdef OTB_USE_SHARK
......
......@@ -24,6 +24,20 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
"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");
SetParameterDescription("model.som.s", "Size of the SOM map");
MandatoryOff("model.som.s");
......@@ -63,7 +77,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
AddParameter(ParameterType_Float, "model.som.iv", "InitialValue");
SetParameterDescription("model.som.iv", "Maximum initial neuron weight");
MandatoryOff("model.som.iv");
;
SetDefaultParameterInt("model.som.sx", 32);
SetDefaultParameterInt("model.som.sy", 32);
SetDefaultParameterInt("model.som.nx", 10);
......@@ -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 <typename somchoice>
void cbLearningApplicationBaseDR<TInputValue,TOutputValue>
......
Markdown is supported
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