/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ /* * File: Stack.cpp * Author: jens * * Created on 25. Oktober 2019, 18:26 */ #include #include "Stack.hpp" using namespace std; Stack::Stack(const std::string &dir, const std::string &name) : m_dir(dir) , m_name(name) , m_pLayers(nullptr) { } Stack::Stack(const Stack& orig) : m_dir(orig.m_dir) , m_name(orig.m_name) , m_pLayers(orig.m_pLayers) { } Stack::~Stack() { Layer *pLayer = m_pLayers; while(pLayer) { Layer *pNextLayer = pLayer->next; delete pLayer; pLayer = pNextLayer; } } void Stack::setName(const std::string& name) { m_name = name; } size_t Stack::numLayers() { size_t count = 0; Layer *pLayer = m_pLayers; while(pLayer) { count++; pLayer = pLayer->next; } return count; } void Stack::addLayer(Layer *pOtherLayer) { if (!m_pLayers) { m_pLayers = pOtherLayer; pOtherLayer->prev = nullptr; } else { Layer *pLayer = m_pLayers; while(pLayer->next) { pLayer = pLayer->next; } pLayer->next = pOtherLayer; pOtherLayer->prev = pLayer; } } void Stack::delLayer(Layer* pLayer) { assert(!"Stack::delLayer: Not implemented!"); } Layer* Stack::getLayer(size_t layerId) const { Layer *pLayer = m_pLayers; while(pLayer) { if (pLayer->id() == layerId) { return pLayer; } pLayer = pLayer->next; } return nullptr; } bool Stack::load(LayerConstructor *pLayerConstructor) { std::cout << "Importing Project " << m_name << std::endl; ifstream ifs(m_dir + "/" + m_name + string(".prj")); Json::Reader reader; Json::Value project; reader.parse(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 Stack::save() { std::cout << "Exporting Project " << m_name << std::endl; ofstream ofs(m_dir + "/" + m_name + string(".prj")); Json::StyledWriter writer; Json::Value project; project["stack"]["name"] = m_name; Json::Value layers(Json::arrayValue); Layer *pLayer = m_pLayers; while(pLayer) { layers.append(pLayer->toJson()); pLayer = pLayer->next; } project["stack"]["layers"] = layers; ofs << writer.write(project); return true; } void Stack::weightsInit(double stddev) { Layer *pLayer = m_pLayers; while(pLayer) { pLayer->weightsInit(stddev); pLayer = pLayer->next; } } bool Stack::loadWeights() { Layer *pLayer = m_pLayers; while(pLayer) { if (!pLayer->weightsLoad(m_dir, m_name)) { return false; } pLayer = pLayer->next; } return true; } bool Stack::saveWeights() { Layer *pLayer = m_pLayers; while(pLayer) { if (!pLayer->weightsSave(m_dir, m_name)) { return false; } pLayer = pLayer->next; } return true; } void Stack::train(Rbm::IListener* pListener) { Layer *pLayer = m_pLayers; while(pLayer) { std::cout << m_name << ": " << " Training of layer " << std::to_string(pLayer->id()) << std::endl; pLayer->setBatch(m_trainingBatch); pLayer->train(pListener); pLayer = pLayer->next; } } arma::mat& Stack::trainingBatch() { return m_trainingBatch; } arma::mat Stack::trainingBatch(Layer* pThatLayer) { arma::mat thisBatch = m_trainingBatch; Layer *pLayer = m_pLayers; while (pLayer) { if (pLayer->id() == pThatLayer->id()) { break; } thisBatch = pLayer->toHiddenProbs(thisBatch); pLayer = pLayer->next; } return thisBatch; } size_t Stack::loadTrainingBatch(bool doNormalize) { std::string filename = m_dir + "/" + m_name + ".training.dat"; std::string path = m_dir + "/" + m_name + ".training.dat"; bool success = m_trainingBatch.load(filename, arma::arma_ascii); if (success) { if (doNormalize) { m_trainingBatch = Rbm::normalize(m_trainingBatch); } std::cout << "Loaded " << m_trainingBatch.n_rows << " training samples\n"; } return m_trainingBatch.n_rows; } size_t Stack::saveTrainingBatch() { std::string filename = m_dir + "/" + m_name + ".training.dat"; bool success = m_trainingBatch.save(filename, arma::arma_ascii); if (success) { std::cout << "Saved " << m_trainingBatch.n_rows << " training samples\n"; } return m_trainingBatch.n_rows; } size_t Stack::numTraining() { return m_trainingBatch.n_rows; } void Stack::addTraining(const arma::mat &toAdd) { m_trainingBatch.insert_rows(m_trainingBatch.n_rows, toAdd); } void Stack::delTraining(int index) { m_trainingBatch.shed_row(index); }