jacobian

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit dea99ee3971e3203d9723294d9348fde0abddbe4
parent e8a15ac4dd5aff2b7f7f629ba2e613edc0413979
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Fri,  3 Jul 2020 15:46:07 -0700

Beginnings of backprop

Diffstat:
Mcnn.cpp | 37+++++++++++++++++++++++++++++--------
1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/cnn.cpp b/cnn.cpp @@ -11,6 +11,7 @@ public: Eigen::MatrixXd* input; Eigen::MatrixXd* kernel; Eigen::MatrixXd* output; + Eigen::MatrixXd* bias; ConvLayer(int x, int y, int stride, int kernel_size, int pad); void convolute(); @@ -130,10 +131,10 @@ void ConvNet::process() conv_layers[i+1].input = pool_layers[i].output; } conv_layers[preprocess_length-1].convolute(); - pool_layers[preprocess_length-1].input = conv_layers[preprocess_length-1].output; - pool_layers[preprocess_length-1].pool(); + //pool_layers[preprocess_length-1].input = conv_layers[preprocess_length-1].output; + //pool_layers[preprocess_length-1].pool(); // std::cout << "Output:\n" << *pool_layers[preprocess_length-1].output << "\n\n"; - Eigen::Map<Eigen::RowVectorXd> flattened (pool_layers[preprocess_length-1].output->data(), pool_layers[preprocess_length-1].output->size()); + Eigen::Map<Eigen::RowVectorXd> flattened (conv_layers[preprocess_length-1].output->data(), conv_layers[preprocess_length-1].output->size()); // std::cout << "Flattened:\n" << flattened << "\n\n"; for (int i = 0; i < flattened.cols(); i++) { (*layers[0].contents)(0, i) = flattened[i]; @@ -153,18 +154,37 @@ void ConvNet::list_net() std::cout << "-----------------------\nOUTPUT LAYER (LAYER " << length-1 << ")\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nActivation Function: " << layers[length-1].activation_str <<"\n\n\u001b[31mACTIVATIONS:\x1B[0;37m\n" << *layers[length-1].contents << "\n\n\u001b[31mBIASES:\x1B[0;37m\n" << *layers[length-1].bias << "\n\n\n"; } -void backpropagate() +void ConvNet::backpropagate() { - //*layers[layers.size()-1] = 1; - // Magic. + std::vector<Eigen::MatrixXd> gradients; + std::vector<Eigen::MatrixXd> deltas; + Eigen::MatrixXd error = ((*layers[length-1].contents) - (*labels)); + gradients.push_back(error.cwiseProduct(*layers[length-1].dZ)); + deltas.push_back((*layers[length-2].contents).transpose() * gradients[0]); + int counter = 1; + for (int i = length-2; i >= 1; i--) { + gradients.push_back((gradients[counter-1] * layers[i].weights->transpose()).cwiseProduct(*layers[i].dZ)); + deltas.push_back(layers[i-1].contents->transpose() * gradients[counter]); + counter++; + } + for (int i = 0; i < length-1; i++) { + *layers[length-2-i].weights -= learning_rate * deltas[i]; + *layers[length-1-i].bias -= bias_lr * gradients[i]; + } + for (int i = 0; i < conv_layers[0].input->cols() - gradients[0].cols()+1; i+=conv_layers[0].stride_len) { + for (int j = 0; j < conv_layers[0].input->rows() - gradients[0].rows()+1; j+=conv_layers[0].stride_len) { + (*conv_layers[0].kernel)(j, i) -= (gradients[0] * (conv_layers[0].input->block(j, i, gradients[0].rows(), gradients[0].cols()))).sum(); + } + } + *conv_layers[0].kernel -= *conv_layers[0].input * gradients[0]; } int main() { ConvNet net ("./data_banknote_authentication.txt", 1, 0.05, 0.01, 0.9); net.add_conv_layer(8,8,1,4,0); - net.add_pool_layer(5,5,1,2,0); - net.add_layer(16, "linear"); + //net.add_pool_layer(5,5,1,2,0); + net.add_layer(25, "linear"); net.add_layer(5, "relu"); net.add_layer(1, "resig"); net.initialize(); @@ -181,5 +201,6 @@ int main() net.conv_layers[0].input = input; net.process(); net.feedforward(); + net.backpropagate(); net.list_net(); }