Neuronal Network mit Genetic Algorithmus
-
Ich suche ein altes einfaches C++ Programm mit NN und genetischem Algorithmus. Es nutzte (bezüglich Suche/Bewegung mutierende) Käfer in einem MFC Programm. Wäre echt nett, wenn mir da jemand helfen könnte, diesen interessanten Code wiederzufinden, habe ihn bei PC-Wechsel offenbar verloren..
-
Die Käfer mal ausgeklammert, dann kannst du das NN doch ganz einfach from scratch/at zero selber implementieren...
-
@NoIDE sagte in Neuronal Network mit Genetic Algorithmus:
Die Käfer mal ausgeklammert, dann kannst du das NN doch ganz einfach from scratch/at zero selber implementieren...
Eher nicht mit geringem Zeitaufwand. Der genetische Algorithmus zur Modifikation der Gewichte ist weniger das Problem.
Zunächst müsste man mal rausfinden, welche Art von ANN dort verwendet wurde, welche Lerntechniken verwendet wurden, welche Eingangsdaten/Trainingsdaten verwendet wurden und ob die vorverarbeitet wurden etc.
Also ganz so einfach ist das nicht.Aber @NoIDE du darfst gern mal anfangen und uns hier nächste Woche deine Erfolge präsentieren
-
Einen MFC Code kenne ich nicht, wohl aber
scikit-learn
bzw.scikit-opt
.Dort habe ich eine Implementierung von Ant Colony Algorithm for TSP gefunden. Aber auch andere Algorithmen wie Simulated Annealing finden sich dort.
-
@It0101 sagte in Neuronal Network mit Genetic Algorithmus:
Zunächst müsste man mal rausfinden, welche Art von ANN dort verwendet wurde
+1 , aber ich hatte dieses "Wissen" einfach vorausgesetzt schon... Ja, es ist nicht so zeitunaufwändig.
-
Sehr schade, dass dieser Code nicht bekannt ist.
-
@Erhard-Henkes Ich habe mir inzwischen mit Unterstützung durch chatGPT-4o ein einfaches Modell in C++ mit WinAPI aufgesetzt. Es bietet Uniform/Ein-Punkt-/Zwei-Punkt-Crossover, Cloning und Mutation. Futter suchende Käfer erben von NeuralNetwork. Funktioniert bereits recht gut.
https://www.henkessoft.de/C++/WinAPI/WinAPI_GDI/NN_und_GA.htm (Tutorial mit Sourcecode)
-
Ja, das stimmt. Einfaches NN ist easy.
constexpr int INPUT_SIZE = 4; constexpr int OUTPUT_SIZE = 2; constexpr double INPUT_3 = 0.0; constexpr double INPUT_4 = 0.0; constexpr int NUM_HIDDEN_LAYERS = 2; constexpr int HIDDEN_LAYER_SIZE = 8; constexpr bool RELU_FOR_HIDDEN = false; constexpr bool SIGMOID_FOR_OUTPUT = false;
#pragma once #include <vector> class NeuralNetwork { public: NeuralNetwork(int inputSize, int outputSize, int numHiddenLayers, int hiddenLayerSize); std::vector<double> FeedForward(const std::vector<double>& inputs); std::vector<double> GetWeights() const; void SetWeights(const std::vector<double>& newWeights); double Sigmoid(double x); double ReLU(double x); private: std::vector<std::vector<double>> weights; int inputSize; int outputSize; int numHiddenLayers; int hiddenLayerSize; void InitializeWeights(); };
#include <random> #include <algorithm> #include <vector> #include <cassert> #include <sstream> #include "NeuralNetwork.h" #include "DebugOutput.h" #include "ConstantData.h" NeuralNetwork::NeuralNetwork(int inputSize, int outputSize, int numHiddenLayers, int hiddenLayerSize) : inputSize(inputSize), outputSize(outputSize), numHiddenLayers(numHiddenLayers), hiddenLayerSize(hiddenLayerSize) { InitializeWeights(); } void NeuralNetwork::InitializeWeights() { std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> dis(-1.0, 1.0); // Initialisiere die Gewichte für die Eingabe zur ersten versteckten Schicht weights.push_back(std::vector<double>(inputSize * hiddenLayerSize)); std::generate(weights.back().begin(), weights.back().end(), [&]() { return dis(gen); }); // Initialisiere die Gewichte für die versteckten Schichten for (int i = 0; i < numHiddenLayers - 1; ++i) { weights.push_back(std::vector<double>(hiddenLayerSize * hiddenLayerSize)); std::generate(weights.back().begin(), weights.back().end(), [&]() { return dis(gen); }); } // Initialisiere die Gewichte für die letzte versteckte Schicht zur Ausgabeschicht weights.push_back(std::vector<double>(hiddenLayerSize * outputSize)); std::generate(weights.back().begin(), weights.back().end(), [&]() { return dis(gen); }); } std::vector<double> NeuralNetwork::FeedForward(const std::vector<double>& inputs) { assert(inputs.size() == inputSize); std::vector<double> outputs(hiddenLayerSize, 0.0); std::vector<double> currentInputs = inputs; // Berechnung der versteckten Schichten for (int l = 0; l < numHiddenLayers; ++l) { outputs.assign(hiddenLayerSize, 0.0); for (int j = 0; j < hiddenLayerSize; ++j) { for (int i = 0; i < currentInputs.size(); ++i) { outputs[j] += currentInputs[i] * weights[l][j * currentInputs.size() + i]; } if (RELU_FOR_HIDDEN) { outputs[j] = ReLU(outputs[j]); // ReLU Aktivierungsfunktion } } currentInputs = outputs; } // Berechnung der Ausgabeschicht outputs.assign(outputSize, 0.0); for (int j = 0; j < outputSize; ++j) { for (int i = 0; i < currentInputs.size(); ++i) { outputs[j] += currentInputs[i] * weights.back()[j * currentInputs.size() + i]; std::ostringstream oss; oss << "\noutput[j]: " << outputs[j]; DebugOutput(oss.str()); } if (SIGMOID_FOR_OUTPUT) { outputs[j] = Sigmoid(outputs[j]) * 600 - 300; // Skalieren, um den Bereich [-300, 300] zu haben --> Käfer bewegen sich seltsam! } } return outputs; } std::vector<double> NeuralNetwork::GetWeights() const { // Alle Gewichtsmatrizen in einen einzelnen Vektor zusammenführen std::vector<double> allWeights; for (const auto& layerWeights : weights) { allWeights.insert(allWeights.end(), layerWeights.begin(), layerWeights.end()); } return allWeights; } void NeuralNetwork::SetWeights(const std::vector<double>& newWeights) { size_t offset = 0; for (auto& layerWeights : weights) { std::copy(newWeights.begin() + offset, newWeights.begin() + offset + layerWeights.size(), layerWeights.begin()); offset += layerWeights.size(); } } double NeuralNetwork::Sigmoid(double x) { return 1.0 / (1.0 + exp(-x)); } double NeuralNetwork::ReLU(double x) { return std::max(0.0, x); }