From ad08b84f164660aef0d485b3e32b2ac0bae3ca43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= <traizetc@cesbio.cnes.fr> Date: Mon, 3 Jul 2017 14:37:02 +0200 Subject: [PATCH] BUG : Serialization of SOM models works again --- app/cbDimensionalityReductionVector.cxx | 56 +++++++++++++++++-------- include/SOMModel.h | 1 + include/SOMModel.txx | 28 +++++-------- include/cbLearningApplicationBaseDR.h | 8 ++-- include/cbTrainSOM.txx | 1 + 5 files changed, 56 insertions(+), 38 deletions(-) diff --git a/app/cbDimensionalityReductionVector.cxx b/app/cbDimensionalityReductionVector.cxx index dbfd87d39a..ce4e1fa1ca 100644 --- a/app/cbDimensionalityReductionVector.cxx +++ b/app/cbDimensionalityReductionVector.cxx @@ -237,7 +237,6 @@ class CbDimensionalityReductionVector : public Application { int dimension = GetParameterInt("pcadim"); m_Model->SetDimension(dimension ); - std::cout << "yo" << std::endl; } @@ -270,26 +269,41 @@ class CbDimensionalityReductionVector : public Application if (GetParameterString("mode")=="overwrite") { output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite); + otb::ogr::Layer newLayer = output->CreateLayer(GetParameterString("out"), + const_cast<OGRSpatialReference*>(layer.GetSpatialRef()), + layer.GetGeomType()); + // Copy existing fields + OGRFeatureDefn &inLayerDefn = layer.GetLayerDefn(); + for (int k=0 ; k<inLayerDefn.GetFieldCount()-nbBands ; k++) // we don't copy the original bands + { + OGRFieldDefn fieldDefn(inLayerDefn.GetFieldDefn(k)); + newLayer.CreateField(fieldDefn); + } } else if (GetParameterString("mode")=="update") { - output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Update_LayerCreateOnly ); + //output = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Update_LayerCreateOnly); + // Update mode + otb::ogr::DataSource::Pointer source_output = otb::ogr::DataSource::New(GetParameterString("out"), otb::ogr::DataSource::Modes::Read); + layer = source_output->GetLayer(0); + updateMode = true; + otbAppLogINFO("Update input vector data."); + + // fill temporary buffer for the transfer + otb::ogr::Layer inputLayer = layer; + layer = buffer->CopyLayer(inputLayer, std::string("Buffer")); + // close input data source + source_output->Clear(); + // Re-open input data source in update mode + output = otb::ogr::DataSource::New(GetParameterString("out"), otb::ogr::DataSource::Modes::Update_LayerUpdate); + } else { - otbAppLogFATAL(<< "Error when creating the output file" << GetParameterString("mode") << " : unsupported writting mode type [update/overwrite]"); + otbAppLogFATAL(<< "Error when creating the output file" << GetParameterString("mode") << " : unsupported writting mode type"); } - otb::ogr::Layer newLayer = output->CreateLayer(GetParameterString("out"), - const_cast<OGRSpatialReference*>(layer.GetSpatialRef()), - layer.GetGeomType()); - // Copy existing fields - OGRFeatureDefn &inLayerDefn = layer.GetLayerDefn(); - for (int k=0 ; k<inLayerDefn.GetFieldCount()-nbBands ; k++) // we don't copy the original bands - { - OGRFieldDefn fieldDefn(inLayerDefn.GetFieldDefn(k)); - newLayer.CreateField(fieldDefn); - } + } /* @@ -309,6 +323,7 @@ class CbDimensionalityReductionVector : public Application otb::ogr::Layer outLayer = output->GetLayer(0); + OGRErr errStart = outLayer.ogr().StartTransaction(); if (errStart != OGRERR_NONE) @@ -337,10 +352,11 @@ class CbDimensionalityReductionVector : public Application } // Add an ID field. (The ID already contained in the layer refers to the polygon) + /* OGRFieldDefn IDField("ID_point", OFTInteger); ogr::FieldDefn IDFieldDef(IDField); outLayer.CreateField(IDFieldDef); - + */ // Fill output layer unsigned int count=0; @@ -351,12 +367,18 @@ class CbDimensionalityReductionVector : public Application for( ; it!=itEnd ; ++it, ++count) { ogr::Feature dstFeature(outLayer.GetLayerDefn()); - dstFeature.SetFrom( *it , TRUE); - dstFeature.SetFID(it->GetFID()); + /* + if (GetParameterString("mode")=="overwrite") + {*/ + dstFeature.SetFrom( *it , TRUE); + dstFeature.SetFID(it->GetFID()); + //} + + for (std::size_t i=0; i<classfieldname.size(); ++i){ dstFeature[classfieldname[i]].SetValue<ValueType>(target->GetMeasurementVector(count)[i]); } - dstFeature["ID_point"].SetValue<int>(id); + //dstFeature["ID_point"].SetValue<int>(id); if (updateMode) { outLayer.SetFeature(dstFeature); diff --git a/include/SOMModel.h b/include/SOMModel.h index 88209ed24e..a5752ac5c9 100644 --- a/include/SOMModel.h +++ b/include/SOMModel.h @@ -46,6 +46,7 @@ public: typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, MapDimension> MapType; typedef typename MapType::SizeType SizeType; typedef typename MapType::SpacingType SpacingType; + //typedef otb::SOM<InputListSampleType, MapType> EstimatorType; typedef otb::SOM<InputListSampleType, MapType> EstimatorType; typedef Functor::CzihoSOMLearningBehaviorFunctor SOMLearningBehaviorFunctorType; diff --git a/include/SOMModel.txx b/include/SOMModel.txx index 7afbd6f501..b0b2229ac7 100644 --- a/include/SOMModel.txx +++ b/include/SOMModel.txx @@ -22,7 +22,7 @@ namespace otb template <class TInputValue, unsigned int MapDimension> SOMModel<TInputValue, MapDimension>::SOMModel() { - //m_Dimension = typename MapType::ImageDimension; + this->m_Dimension = MapType::ImageDimension; } @@ -46,12 +46,9 @@ void SOMModel<TInputValue, MapDimension>::Train() estimator->SetBetaEnd(m_BetaEnd); estimator->SetMaxWeight(m_MaxWeight); //AddProcess(estimator,"Learning"); - estimator->Update(); - m_SOMMap = estimator->GetOutput(); - std::cout << "dr of the first sample : " << m_SOMMap->GetWinner(m_ListSample->GetMeasurementVector(0)) << std::endl; -} + } @@ -100,7 +97,7 @@ void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, con inputIterator.GoToBegin(); std::ofstream ofs(filename, std::ios::binary); binary_write_string(ofs,"som"); - binary_write(ofs,static_cast<int>(MapDimension)); + binary_write(ofs,static_cast<unsigned int>(MapDimension)); SizeType size = m_SOMMap->GetLargestPossibleRegion().GetSize() ; for (size_t i=0;i<MapDimension;i++){ binary_write(ofs,size[i]); @@ -129,12 +126,10 @@ void SOMModel<TInputValue, MapDimension>::Load(const std::string & filename, con binary_read(ifs,s[i]); } std::string modelType(s); - /** Read the dimension of the map (should be equal to MapDimension) */ - int dimension; + unsigned int dimension; binary_read(ifs,dimension); - if (modelType != "som" || dimension != MapDimension){ itkExceptionMacro(<< "Error opening " << filename.c_str() ); } @@ -146,10 +141,8 @@ void SOMModel<TInputValue, MapDimension>::Load(const std::string & filename, con binary_read(ifs,size[i]); index[i]=0; } - unsigned int numberOfElements; binary_read(ifs,numberOfElements); - m_SOMMap = MapType::New(); typename MapType::RegionType region; region.SetSize( size ); @@ -165,13 +158,15 @@ void SOMModel<TInputValue, MapDimension>::Load(const std::string & filename, con InputSampleType vect(numberOfElements); for (int i=0 ; i<numberOfElements; i++) { - binary_read(ifs,vect[i]); + float v; // InputValue type is not the same during training anddimredvector. + binary_read(ifs,v); + vect[i] = static_cast<double>(v); } outputIterator.Set(vect); ++outputIterator; } - ifs.close(); + this->m_Dimension = MapType::ImageDimension; } @@ -180,15 +175,14 @@ template <class TInputValue, unsigned int MapDimension> typename SOMModel<TInputValue, MapDimension>::TargetSampleType SOMModel<TInputValue, MapDimension>::DoPredict(const InputSampleType & value, ConfidenceValueType * quality) const { - unsigned int dimension =MapType::ImageDimension; TargetSampleType target; - target.SetSize(dimension); + target.SetSize(this->m_Dimension); auto winner =m_SOMMap->GetWinner(value); - for (int i=0; i< dimension ;i++) { + for (int i=0; i< this->m_Dimension ;i++) { target[i] = winner.GetElement(i); } - + return target; } diff --git a/include/cbLearningApplicationBaseDR.h b/include/cbLearningApplicationBaseDR.h index 94c62d1b43..3d90432fa9 100644 --- a/include/cbLearningApplicationBaseDR.h +++ b/include/cbLearningApplicationBaseDR.h @@ -87,16 +87,16 @@ public: // Dimensionality reduction models - typedef SOMMap<TInputValue,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 2> Map2DType; + //typedef SOMMap<TInputValue,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 2> Map2DType; typedef otb::SOMModel<InputValueType, 2> SOM2DModelType; - typedef SOMMap<TInputValue,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 3> Map3DType; + //typedef SOMMap<TInputValue,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 3> Map3DType; typedef otb::SOMModel<InputValueType, 3> SOM3DModelType; - typedef SOMMap<TInputValue,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 4> Map4DType; + //typedef SOMMap<TInputValue,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 4> Map4DType; typedef otb::SOMModel<InputValueType, 4> SOM4DModelType; - typedef SOMMap<TInputValue,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 5> Map5DType; + //typedef SOMMap<TInputValue,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 5> Map5DType; typedef otb::SOMModel<InputValueType, 5> SOM5DModelType; diff --git a/include/cbTrainSOM.txx b/include/cbTrainSOM.txx index 9ac28dd906..538ccea03c 100644 --- a/include/cbTrainSOM.txx +++ b/include/cbTrainSOM.txx @@ -117,6 +117,7 @@ void cbLearningApplicationBaseDR<TInputValue,TOutputValue> using TemplateEstimatorType = typename somchoice::EstimatorType; typename somchoice::Pointer dimredTrainer = somchoice::New(); unsigned int dim = dimredTrainer->GetDimension(); + std::cout << dim << std::endl; dimredTrainer->SetNumberOfIterations(GetParameterInt("model.som.ni")); dimredTrainer->SetBetaInit(GetParameterFloat("model.som.bi")); dimredTrainer->SetBetaEnd(GetParameterFloat("model.som.bf")); -- GitLab