From 8b526a0545007867ff12821b0fc27b837f2b4ceb Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:11:11 +0400 Subject: [PATCH 01/22] Added dotProdVis Added new method so we can propagate down to multiply visible neurons by weights of hidden layer --- modules/DNN/NeuronLayer.cpp | 71 ++++++++++++++++++++++--------------- modules/DNN/NeuronLayer.h | 2 +- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/modules/DNN/NeuronLayer.cpp b/modules/DNN/NeuronLayer.cpp index 4009c0b6..6067ad8b 100644 --- a/modules/DNN/NeuronLayer.cpp +++ b/modules/DNN/NeuronLayer.cpp @@ -3,37 +3,52 @@ #include "DGM/parallel.h" #include "macroses.h" -namespace DirectGraphicalModels { namespace dnn -{ - void CNeuronLayer::generateRandomWeights(void) +namespace DirectGraphicalModels { + namespace dnn { - m_weights = random::U(m_weights.size(), m_weights.type(), -0.5f, 0.5f); - m_biases = random::U(m_biases.size(), m_biases.type(), -0.5f, 0.5f); - } + void CNeuronLayer::generateRandomWeights(void) + { + m_weights = random::U(m_weights.size(), m_weights.type(), -0.5f, 0.5f); + m_biases = random::U(m_biases.size(), m_biases.type(), -0.5f, 0.5f); + } - void CNeuronLayer::dotProd(const Mat& values) - { - // this->m_netValues = this->m_weights * values + m_biases; - gemm(m_weights.t(), values, 1, m_biases, 1, m_netValues); - } + void CNeuronLayer::dotProd(const Mat& values) + { + // this->m_netValues = this->m_weights * values + m_biases; + gemm(m_weights.t(), values, 1, m_biases, 1, m_netValues); + } + void CNeuronLayer::dotProdVis(const Mat& values, Mat weights) + { + gemm(weights, values, 1, m_biases, 1, m_netValues); - void CNeuronLayer::setNetValues(const Mat& values) - { - // Assertions - DGM_ASSERT(values.type() == m_netValues.type()); - DGM_ASSERT(values.size() == m_netValues.size()); - values.copyTo(m_netValues); - } + //this->m_netValues = temp.t(); + /*for (int i = 0; i < weights.rows; i++){ + for (int j = 0; j < weights.cols; j++) { + m_netValues.at(i, 0) += values.at(i, 0) * weights.at(i, j); + } + } + m_netValues += m_biases; + */ + } - Mat CNeuronLayer::getValues(void) const - { - Mat res(m_netValues.clone()); - for (int y = 0; y < res.rows; y++) { - float* pRes = res.ptr(y); - for (int x = 0; x < res.cols; x++) - pRes[x] = m_activationFunction(pRes[x]); + void CNeuronLayer::setNetValues(const Mat& values) + { + // Assertions + DGM_ASSERT(values.type() == m_netValues.type()); + DGM_ASSERT(values.size() == m_netValues.size()); + values.copyTo(m_netValues); } - return res; - } -}} + Mat CNeuronLayer::getValues(void) const + { + Mat res(m_netValues.clone()); + for (int y = 0; y < res.rows; y++) { + float* pRes = res.ptr(y); + for (int x = 0; x < res.cols; x++) + pRes[x] = m_activationFunction(pRes[x]); + } + return res; + } + + } +} \ No newline at end of file diff --git a/modules/DNN/NeuronLayer.h b/modules/DNN/NeuronLayer.h index 72de381e..a85742f4 100644 --- a/modules/DNN/NeuronLayer.h +++ b/modules/DNN/NeuronLayer.h @@ -36,6 +36,7 @@ namespace DirectGraphicalModels { * @details This function updates the neurons' values as \f$ netValues_{(1\times N)} = weights^{\top}_{(C\times N)}\times values_{(1\times C)} + biases_{((1\times N))}\f$ * @note This method updates only the nodes' net values */ + DllExport void dotProdVis(const Mat& values, Mat weights); //new method was added, purpose for it is to multiply visible neurons by weights of hidden layer. DllExport void dotProd(const Mat& values); /** * @brief Returns the values of the neurons of the layer @@ -64,4 +65,3 @@ namespace DirectGraphicalModels { using ptr_nl_t = std::shared_ptr; } } - From 2cf51d77bed194fa3fa4094a19876d7eb5c68190 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:11:35 +0400 Subject: [PATCH 02/22] Updated for RBM --- modules/DNN/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/DNN/CMakeLists.txt b/modules/DNN/CMakeLists.txt index 6e8924de..5ddb7fa4 100644 --- a/modules/DNN/CMakeLists.txt +++ b/modules/DNN/CMakeLists.txt @@ -8,7 +8,9 @@ source_group("Include" FILES ${DNN_INCLUDE}) source_group("" FILES ${DNN_SOURCES} ${DNN_HEADERS}) source_group("Source Files\\Neuron" FILES "Neuron.h" "Neuron.cpp") source_group("Source Files\\Neuron Layer" FILES "NeuronLayer.h" "NeuronLayer.cpp") +source_group("Source Files\\Neuron Layer Bias" FILES "NeuronLayerBias.h" "NeuronLayerBias.cpp") source_group("Source Files\\Perceptron" FILES "Perceptron.h" "Perceptron.cpp") +source_group("Source Files\\RBM" FILES "RBM.h" "RBM.cpp") # Properties -> C/C++ -> General -> Additional Include Directories include_directories(${PROJECT_SOURCE_DIR}/include From 708c1a0b88719d05def14cf29ad81db87a276b3c Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:12:27 +0400 Subject: [PATCH 03/22] RBM implementation --- modules/DNN/RBM.cpp | 132 ++++++++++++++++++++++++++++++++++++++++++++ modules/DNN/RBM.h | 47 ++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 modules/DNN/RBM.cpp create mode 100644 modules/DNN/RBM.h diff --git a/modules/DNN/RBM.cpp b/modules/DNN/RBM.cpp new file mode 100644 index 00000000..cd6b00ea --- /dev/null +++ b/modules/DNN/RBM.cpp @@ -0,0 +1,132 @@ +#include "RBM.h" +#include "macroses.h" + +namespace DirectGraphicalModels { + namespace dnn { + CRBM::CRBM(const std::vector& vpLayers){ + for (auto& nl : vpLayers) + m_vpNeuronLayers.push_back(nl); + } + Mat CRBM::getBinomial(Mat mean) { + + Mat res(mean.clone()); + for (int y = 0; y < res.rows; y++) { + float* pRes = res.ptr(y); + for (int x = 0; x < res.cols; x++) { + if (pRes[x] < 0 || pRes[x]>1) { + pRes[x] = 0; + } + double r = rand() / (RAND_MAX + 1.0); + if (r < pRes[x]) + { + pRes[x] = 1; + } + else + { + pRes[x] = 0; + } + } + } + return res; + } + + void CRBM::debug() { + std::cout << "Weight - rows: " << m_vpNeuronLayers[1]->getWeights().rows << " cols: " << m_vpNeuronLayers[1]->getWeights().cols << std::endl; + + std::cout << "Positive H mean - rows: " << m_positiveHMean.rows << " cols: " << m_positiveHMean.cols << std::endl; + std::cout << "Positive H sample - rows: " << m_positiveHSample.rows << " cols: " << m_positiveHSample.cols << std::endl; + std::cout << "Negative H mean - rows: " << m_negativeHMean.rows << " cols: " << m_negativeHMean.cols << std::endl; + std::cout << "Negative H sample - rows: " << m_negativeHSample.rows << " cols: " << m_negativeHSample.cols << std::endl; + std::cout << "Negative V mean - rows: " << m_negativeVMean.rows << " cols: " << m_negativeVMean.cols << std::endl; + std::cout << "Negative V sample - rows: " << m_negativeVSample.rows << " cols: " << m_negativeVSample.cols << std::endl; + + //m_vpNeuronLayers[0]->getWeights() = m_vpNeuronLayers[1]->getWeights(); + + //std::cout << "Weight visible layer - rows: " << m_vpNeuronLayers[0]->getWeights().rows << " cols: " << m_vpNeuronLayers[0]->getWeights().cols << std::endl; + + } + + void CRBM::sampleVisible(Mat values) { + m_negativeVMean = propagateDown(values); + m_negativeVSample = getBinomial(m_negativeVMean); + + } + + void CRBM::sampleHiddenPositive(Mat values) { + + m_positiveHMean = propagateUp(values); + m_positiveHSample = getBinomial(m_positiveHMean); + + /*for (int y = 0; y < sample.rows; y++) { + float* pRess = sample.ptr(y); + for (int x = 0; x < sample.cols; x++) + std::cout << pRess[x] << std::endl; + }*/ + } + void CRBM::sampleHiddenNegative(Mat values) { + m_negativeHMean = propagateUp(values); + m_negativeHSample = getBinomial(m_negativeHMean); + + } + + Mat CRBM::propagateUp(Mat values) { + m_vpNeuronLayers[0]->setNetValues(values); //set the visible layer values + + m_vpNeuronLayers[1]->dotProd(m_vpNeuronLayers[0]->getValues()); //sigmoid(sum(visible * weights)+bias) + + return m_vpNeuronLayers.back()->getValues(); + } + + Mat CRBM::propagateDown(Mat values){ + m_vpNeuronLayers[0]->dotProdVis(values, m_vpNeuronLayers[1]->getWeights()); + + return m_vpNeuronLayers[0]->getValues(); + } + + void CRBM::gibbsHVH(Mat hiddenSample) { + + sampleVisible(hiddenSample); + sampleHiddenNegative(m_negativeVSample); + + } + + /* This implementation of RBM uses single step contrastive divergence algorithm, called CD-1 */ + void CRBM::contrastiveDivergence(const Mat& values, float learningRate) { + //-------POSITIVE PHASE-------------------- + /*In the positive phase, the input sample “v” from the visible layer is “clamped” to the input layer, + and then is propagated to the hidden layer. The result of the hidden layer activation is h. */ + sampleHiddenPositive(values); + + //------NEGATIVE PHASE--------------------- + /*In the negative phase, “h” from the hidden layer is propagated back to the visible layer with the + new v, say v’. This is then propagated back to the hidden layer with activation result “h” */ + gibbsHVH(m_positiveHMean); + + + std::vector test = m_negativeHSample; + for (int i = 0; i < m_vpNeuronLayers[1]->getNumNeurons(); i++) { + //std::cout << i << std::endl; + for (int j = 0; j < m_vpNeuronLayers[0]->getNumNeurons(); j++) + { + m_vpNeuronLayers[1]->getWeights().at(j, i) += + learningRate * (m_positiveHMean.at(i, 0) * values.at(j, 0) - m_negativeHMean.at(i, 0) * m_negativeVSample.at(j, 0))/4000; // divide + } + m_vpNeuronLayers[1]->getBiases().at(i, 0) += learningRate * (m_positiveHSample.at(i, 0) - m_negativeHMean.at(i, 0))/4000; //divide + } + for (int i = 0; i < m_vpNeuronLayers[0]->getNumNeurons(); i++) + { + //std::cout << i << std::endl; + m_vpNeuronLayers[0]->getBiases().at(i, 0) += learningRate * (values.at(i, 0) * m_negativeVSample.at(i, 0))/4000; //divide + } + + } + + Mat CRBM::reconstruct(Mat values) { + Mat h, temp; + + h = propagateUp(values); + temp = propagateDown(h); + return temp; + } + } +} \ No newline at end of file diff --git a/modules/DNN/RBM.h b/modules/DNN/RBM.h new file mode 100644 index 00000000..d1fe7cf3 --- /dev/null +++ b/modules/DNN/RBM.h @@ -0,0 +1,47 @@ +#pragma once + +#include "types.h" +#include "NeuronLayer.h" + +namespace DirectGraphicalModels { + namespace dnn { + class CRBM { + public: + DllExport CRBM(const std::vector& vpLayers); + DllExport CRBM(const CRBM&) = delete; + DllExport ~CRBM(void) = default; + + DllExport bool operator=(const CRBM&) = delete; + + DllExport void debug(); //printing out rows and cols just to be sure they are correct + + DllExport Mat getBinomial(Mat mean); + DllExport Mat propagateUp( Mat values); //hidden layer = sigmoid(sum(visible*weights)+bias) + DllExport Mat propagateDown(Mat values); //visible layer = sigmoid(sum(hidden*weights)+bias) + + DllExport void sampleVisible(Mat values); //sample viible for negative phase + DllExport void sampleHiddenPositive(Mat values); //sample hidden for positive phase + DllExport void sampleHiddenNegative(Mat values); //sample hidden for negative phase + + DllExport void gibbsHVH(Mat hiddenSample); //gibbs sampling(sample visible and then sample hidden negative phase) + DllExport void contrastiveDivergence(const Mat& values, float learningRate); + DllExport Mat reconstruct(Mat values); + //DllExport void gibbsHVH() + + private: + + + std::vector m_vpNeuronLayers; + + Mat m_positiveHMean; + Mat m_positiveHSample; + + Mat m_negativeHMean; + Mat m_negativeHSample; + + Mat m_negativeVMean; + Mat m_negativeVSample; + + }; + } +} \ No newline at end of file From 9e72b7ef0cba9d346ba0583ad9a7860ed55937fe Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:13:16 +0400 Subject: [PATCH 04/22] Updated for Demo RBM --- demos/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt index fcc7d0b8..98f06e3a 100644 --- a/demos/CMakeLists.txt +++ b/demos/CMakeLists.txt @@ -72,3 +72,6 @@ create_demo(Demo_Stereo "Demo Stereo" "DGM") # ================================================ DEMO ICR ================================================= create_demo(Demo_ICR "Demo ICR" "DGM;DNN;VIS") + +# ================================================ DEMO RBM ================================================= +create_demo(Demo_RBM "Demo RBM" "DGM;DNN;VIS") From 0ddca9cba4154d209730169610ffd211696241a1 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:13:38 +0400 Subject: [PATCH 05/22] Added DemoRBM --- demos/Demo RBM.cpp | 125 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 demos/Demo RBM.cpp diff --git a/demos/Demo RBM.cpp b/demos/Demo RBM.cpp new file mode 100644 index 00000000..877231f6 --- /dev/null +++ b/demos/Demo RBM.cpp @@ -0,0 +1,125 @@ +#include "DNN.h" +#include "DGM.h" +#include "VIS.h" +#include "DGM/timer.h" +#include + +namespace dgm = DirectGraphicalModels; + +/** + * Reads the digits numerical value in a decimal notation + * + * @param file to read, and the number of digits to read + * @return an array of digit labels + */ +std::vector readGroundTruth(const std::string& fileName) +{ + std::vector res; + std::ifstream inFile; + inFile.open(fileName.c_str()); + + if (inFile.is_open()) { + int val; + while (!inFile.eof()) { + inFile >> val; + res.push_back(static_cast(val)); + } + inFile.close(); + } + return res; +} + + +float sigmoidFunction(float x) +{ + return 1.0f / (1.0f + expf(-x)); +} + +float sigmoidFunction_derivative(float x) +{ + float s = sigmoidFunction(x); + return s * (1 - s); +} + +int main() +{ + const float learningRate = 0.05f; + const size_t numEpochs = 20; + const size_t numTestSamples = 2000; + const size_t numTrainSamples = 4000; + + //const byte nStates = 10; + const word nFeatures = 28 * 28; + const size_t numNeuronsHiddenLayer = 10; + +#ifdef WIN32 + const std::string dataPath = "../../data/digits/"; +#else + const std::string dataPath = "../../../data/digits/"; +#endif + + auto pLayerVisible = std::make_shared(nFeatures, 1, [](float x) { return x; }, [](float x) { return 1.0f; }); + auto pLayerHidden = std::make_shared(numNeuronsHiddenLayer, nFeatures, &sigmoidFunction, &sigmoidFunction_derivative); + + pLayerVisible->generateRandomWeights(); + pLayerHidden->generateRandomWeights(); + + dgm::dnn::CRBM rbm({ pLayerVisible, pLayerHidden }); + + //rbm.debug(); + Mat fv; + + // ==================== TRAINING DIGITS ==================== + dgm::Timer::start("Training...\n"); + auto trainGT = readGroundTruth(dataPath + "train_gt.txt"); + for (size_t e = 0; e < numEpochs; e++) + for (int s = 0; s < numTrainSamples; s++) { + std::stringstream ss; + ss << dataPath << "train/digit_" << std::setfill('0') << std::setw(4) << s << ".png"; + std::string fileName = samples::findFile(ss.str()); + Mat img = imread(fileName, 0); + img = img.reshape(1, img.cols * img.rows); + img.convertTo(fv, CV_32FC1, 1.0 / 255); + fv = Scalar(1.0f) - fv; + + rbm.contrastiveDivergence(fv, 0.5f); + } // samples + dgm::Timer::stop(); + + // ==================== TESTING DIGITS ==================== + //dgm::CCMat confMat(nStates); + dgm::Timer::start("Testing..."); + auto testGT = readGroundTruth(dataPath + "test_gt.txt"); + for (size_t s = 0; s < numTestSamples; s++) { + std::stringstream ss; + ss << dataPath << "test/digit_" << std::setfill('0') << std::setw(4) << s << ".png"; + std::string fileName = samples::findFile(ss.str()); + Mat img = imread(fileName, 0); + img = img.reshape(1, img.cols * img.rows); + img.convertTo(fv, CV_32FC1, 1.0 / 255); + fv = Scalar(1.0f) - fv; + + Mat outputValues = rbm.reconstruct(fv); + + Point maxclass; + minMaxLoc(outputValues, NULL, NULL, NULL, &maxclass); + int number = maxclass.y; + + //confMat.estimate(number, testGT[s]); + //printf("prediction [%d] for digit %d with %.3f%s at position %zu \n", number, testDataDigit[z], maxAccuracy, "%", z); + } // samples + dgm::Timer::stop(); + //printf("Accuracy = %.2f%%\n", confMat.getAccuracy()); + + // Confusion matrix + dgm::vis::CMarker marker; + //Mat cMat = confMat.getConfusionMatrix(); + //Mat cMatImg = marker.drawConfusionMatrix(cMat, dgm::vis::MARK_BW); + //imshow("Confusion Matrix", cMatImg); + rbm.debug(); + + waitKey(); + + return 0; + +} From cd22c2bb849d8381bd31ad9de3526466180a5234 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:29:28 +0400 Subject: [PATCH 06/22] Fixed empty lines --- modules/DNN/Demo RBM.cpp | 124 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 modules/DNN/Demo RBM.cpp diff --git a/modules/DNN/Demo RBM.cpp b/modules/DNN/Demo RBM.cpp new file mode 100644 index 00000000..b6750a3f --- /dev/null +++ b/modules/DNN/Demo RBM.cpp @@ -0,0 +1,124 @@ +#include "DNN.h" +#include "DGM.h" +#include "VIS.h" +#include "DGM/timer.h" +#include + +namespace dgm = DirectGraphicalModels; + +/** + * Reads the digits numerical value in a decimal notation + * + * @param file to read, and the number of digits to read + * @return an array of digit labels + */ +std::vector readGroundTruth(const std::string& fileName) +{ + std::vector res; + std::ifstream inFile; + inFile.open(fileName.c_str()); + + if (inFile.is_open()) { + int val; + while (!inFile.eof()) { + inFile >> val; + res.push_back(static_cast(val)); + } + inFile.close(); + } + return res; +} + + +float sigmoidFunction(float x) +{ + return 1.0f / (1.0f + expf(-x)); +} + +float sigmoidFunction_derivative(float x) +{ + float s = sigmoidFunction(x); + return s * (1 - s); +} + +int main() +{ + const float learningRate = 0.05f; + const size_t numEpochs = 20; + const size_t numTestSamples = 2000; + const size_t numTrainSamples = 4000; + + //const byte nStates = 10; + const word nFeatures = 28 * 28; + const size_t numNeuronsHiddenLayer = 10; + +#ifdef WIN32 + const std::string dataPath = "../../data/digits/"; +#else + const std::string dataPath = "../../../data/digits/"; +#endif + + auto pLayerVisible = std::make_shared(nFeatures, 1, [](float x) { return x; }, [](float x) { return 1.0f; }); + auto pLayerHidden = std::make_shared(numNeuronsHiddenLayer, nFeatures, &sigmoidFunction, &sigmoidFunction_derivative); + + pLayerVisible->generateRandomWeights(); + pLayerHidden->generateRandomWeights(); + + dgm::dnn::CRBM rbm({ pLayerVisible, pLayerHidden }); + + //rbm.debug(); + Mat fv; + + // ==================== TRAINING DIGITS ==================== + dgm::Timer::start("Training...\n"); + auto trainGT = readGroundTruth(dataPath + "train_gt.txt"); + for (size_t e = 0; e < numEpochs; e++) + for (int s = 0; s < numTrainSamples; s++) { + std::stringstream ss; + ss << dataPath << "train/digit_" << std::setfill('0') << std::setw(4) << s << ".png"; + std::string fileName = samples::findFile(ss.str()); + Mat img = imread(fileName, 0); + img = img.reshape(1, img.cols * img.rows); + img.convertTo(fv, CV_32FC1, 1.0 / 255); + fv = Scalar(1.0f) - fv; + + rbm.contrastiveDivergence(fv, 0.5f); + } // samples + dgm::Timer::stop(); + + // ==================== TESTING DIGITS ==================== + //dgm::CCMat confMat(nStates); + dgm::Timer::start("Testing..."); + auto testGT = readGroundTruth(dataPath + "test_gt.txt"); + for (size_t s = 0; s < numTestSamples; s++) { + std::stringstream ss; + ss << dataPath << "test/digit_" << std::setfill('0') << std::setw(4) << s << ".png"; + std::string fileName = samples::findFile(ss.str()); + Mat img = imread(fileName, 0); + img = img.reshape(1, img.cols * img.rows); + img.convertTo(fv, CV_32FC1, 1.0 / 255); + fv = Scalar(1.0f) - fv; + + Mat outputValues = rbm.reconstruct(fv); + + Point maxclass; + minMaxLoc(outputValues, NULL, NULL, NULL, &maxclass); + int number = maxclass.y; + + //confMat.estimate(number, testGT[s]); + //printf("prediction [%d] for digit %d with %.3f%s at position %zu \n", number, testDataDigit[z], maxAccuracy, "%", z); + } // samples + dgm::Timer::stop(); + //printf("Accuracy = %.2f%%\n", confMat.getAccuracy()); + + // Confusion matrix + dgm::vis::CMarker marker; + //Mat cMat = confMat.getConfusionMatrix(); + //Mat cMatImg = marker.drawConfusionMatrix(cMat, dgm::vis::MARK_BW); + //imshow("Confusion Matrix", cMatImg); + rbm.debug(); + + waitKey(); + + return 0; +} From 204f870c47ac93c329dae74bebe3b6de7c34896e Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:29:59 +0400 Subject: [PATCH 07/22] Fixed empty lines --- modules/DNN/NeuronLayer.cpp | 3 +-- modules/DNN/RBM.cpp | 9 ++------- modules/DNN/RBM.h | 3 --- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/modules/DNN/NeuronLayer.cpp b/modules/DNN/NeuronLayer.cpp index 6067ad8b..061be39a 100644 --- a/modules/DNN/NeuronLayer.cpp +++ b/modules/DNN/NeuronLayer.cpp @@ -3,8 +3,7 @@ #include "DGM/parallel.h" #include "macroses.h" -namespace DirectGraphicalModels { - namespace dnn +namespace DirectGraphicalModels { namespace dnn { void CNeuronLayer::generateRandomWeights(void) { diff --git a/modules/DNN/RBM.cpp b/modules/DNN/RBM.cpp index cd6b00ea..10564cc2 100644 --- a/modules/DNN/RBM.cpp +++ b/modules/DNN/RBM.cpp @@ -7,8 +7,8 @@ namespace DirectGraphicalModels { for (auto& nl : vpLayers) m_vpNeuronLayers.push_back(nl); } - Mat CRBM::getBinomial(Mat mean) { + Mat CRBM::getBinomial(Mat mean) { Mat res(mean.clone()); for (int y = 0; y < res.rows; y++) { float* pRes = res.ptr(y); @@ -43,7 +43,6 @@ namespace DirectGraphicalModels { //m_vpNeuronLayers[0]->getWeights() = m_vpNeuronLayers[1]->getWeights(); //std::cout << "Weight visible layer - rows: " << m_vpNeuronLayers[0]->getWeights().rows << " cols: " << m_vpNeuronLayers[0]->getWeights().cols << std::endl; - } void CRBM::sampleVisible(Mat values) { @@ -53,7 +52,6 @@ namespace DirectGraphicalModels { } void CRBM::sampleHiddenPositive(Mat values) { - m_positiveHMean = propagateUp(values); m_positiveHSample = getBinomial(m_positiveHMean); @@ -63,6 +61,7 @@ namespace DirectGraphicalModels { std::cout << pRess[x] << std::endl; }*/ } + void CRBM::sampleHiddenNegative(Mat values) { m_negativeHMean = propagateUp(values); m_negativeHSample = getBinomial(m_negativeHMean); @@ -84,12 +83,10 @@ namespace DirectGraphicalModels { } void CRBM::gibbsHVH(Mat hiddenSample) { - sampleVisible(hiddenSample); sampleHiddenNegative(m_negativeVSample); } - /* This implementation of RBM uses single step contrastive divergence algorithm, called CD-1 */ void CRBM::contrastiveDivergence(const Mat& values, float learningRate) { //-------POSITIVE PHASE-------------------- @@ -102,7 +99,6 @@ namespace DirectGraphicalModels { new v, say v’. This is then propagated back to the hidden layer with activation result “h” */ gibbsHVH(m_positiveHMean); - std::vector test = m_negativeHSample; for (int i = 0; i < m_vpNeuronLayers[1]->getNumNeurons(); i++) { //std::cout << i << std::endl; @@ -118,7 +114,6 @@ namespace DirectGraphicalModels { //std::cout << i << std::endl; m_vpNeuronLayers[0]->getBiases().at(i, 0) += learningRate * (values.at(i, 0) * m_negativeVSample.at(i, 0))/4000; //divide } - } Mat CRBM::reconstruct(Mat values) { diff --git a/modules/DNN/RBM.h b/modules/DNN/RBM.h index d1fe7cf3..d68704e2 100644 --- a/modules/DNN/RBM.h +++ b/modules/DNN/RBM.h @@ -29,8 +29,6 @@ namespace DirectGraphicalModels { //DllExport void gibbsHVH() private: - - std::vector m_vpNeuronLayers; Mat m_positiveHMean; @@ -41,7 +39,6 @@ namespace DirectGraphicalModels { Mat m_negativeVMean; Mat m_negativeVSample; - }; } } \ No newline at end of file From f060c82e211afd2dd4f7f988bfcb6d97c9f39853 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:31:32 +0400 Subject: [PATCH 08/22] Fixed empty lines --- demos/Demo RBM.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/demos/Demo RBM.cpp b/demos/Demo RBM.cpp index 877231f6..b6750a3f 100644 --- a/demos/Demo RBM.cpp +++ b/demos/Demo RBM.cpp @@ -121,5 +121,4 @@ int main() waitKey(); return 0; - } From c41ea5196996f87a8a79b1ae621ab76f5763f564 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 16:05:35 +0400 Subject: [PATCH 09/22] Fixed empty lines --- modules/DNN/RBM.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/DNN/RBM.cpp b/modules/DNN/RBM.cpp index 10564cc2..f4e6889e 100644 --- a/modules/DNN/RBM.cpp +++ b/modules/DNN/RBM.cpp @@ -39,16 +39,11 @@ namespace DirectGraphicalModels { std::cout << "Negative H sample - rows: " << m_negativeHSample.rows << " cols: " << m_negativeHSample.cols << std::endl; std::cout << "Negative V mean - rows: " << m_negativeVMean.rows << " cols: " << m_negativeVMean.cols << std::endl; std::cout << "Negative V sample - rows: " << m_negativeVSample.rows << " cols: " << m_negativeVSample.cols << std::endl; - - //m_vpNeuronLayers[0]->getWeights() = m_vpNeuronLayers[1]->getWeights(); - - //std::cout << "Weight visible layer - rows: " << m_vpNeuronLayers[0]->getWeights().rows << " cols: " << m_vpNeuronLayers[0]->getWeights().cols << std::endl; } void CRBM::sampleVisible(Mat values) { m_negativeVMean = propagateDown(values); m_negativeVSample = getBinomial(m_negativeVMean); - } void CRBM::sampleHiddenPositive(Mat values) { From f9117aa8909f104a5d57c899d034298b5bc72f58 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 16:10:19 +0400 Subject: [PATCH 10/22] Update --- demos/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt index 98f06e3a..8628b1cc 100644 --- a/demos/CMakeLists.txt +++ b/demos/CMakeLists.txt @@ -74,4 +74,4 @@ create_demo(Demo_Stereo "Demo Stereo" "DGM") create_demo(Demo_ICR "Demo ICR" "DGM;DNN;VIS") # ================================================ DEMO RBM ================================================= -create_demo(Demo_RBM "Demo RBM" "DGM;DNN;VIS") +create_demo(Demo_RBM "Demo RBM" "DNN") From a5f57de24a9f9877d4bfae3c022647c26256ac65 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 23:49:32 +0400 Subject: [PATCH 11/22] Delete Demo RBM.cpp --- modules/DNN/Demo RBM.cpp | 124 --------------------------------------- 1 file changed, 124 deletions(-) delete mode 100644 modules/DNN/Demo RBM.cpp diff --git a/modules/DNN/Demo RBM.cpp b/modules/DNN/Demo RBM.cpp deleted file mode 100644 index b6750a3f..00000000 --- a/modules/DNN/Demo RBM.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "DNN.h" -#include "DGM.h" -#include "VIS.h" -#include "DGM/timer.h" -#include - -namespace dgm = DirectGraphicalModels; - -/** - * Reads the digits numerical value in a decimal notation - * - * @param file to read, and the number of digits to read - * @return an array of digit labels - */ -std::vector readGroundTruth(const std::string& fileName) -{ - std::vector res; - std::ifstream inFile; - inFile.open(fileName.c_str()); - - if (inFile.is_open()) { - int val; - while (!inFile.eof()) { - inFile >> val; - res.push_back(static_cast(val)); - } - inFile.close(); - } - return res; -} - - -float sigmoidFunction(float x) -{ - return 1.0f / (1.0f + expf(-x)); -} - -float sigmoidFunction_derivative(float x) -{ - float s = sigmoidFunction(x); - return s * (1 - s); -} - -int main() -{ - const float learningRate = 0.05f; - const size_t numEpochs = 20; - const size_t numTestSamples = 2000; - const size_t numTrainSamples = 4000; - - //const byte nStates = 10; - const word nFeatures = 28 * 28; - const size_t numNeuronsHiddenLayer = 10; - -#ifdef WIN32 - const std::string dataPath = "../../data/digits/"; -#else - const std::string dataPath = "../../../data/digits/"; -#endif - - auto pLayerVisible = std::make_shared(nFeatures, 1, [](float x) { return x; }, [](float x) { return 1.0f; }); - auto pLayerHidden = std::make_shared(numNeuronsHiddenLayer, nFeatures, &sigmoidFunction, &sigmoidFunction_derivative); - - pLayerVisible->generateRandomWeights(); - pLayerHidden->generateRandomWeights(); - - dgm::dnn::CRBM rbm({ pLayerVisible, pLayerHidden }); - - //rbm.debug(); - Mat fv; - - // ==================== TRAINING DIGITS ==================== - dgm::Timer::start("Training...\n"); - auto trainGT = readGroundTruth(dataPath + "train_gt.txt"); - for (size_t e = 0; e < numEpochs; e++) - for (int s = 0; s < numTrainSamples; s++) { - std::stringstream ss; - ss << dataPath << "train/digit_" << std::setfill('0') << std::setw(4) << s << ".png"; - std::string fileName = samples::findFile(ss.str()); - Mat img = imread(fileName, 0); - img = img.reshape(1, img.cols * img.rows); - img.convertTo(fv, CV_32FC1, 1.0 / 255); - fv = Scalar(1.0f) - fv; - - rbm.contrastiveDivergence(fv, 0.5f); - } // samples - dgm::Timer::stop(); - - // ==================== TESTING DIGITS ==================== - //dgm::CCMat confMat(nStates); - dgm::Timer::start("Testing..."); - auto testGT = readGroundTruth(dataPath + "test_gt.txt"); - for (size_t s = 0; s < numTestSamples; s++) { - std::stringstream ss; - ss << dataPath << "test/digit_" << std::setfill('0') << std::setw(4) << s << ".png"; - std::string fileName = samples::findFile(ss.str()); - Mat img = imread(fileName, 0); - img = img.reshape(1, img.cols * img.rows); - img.convertTo(fv, CV_32FC1, 1.0 / 255); - fv = Scalar(1.0f) - fv; - - Mat outputValues = rbm.reconstruct(fv); - - Point maxclass; - minMaxLoc(outputValues, NULL, NULL, NULL, &maxclass); - int number = maxclass.y; - - //confMat.estimate(number, testGT[s]); - //printf("prediction [%d] for digit %d with %.3f%s at position %zu \n", number, testDataDigit[z], maxAccuracy, "%", z); - } // samples - dgm::Timer::stop(); - //printf("Accuracy = %.2f%%\n", confMat.getAccuracy()); - - // Confusion matrix - dgm::vis::CMarker marker; - //Mat cMat = confMat.getConfusionMatrix(); - //Mat cMatImg = marker.drawConfusionMatrix(cMat, dgm::vis::MARK_BW); - //imshow("Confusion Matrix", cMatImg); - rbm.debug(); - - waitKey(); - - return 0; -} From a7b0c91c1b3973cc0f22d809380cee84b8d6b096 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Thu, 2 Dec 2021 23:51:03 +0400 Subject: [PATCH 12/22] Update DNN.h --- include/DNN.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/DNN.h b/include/DNN.h index 7eb05db3..7051d58a 100644 --- a/include/DNN.h +++ b/include/DNN.h @@ -2,6 +2,7 @@ #include "DNN/Neuron.h" #include "DNN/NeuronLayer.h" #include "DNN/Perceptron.h" +#include "DNN/RBM.h" // #include "DNN/Functions.hpp" /** From 81b3bb946b338e58a771137b96691ebd87d7495f Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Fri, 3 Dec 2021 00:18:11 +0400 Subject: [PATCH 13/22] Update Demo RBM --- demos/Demo RBM.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demos/Demo RBM.cpp b/demos/Demo RBM.cpp index b6750a3f..bba45315 100644 --- a/demos/Demo RBM.cpp +++ b/demos/Demo RBM.cpp @@ -101,9 +101,9 @@ int main() Mat outputValues = rbm.reconstruct(fv); - Point maxclass; - minMaxLoc(outputValues, NULL, NULL, NULL, &maxclass); - int number = maxclass.y; + //Point maxclass; + //minMaxLoc(outputValues, NULL, NULL, NULL, &maxclass); + //int number = maxclass.y; //confMat.estimate(number, testGT[s]); //printf("prediction [%d] for digit %d with %.3f%s at position %zu \n", number, testDataDigit[z], maxAccuracy, "%", z); @@ -112,7 +112,7 @@ int main() //printf("Accuracy = %.2f%%\n", confMat.getAccuracy()); // Confusion matrix - dgm::vis::CMarker marker; + //dgm::vis::CMarker marker; //Mat cMat = confMat.getConfusionMatrix(); //Mat cMatImg = marker.drawConfusionMatrix(cMat, dgm::vis::MARK_BW); //imshow("Confusion Matrix", cMatImg); From 4d655f5836ad081b706064267c38ee8ada1dd0ae Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Fri, 3 Dec 2021 00:25:27 +0400 Subject: [PATCH 14/22] Update RBM.cpp --- modules/DNN/RBM.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/DNN/RBM.cpp b/modules/DNN/RBM.cpp index f4e6889e..a1395ea7 100644 --- a/modules/DNN/RBM.cpp +++ b/modules/DNN/RBM.cpp @@ -60,7 +60,6 @@ namespace DirectGraphicalModels { void CRBM::sampleHiddenNegative(Mat values) { m_negativeHMean = propagateUp(values); m_negativeHSample = getBinomial(m_negativeHMean); - } Mat CRBM::propagateUp(Mat values) { @@ -80,18 +79,17 @@ namespace DirectGraphicalModels { void CRBM::gibbsHVH(Mat hiddenSample) { sampleVisible(hiddenSample); sampleHiddenNegative(m_negativeVSample); - } /* This implementation of RBM uses single step contrastive divergence algorithm, called CD-1 */ void CRBM::contrastiveDivergence(const Mat& values, float learningRate) { //-------POSITIVE PHASE-------------------- - /*In the positive phase, the input sample “v” from the visible layer is “clamped” to the input layer, + /*In the positive phase, the input sample “v” from the visible layer is “clamped” to the input layer, and then is propagated to the hidden layer. The result of the hidden layer activation is h. */ sampleHiddenPositive(values); //------NEGATIVE PHASE--------------------- - /*In the negative phase, “h” from the hidden layer is propagated back to the visible layer with the - new v, say v’. This is then propagated back to the hidden layer with activation result “h” */ + /*In the negative phase, “h” from the hidden layer is propagated back to the visible layer with the + new v, say v’. This is then propagated back to the hidden layer with activation result “h” */ gibbsHVH(m_positiveHMean); std::vector test = m_negativeHSample; @@ -119,4 +117,4 @@ namespace DirectGraphicalModels { return temp; } } -} \ No newline at end of file +} From 7d82bbcd3aecaff3563794e19e86acc992e508c4 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Fri, 3 Dec 2021 00:47:49 +0400 Subject: [PATCH 15/22] Update CMakeLists.txt --- demos/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt index 8628b1cc..98f06e3a 100644 --- a/demos/CMakeLists.txt +++ b/demos/CMakeLists.txt @@ -74,4 +74,4 @@ create_demo(Demo_Stereo "Demo Stereo" "DGM") create_demo(Demo_ICR "Demo ICR" "DGM;DNN;VIS") # ================================================ DEMO RBM ================================================= -create_demo(Demo_RBM "Demo RBM" "DNN") +create_demo(Demo_RBM "Demo RBM" "DGM;DNN;VIS") From a0fdf88c7ec8f4e7cb120787f077ef693a56157e Mon Sep 17 00:00:00 2001 From: Sergey Kosov Date: Wed, 8 Dec 2021 21:09:00 +0100 Subject: [PATCH 16/22] Substitute rand() with random::U() --- modules/DNN/RBM.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/DNN/RBM.cpp b/modules/DNN/RBM.cpp index a1395ea7..3297ac59 100644 --- a/modules/DNN/RBM.cpp +++ b/modules/DNN/RBM.cpp @@ -1,4 +1,5 @@ #include "RBM.h" +#include "DGM/random.h" #include "macroses.h" namespace DirectGraphicalModels { @@ -16,7 +17,7 @@ namespace DirectGraphicalModels { if (pRes[x] < 0 || pRes[x]>1) { pRes[x] = 0; } - double r = rand() / (RAND_MAX + 1.0); + double r = random::U(); // uniformly distributed random number betwee 0 and 1 if (r < pRes[x]) { pRes[x] = 1; From 1653d8a57ec3e9dcc327bb5425f7f590999623f6 Mon Sep 17 00:00:00 2001 From: Sergey Kosov Date: Wed, 8 Dec 2021 21:11:40 +0100 Subject: [PATCH 17/22] Remove Neuron Layer Bias --- modules/DNN/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/DNN/CMakeLists.txt b/modules/DNN/CMakeLists.txt index 5ddb7fa4..bff0659c 100644 --- a/modules/DNN/CMakeLists.txt +++ b/modules/DNN/CMakeLists.txt @@ -8,7 +8,6 @@ source_group("Include" FILES ${DNN_INCLUDE}) source_group("" FILES ${DNN_SOURCES} ${DNN_HEADERS}) source_group("Source Files\\Neuron" FILES "Neuron.h" "Neuron.cpp") source_group("Source Files\\Neuron Layer" FILES "NeuronLayer.h" "NeuronLayer.cpp") -source_group("Source Files\\Neuron Layer Bias" FILES "NeuronLayerBias.h" "NeuronLayerBias.cpp") source_group("Source Files\\Perceptron" FILES "Perceptron.h" "Perceptron.cpp") source_group("Source Files\\RBM" FILES "RBM.h" "RBM.cpp") From 921d59bad951a23787ad9a7ce9d7d8c0480111d4 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Wed, 15 Dec 2021 17:11:48 +0400 Subject: [PATCH 18/22] Added comments, const reference --- modules/DNN/NeuronLayer.cpp | 96 ++++++++++++++++++------------------- modules/DNN/NeuronLayer.h | 8 +++- 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/modules/DNN/NeuronLayer.cpp b/modules/DNN/NeuronLayer.cpp index 061be39a..4e9dffac 100644 --- a/modules/DNN/NeuronLayer.cpp +++ b/modules/DNN/NeuronLayer.cpp @@ -1,53 +1,53 @@ -#include "NeuronLayer.h" -#include "DGM/random.h" -#include "DGM/parallel.h" -#include "macroses.h" - -namespace DirectGraphicalModels { namespace dnn - { - void CNeuronLayer::generateRandomWeights(void) - { - m_weights = random::U(m_weights.size(), m_weights.type(), -0.5f, 0.5f); - m_biases = random::U(m_biases.size(), m_biases.type(), -0.5f, 0.5f); - } - - void CNeuronLayer::dotProd(const Mat& values) - { - // this->m_netValues = this->m_weights * values + m_biases; - gemm(m_weights.t(), values, 1, m_biases, 1, m_netValues); - } - void CNeuronLayer::dotProdVis(const Mat& values, Mat weights) - { - gemm(weights, values, 1, m_biases, 1, m_netValues); - - //this->m_netValues = temp.t(); +#include "NeuronLayer.h" +#include "DGM/random.h" +#include "DGM/parallel.h" +#include "macroses.h" + +namespace DirectGraphicalModels { namespace dnn + { + void CNeuronLayer::generateRandomWeights(void) + { + m_weights = random::U(m_weights.size(), m_weights.type(), -0.5f, 0.5f); + m_biases = random::U(m_biases.size(), m_biases.type(), -0.5f, 0.5f); + } + + void CNeuronLayer::dotProd(const Mat& values) + { + // this->m_netValues = this->m_weights * values + m_biases; + gemm(m_weights.t(), values, 1, m_biases, 1, m_netValues); + } + void CNeuronLayer::dotProdVis(const Mat& values, const Mat& weights) + { + gemm(weights, values, 1, m_biases, 1, m_netValues); + + //this->m_netValues = temp.t(); /*for (int i = 0; i < weights.rows; i++){ for (int j = 0; j < weights.cols; j++) { m_netValues.at(i, 0) += values.at(i, 0) * weights.at(i, j); } - } - m_netValues += m_biases; - */ - } - - void CNeuronLayer::setNetValues(const Mat& values) - { - // Assertions - DGM_ASSERT(values.type() == m_netValues.type()); - DGM_ASSERT(values.size() == m_netValues.size()); - values.copyTo(m_netValues); - } - - Mat CNeuronLayer::getValues(void) const - { - Mat res(m_netValues.clone()); - for (int y = 0; y < res.rows; y++) { - float* pRes = res.ptr(y); - for (int x = 0; x < res.cols; x++) - pRes[x] = m_activationFunction(pRes[x]); - } - return res; - } - - } + } + m_netValues += m_biases; + */ + } + + void CNeuronLayer::setNetValues(const Mat& values) + { + // Assertions + DGM_ASSERT(values.type() == m_netValues.type()); + DGM_ASSERT(values.size() == m_netValues.size()); + values.copyTo(m_netValues); + } + + Mat CNeuronLayer::getValues(void) const + { + Mat res(m_netValues.clone()); + for (int y = 0; y < res.rows; y++) { + float* pRes = res.ptr(y); + for (int x = 0; x < res.cols; x++) + pRes[x] = m_activationFunction(pRes[x]); + } + return res; + } + + } } \ No newline at end of file diff --git a/modules/DNN/NeuronLayer.h b/modules/DNN/NeuronLayer.h index a85742f4..7b7b2fec 100644 --- a/modules/DNN/NeuronLayer.h +++ b/modules/DNN/NeuronLayer.h @@ -36,9 +36,15 @@ namespace DirectGraphicalModels { * @details This function updates the neurons' values as \f$ netValues_{(1\times N)} = weights^{\top}_{(C\times N)}\times values_{(1\times C)} + biases_{((1\times N))}\f$ * @note This method updates only the nodes' net values */ - DllExport void dotProdVis(const Mat& values, Mat weights); //new method was added, purpose for it is to multiply visible neurons by weights of hidden layer. DllExport void dotProd(const Mat& values); /** + * In the dotProd method, we cant multiply hidden neuron values by hidden neuron weights, so dotProdVis is created + * which we can input by which weights neuron are multiplied by. + * in dotProd -> this->m_netValues = this->m_weights * values + this->m_biases; + * in dotProdVis -> this->m_netValues = m_weights * values + this->m_biases; + */ + DllExport void dotProdVis(const Mat& values, const Mat& weights); + /** * @brief Returns the values of the neurons of the layer * @note This method returns the result of per-element application of the activation function to the neurons' net values, i.e. activationFunction(netValues) * @returns The values of the neurons of the layer (size: 1 x numNeurons; type: CV_32FC1) From b9317b1f264a839c9cca629971e869439957ba5b Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Wed, 15 Dec 2021 17:12:36 +0400 Subject: [PATCH 19/22] Added comments, const references --- modules/DNN/RBM.cpp | 26 ++++++++++++++------------ modules/DNN/RBM.h | 16 ++++++++-------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/modules/DNN/RBM.cpp b/modules/DNN/RBM.cpp index 3297ac59..bb9962d2 100644 --- a/modules/DNN/RBM.cpp +++ b/modules/DNN/RBM.cpp @@ -9,7 +9,7 @@ namespace DirectGraphicalModels { m_vpNeuronLayers.push_back(nl); } - Mat CRBM::getBinomial(Mat mean) { + Mat CRBM::getBinomial(const Mat& mean) { Mat res(mean.clone()); for (int y = 0; y < res.rows; y++) { float* pRes = res.ptr(y); @@ -42,12 +42,12 @@ namespace DirectGraphicalModels { std::cout << "Negative V sample - rows: " << m_negativeVSample.rows << " cols: " << m_negativeVSample.cols << std::endl; } - void CRBM::sampleVisible(Mat values) { + void CRBM::sampleVisible(const Mat& values) { m_negativeVMean = propagateDown(values); m_negativeVSample = getBinomial(m_negativeVMean); } - void CRBM::sampleHiddenPositive(Mat values) { + void CRBM::sampleHiddenPositive(const Mat& values) { m_positiveHMean = propagateUp(values); m_positiveHSample = getBinomial(m_positiveHMean); @@ -58,12 +58,13 @@ namespace DirectGraphicalModels { }*/ } - void CRBM::sampleHiddenNegative(Mat values) { + void CRBM::sampleHiddenNegative(const Mat& values) { m_negativeHMean = propagateUp(values); m_negativeHSample = getBinomial(m_negativeHMean); + } - Mat CRBM::propagateUp(Mat values) { + Mat CRBM::propagateUp(const Mat& values) { m_vpNeuronLayers[0]->setNetValues(values); //set the visible layer values m_vpNeuronLayers[1]->dotProd(m_vpNeuronLayers[0]->getValues()); //sigmoid(sum(visible * weights)+bias) @@ -71,26 +72,27 @@ namespace DirectGraphicalModels { return m_vpNeuronLayers.back()->getValues(); } - Mat CRBM::propagateDown(Mat values){ + Mat CRBM::propagateDown(const Mat& values){ m_vpNeuronLayers[0]->dotProdVis(values, m_vpNeuronLayers[1]->getWeights()); return m_vpNeuronLayers[0]->getValues(); } - void CRBM::gibbsHVH(Mat hiddenSample) { + void CRBM::gibbsHVH(const Mat& hiddenSample) { sampleVisible(hiddenSample); sampleHiddenNegative(m_negativeVSample); + } /* This implementation of RBM uses single step contrastive divergence algorithm, called CD-1 */ void CRBM::contrastiveDivergence(const Mat& values, float learningRate) { //-------POSITIVE PHASE-------------------- - /*In the positive phase, the input sample “v” from the visible layer is “clamped” to the input layer, + /*In the positive phase, the input sample “v” from the visible layer is “clamped” to the input layer, and then is propagated to the hidden layer. The result of the hidden layer activation is h. */ sampleHiddenPositive(values); //------NEGATIVE PHASE--------------------- - /*In the negative phase, “h” from the hidden layer is propagated back to the visible layer with the - new v, say v’. This is then propagated back to the hidden layer with activation result “h” */ + /*In the negative phase, “h” from the hidden layer is propagated back to the visible layer with the + new v, say v’. This is then propagated back to the hidden layer with activation result “h” */ gibbsHVH(m_positiveHMean); std::vector test = m_negativeHSample; @@ -110,7 +112,7 @@ namespace DirectGraphicalModels { } } - Mat CRBM::reconstruct(Mat values) { + Mat CRBM::reconstruct(const Mat& values) { Mat h, temp; h = propagateUp(values); @@ -118,4 +120,4 @@ namespace DirectGraphicalModels { return temp; } } -} +} \ No newline at end of file diff --git a/modules/DNN/RBM.h b/modules/DNN/RBM.h index d68704e2..9c899107 100644 --- a/modules/DNN/RBM.h +++ b/modules/DNN/RBM.h @@ -15,17 +15,17 @@ namespace DirectGraphicalModels { DllExport void debug(); //printing out rows and cols just to be sure they are correct - DllExport Mat getBinomial(Mat mean); - DllExport Mat propagateUp( Mat values); //hidden layer = sigmoid(sum(visible*weights)+bias) - DllExport Mat propagateDown(Mat values); //visible layer = sigmoid(sum(hidden*weights)+bias) + DllExport Mat getBinomial(const Mat& mean); //binomial ddistribution + DllExport Mat propagateUp(const Mat& values); //hidden layer = sigmoid(sum(visible*weights)+bias) + DllExport Mat propagateDown(const Mat& values); //visible layer = sigmoid(sum(hidden*weights)+bias) - DllExport void sampleVisible(Mat values); //sample viible for negative phase - DllExport void sampleHiddenPositive(Mat values); //sample hidden for positive phase - DllExport void sampleHiddenNegative(Mat values); //sample hidden for negative phase + DllExport void sampleVisible(const Mat& values); //sample viible for negative phase + DllExport void sampleHiddenPositive(const Mat& values); //sample hidden for positive phase + DllExport void sampleHiddenNegative(const Mat& values); //sample hidden for negative phase - DllExport void gibbsHVH(Mat hiddenSample); //gibbs sampling(sample visible and then sample hidden negative phase) + DllExport void gibbsHVH(const Mat& hiddenSample); //gibbs sampling(sample visible and then sample hidden negative phase) DllExport void contrastiveDivergence(const Mat& values, float learningRate); - DllExport Mat reconstruct(Mat values); + DllExport Mat reconstruct(const Mat& values); //DllExport void gibbsHVH() private: From c97278e4d7bd04583dada5694ee0a588a6d9344d Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Wed, 15 Dec 2021 17:13:53 +0400 Subject: [PATCH 20/22] Fixed redundant lines --- modules/DNN/RBM.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/DNN/RBM.cpp b/modules/DNN/RBM.cpp index bb9962d2..7f6a05f3 100644 --- a/modules/DNN/RBM.cpp +++ b/modules/DNN/RBM.cpp @@ -61,7 +61,6 @@ namespace DirectGraphicalModels { void CRBM::sampleHiddenNegative(const Mat& values) { m_negativeHMean = propagateUp(values); m_negativeHSample = getBinomial(m_negativeHMean); - } Mat CRBM::propagateUp(const Mat& values) { @@ -81,7 +80,6 @@ namespace DirectGraphicalModels { void CRBM::gibbsHVH(const Mat& hiddenSample) { sampleVisible(hiddenSample); sampleHiddenNegative(m_negativeVSample); - } /* This implementation of RBM uses single step contrastive divergence algorithm, called CD-1 */ void CRBM::contrastiveDivergence(const Mat& values, float learningRate) { From 6c19bc04578cdb7031306e806b65d379c63b81ea Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Wed, 15 Dec 2021 17:17:41 +0400 Subject: [PATCH 21/22] Fix --- modules/DNN/NeuronLayer.cpp | 73 ++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/modules/DNN/NeuronLayer.cpp b/modules/DNN/NeuronLayer.cpp index 4e9dffac..4457d1cd 100644 --- a/modules/DNN/NeuronLayer.cpp +++ b/modules/DNN/NeuronLayer.cpp @@ -4,50 +4,41 @@ #include "macroses.h" namespace DirectGraphicalModels { namespace dnn +{ + void CNeuronLayer::generateRandomWeights(void) { - void CNeuronLayer::generateRandomWeights(void) - { - m_weights = random::U(m_weights.size(), m_weights.type(), -0.5f, 0.5f); - m_biases = random::U(m_biases.size(), m_biases.type(), -0.5f, 0.5f); - } - - void CNeuronLayer::dotProd(const Mat& values) - { - // this->m_netValues = this->m_weights * values + m_biases; - gemm(m_weights.t(), values, 1, m_biases, 1, m_netValues); - } - void CNeuronLayer::dotProdVis(const Mat& values, const Mat& weights) - { - gemm(weights, values, 1, m_biases, 1, m_netValues); + m_weights = random::U(m_weights.size(), m_weights.type(), -0.5f, 0.5f); + m_biases = random::U(m_biases.size(), m_biases.type(), -0.5f, 0.5f); + } - //this->m_netValues = temp.t(); - /*for (int i = 0; i < weights.rows; i++){ - for (int j = 0; j < weights.cols; j++) { - m_netValues.at(i, 0) += values.at(i, 0) * weights.at(i, j); - } - } - m_netValues += m_biases; - */ - } + void CNeuronLayer::dotProd(const Mat& values) + { + // this->m_netValues = this->m_weights * values + m_biases; + gemm(m_weights.t(), values, 1, m_biases, 1, m_netValues); + } + void CNeuronLayer::dotProdVis(const Mat& values, const Mat& weights) + { + // this->m_netValues = weights * values + m_biases; + gemm(weights, values, 1, m_biases, 1, m_netValues); + } - void CNeuronLayer::setNetValues(const Mat& values) - { - // Assertions - DGM_ASSERT(values.type() == m_netValues.type()); - DGM_ASSERT(values.size() == m_netValues.size()); - values.copyTo(m_netValues); - } + void CNeuronLayer::setNetValues(const Mat& values) + { + // Assertions + DGM_ASSERT(values.type() == m_netValues.type()); + DGM_ASSERT(values.size() == m_netValues.size()); + values.copyTo(m_netValues); + } - Mat CNeuronLayer::getValues(void) const - { - Mat res(m_netValues.clone()); - for (int y = 0; y < res.rows; y++) { - float* pRes = res.ptr(y); - for (int x = 0; x < res.cols; x++) - pRes[x] = m_activationFunction(pRes[x]); - } - return res; + Mat CNeuronLayer::getValues(void) const + { + Mat res(m_netValues.clone()); + for (int y = 0; y < res.rows; y++) { + float* pRes = res.ptr(y); + for (int x = 0; x < res.cols; x++) + pRes[x] = m_activationFunction(pRes[x]); } - + return res; } -} \ No newline at end of file + +}} \ No newline at end of file From c94df6483a6e7aaec815bead42a2622c195dafd4 Mon Sep 17 00:00:00 2001 From: Shahin Mammadov <71777445+shahinmv@users.noreply.github.com> Date: Wed, 15 Dec 2021 17:20:38 +0400 Subject: [PATCH 22/22] Fix --- modules/DNN/NeuronLayer.cpp | 69 +++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/modules/DNN/NeuronLayer.cpp b/modules/DNN/NeuronLayer.cpp index 4457d1cd..60c65160 100644 --- a/modules/DNN/NeuronLayer.cpp +++ b/modules/DNN/NeuronLayer.cpp @@ -3,42 +3,43 @@ #include "DGM/parallel.h" #include "macroses.h" -namespace DirectGraphicalModels { namespace dnn -{ - void CNeuronLayer::generateRandomWeights(void) +namespace DirectGraphicalModels { + namespace dnn { - m_weights = random::U(m_weights.size(), m_weights.type(), -0.5f, 0.5f); - m_biases = random::U(m_biases.size(), m_biases.type(), -0.5f, 0.5f); - } - - void CNeuronLayer::dotProd(const Mat& values) - { - // this->m_netValues = this->m_weights * values + m_biases; - gemm(m_weights.t(), values, 1, m_biases, 1, m_netValues); - } - void CNeuronLayer::dotProdVis(const Mat& values, const Mat& weights) - { - // this->m_netValues = weights * values + m_biases; - gemm(weights, values, 1, m_biases, 1, m_netValues); - } + void CNeuronLayer::generateRandomWeights(void) + { + m_weights = random::U(m_weights.size(), m_weights.type(), -0.5f, 0.5f); + m_biases = random::U(m_biases.size(), m_biases.type(), -0.5f, 0.5f); + } - void CNeuronLayer::setNetValues(const Mat& values) - { - // Assertions - DGM_ASSERT(values.type() == m_netValues.type()); - DGM_ASSERT(values.size() == m_netValues.size()); - values.copyTo(m_netValues); - } + void CNeuronLayer::dotProd(const Mat& values) + { + // this->m_netValues = this->m_weights * values + m_biases; + gemm(m_weights.t(), values, 1, m_biases, 1, m_netValues); + } + void CNeuronLayer::dotProdVis(const Mat& values, const Mat& weights) + { + // this->m_netValues = weights * values + m_biases; + gemm(weights, values, 1, m_biases, 1, m_netValues); + } + void CNeuronLayer::setNetValues(const Mat& values) + { + // Assertions + DGM_ASSERT(values.type() == m_netValues.type()); + DGM_ASSERT(values.size() == m_netValues.size()); + values.copyTo(m_netValues); + } - Mat CNeuronLayer::getValues(void) const - { - Mat res(m_netValues.clone()); - for (int y = 0; y < res.rows; y++) { - float* pRes = res.ptr(y); - for (int x = 0; x < res.cols; x++) - pRes[x] = m_activationFunction(pRes[x]); + Mat CNeuronLayer::getValues(void) const + { + Mat res(m_netValues.clone()); + for (int y = 0; y < res.rows; y++) { + float* pRes = res.ptr(y); + for (int x = 0; x < res.cols; x++) + pRes[x] = m_activationFunction(pRes[x]); + } + return res; } - return res; - } -}} \ No newline at end of file + } +} \ No newline at end of file