#pragma once #include "../Network.h" #include namespace NeuralNetwork { namespace Cascade { class Network : public NeuralNetwork::Network { public: /** * @brief Constructor for Network * @param _inputSize is number of inputs to network */ Network(std::size_t inputSize, std::size_t outputSize, const ActivationFunction::ActivationFunction &activationFunction=ActivationFunction::Sigmoid(-4.9)) : NeuralNetwork::Network(inputSize,outputSize) { _neurons.push_back(std::make_shared()); for(std::size_t i = 0; i < inputSize; i++) { _neurons.push_back(std::make_shared(_neurons.size())); } for(std::size_t i = 0; i < outputSize; i++) { _neurons.push_back(std::make_shared(_neurons.size(),activationFunction)); _neurons.back()->setInputSize(inputSize + 1); // +1 is bias } } virtual std::vector computeOutput(const std::vector &input) override { std::vector compute; compute.resize(_neurons.size()); compute[0] = 1.0; for(std::size_t i = 0; i < _inputs; i++) { compute[i+1] = input[i]; } // 0 is bias, 1-_inputSize is input for(std::size_t i = _inputs + 1; i < _neurons.size(); i++) { compute[i] = (*_neurons[i].get())(compute); } return std::vector(compute.end() - _outputs, compute.end()); } std::size_t getNeuronSize() const { return _neurons.size(); } const std::vector>& getNeurons() { return _neurons; } std::shared_ptr getNeuron(std::size_t id) { return _neurons[id]; } std::vector> getOutputNeurons() { return std::vector>(_neurons.end()-_outputs,_neurons.end()); } void removeLastHiddenNeuron() { _neurons.erase(_neurons.begin()+_neurons.size()-outputs()-1); std::size_t maxIndexOfHiddenNeuron = _neurons.size() - outputs(); std::size_t maxIndexOfNeuron = _neurons.size() - 1; for(std::size_t i = 0; i < _outputs; i++) { _neurons[maxIndexOfNeuron-i]->setInputSize(maxIndexOfHiddenNeuron); } } std::shared_ptr addNeuron() { _neurons.push_back(std::make_shared()); auto neuron = _neurons.back(); neuron->setInputSize(_neurons.size() - _outputs-1); // 0 is bias, 1-_inputSize is input std::size_t maxIndexOfNeuron = _neurons.size() - 1; // move output to right position for(std::size_t i = 0; i < _outputs; i++) { std::swap(_neurons[maxIndexOfNeuron - i], _neurons[maxIndexOfNeuron - i - 1]); } for(std::size_t i = 0; i < _outputs; i++) { _neurons[maxIndexOfNeuron - i]->setInputSize(_neurons.size() - _outputs); } return neuron; } virtual SimpleJSON::Type::Object serialize() const override { std::vector neuronsSerialized; for(auto &neuron: _neurons) { neuronsSerialized.push_back(neuron->serialize()); } return { {"class", "NeuralNetwork::Recurrent::Network"}, {"inputSize", _inputs}, {"outputSize", _outputs}, {"neurons", neuronsSerialized} }; } static std::unique_ptr deserialize(const SimpleJSON::Type::Object &obj) { const int inputSize = obj["inputSize"].as(); const int outputSize = obj["outputSize"].as(); Network *net = new Network(inputSize, outputSize); net->_neurons.clear(); for(const auto &neuronObj: obj["neurons"].as()) { net->_neurons.push_back(Neuron::Factory::deserialize(neuronObj.as())); } return std::unique_ptr(net); } //I I H H O O 6 void randomizeWeights() { std::mt19937 _generator(rand()); std::uniform_real_distribution<> _distribution(-0.3,0.3); for(auto& neuron :getOutputNeurons()) { for(std::size_t weight = 0; weight < neuron->getWeights().size(); weight++) { neuron->weight(weight) = _distribution(_generator); } } } protected: std::vector> _neurons = {}; SIMPLEJSON_REGISTER(NeuralNetwork::Cascade::Network::Factory, NeuralNetwork::Cascade::Network, deserialize) }; } }