diff --git a/source/AStack.cpp b/source/AStack.cpp index f8a3a7e..bb6ea46 100644 --- a/source/AStack.cpp +++ b/source/AStack.cpp @@ -12,15 +12,17 @@ */ #include "AStack.hpp" +#include "StackCreator.hpp" #include using namespace std; -AStack::AStack(const std::string &dir, StackType type, const std::string &name) +const char *AStack::stackTypeStrings[NUM_STACKTYPES] = {"None", "Deep", "Rnn"}; + +AStack::AStack(StackType type, const std::string &name) : m_name(name) , m_type(type) , m_pLayers(nullptr) -, m_dir(dir) { } @@ -39,6 +41,39 @@ AStack::~AStack() } } +AStack::AStack(StackType type, const std::string &name, Json::Value& layers, LayerConstructor* pLayerConstructor) +: m_type(type) +, m_name(name) +, m_pLayers(nullptr) +{ + for (int i=0; i < layers.size(); i++) + { + Json::Value &layer = layers[i]; + + string layername = layer["name"].asString(); + int numVisibleX = layer["numVisibleX"].asInt(); + int numVisibleY = layer["numVisibleY"].asInt(); + int numHidden = layer["numHidden"].asInt(); + int numContext = layer["numContext"].asInt(); + + Layer *pLayer = nullptr; + if (!pLayerConstructor) + { + pLayer = new Layer(layername, i, numVisibleX, numVisibleY, numHidden, numContext); + } + else + { + pLayer = pLayerConstructor->onConstruct(this, layername, i, numVisibleX, numVisibleY, numHidden, numContext); + } + + assert(pLayer != nullptr); + + pLayer->fromJson(layer["rbm"]); + addLayer(pLayer); + } + +} + AStack::StackType AStack::type() { return m_type; @@ -100,68 +135,9 @@ Layer* AStack::getLayer(size_t layerId) const } -bool AStack::load(LayerConstructor *pLayerConstructor) +bool AStack::save(const std::string &dir) { - std::cout << "Importing Project " << m_name << std::endl; - ifstream ifs(m_dir + "/" + m_name + string(".prj")); - - Json::Value project; - ifs >> project; - - const string &name = project["stack"]["name"].asString(); - Json::Value &layers = project["stack"]["layers"]; - - for (int i=0; i < layers.size(); i++) - { - Json::Value &layer = layers[i]; - - string layername = layer["name"].asString(); - int numVisibleX = layer["numVisibleX"].asInt(); - int numVisibleY = layer["numVisibleY"].asInt(); - int numHidden = layer["numHidden"].asInt(); - int numContext = layer["numContext"].asInt(); - - Layer *pLayer = nullptr; - if (!pLayerConstructor) - { - pLayer = new Layer(layername, i, numVisibleX, numVisibleY, numHidden, numContext); - } - else - { - pLayer = pLayerConstructor->onConstruct(layername, i, numVisibleX, numVisibleY, numHidden, numContext); - } - - assert(pLayer != nullptr); - - pLayer->fromJson(layer["rbm"]); - addLayer(pLayer); - } - - return true; -} - -bool AStack::save() -{ - std::cout << "Exporting Project " << m_name << std::endl; - ofstream ofs(m_dir + "/" + m_name + string(".prj")); - - Json::Value project; - project["stack"]["name"] = m_name; - project["stack"]["type_string"] = stackTypeStrings[m_type]; - project["stack"]["type"] = m_type; - - Json::Value layers(Json::arrayValue); - Layer *pLayer = m_pLayers; - while(pLayer) - { - layers.append(pLayer->toJson()); - pLayer = pLayer->next; - } - project["stack"]["layers"] = layers; - - ofs << project; - - return true; + return StackCreator::toFile(this, dir, m_name); } void AStack::weightsInit(double stddev) @@ -174,12 +150,12 @@ void AStack::weightsInit(double stddev) } } -bool AStack::loadWeights() +bool AStack::loadWeights(const std::string &dir) { Layer *pLayer = m_pLayers; while(pLayer) { - if (!pLayer->weightsLoad(m_dir, m_name)) + if (!pLayer->weightsLoad(dir, m_name)) { return false; } @@ -188,12 +164,12 @@ bool AStack::loadWeights() return true; } -bool AStack::saveWeights() +bool AStack::saveWeights(const std::string &dir) { Layer *pLayer = m_pLayers; while(pLayer) { - if (!pLayer->weightsSave(m_dir, m_name)) + if (!pLayer->weightsSave(dir, m_name)) { return false; } diff --git a/source/AStack.hpp b/source/AStack.hpp index d31cc9c..80815b2 100644 --- a/source/AStack.hpp +++ b/source/AStack.hpp @@ -21,13 +21,14 @@ #include "Layer.hpp" #include +class AStack; class LayerConstructor { public: LayerConstructor() {} virtual ~LayerConstructor() {} - virtual Layer* onConstruct(const std::string &name, size_t id, size_t numVisibleX, size_t numVisibleY, size_t numHidden, size_t numContext) + virtual Layer* onConstruct(AStack *pStack, const std::string &name, size_t id, size_t numVisibleX, size_t numVisibleY, size_t numHidden, size_t numContext) { return nullptr; } @@ -44,9 +45,10 @@ public: NUM_STACKTYPES }; - const char *stackTypeStrings[NUM_STACKTYPES] = {"None", "Deep", "Rnn"}; + static const char *stackTypeStrings[NUM_STACKTYPES]; - AStack(const std::string &dir, StackType type, const std::string &name); + AStack(StackType type, const std::string &name); + AStack(StackType type, const std::string &name, Json::Value &layers, LayerConstructor *pLayerConstructor=nullptr); AStack(const AStack& orig); virtual ~AStack(); @@ -58,12 +60,11 @@ public: Layer* getLayer(size_t layerId) const; - bool load(LayerConstructor *pLayerConstructor=nullptr); - bool save(); + bool save(const std::string &dir); void weightsInit(double stddev); - bool loadWeights(); - bool saveWeights(); + bool loadWeights(const std::string &dir); + bool saveWeights(const std::string &dir); virtual void train(size_t layerId, const arma::mat& batch, Rbm::IListener* pListener) = 0; virtual void train(const arma::mat& batch, Rbm::IListener* pListener) = 0; @@ -73,7 +74,6 @@ protected: StackType m_type; std::string m_name; Layer *m_pLayers; - std::string m_dir; private: diff --git a/source/DeepStack.cpp b/source/DeepStack.cpp index aea2f83..602ee75 100644 --- a/source/DeepStack.cpp +++ b/source/DeepStack.cpp @@ -15,14 +15,15 @@ using namespace std; -DeepStack::DeepStack(const std::string &dir, const std::string &name, StackType type) -: AStack(dir, type, name) +DeepStack::DeepStack(const std::string &name) +: AStack(StackType::Deep, name) { } -DeepStack::DeepStack(const DeepStack& orig) -: AStack(orig) +DeepStack::DeepStack(const std::string &name, Json::Value& layers, LayerConstructor* pLayerConstructor) +: AStack(StackType::Deep, name, layers, pLayerConstructor) { + } DeepStack::~DeepStack() @@ -62,10 +63,10 @@ arma::mat& DeepStack::trainingBatch() return m_trainingBatch; } -size_t DeepStack::loadTrainingBatch(bool doNormalize) +size_t DeepStack::loadTrainingBatch(const std::string &dir, bool doNormalize) { - std::string filename = m_dir + "/" + m_name + ".training.dat"; - std::string path = m_dir + "/" + m_name + ".training.dat"; + std::string filename = dir + "/" + m_name + ".training.dat"; + std::string path = dir + "/" + m_name + ".training.dat"; bool success = m_trainingBatch.load(filename, arma::arma_ascii); if (success) @@ -95,9 +96,9 @@ size_t DeepStack::loadTrainingBatch(bool doNormalize) return m_trainingBatch.n_rows; } -size_t DeepStack::saveTrainingBatch() +size_t DeepStack::saveTrainingBatch(const std::string &dir) { - std::string filename = m_dir + "/" + m_name + ".training.dat"; + std::string filename = dir + "/" + m_name + ".training.dat"; bool success = m_trainingBatch.save(filename, arma::arma_ascii); if (success) diff --git a/source/DeepStack.hpp b/source/DeepStack.hpp index bcb425a..af15f26 100644 --- a/source/DeepStack.hpp +++ b/source/DeepStack.hpp @@ -24,8 +24,9 @@ class DeepStack : public AStack { public: - DeepStack(const std::string &dir, const std::string &name, StackType type=StackType::None); - DeepStack(const DeepStack& orig); + DeepStack(const std::string &name); + DeepStack(const std::string &name, Json::Value &layers, LayerConstructor *pLayerConstructor=nullptr); + DeepStack(const DeepStack& orig) = delete; virtual ~DeepStack(); void train(const arma::mat& batch, Rbm::IListener* pListener) override; @@ -38,8 +39,8 @@ public: size_t numTraining(); void addTraining(const arma::mat &toAdd); void delTraining(int index); - size_t loadTrainingBatch(bool doNormalize=false); - size_t saveTrainingBatch(); + size_t loadTrainingBatch(const std::string &dir, bool doNormalize=false); + size_t saveTrainingBatch(const std::string &dir); arma::mat& trainingBatch(); private: diff --git a/source/MainComponent.cpp b/source/MainComponent.cpp index 80a7db5..85b108d 100644 --- a/source/MainComponent.cpp +++ b/source/MainComponent.cpp @@ -24,6 +24,7 @@ #include #include #include "MainComponent.hpp" +#include "StackCreator.hpp" //[MiscUserDefs] You can add your own user definitions and misc code here... @@ -47,6 +48,7 @@ MainComponent::MainComponent (const String prjname) , m_weightIndex(0) , m_toolTipWindow(this) , m_file(prjname) +, m_dir(".") { addAndMakeVisible (trainButton = new TextButton ("Train button")); trainButton->setTooltip (TRANS("Start/Stop training")); @@ -557,7 +559,7 @@ void MainComponent::buttonClicked (Button* buttonThatWasClicked) if (!m_stack) { - m_stack = new DeepStack(m_file.getParentDirectory().getFullPathName().toStdString(), std::string(projectNameLabel->getText().getCharPointer())); + m_stack = new DeepStack(std::string(projectNameLabel->getText().getCharPointer())); } Layer *pPrev = m_stack->getLayer(next_index-1); if (pPrev) @@ -565,7 +567,7 @@ void MainComponent::buttonClicked (Button* buttonThatWasClicked) numVisX = pPrev->bh().n_elem; numVisY = 1; } - m_stack->addLayer(onConstruct("Layer", next_index, numVisX, numVisY, numHid, numCtx)); + m_stack->addLayer(onConstruct(m_stack, "Layer", next_index, numVisX, numVisY, numHid, numCtx)); m_rbmSelect->addItem(String(next_index), next_index+1); m_rbmSelect->setSelectedId(next_index+1, sendNotification); //[/UserButtonCode_createButton] @@ -583,9 +585,10 @@ void MainComponent::buttonClicked (Button* buttonThatWasClicked) { m_file = fc->getResult(); projectNameLabel->setText(m_file.getFileNameWithoutExtension(), NotificationType::dontSendNotification); - m_stack = new DeepStack(m_file.getParentDirectory().getFullPathName().toStdString(), std::string(projectNameLabel->getText().getCharPointer())); - m_stack->load(this); - m_stack->loadWeights(); + AStack *pStack = StackCreator::fromFile(m_file.getParentDirectory().getFullPathName().toStdString(), std::string(projectNameLabel->getText().getCharPointer()), this); + m_stack = reinterpret_cast(pStack); + // m_stack->load(this); + m_stack->loadWeights(m_dir); m_rbmSelect->clear(dontSendNotification); for (int id=0; id < m_stack->numLayers(); id++) @@ -880,9 +883,9 @@ void MainComponent::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails //[MiscUserCode] You can add your own definitions of your custom methods or any other code here... void MainComponent::save () { - m_stack->saveTrainingBatch(); - m_stack->saveWeights(); - m_stack->save(); + m_stack->saveTrainingBatch(m_dir); + m_stack->saveWeights(m_dir); + m_stack->save(m_dir); } const juce::String& MainComponent::getBaseDir() diff --git a/source/MainComponent.hpp b/source/MainComponent.hpp index 0ffa95b..1bcd725 100644 --- a/source/MainComponent.hpp +++ b/source/MainComponent.hpp @@ -72,9 +72,10 @@ public: void mouseDoubleClick (const MouseEvent& e); void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel); - Layer* onConstruct(const std::string &name, size_t id, size_t numVisibleX, size_t numVisibleY, size_t numHidden, size_t numContext) + Layer* onConstruct(AStack *pStack, const std::string &name, size_t id, size_t numVisibleX, size_t numVisibleY, size_t numHidden, size_t numContext) { - RbmComponent *pComp = new RbmComponent(*m_stack, name, id, numVisibleX, numVisibleY, numHidden, numContext); + DeepStack &deepStack = reinterpret_cast(*pStack); + RbmComponent *pComp = new RbmComponent(deepStack, name, id, numVisibleX, numVisibleY, numHidden, numContext); addAndMakeVisible(pComp); return static_cast(pComp); } @@ -103,13 +104,13 @@ private: void loadTraining() { - m_stack->loadTrainingBatch(rbmNormalizeDataToggleButton->getToggleState()); + m_stack->loadTrainingBatch(m_dir, rbmNormalizeDataToggleButton->getToggleState()); patterSlider->setRange(0, m_stack->numTraining()-1, 1); } void saveTraining() { - m_stack->save(); + m_stack->save(m_dir); } void addTraining(const arma::mat &training) @@ -174,7 +175,7 @@ private: ScopedPointer rbmDoSampleBatch; ScopedPointer