Skip to content
Commits on Source (11)
......@@ -62,17 +62,11 @@
# either expressed or implied, of the FreeBSD Project.
#=============================================================================
# message( "QWT_INCLUDE_DIR: '${QWT_INCLUDE_DIR}'" )
# message( "QWT_INCLUDE_DIR: '${QT_INCLUDE_DIR}'" )
find_path( QWT_INCLUDE_DIR
NAMES qwt_plot.h
PATH_SUFFIXES qwt
PATH_SUFFIXES qwt-qt5 qwt qwt6
)
# message( "QWT_INCLUDE_DIR: '${QWT_INCLUDE_DIR}'" )
# message( "QWT_INCLUDE_DIR: '${QT_INCLUDE_DIR}'" )
set ( QWT_INCLUDE_DIRS ${QWT_INCLUDE_DIR} )
# version
......@@ -104,8 +98,7 @@ endif ()
find_library ( QWT_LIBRARY
NAMES qwt qwt${QWT_MAJOR_VERSION}
HINTS ${QT_LIBRARY_DIR}
NAMES qwt-qt5 qwt6-qt5 qwt qwt6
)
set ( QWT_LIBRARIES ${QWT_LIBRARY} )
......
......@@ -120,7 +120,7 @@ endif()
if(SHARK_USE_CBLAS AND SHARK_USE_DYNLIB)
set(REQUIRED_CBLAS_LIB CBLAS_LIBRARY)
find_library(CBLAS_LIBRARY NAMES cblas)
find_library(CBLAS_LIBRARY NAMES cblas blas PATH_SUFFIXES blas)
else()
set(REQUIRED_CBLAS_LIB)
endif()
......
......@@ -138,7 +138,7 @@ public:
* \return the point projected in the image coordinates system.
* \throw None
*/
void TransformPointToPhysicalPoint(const PointType& point) const
PointType TransformPointToPhysicalPoint(const PointType& point) const
{
// why no loop on VDimension ?
PointType physicalPoint;
......
......@@ -291,15 +291,12 @@ protected:
itkExceptionMacro(<< "File : " << modelFileName << " couldn't be opened");
}
// get the line with the centroids (starts with "2 ")
// get the end line with the centroids
std::string line, centroidLine;
while(std::getline(infile,line))
{
if (line.size() > 2 && line[0] == '2' && line[1] == ' ')
{
if (!line.empty())
centroidLine = line;
break;
}
}
std::vector<std::string> centroidElm;
......
......@@ -165,7 +165,7 @@ private:
"histogram. That gives us gain for each bin that transform the original "
"histogram into the flat one. This gain is then apply on the original "
"image."
"\nThe application proposes several option to allow a finer result : "
"\nThe application proposes several options to allow a finer result: "
"\n- There is an option to limit contrast. We choose to limit the contrast "
"by modifying the original histogram. To do so we clip the histogram at a "
"given height and redistribute equally among the bins the clipped population. "
......@@ -219,27 +219,34 @@ private:
AddParameter(ParameterType_Int,"spatial.local.h" ,
"Thumbnail height in pixel");
"Thumbnail height");
SetParameterDescription("spatial.local.h","Height of the thumbnail "
"over which the histogram will be computed. The value is in pixels.");
AddParameter(ParameterType_Int,"spatial.local.w" ,
"Thumbnail width in pixel");
"Thumbnail width");
SetParameterDescription("spatial.local.w","Width of the thumbnail "
"over which the histogram will be computed. The value is in pixels.");
AddParameter(ParameterType_Choice , "minmax" , "Minimum and maximum "
"settings");
SetParameterDescription("minmax","Minimum and maximum value that will "
"bound the histogram.");
"bound the histogram and thus the dynamic of the resulting image. Values "
"over those boundaries will be clipped.");
AddChoice( "minmax.auto" , "Automatic" );
SetParameterDescription("minmax.auto" , "Minimum and maximum value will "
"be computed on the image (nodata value won't be taken "
"into account) . Each band will have a minimum and a maximum.");
AddParameter(ParameterType_Bool, "minmax.auto.global", "Global");
SetParameterDescription("minmax.auto.global" , "Automatic"
SetParameterDescription("minmax.auto.global" ,
"Min/max computation will result in the same minimum and maximum for "
"all the bands.");
AddChoice( "minmax.manual" , "Manual settings of min/max values" );
SetParameterDescription("minmax.auto","Minimum and maximum value will be "
AddChoice( "minmax.manual" , "Manual settings for min/max values" );
SetParameterDescription("minmax.manual","Minimum and maximum value will be "
"set by the user");
AddParameter(ParameterType_Float , "minmax.manual.min" , "Minimum value");
AddParameter(ParameterType_Float , "minmax.manual.max" , "Maximum value");
// SetDefaultParameterFloat("minmax.manual.min", 0 );
// SetDefaultParameterFloat("minmax.manual.max", 255 );
MandatoryOff("minmax.manual.min");
MandatoryOff("minmax.manual.max");
......@@ -249,9 +256,9 @@ private:
"Each channel is equalized independently" );
AddChoice( "mode.lum" , "Luminance" );
SetParameterDescription( "mode.lum" ,
"The relative luminance is calculated thanks to the coefficients."
"Then the histogram is equalized and then a gain is applied on each channels."
"This gain for each channels will depend on"
"The relative luminance is computed according to the coefficients."
"Then the histogram is equalized and the gain is applied to each of the "
"channels. The channel gain will depend on "
"the weight (coef) of the channel in the luminance."
"\nNote that default values come from color space theories "
"on how human eyes perceive colors)"
......
......@@ -629,23 +629,18 @@ private:
{
case Interpolator_Linear:
{
typedef itk::LinearInterpolateImageFunction<FloatVectorImageType,
double> LinearInterpolationType;
LinearInterpolationType::Pointer interpolator = LinearInterpolationType::New();
m_ResampleFilter->SetInterpolator(interpolator);
}
break;
case Interpolator_NNeighbor:
{
typedef itk::NearestNeighborInterpolateImageFunction<FloatVectorImageType,
double> NearestNeighborInterpolationType;
NearestNeighborInterpolationType::Pointer interpolator = NearestNeighborInterpolationType::New();
m_ResampleFilter->SetInterpolator(interpolator);
}
break;
case Interpolator_BCO:
{
typedef otb::BCOInterpolateImageFunction<FloatVectorImageType> BCOInterpolationType;
BCOInterpolationType::Pointer interpolator = BCOInterpolationType::New();
interpolator->SetRadius(GetParameterInt("interpolator.bco.radius"));
m_ResampleFilter->SetInterpolator(interpolator);
......
......@@ -964,13 +964,13 @@ LineSegmentDetector<TInputImage, TPrecision>
*/
/** Compute the number of points aligned */
typedef otb::Rectangle<double> RectangleType;
RectangleType::Pointer rectangle = RectangleType::New();
typedef otb::Rectangle<double> OTBRectangleType;
OTBRectangleType::Pointer rectangle = OTBRectangleType::New();
/** Fill the rectangle with the points*/
for (int i = 0; i < 2; ++i)
{
typename RectangleType::VertexType vertex;
typename OTBRectangleType::VertexType vertex;
vertex[0] = rec[2 * i];
vertex[1] = rec[2 * i + 1];
rectangle->AddVertex(vertex);
......
......@@ -68,6 +68,7 @@ public:
typedef typename Superclass::OutputVectorDataType OutputVectorDataType;
typedef typename Superclass::OutputVectorDataPointerType OutputVectorDataPointerType;
typedef typename Superclass::ExtractImageFilterType ExtractImageFilterType;
/** Method for creation through the object factory. */
itkNewMacro(Self);
......
......@@ -68,7 +68,6 @@ PersistentStreamingLineSegmentDetector<TInputImage>
::ProcessTile()
{
// Apply an ExtractImageFilter to avoid problems with filters asking for the LargestPossibleRegion
typedef itk::ExtractImageFilter<InputImageType, InputImageType> ExtractImageFilterType;
typename ExtractImageFilterType::Pointer extract = ExtractImageFilterType::New();
extract->SetInput( this->GetInput() );
extract->SetExtractionRegion( this->GetInput()->GetBufferedRegion() );
......
......@@ -80,12 +80,17 @@ public:
* - NaN values will be considered as no data and replaced as well
* - Output image will have no-data flags and values for all bands
*
* If NaNIsNoData is false:
* If NaNIsNoData is false and the input has at least one band with no-data
* flag and no-data value :
* - Band for which input no-data flags is false will remain
* untouched
* - Output image will have no-data flags and values only for bands
* for which input no-data flag is true.
*
* If NaNIsNoData is false and the input has no band with no-data
* flag and no-data value :
* - Output image will have no-data flags and values for all bands
*
* \ingroup Streamed
* \ingroup MultiThreaded
* \ingroup OTBImageManipulation
......@@ -160,7 +165,7 @@ protected:
std::vector<bool> flags = noDataValueAvailable;
if(this->GetFunctor().m_NaNIsNoData)
if((this->GetFunctor().m_NaNIsNoData) || (!ret))
{
flags = std::vector<bool>(flags.size(),true);
}
......
......@@ -229,8 +229,10 @@ public:
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef TInputImage InputImageType;
typedef typename InputImageType::ConstPointer InputImagePointer;
typedef typename TOutputImage::PixelType OutputPixelType;
typedef typename TInputImage::PixelType InputPixelType;
typedef typename InputImageType::PixelType InputPixelType;
typedef typename InputPixelType::ValueType InputValueType;
typedef typename OutputPixelType::ValueType OutputValueType;
typedef typename itk::NumericTraits<InputValueType>::RealType InputRealType;
......
......@@ -88,8 +88,8 @@ VectorRescaleIntensityImageFilter<TInputImage, TOutputImage>
if (m_AutomaticInputMinMaxComputation)
{
typedef typename Superclass::InputImageType InputImageType;
typedef typename Superclass::InputImagePointer InputImagePointer;
// typedef typename Superclass::InputImageType InputImageType;
// typedef typename Superclass::InputImagePointer InputImagePointer;
// Get the input
InputImagePointer inputImage = this->GetInput();
......
......@@ -185,7 +185,6 @@ PleiadesPToXSAffineTransformCalculator
OffsetType offset = ComputeOffset(panchromaticImage,xsImage);
// Apply the scaling
typedef itk::ScalableAffineTransform<double, 2> TransformType;
TransformType::Pointer transform = TransformType::New();
transform->SetIdentity();
......
......@@ -99,7 +99,7 @@ OGRIOHelper
}
inline void
void
OGRIOHelper
::ConvertGeometryToPolygonNode(const OGRGeometry * ogrGeometry, DataNodePointerType node) const
{
......
......@@ -164,7 +164,6 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
ioSize[i] = dimSize[i];
}
typedef typename TOutputImage::IndexType IndexType;
IndexType start;
if (!this->m_ImageIO->CanStreamRead()) start.Fill(0);
else start = output->GetRequestedRegion().GetIndex();
......@@ -521,8 +520,6 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
this->SetMetaDataDictionary(dictLight);
}
typedef typename TOutputImage::IndexType IndexType;
IndexType start;
start.Fill(0);
......
......@@ -33,9 +33,8 @@
#endif
#include "otb_shark.h"
#include <shark/Algorithms/StoppingCriteria/AbstractStoppingCriterion.h>
#include <shark/Models/LinearModel.h>
#include <shark/Models/ConcatenatedModel.h>
#include <shark/Models/NeuronLayers.h>
#include <shark/Models/FFNet.h>
#include <shark/Models/Autoencoder.h>
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
......@@ -77,9 +76,9 @@ public:
typedef typename Superclass::ConfidenceListSampleType ConfidenceListSampleType;
/// Neural network related typedefs
typedef shark::ConcatenatedModel<shark::RealVector> ModelType;
typedef shark::LinearModel<shark::RealVector,NeuronType> LayerType;
typedef shark::LinearModel<shark::RealVector, shark::LinearNeuron> OutLayerType;
typedef shark::Autoencoder<NeuronType,shark::LinearNeuron> OutAutoencoderType;
typedef shark::Autoencoder<NeuronType,NeuronType> AutoencoderType;
typedef shark::FFNet<NeuronType,shark::LinearNeuron> NetworkType;
itkNewMacro(Self);
itkTypeMacro(AutoencoderModel, DimensionalityReductionModel);
......@@ -128,16 +127,18 @@ public:
void Train() override;
template <class T>
template <class T, class Autoencoder>
void TrainOneLayer(
shark::AbstractStoppingCriterion<T> & criterion,
Autoencoder &,
unsigned int,
shark::Data<shark::RealVector> &,
std::ostream&);
template <class T>
template <class T, class Autoencoder>
void TrainOneSparseLayer(
shark::AbstractStoppingCriterion<T> & criterion,
Autoencoder &,
unsigned int,
shark::Data<shark::RealVector> &,
std::ostream&);
......@@ -165,9 +166,7 @@ protected:
private:
/** Internal Network */
ModelType m_Encoder;
std::vector<LayerType> m_InLayers;
OutLayerType m_OutLayer;
NetworkType m_Net;
itk::Array<unsigned int> m_NumberOfHiddenNeurons;
/** Training parameters */
unsigned int m_NumberOfIterations; // stop the training after a fixed number of iterations
......
......@@ -34,17 +34,18 @@
#include "otbSharkUtils.h"
//include train function
#include <shark/ObjectiveFunctions/ErrorFunction.h>
//~ #include <shark/ObjectiveFunctions/SparseAutoencoderError.h>//the error function performing the regularisation of the hidden neurons
#include <shark/ObjectiveFunctions/SparseAutoencoderError.h>//the error function performing the regularisation of the hidden neurons
#include <shark/Algorithms/GradientDescent/Rprop.h>// the RProp optimization algorithm
#include <shark/ObjectiveFunctions/Loss/SquaredLoss.h> // squared loss used for regression
#include <shark/ObjectiveFunctions/Regularizer.h> //L2 regulariziation
//~ #include <shark/Models/ImpulseNoiseModel.h> //noise source to corrupt the inputs
#include <shark/Models/ImpulseNoiseModel.h> //noise source to corrupt the inputs
#include <shark/Models/ConcatenatedModel.h>//to concatenate the noise with the model
#include <shark/Algorithms/StoppingCriteria/MaxIterations.h> //A simple stopping criterion that stops after a fixed number of iterations
#include <shark/Algorithms/StoppingCriteria/TrainingProgress.h> //Stops when the algorithm seems to converge, Tracks the progress of the training error over a period of time
#include <shark/Algorithms/GradientDescent/Adam.h>
#include <shark/Algorithms/GradientDescent/SteepestDescent.h>
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
......@@ -82,56 +83,96 @@ AutoencoderModel<TInputValue,NeuronType>
}
// Initialization of the feed forward neural network
m_Encoder = ModelType();
m_InLayers.clear();
size_t previousShape = shark::dataDimension(inputSamples);
std::vector<size_t> layers;
layers.push_back(shark::dataDimension(inputSamples));
for (unsigned int i = 0 ; i < m_NumberOfHiddenNeurons.Size(); ++i)
{
m_InLayers.push_back( LayerType(previousShape, m_NumberOfHiddenNeurons[i]) );
previousShape = m_NumberOfHiddenNeurons[i];
m_Encoder.add(&(m_InLayers.back()), true);
layers.push_back(m_NumberOfHiddenNeurons[i]);
}
for (unsigned int i = std::max(0,static_cast<int>(m_NumberOfHiddenNeurons.Size()-1)) ; i > 0; --i)
{
m_InLayers.push_back( LayerType(previousShape, m_NumberOfHiddenNeurons[i-1]) );
previousShape = m_NumberOfHiddenNeurons[i-1];
layers.push_back(m_NumberOfHiddenNeurons[i-1]);
}
m_OutLayer = OutLayerType(previousShape, shark::dataDimension(inputSamples));
// Training of the autoencoders pairwise, starting from the first and last layers
for (unsigned int i = 0 ; i < m_NumberOfHiddenNeurons.Size(); ++i)
layers.push_back(shark::dataDimension(inputSamples));
m_Net.setStructure(layers);
shark::initRandomNormal(m_Net,0.1);
// Training of the first Autoencoder (first and last layer of the FF network)
if (m_Epsilon > 0)
{
shark::TrainingProgress<> criterion(5,m_Epsilon);
OutAutoencoderType net;
// Shark doesn't allow to train a layer using a sparsity term AND a noisy input.
if (m_Noise[0] != 0)
{
TrainOneLayer(criterion, net, 0, inputSamples, ofs);
}
else
{
TrainOneSparseLayer(criterion, net, 0, inputSamples, ofs);
}
criterion.reset();
}
else
{
shark::MaxIterations<> criterion(m_NumberOfIterations);
OutAutoencoderType net;
// Shark doesn't allow to train a layer using a sparsity term AND a noisy input.
if (m_Noise[0] != 0)
{
TrainOneLayer(criterion, net, 0, inputSamples, ofs);
otbMsgDevMacro(<< "m_Noise " << m_Noise[0]);
}
else
{
TrainOneSparseLayer(criterion, net, 0, inputSamples, ofs);
}
criterion.reset();
}
// Training of the other autoencoders
if (m_Epsilon > 0)
{
shark::TrainingProgress<> criterion(5,m_Epsilon);
for (unsigned int i = 1 ; i < m_NumberOfHiddenNeurons.Size(); ++i)
{
AutoencoderType net;
// Shark doesn't allow to train a layer using a sparsity term AND a noisy input.
if (m_Noise[i] != 0)
{
TrainOneLayer(criterion, i, inputSamples, ofs);
TrainOneLayer(criterion, net, i, inputSamples, ofs);
}
else
{
TrainOneSparseLayer(criterion, i, inputSamples, ofs);
TrainOneSparseLayer(criterion, net, i, inputSamples, ofs);
}
criterion.reset();
}
}
else
{
shark::MaxIterations<> criterion(m_NumberOfIterations);
for (unsigned int i = 1 ; i < m_NumberOfHiddenNeurons.Size(); ++i)
{
AutoencoderType net;
// Shark doesn't allow to train a layer using a sparsity term AND a noisy input.
if (m_Noise[i] != 0)
{
TrainOneLayer(criterion, i, inputSamples, ofs);
TrainOneLayer(criterion, net, i, inputSamples, ofs);
otbMsgDevMacro(<< "m_Noise " << m_Noise[0]);
}
else
{
TrainOneSparseLayer( criterion, i, inputSamples, ofs);
TrainOneSparseLayer( criterion, net, i, inputSamples, ofs);
}
criterion.reset();
}
// encode the samples with the last encoder trained
inputSamples = m_InLayers[i](inputSamples);
}
if (m_NumberOfIterationsFineTuning > 0)
{
......@@ -142,37 +183,31 @@ AutoencoderModel<TInputValue,NeuronType>
}
template <class TInputValue, class NeuronType>
template <class T>
template <class T, class Autoencoder>
void
AutoencoderModel<TInputValue,NeuronType>
::TrainOneLayer(
shark::AbstractStoppingCriterion<T> & criterion,
Autoencoder & net,
unsigned int layer_index,
shark::Data<shark::RealVector> &samples,
std::ostream& File)
{
typedef shark::AbstractModel<shark::RealVector,shark::RealVector> BaseModelType;
ModelType net;
net.add(&(m_InLayers[layer_index]), true);
net.add( (layer_index ?
(BaseModelType*) &(m_InLayers[m_NumberOfHiddenNeurons.Size()*2 - 1 - layer_index]) :
(BaseModelType*) &m_OutLayer) , true);
otbMsgDevMacro(<< "Noise " << m_Noise[layer_index]);
std::size_t inputs = dataDimension(samples);
net.setStructure(inputs, m_NumberOfHiddenNeurons[layer_index]);
initRandomUniform(net,-m_InitFactor*std::sqrt(1.0/inputs),m_InitFactor*std::sqrt(1.0/inputs));
//~ shark::ImpulseNoiseModel noise(inputs,m_Noise[layer_index],1.0); //set an input pixel with probability m_Noise to 0
//~ shark::ConcatenatedModel<shark::RealVector,shark::RealVector> model = noise>> net;
shark::ImpulseNoiseModel noise(inputs,m_Noise[layer_index],1.0); //set an input pixel with probability m_Noise to 0
shark::ConcatenatedModel<shark::RealVector,shark::RealVector> model = noise>> net;
shark::LabeledData<shark::RealVector,shark::RealVector> trainSet(samples,samples);//labels identical to inputs
shark::SquaredLoss<shark::RealVector> loss;
//~ shark::ErrorFunction error(trainSet, &model, &loss);
shark::ErrorFunction<> error(trainSet, &net, &loss);
shark::ErrorFunction error(trainSet, &model, &loss);
shark::TwoNormRegularizer<> regularizer(error.numberOfVariables());
shark::TwoNormRegularizer regularizer(error.numberOfVariables());
error.setRegularizer(m_Regularization[layer_index],&regularizer);
shark::Adam<> optimizer;
shark::IRpropPlusFull optimizer;
error.init();
optimizer.init(error);
......@@ -195,37 +230,35 @@ AutoencoderModel<TInputValue,NeuronType>
} while( !criterion.stop( optimizer.solution() ) );
net.setParameterVector(optimizer.solution().point);
m_Net.setLayer(layer_index,net.encoderMatrix(),net.hiddenBias()); // Copy the encoder in the FF neural network
m_Net.setLayer( m_NumberOfHiddenNeurons.Size()*2 - 1 - layer_index,net.decoderMatrix(),net.outputBias()); // Copy the decoder in the FF neural network
samples = net.encode(samples);
}
template <class TInputValue, class NeuronType>
template <class T>
template <class T, class Autoencoder>
void AutoencoderModel<TInputValue,NeuronType>::TrainOneSparseLayer(
shark::AbstractStoppingCriterion<T> & criterion,
Autoencoder & net,
unsigned int layer_index,
shark::Data<shark::RealVector> &samples,
std::ostream& File)
{
typedef shark::AbstractModel<shark::RealVector,shark::RealVector> BaseModelType;
ModelType net;
net.add(&(m_InLayers[layer_index]), true);
net.add( (layer_index ?
(BaseModelType*) &(m_InLayers[m_NumberOfHiddenNeurons.Size()*2 - 1 - layer_index]) :
(BaseModelType*) &m_OutLayer) , true);
//AutoencoderType net;
std::size_t inputs = dataDimension(samples);
net.setStructure(inputs, m_NumberOfHiddenNeurons[layer_index]);
shark::initRandomUniform(net,-m_InitFactor*std::sqrt(1.0/inputs),m_InitFactor*std::sqrt(1.0/inputs));
// Idea : set the initials value for the output weights higher than the input weights
shark::LabeledData<shark::RealVector,shark::RealVector> trainSet(samples,samples);//labels identical to inputs
shark::SquaredLoss<shark::RealVector> loss;
//~ shark::SparseAutoencoderError error(trainSet,&net, &loss, m_Rho[layer_index], m_Beta[layer_index]);
// SparseAutoencoderError doesn't exist anymore, for now use a plain ErrorFunction
shark::ErrorFunction<> error(trainSet, &net, &loss);
shark::SparseAutoencoderError error(trainSet,&net, &loss, m_Rho[layer_index], m_Beta[layer_index]);
shark::TwoNormRegularizer<> regularizer(error.numberOfVariables());
shark::TwoNormRegularizer regularizer(error.numberOfVariables());
error.setRegularizer(m_Regularization[layer_index],&regularizer);
shark::Adam<> optimizer;
shark::IRpropPlusFull optimizer;
error.init();
optimizer.init(error);
......@@ -246,6 +279,9 @@ void AutoencoderModel<TInputValue,NeuronType>::TrainOneSparseLayer(
File << "end layer" << std::endl;
}
net.setParameterVector(optimizer.solution().point);
m_Net.setLayer(layer_index,net.encoderMatrix(),net.hiddenBias()); // Copy the encoder in the FF neural network
m_Net.setLayer( m_NumberOfHiddenNeurons.Size()*2 - 1 - layer_index,net.decoderMatrix(),net.outputBias()); // Copy the decoder in the FF neural network
samples = net.encode(samples);
}
template <class TInputValue, class NeuronType>
......@@ -257,23 +293,15 @@ AutoencoderModel<TInputValue,NeuronType>
shark::Data<shark::RealVector> &samples,
std::ostream& File)
{
// create full network
ModelType net;
for (auto &layer : m_InLayers)
{
net.add(&layer, true);
}
net.add(&m_OutLayer, true);
//labels identical to inputs
shark::LabeledData<shark::RealVector,shark::RealVector> trainSet(samples,samples);
shark::SquaredLoss<shark::RealVector> loss;
shark::ErrorFunction<> error(trainSet, &net, &loss);
shark::TwoNormRegularizer<> regularizer(error.numberOfVariables());
shark::ErrorFunction error(trainSet, &m_Net, &loss);
shark::TwoNormRegularizer regularizer(error.numberOfVariables());
error.setRegularizer(m_Regularization[0],&regularizer);
shark::Adam<> optimizer;
shark::IRpropPlusFull optimizer;
error.init();
optimizer.init(error);
otbMsgDevMacro(<<"Error before training : " << optimizer.solution().value);
......@@ -298,6 +326,7 @@ AutoencoderModel<TInputValue,NeuronType>
try
{
this->Load(filename);
m_Net.name();
}
catch(...)
{
......@@ -321,15 +350,22 @@ AutoencoderModel<TInputValue,NeuronType>
{
otbMsgDevMacro(<< "saving model ...");
std::ofstream ofs(filename);
ofs << "Autoencoder" << std::endl; // the first line of the model file contains a key
ofs << (m_InLayers.size() + 1) << std::endl; // second line is the number of encoders/decoders
ofs << m_Net.name() << std::endl; // the first line of the model file contains a key
shark::TextOutArchive oa(ofs);
for (const auto &layer : m_InLayers)
oa << m_Net;
ofs.close();
if (this->m_WriteWeights == true) // output the map vectors in a txt file
{
oa << layer;
std::ofstream otxt(filename+".txt");
for (unsigned int i = 0 ; i < m_Net.layerMatrices().size(); ++i)
{
otxt << "layer " << i << std::endl;
otxt << m_Net.layerMatrix(i) << std::endl;
otxt << m_Net.bias(i) << std::endl;
otxt << std::endl;
}
}
oa << m_OutLayer;
ofs.close();
}
template <class TInputValue, class NeuronType>
......@@ -337,39 +373,23 @@ void
AutoencoderModel<TInputValue,NeuronType>
::Load(const std::string & filename, const std::string & /*name*/)
{
NetworkType net;
std::ifstream ifs(filename);
char buffer[256];
// check first line
ifs.getline(buffer,256);
std::string bufferStr(buffer);
if (bufferStr != "Autoencoder"){
char autoencoder[256];
ifs.getline(autoencoder,256);
std::string autoencoderstr(autoencoder);
if (autoencoderstr != net.name()){
itkExceptionMacro(<< "Error opening " << filename.c_str() );
}
// check second line
ifs.getline(buffer,256);
int nbLevels = boost::lexical_cast<int>(buffer);
if (nbLevels < 2 || nbLevels%2 == 1)
{
itkExceptionMacro(<< "Unexpected number of levels : "<<buffer );
}
m_InLayers.clear();
m_Encoder = ModelType();
shark::TextInArchive ia(ifs);
for (int i=0 ; (i+1) < nbLevels ; i++)
{
LayerType layer;
ia >> layer;
m_InLayers.push_back(layer);
}
ia >> m_OutLayer;
ia >> m_Net;
ifs.close();
for (int i=0 ; i < nbLevels/2 ; i++)
{
m_Encoder.add(&(m_InLayers[i]) ,true);
}
this->SetDimension( m_Encoder.outputShape()[0] );
// This gives us the dimension if we keep the encoder and decoder
size_t feature_layer_index = m_Net.layerMatrices().size()/2;
// number of neurons in the feature layer (second dimension of the first decoder weight matrix)
this->SetDimension(m_Net.layerMatrix(feature_layer_index).size2());
}
template <class TInputValue, class NeuronType>
......@@ -389,7 +409,7 @@ AutoencoderModel<TInputValue,NeuronType>
shark::Data<shark::RealVector> data = shark::createDataFromRange(features);
// features layer for a network containing the encoder and decoder part
data = m_Encoder(data);
data = m_Net.evalLayer( m_Net.layerMatrices().size()/2-1 ,data);
TargetSampleType target;
target.SetSize(this->m_Dimension);
......@@ -415,7 +435,7 @@ AutoencoderModel<TInputValue,NeuronType>
shark::Data<shark::RealVector> data = shark::createDataFromRange(features);
TargetSampleType target;
// features layer for a network containing the encoder and decoder part
data = m_Encoder(data);
data = m_Net.evalLayer( m_Net.layerMatrices().size()/2-1 ,data);
unsigned int id = startIndex;
target.SetSize(this->m_Dimension);
......
......@@ -137,11 +137,11 @@ PCAModel<TInputValue>::Load(const std::string & filename, const std::string & /*
ifs.close();
if (this->m_Dimension ==0)
{
this->m_Dimension = m_Encoder.outputShape()[0];
this->m_Dimension = m_Encoder.outputSize();
}
auto eigenvectors = m_Encoder.matrix();
eigenvectors.resize(this->m_Dimension,m_Encoder.inputShape()[0]);
eigenvectors.resize(this->m_Dimension,m_Encoder.inputSize());
m_Encoder.setStructure(eigenvectors, m_Encoder.offset() );
}
......
......@@ -28,11 +28,7 @@ otb_module(OTBLearningBase
OTBImageBase
OTBITK
OPTIONAL_DEPENDS
OTBShark
TEST_DEPENDS
OTBBoost
OTBTestKernel
OTBImageIO
......
......@@ -32,10 +32,6 @@ otbKMeansImageClassificationFilterNew.cxx
otbMachineLearningModelTemplates.cxx
)
if(OTB_USE_SHARK)
set(OTBLearningBaseTests ${OTBLearningBaseTests} otbSharkUtilsTests.cxx)
endif()
add_executable(otbLearningBaseTestDriver ${OTBLearningBaseTests})
target_link_libraries(otbLearningBaseTestDriver ${OTBLearningBase-Test_LIBRARIES})
otb_module_target_label(otbLearningBaseTestDriver)
......@@ -72,7 +68,3 @@ otb_add_test(NAME leTuDecisionTreeNew COMMAND otbLearningBaseTestDriver
otb_add_test(NAME leTuKMeansImageClassificationFilterNew COMMAND otbLearningBaseTestDriver
otbKMeansImageClassificationFilterNew)
if(OTB_USE_SHARK)
otb_add_test(NAME leTuSharkNormalizeLabels COMMAND otbLearningBaseTestDriver
otbSharkNormalizeLabels)
endif()