2026-08-13 23:48:47 +03:00 | | | //+------------------------------------------------------------------+
|
2026-06-05 22:00:59 +03:00 | | | //| NetGenetic.mqh |
|
| | | //| Copyright DNG® |
|
| | | //| https://www.mql5.com/ru/users/dng |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright DNG®"
|
| | | #property link "https://www.mql5.com/ru/users/dng"
|
| | | #property version "1.00"
|
| | | #include "..\NeuroNet_DNG\NeuroNet.mqh"
|
| | | //---
|
| | | #define MaxMutation 0.5f
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | class CNetGenetic : public CNet
|
| | | {
|
| | | protected:
|
| | | uint i_PopulationSize;
|
| | | vectorf v_Probability;
|
| | | vectorf v_Rewards;
|
| | | matrixf m_Weights;
|
| | | matrixf m_WeightsConv;
|
| | |
|
| | | //---
|
| | | virtual bool CreatePopulation(void);
|
| | | virtual int GetAction(CBufferFloat * probability);
|
| | | virtual bool GetWeights(uint layer);
|
| | | float NextGenerationWeight(matrixf &array, uint shift, vectorf &probability);
|
| | | float GenerateWeight(uint total);
|
| | |
|
| | | public:
|
| | | CNetGenetic();
|
| | | ~CNetGenetic();
|
| | | //---
|
| | | virtual bool Create(CArrayObj *Description, uint population_size);
|
| | | virtual bool SetPopulationSize(uint size);
|
| | | virtual bool feedForward(CArrayFloat *inputVals, int window = 1, bool tem = true);
|
| | | virtual bool Rewards(CArrayFloat *rewards);
|
| | | virtual bool NextGeneration(float quantile, float mutation, float &average, float &mamximum);
|
| | | virtual bool Load(string file_name, uint population_size, bool common = true);
|
| | | virtual bool SaveModel(string file_name, int model, bool common = true);
|
| | | //---
|
| | | virtual bool CopyModel(CArrayLayer *source, uint model);
|
| | | virtual bool Detach(void);
|
| | | };
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CNetGenetic::CNetGenetic() : i_PopulationSize(100)
|
| | | {
|
| | | SetPopulationSize(i_PopulationSize);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CNetGenetic::~CNetGenetic()
|
| | | {
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::Create(CArrayObj *Description, uint population_size)
|
| | | {
|
| | | if(CheckPointer(Description) == POINTER_INVALID)
|
| | | return false;
|
| | | //---
|
| | | if(!SetPopulationSize(population_size))
|
| | | return false;
|
| | | CNet::Create(Description);
|
| | | return CreatePopulation();
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::SetPopulationSize(uint size)
|
| | | {
|
| | | i_PopulationSize = size;
|
| | | v_Probability = vectorf::Zeros(i_PopulationSize);
|
| | | v_Rewards = vectorf::Zeros(i_PopulationSize);
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::Load(string file_name, uint population_size, bool common = true)
|
| | | {
|
| | | float temp;
|
| | | datetime dt;
|
| | | if(!CNet::Load(file_name, temp, temp, temp, dt, common))
|
| | | return false;
|
| | | //---
|
| | | if(!SetPopulationSize(population_size))
|
| | | return false;
|
| | | return CreatePopulation();
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::CreatePopulation(void)
|
| | | {
|
| | | if(!layers || layers.Total() < 2)
|
| | | return false;
|
| | | //---
|
| | | CLayer *layer = layers.At(0);
|
| | | if(!layer || !layer.At(0))
|
| | | return false;
|
| | | //---
|
| | | CNeuronBaseOCL *neuron_ocl = layer.At(0);
|
| | | int prev_count = neuron_ocl.Neurons();
|
| | | for(int i = 1; i < layers.Total(); i++)
|
| | | {
|
| | | layer = layers.At(i);
|
| | | if(!layer || !layer.At(0))
|
| | | return false;
|
| | | //---
|
| | | neuron_ocl = layer.At(0);
|
| | | CLayerDescription *desc = neuron_ocl.GetLayerInfo();
|
| | | int outputs = neuron_ocl.getConnections();
|
| | | //---
|
| | | for(uint n = layer.Total(); n < i_PopulationSize; n++)
|
| | | {
|
| | | CNeuronConvOCL *neuron_conv_ocl = NULL;
|
| | | CNeuronProofOCL *neuron_proof_ocl = NULL;
|
| | | CNeuronAttentionOCL *neuron_attention_ocl = NULL;
|
| | | CNeuronMLMHAttentionOCL *neuron_mlattention_ocl = NULL;
|
| | | CNeuronDropoutOCL *dropout = NULL;
|
| | | CNeuronBatchNormOCL *batch = NULL;
|
| | | CVAE *vae = NULL;
|
| | | CNeuronLSTMOCL *lstm = NULL;
|
| | | switch(layer.At(0).Type())
|
| | | {
|
| | | case defNeuron:
|
| | | case defNeuronBaseOCL:
|
| | | neuron_ocl = new CNeuronBaseOCL();
|
| | | if(CheckPointer(neuron_ocl) == POINTER_INVALID)
|
| | | return false;
|
| | | if(!neuron_ocl.Init(outputs, n, opencl, desc.count, desc.optimization, desc.batch))
|
| | | {
|
| | | delete neuron_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_ocl.SetActivationFunction(desc.activation);
|
| | | if(!layer.Add(neuron_ocl))
|
| | | {
|
| | | delete neuron_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_ocl = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronConvOCL:
|
| | | neuron_conv_ocl = new CNeuronConvOCL();
|
| | | if(CheckPointer(neuron_conv_ocl) == POINTER_INVALID)
|
| | | return false;
|
| | | if(!neuron_conv_ocl.Init(outputs, n, opencl, desc.window, desc.step, desc.window_out, desc.count, desc.optimization, desc.batch))
|
| | | {
|
| | | delete neuron_conv_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_conv_ocl.SetActivationFunction(desc.activation);
|
| | | if(!layer.Add(neuron_conv_ocl))
|
| | | {
|
| | | delete neuron_conv_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_conv_ocl = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronProofOCL:
|
| | | neuron_proof_ocl = new CNeuronProofOCL();
|
| | | if(!neuron_proof_ocl)
|
| | | return false;
|
| | | if(!neuron_proof_ocl.Init(outputs, n, opencl, desc.window, desc.step, desc.count, desc.optimization, desc.batch))
|
| | | {
|
| | | delete neuron_proof_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_proof_ocl.SetActivationFunction(desc.activation);
|
| | | if(!layer.Add(neuron_proof_ocl))
|
| | | {
|
| | | delete neuron_proof_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_proof_ocl = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronAttentionOCL:
|
| | | neuron_attention_ocl = new CNeuronAttentionOCL();
|
| | | if(CheckPointer(neuron_attention_ocl) == POINTER_INVALID)
|
| | | return false;
|
| | | if(!neuron_attention_ocl.Init(outputs, n, opencl, desc.window, desc.count, desc.optimization, desc.batch))
|
| | | {
|
| | | delete neuron_attention_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_attention_ocl.SetActivationFunction(desc.activation);
|
| | | if(!layer.Add(neuron_attention_ocl))
|
| | | {
|
| | | delete neuron_attention_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_attention_ocl = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronMHAttentionOCL:
|
| | | neuron_attention_ocl = new CNeuronMHAttentionOCL();
|
| | | if(CheckPointer(neuron_attention_ocl) == POINTER_INVALID)
|
| | | return false;
|
| | | if(!neuron_attention_ocl.Init(outputs, n, opencl, desc.window, desc.count, desc.optimization, desc.batch))
|
| | | {
|
| | | delete neuron_attention_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_attention_ocl.SetActivationFunction(desc.activation);
|
| | | if(!layer.Add(neuron_attention_ocl))
|
| | | {
|
| | | delete neuron_attention_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_attention_ocl = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronMLMHAttentionOCL:
|
| | | neuron_mlattention_ocl = new CNeuronMLMHAttentionOCL();
|
| | | if(CheckPointer(neuron_mlattention_ocl) == POINTER_INVALID)
|
| | | return false;
|
| | | if(!neuron_mlattention_ocl.Init(outputs, n, opencl, desc.window, desc.window_out, desc.step, desc.count, desc.layers, desc.optimization, desc.batch))
|
| | | {
|
| | | delete neuron_mlattention_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_mlattention_ocl.SetActivationFunction(desc.activation);
|
| | | if(!layer.Add(neuron_mlattention_ocl))
|
| | | {
|
| | | delete neuron_mlattention_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_mlattention_ocl = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronDropoutOCL:
|
| | | dropout = new CNeuronDropoutOCL();
|
| | | if(CheckPointer(dropout) == POINTER_INVALID)
|
| | | return false;
|
| | | if(!dropout.Init(outputs, n, opencl, desc.count, desc.probability, desc.optimization, desc.batch))
|
| | | {
|
| | | delete dropout;
|
| | | return false;
|
| | | }
|
| | | if(!layer.Add(dropout))
|
| | | {
|
| | | delete dropout;
|
| | | return false;
|
| | | }
|
| | | dropout = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronBatchNormOCL:
|
| | | batch = new CNeuronBatchNormOCL();
|
| | | if(CheckPointer(batch) == POINTER_INVALID)
|
| | | return false;
|
| | | if(!batch.Init(outputs, n, opencl, desc.count, desc.batch, desc.optimization))
|
| | | {
|
| | | delete batch;
|
| | | return false;
|
| | | }
|
| | | batch.SetActivationFunction(desc.activation);
|
| | | if(!layer.Add(batch))
|
| | | {
|
| | | delete batch;
|
| | | return false;
|
| | | }
|
| | | batch = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronVAEOCL:
|
| | | vae = new CVAE();
|
| | | if(!vae)
|
| | | return false;
|
| | | if(!vae.Init(outputs, n, opencl, desc.count, desc.optimization, desc.batch))
|
| | | {
|
| | | delete vae;
|
| | | return false;
|
| | | }
|
| | | if(!layer.Add(vae))
|
| | | {
|
| | | delete vae;
|
| | | return false;
|
| | | }
|
| | | vae = NULL;
|
| | | break;
|
| | | case defNeuronLSTMOCL:
|
| | | lstm = new CNeuronLSTMOCL();
|
| | | if(!lstm)
|
| | | return false;
|
| | | if(!lstm.Init(outputs, n, opencl, desc.count, desc.optimization, desc.batch))
|
| | | {
|
| | | delete lstm;
|
| | | return false;
|
| | | }
|
| | | if(!lstm.SetInputs(prev_count))
|
| | | {
|
| | | delete lstm;
|
| | | return false;
|
| | | }
|
| | | if(!layer.Add(lstm))
|
| | | {
|
| | | delete lstm;
|
| | | return false;
|
| | | }
|
| | | lstm = NULL;
|
| | | break;
|
| | | //---
|
| | | case defNeuronSoftMaxOCL:
|
| | | neuron_ocl = new CNeuronSoftMaxOCL();
|
| | | if(!neuron_ocl)
|
| | | return false;
|
| | | if(!neuron_ocl.Init(outputs, n, opencl, desc.count, desc.optimization, desc.batch))
|
| | | {
|
| | | delete neuron_ocl;
|
| | | return false;
|
| | | }
|
| | | if(!layer.Add(neuron_ocl))
|
| | | {
|
| | | delete neuron_ocl;
|
| | | return false;
|
| | | }
|
| | | neuron_ocl = NULL;
|
| | | break;
|
| | | //---
|
| | | default:
|
| | | return false;
|
| | | break;
|
| | | }
|
| | | }
|
| | | if(layer.Total() > (int)i_PopulationSize)
|
| | | layer.Resize(i_PopulationSize);
|
| | | delete desc;
|
| | | }
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::feedForward(CArrayFloat *inputVals, int window = 1, bool tem = true)
|
| | | {
|
| | | if(CheckPointer(layers) == POINTER_INVALID || CheckPointer(inputVals) == POINTER_INVALID || layers.Total() <= 1)
|
| | | return false;
|
| | | //---
|
| | | CLayer *previous = NULL;
|
| | | CLayer *current = layers.At(0);
|
| | | int total = MathMin(current.Total(), inputVals.Total());
|
| | | CNeuronBase *neuron = NULL;
|
| | | if(CheckPointer(opencl) == POINTER_INVALID)
|
| | | return false;
|
| | | CNeuronBaseOCL *neuron_ocl = current.At(0);
|
| | | CBufferFloat *inputs = neuron_ocl.getOutput();
|
| | | int total_data = inputVals.Total();
|
| | | if(!inputs.Resize(total_data))
|
| | | return false;
|
| | | for(int d = 0; d < total_data; d++)
|
| | | {
|
| | | int pos = d;
|
| | | int dim = 0;
|
| | | if(window > 1)
|
| | | {
|
| | | dim = d % window;
|
| | | pos = (d - dim) / window;
|
| | | }
|
| | | float value = pos / pow(10000, (2 * dim + 1) / (float)(window + 1));
|
| | | value = (float)(tem ? (dim % 2 == 0 ? sin(value) : cos(value)) : 0);
|
| | | value += inputVals.At(d);
|
| | | if(!inputs.Update(d, value))
|
| | | return false;
|
| | | }
|
| | | if(!inputs.BufferWrite())
|
| | | return false;
|
| | | //---
|
| | | CNeuronBaseOCL *current_ocl;
|
| | | for(int l = 1; l < layers.Total(); l++)
|
| | | {
|
| | | previous = current;
|
| | | current = layers.At(l);
|
| | | if(CheckPointer(current) == POINTER_INVALID)
|
| | | return false;
|
| | | //---
|
| | | for(uint n = 0; n < i_PopulationSize; n++)
|
| | | {
|
| | | current_ocl = current.At(n);
|
| | | if(!current_ocl.FeedForward(previous.At(l == 1 ? 0 : n)))
|
| | | return false;
|
| | | continue;
|
| | | }
|
| | | }
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::Rewards(CArrayFloat *rewards)
|
| | | {
|
| | | if(!rewards || !layers || layers.Total() < 2)
|
| | | return false;
|
| | | //---
|
| | | CLayer *output = layers.At(layers.Total() - 1);
|
| | | if(!output)
|
| | | return false;
|
| | | //---
|
| | | for(int i = 0; i < output.Total(); i++)
|
| | | {
|
| | | CNeuronBaseOCL *neuron = output.At(i);
|
| | | if(!neuron)
|
| | | continue;
|
| | | int action = GetAction(neuron.getOutput());
|
| | | v_Rewards[i] += rewards.At(action >= 0 ? action : rewards.Minimum(0, WHOLE_ARRAY));
|
| | | }
|
| | | //---
|
| | | v_Probability = v_Rewards - v_Rewards.Min();
|
| | | if(!v_Probability.Clip(0, v_Probability.Max()))
|
| | | return false;
|
| | | v_Probability = v_Probability / v_Probability.Sum();
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | int CNetGenetic::GetAction(CBufferFloat * probability)
|
| | | {
|
| | | vectorf prob;
|
| | | if(!probability.GetData(prob))
|
| | | return -1;
|
| | | prob = prob.CumSum();
|
| | | prob = prob / prob.Max();
|
| | | int err_code;
|
| | | float random = (float)MathRandomNormal(0.5, 0.5, err_code);
|
| | | if(random >= 1)
|
| | | return (int)prob.Size() - 1;
|
| | | for(int i = 0; i < (int)prob.Size(); i++)
|
| | | if(random <= prob[i] && prob[i] > 0)
|
| | | return i;
|
| | | //---
|
| | | return -1;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::NextGeneration(float quantile, float mutation, float &average, float &maximum)
|
| | | {
|
| | | maximum = v_Rewards.Max();
|
| | | mutation = MathMin(mutation, MaxMutation);
|
| | | v_Probability = v_Rewards - v_Rewards.Quantile(quantile);
|
| | | if(!v_Probability.Clip(0, v_Probability.Max()))
|
| | | return false;
|
| | | v_Probability = v_Probability / v_Probability.Sum();
|
| | | average = v_Rewards.Average(v_Probability);
|
| | | //---
|
| | | if(!v_Probability.Resize(i_PopulationSize + 1))
|
| | | return false;
|
| | | v_Probability[i_PopulationSize] = mutation;
|
| | | v_Probability = (v_Probability / (1 + mutation)).CumSum();
|
| | | //---
|
| | | for(int l = 1; l < layers.Total(); l++)
|
| | | {
|
| | | if(!GetWeights(l))
|
| | | {
|
| | | PrintFormat("Error of load weights from layer %d", l);
|
| | | return false;
|
| | | }
|
| | | CLayer* layer = layers.At(l);
|
| | | if(!layer)
|
| | | return false;
|
| | | for(uint i = 0; i < i_PopulationSize; i++)
|
| | | {
|
| | | CNeuronBaseOCL* neuron = layer.At(i);
|
| | | CBufferFloat* weights = neuron.getWeights();
|
| | | if(!!weights)
|
| | | {
|
| | | for(int w = 0; w < weights.Total(); w++)
|
| | | if(!weights.Update(w, NextGenerationWeight(m_Weights, w, v_Probability)))
|
| | | {
|
| | | Print("Error of update weights");
|
| | | return false;
|
| | | }
|
| | | weights.BufferWrite();
|
| | | }
|
| | | if(neuron.Type() != defNeuronConvOCL)
|
| | | continue;
|
| | | CNeuronConvOCL* temp = neuron;
|
| | | weights = temp.GetWeightsConv();
|
| | | for(int w = 0; w < weights.Total(); w++)
|
| | | if(!weights.Update(w, NextGenerationWeight(m_WeightsConv, w, v_Probability)))
|
| | | {
|
| | | Print("Error of update weights");
|
| | | return false;
|
| | | }
|
| | | weights.BufferWrite();
|
| | | }
|
| | | }
|
| | | v_Rewards.Fill(0);
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | float CNetGenetic::NextGenerationWeight(matrixf &array, uint shift, vectorf &probability)
|
| | | {
|
| | | int err_code;
|
| | | float random = (float)MathRandomNormal(0.5, 0.5, err_code);
|
| | | for(int i = 0; i < (int)probability.Size(); i++)
|
| | | if(probability[i] > 0 && random <= probability[i] && i < (int)array.Rows())
|
| | | {
|
| | | return array[i, shift];
|
| | | }
|
| | | //---
|
| | | return GenerateWeight((uint)array.Cols());
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::GetWeights(uint layer)
|
| | | {
|
| | | if(!layers)
|
| | | return false;
|
| | | CLayer *current_layer = layers.At(layer);
|
| | | if(!current_layer)
|
| | | return false;
|
| | | int total = current_layer.Total();
|
| | | m_Weights = matrixf::Zeros(total, 0);
|
| | | m_WeightsConv = matrixf::Zeros(total, 0);
|
| | | for(int m = 0; m < total; m++)
|
| | | {
|
| | | CNeuronBaseOCL *neuron = current_layer.At(m);
|
| | | if(!neuron)
|
| | | return false;
|
| | | vectorf buffer;
|
| | | if(!!neuron.getWeights())
|
| | | {
|
| | | neuron.getWeights().GetData(buffer);
|
| | | if(m_Weights.Cols() <= 0)
|
| | | if(!m_Weights.Resize(total, buffer.Size()))
|
| | | return false;
|
| | | if(!m_Weights.Row(buffer, m))
|
| | | continue;
|
| | | }
|
| | | //---
|
| | | if(neuron.Type() != defNeuronConvOCL)
|
| | | continue;
|
| | | CNeuronConvOCL *temp = neuron;
|
| | | if(temp.GetWeightsConv().GetData(buffer) <= 0)
|
| | | return false;
|
| | | if(m_WeightsConv.Cols() != buffer.Size())
|
| | | if(!m_WeightsConv.Resize(total, buffer.Size()))
|
| | | return false;
|
| | | if(!m_WeightsConv.Row(buffer, m))
|
| | | return false;
|
| | | }
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::SaveModel(string file_name, int model, bool common = true)
|
| | | {
|
| | | if(model < 0 || model >= (int)i_PopulationSize)
|
| | | model = (int)v_Probability.ArgMax();
|
| | | //---
|
| | | CNetGenetic *new_model = new CNetGenetic();
|
| | | if(!new_model)
|
| | | return false;
|
| | | if(!new_model.CopyModel(layers, model))
|
| | | {
|
| | | new_model.Detach();
|
| | | delete new_model;
|
| | | return false;
|
| | | }
|
| | | bool result = new_model.Save(file_name, 0, 0, 0, 0, common);
|
| | | new_model.Detach();
|
| | | delete new_model;
|
| | | //---
|
| | | return result;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::CopyModel(CArrayLayer *source, uint model)
|
| | | {
|
| | | if(!source)
|
| | | return false;
|
| | | if(!layers)
|
| | | {
|
| | | layers = new CArrayLayer();
|
| | | if(!layers)
|
| | | return false;
|
| | | }
|
| | | else
|
| | | layers.Clear();
|
| | | for(int l = 0; l < source.Total(); l++)
|
| | | {
|
| | | CLayer* source_layer = source.At(l);
|
| | | if(!source_layer)
|
| | | return false;
|
| | | CLayer* new_layer = new CLayer(source_layer.Outputs(), -1, opencl);
|
| | | if(!new_layer)
|
| | | return false;
|
| | | if(!new_layer.Add(source_layer.At(l == 0 ? 0 : model)))
|
| | | return false;
|
| | | if(!layers.Add(new_layer))
|
| | | return false;
|
| | | }
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CNetGenetic::Detach(void)
|
| | | {
|
| | | if(!layers || layers.Total() <= 0)
|
| | | return true;
|
| | | int total = layers.Total();
|
| | | for(int i = 0; i < total; i++)
|
| | | {
|
| | | CLayer *layer = layers.At(i);
|
| | | if(!layer)
|
| | | continue;
|
| | | for(int n = layer.Total() - 1; n >= 0; n--)
|
| | | CObject *temp = layer.Detach(n);
|
| | | }
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | float CNetGenetic::GenerateWeight(uint total)
|
| | | {
|
| | | xor128;
|
| | | float result = (float)rnd_w / UINT_MAX;
|
| | | if(result == 0)
|
| | | return GenerateWeight(total);
|
| | | float k = (float)(1 / sqrt(total + 1));
|
| | | result = (2 * result * k - k) * WeightsMultiplier;
|
| | | //---
|
| | | return result;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
2026-08-13 23:48:47 +03:00 | | |
|