diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..ac958ceb4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 GALIH RIDHO UTOMO + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index b0d325c61..6cc87dfd7 100644 --- a/README.md +++ b/README.md @@ -1,139 +1,344 @@ -# Arduino Library Manager list - -This repository contains the list of libraries in the -[Arduino Library Manager](https://docs.arduino.cc/software/ide-v1/tutorials/installing-libraries#using-the-library-manager) index. +# FNN (Fuzzy Neural Network) Module Documentation ## Table of Contents - - - -- [Frequently asked questions](#frequently-asked-questions) -- [Adding a library to Library Manager](#adding-a-library-to-library-manager) - - [Instructions](#instructions) - - [If the problem is with the pull request:](#if-the-problem-is-with-the-pull-request) - - [If the problem is with the library:](#if-the-problem-is-with-the-library) -- [Changing the URL of a library already in Library Manager](#changing-the-url-of-a-library-already-in-library-manager) -- [Removing a library from Library Manager](#removing-a-library-from-library-manager) -- [Report a problem with Library Manager](#report-a-problem-with-library-manager) -- [Security & Malware Reporting](#security--malware-reporting) - - - -## Frequently asked questions - -For more information about Arduino Library Manager and how the index is maintained, please see [the FAQ](FAQ.md). - -## Adding a library to Library Manager - -If you would like to make a library available for installation via Library Manager, just submit a -[pull request](https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests) -that adds the repository URL to [the list](repositories.txt). You are welcome to add multiple libraries at once. - -See the instructions below for detailed instructions on how to do this via the GitHub web interface. - -### Instructions - ---- - -⚠ If you behave irresponsibly in your interactions with this repository, your Library Manager Registry privileges will be revoked. - -Carefully read and follow the instructions in any comments the bot and human maintainers make on your pull requests. If you are having trouble following the instructions, add a comment that provides a detailed description of the problem you are having and a human maintainer will provide assistance. - -Although we have set up automation for the most basic tasks, this repository is maintained by humans. So behave in a manner appropriate for interacting with humans, including clearly communicating what you are hoping to accomplish. - ---- - -1. You may want to first take a look at - [the requirements for admission into the Arduino Library Manager index](FAQ.md#submission-requirements). Each submission will be checked for - compliance before being accepted. -1. Click the following link:
- https://github.com/arduino/library-registry/fork
- The "**Create a new fork**" page will open. -1. Click the Create fork button in the "**Create a new fork**" page.
- A "**Forking arduino/library-registry**" page will open while the fork is in the process of being created. -1. Wait for the "Forking" process to finish.
- The home page of your [fork](https://docs.github.com/get-started/quickstart/fork-a-repo) of the **library-registry** repository will open. -1. Click on the file `repositories.txt` under the list of files you see in that page.
- The "**library-registry/repositories.txt**" page will open. -1. Click the pencil icon ("Edit this file") at the right side of the toolbar in the "**library-registry/repositories.txt**" page.
- The `repositories.txt` file will open in the online text editor. -1. Add the library repository's URL to the list (it doesn't matter where in the list). This should be the URL of the repository home page. For example: - `https://github.com/arduino-libraries/Servo` -1. Click the Commit changes... button located near the top right corner of the page.
- The "**Commit changes**" dialog will open. -1. Click the Commit changes button in the "**Commit changes**" dialog.
- The "**library-registry/repositories.txt**" page will open. -1. Click the "**library-registry**" link at the top of the "**library-registry/repositories.txt**" page.
- The home page of your fork of the **library-registry** repository will open. -1. You should see a banner on the page that says: - - > **This branch is 1 commit ahead of arduino:main.** - - Click the "**Contribute**" link near the right side of that banner.
- A menu will open. - -1. Click the Open pull request button in the menu.
- The "**Open a pull request**" page will open. -1. In the **"Open a pull request"** window that opens, click the Create pull request button. - -The library will be automatically checked for compliance as soon as the pull request is submitted. If no problems were -found, the pull request will be immediately merged and the library will be available for installation via Library -Manager within a day's time. - -If any problems are found, a bot will comment on the pull request to tell you what is wrong. The problem may be either -with your pull request or with the library. - -#### If the problem is with the pull request: - -Edit the file in the -[branch](https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches) -you submitted the pull request from in your fork of the `arduino/library-registry` repository, then commit. - -Doing this will update the pull request and cause the automated checks to run again. - -#### If the problem is with the library: - -1. Make the necessary fix in the library repository. -1. Increment the `version` value in the library's - [library.properties file](https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata). -1. Create a - [release](https://docs.github.com/repositories/releasing-projects-on-github/managing-releases-in-a-repository) - or [tag](https://git-scm.com/docs/git-tag). The Library Manager index always uses tagged versions of the libraries, - so even if the development version of the library is compliant, it can't be accepted until the latest release or tag - is compliant. Alternatively, you can redo the existing release/tag if you prefer. -1. Comment on your pull request here in the `arduino/library-registry` repository, mentioning **@ArduinoBot** in the - comment. Doing this will cause the automated check to run again. - -## Changing the URL of a library already in Library Manager - -Submit a pull request that changes the URL as desired in [repositories.txt](repositories.txt). This can be done by -following [the instructions above](#instructions). - -Since this type of request must be reviewed by a human maintainer, please write an explanation in the pull request -description, making it clear that the URL is intentionally being changed. - -## Removing a library from Library Manager - -Submit a pull request that removes the URL from [repositories.txt](repositories.txt). This can be done by following -[the instructions above](#instructions). - -Since this type of request must be reviewed by a human maintainer, please write an explanation in the pull request -description, making it clear that the URL is intentionally being removed. - -## Report a problem with Library Manager - -First, please take a look at [the FAQ](FAQ.md). If a library release is missing from Library Manager, it is usually -because it was not compliant with all [the requirements](FAQ.md#update-requirements) listed in that document. - -This repository is not an appropriate place to request support or report problems with a library. Check the library's -own documentation for instructions or ask on the [Arduino Forum](https://forum.arduino.cc/). - -If the problem is about something else, please submit an issue report [here](https://github.com/arduino/library-registry/issues/new/choose). - -## Security & Malware Reporting - -If you think you found a vulnerability, malware or other security-related defect in any Arduino Library projects, please take a look at our security policy and report it to our Security Team 🛡️. - -Thank you! - -E-mail contact: security@arduino.cc +1. [Overview](#overview) +2. [Core Components](#core-components) +3. [Mathematical Foundation](#mathematical-foundation) +4. [Class Reference](#class-reference) +5. [Activation Functions](#activation-functions) +6. [Training Method](#training-methods) +7. [Evaluation Metrics](#evaluation-metrics) +8. [Implementation Guide](#implementation-guide) +9. [Example Usage](#example-usage) + +## Overview +The FNN (Fuzzy Neural Network) module implements a hybrid intelligent system that combines neural networks with fuzzy logic principles. This implementation is specifically optimized for Arduino platforms, providing efficient computation while maintaining prediction accuracy. + +## Core Components + +### Class Structure +```cpp +class FNN { +private: + std::vector> weights; // Layer weights + std::vector biases; // Layer biases + std::function activationFunction; // Activation function + std::map fuzzyRules; // Fuzzy ruleset + ... +} +``` + +### Key Features +- Multi-layer neural network architecture +- Customizable activation functions +- Integrated fuzzy rule system +- Gradient descent-based training +- Comprehensive evaluation metrics + +## Mathematical Foundation + +### 1. Network Architecture + +#### Input Layer +- Accepts normalized input vectors +- Dimension: `inputSize` (user-defined) +- Data type: `std::vector` + +#### Hidden Layer +Computation formula: + +$$ +h_j = f( \sum_{i=1}^{n} w_{ji} x_i + b_j) +$$ + +Where: +- $h_j$: Hidden layer neuron output +- $w_{ji}$: Connection weight +- $x_i$: Input value +- $b_j$: Bias term +- $f$: Activation function + +#### Output Layer +Final computation: + +$$o = f( \sum_{j=1}^{m} w_j h_j + b_o)$$ + +Parameters: +- $h_j$: Hidden layer outputs +- $w_j$: Output weights +- $b_o$: Output bias + +### 2. Learning Process + +#### Loss Function (MSE) + +$$ +L = \frac{1}{N} \sum_{i=1}^{N} (y_i - \hat{y}_i)^2 +$$ + +Components: +- $y_i$: Expected output +- $\hat{y}_i$: Predicted output +- $N$: Sample size + +#### Weight Update Rule + +$$ +w_{new} = w_{old} - \eta \frac{\partial L}{\partial w} +$$ + +Where: +- $\eta$: Learning rate +- $\frac{\partial L}{\partial w}$: Loss gradient + +## Class Reference + +### Constructor +```cpp +FNN(int inputSize = 3, float bias = 0.1, std::function activation = nullptr) +``` +Parameters: +- `inputSize`: Number of input neurons +- `bias`: Initial bias value +- `activation`: Activation function (defaults to sigmoid) + +### Public Methods + +#### `setWeights` +```cpp +void setWeights(const std::vector& newWeights) +``` +Purpose: Sets network layer weights +Parameters: +- `newWeights`: Vector of weight values +Validation: Checks dimension compatibility + +#### `setBiases` +```cpp +void setBiases(const std::vector& newBiases) +``` +Purpose: Sets layer biases +Parameters: +- `newBiases`: Vector of bias values +Validation: Verifies vector size + +#### `setFuzzyRules` +```cpp +void setFuzzyRules(const std::map& rules) +``` +Purpose: Defines fuzzy classification rules +Parameters: +- `rules`: Map of linguistic terms to numeric values + +### Training Methods + +#### `train` +```cpp +void train(const std::vector>& inputs, + const std::vector& targets, + int epochs = 100, + float learningRate = 0.01) +``` +Purpose: Trains the network +Parameters: +- `inputs`: Training data matrix +- `targets`: Expected outputs +- `epochs`: Training iterations +- `learningRate`: Learning rate + +## Activation Functions + +### 1. Sigmoid + +$$ +\sigma(x) = \frac{1}{1 + e^{-x}} +$$ + +Implementation: +```cpp +static float sigmoid(float x) { + return 1.0 / (1.0 + exp(-x)); +} +``` +Use case: General classification tasks + +### 2. Hyperbolic Tangent + +$$ +\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} +$$ + +Implementation: +```cpp +static float tanh(float x) { + return std::tanh(x); +} +``` +Use case: Normalized data ranges + +### 3. Leaky ReLU + +$$ +f(x) = \begin{cases} x, & x > 0 \\ \alpha x, & x \leq 0 \end{cases} +$$ + +Implementation: +```cpp +static std::function leakyRelu(float alpha = 0.01) +``` +Use case: Deep networks, preventing dying ReLU + +## Evaluation Metrics + +### Accuracy +```cpp +float evaluateAccuracy(const std::vector>& testInputs, + const std::vector& expectedOutputs) +``` +Calculation: +``` +accuracy = (correct_predictions / total_predictions) * 100 +``` + +### Precision +```cpp +float evaluatePrecision(const std::vector>& testInputs, + const std::vector& expectedOutputs) +``` +Calculation: +``` +precision = (true_positives / (true_positives + false_positives)) * 100 +``` + +## Implementation Guide + +### Basic Setup +```cpp +#include "fnn.h" + +FNN fnn(6); // 6 input neurons +``` + +### Configuration +```cpp +// Weight initialization +fnn.setWeights({0.3, 0.5, 0.2, 0.4, 0.1, 0.6}); + +// Bias configuration +fnn.setBiases({0.1, 0.2}); + +// Activation function selection +fnn.setActivationFunction(FNN::sigmoid); + +// Fuzzy rule definition +fnn.setFuzzyRules({ + {"Not Suitable", 0.0}, + {"Low", 0.2}, + {"High", 1.0} +}); +``` + +### Training Configuration +```cpp +// Training parameters +int numEpochs = 1000; +float learningRate = 0.01; + +// Training data format +std::vector> trainingInputs = { + {4.5, 2.8, 0.9, 3.7, 3.1, 7.9}, + {1.2, 0.6, 0.3, 0.5, 0.2, 0.7} +}; +std::vector trainingTargets = {"High", "Low"}; +``` + +## Example Usage + +### Complete Arduino Implementation +```cpp +#include "fnn.h" + +FNN fnn(6); + +void setup() { + Serial.begin(9600); + + // Configuration + fnn.setWeights({0.3, 0.5, 0.2, 0.4, 0.1, 0.6}); + fnn.setBiases({0.1, 0.2}); + fnn.setActivationFunction(FNN::sigmoid); + + // Fuzzy rules + fnn.setFuzzyRules({ + {"Not Suitable", 0.0}, + {"Low", 0.2}, + {"Very Low", 0.4}, + {"Below Average", 0.6}, + {"Above Average", 0.7}, + {"High", 1.0}, + {"Extreme", 1.1} + }); + + // Training data + std::vector> trainingInputs = { + {4.5, 2.8, 0.9, 3.7, 3.1, 7.9}, + {1.2, 0.6, 0.3, 0.5, 0.2, 0.7}, + {0.4, 0.3, 0.2, 0.6, 0.5, 0.4} + }; + std::vector trainingTargets = { + "High", "Low", "Not Suitable" + }; + + // Training + int numEpochs = 1000; + float learningRate = 0.01; + + // Train and evaluate + for (int epoch = 0; epoch < numEpochs; ++epoch) { + fnn.train(trainingInputs, trainingTargets, 1, learningRate); + + if (epoch % 100 == 0) { + float accuracy = fnn.evaluateAccuracy(trainingInputs, trainingTargets); + Serial.print("Epoch: "); + Serial.print(epoch); + Serial.print(" Accuracy: "); + Serial.println(accuracy); + } + } +} + +void loop() { + // Prediction example + std::vector newInput = {4.5, 2.8, 0.9, 3.7, 3.1, 7.9}; + String prediction = fnn.predictFNN(newInput).c_str(); + Serial.println(prediction); + delay(1000); +} +``` + +### Performance Optimization +1. Use fixed-point arithmetic where possible +2. Minimize dynamic memory allocation +3. Optimize matrix operations +4. Cache frequently used calculations + +## Error Handling +The module includes comprehensive error checking: +1. Input validation +2. Memory allocation verification +3. Dimension compatibility checks +4. Fuzzy rule consistency validation + +## Contributing +Contributions are welcome. Please follow the standard pull request process: +1. Fork the repository +2. Create your feature branch +3. Commit your changes +4. Push to the branch +5. Create a Pull Request + +## Support +For issues and feature requests, please create an issue in the repository. + +## Author +1. GALIH RIDHO UTOMO diff --git a/examples/sigmoid.ino b/examples/sigmoid.ino new file mode 100644 index 000000000..50003e3ee --- /dev/null +++ b/examples/sigmoid.ino @@ -0,0 +1,75 @@ +#include "fnn.h" + +FNN fnn(6); // Neural network dengan 6 input + +void setup() { + Serial.begin(9600); + + // Set bobot, bias, dan fungsi aktivasi + fnn.setWeights({0.3, 0.5, 0.2, 0.4, 0.1, 0.6}); + fnn.setBiases({0.1, 0.2}); // Menambahkan biases untuk hidden dan output layer + fnn.setActivationFunction(FNN::sigmoid); // Mencoba fungsi aktivasi yang lebih cocok untuk klasifikasi + + // Aturan fuzzy (perhatikan bahwa Anda perlu menyesuaikan output dengan label) + fnn.setFuzzyRules({ + {"Tidak sesuai", 0.0}, + {"Sedikit", 0.2}, + {"Sangat Belum", 0.4}, + {"Belum Banyak", 0.6}, + {"Sedikit Banyak", 0.7}, + {"Banyak", 1.0}, + {"Extrem", 1.1} + }); + + // Data pelatihan + std::vector> trainingInputs = { + {4.5, 2.8, 0.9, 3.7, 3.1, 7.9}, + {1.2, 0.6, 0.3, 0.5, 0.2, 0.7}, + {0.4, 0.3, 0.2, 0.6, 0.5, 0.4}, + {5.1, 2.4, 1.2, 4.1, 3.2, 6.5}, + {3.3, 1.7, 0.6, 3.4, 2.3, 6.1} + }; + std::vector trainingTargets = {"Banyak", "Sedikit", "Tidak sesuai", "Sedikit Banyak", "Banyak"}; + + // Data testing + std::vector> testInputs = { + {4.5, 2.8, 0.9, 3.7, 3.1, 7.9}, + {1.2, 0.6, 0.3, 0.5, 0.2, 0.7}, + {0.4, 0.3, 0.2, 0.6, 0.5, 0.4} + }; + std::vector testTargets = {"Banyak", "Sedikit", "Tidak sesuai"}; + + int numEpochs = 1000; + float learningRate = 0.01; + + // Melatih model + for (int epoch = 0; epoch < numEpochs; ++epoch) { + fnn.train(trainingInputs, trainingTargets, numEpochs, learningRate); // Latih model + + if (epoch % 100 == 0) { // Evaluasi setiap 100 epoch + float accuracy = fnn.evaluateAccuracy(testInputs, testTargets); + float precision = fnn.evaluatePrecision(testInputs, testTargets); + Serial.print("Epoch: "); + Serial.print(epoch); + Serial.print(" | Akurasi: "); + Serial.print(accuracy); + Serial.print("% | Presisi: "); + Serial.print(precision); + Serial.println("%"); + } + } + + // Prediksi setelah pelatihan + Serial.println("Hasil Prediksi setelah Pelatihan:"); + for (size_t i = 0; i < testInputs.size(); ++i) { + String result = fnn.predictFNN(testInputs[i]).c_str(); // Prediksi hasil + Serial.print("Input ke-"); + Serial.print(i + 1); + Serial.print(": "); + Serial.println(result); + } +} + +void loop() { + // Tidak ada loop untuk contoh ini +} diff --git a/library.properties b/library.properties new file mode 100644 index 000000000..55d502599 --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=fnn +version=1.0.0 +author=GALIH RIDHO UTOMO +maintainer=GALIH RIDHO UTOMO +sentence=Fuzzy Neural Network for Arduino. +paragraph=The FNN (Fuzzy Neural Network) module implements a hybrid intelligent system that combines neural networks with fuzzy logic principles. This implementation is specifically optimized for Arduino platforms, providing efficient computation while maintaining prediction accuracy. +category=Signal Input/Output +url=https://github.com/4211421036/fnn.git +architectures=* diff --git a/repositories.txt b/repositories.txt index e41d390f1..790a0c857 100644 --- a/repositories.txt +++ b/repositories.txt @@ -7809,3 +7809,4 @@ https://github.com/yunussandikci/ArduinoMessageBus https://bitbucket.org/mgf_ryan/smartsystem https://github.com/SequentMicrosystems/Sequent-8crt-Library https://github.com/dac1e/RtcDueRcf +https://github.com/4211421036/fnn diff --git a/src/fnn.cpp b/src/fnn.cpp new file mode 100644 index 000000000..3292c2944 --- /dev/null +++ b/src/fnn.cpp @@ -0,0 +1,155 @@ +#include "fnn.h" +#include + +// Konstruktor +FNN::FNN(int inputSize, float bias, std::function activation) + : weights(2, std::vector(inputSize, 0.0)), biases(2, bias), activationFunction(activation) { + if (!activationFunction) { + activationFunction = sigmoid; // Default fungsi aktivasi adalah sigmoid + } +} + +// Set bobot +void FNN::setWeights(const std::vector& newWeights) { + if (newWeights.size() == weights[0].size()) { + weights[0] = newWeights; + } +} + +// Set bias +void FNN::setBiases(const std::vector& newBiases) { + if (newBiases.size() == biases.size()) { + biases = newBiases; + } +} + +// Set fungsi aktivasi +void FNN::setActivationFunction(std::function activation) { + activationFunction = activation; +} + +// Set fuzzy rules +void FNN::setFuzzyRules(const std::map& rules) { + fuzzyRules = rules; +} + +// Fungsi aktivasi: Sigmoid +float FNN::sigmoid(float x) { + return 1.0 / (1.0 + exp(-x)); +} + +// Fungsi aktivasi: Tanh +float FNN::tanh(float x) { + return std::tanh(x); +} + +// Fungsi aktivasi: Leaky ReLU +std::function FNN::leakyRelu(float alpha) { + return [alpha](float x) { return (x > 0) ? x : alpha * x; }; +} + +// Fungsi aktivasi: ELU +std::function FNN::elu(float alpha) { + return [alpha](float x) { return (x > 0) ? x : alpha * (exp(x) - 1); }; +} + +// Fungsi aktivasi: Softplus +float FNN::softplus(float x) { + return log(1 + exp(x)); +} + +// Defuzzifikasi +std::string FNN::defuzzify(float fuzzyOutput) { + for (const auto& rule : fuzzyRules) { + if (fuzzyOutput <= rule.second) { + return rule.first; + } + } + return "Undefined"; +} + +// Compute Loss +float FNN::computeLoss(const std::vector& predicted, const std::vector& expected) { + float loss = 0.0f; + for (size_t i = 0; i < predicted.size(); ++i) { + loss += pow(predicted[i] - expected[i], 2); + } + return loss / predicted.size(); +} + +// Train +void FNN::train(const std::vector>& inputs, const std::vector& targets, int epochs, float learningRate) { + for (int epoch = 0; epoch < epochs; ++epoch) { + for (size_t i = 0; i < inputs.size(); ++i) { + float hiddenSum = biases[0]; + for (size_t j = 0; j < weights[0].size(); ++j) { + hiddenSum += inputs[i][j] * weights[0][j]; + } + float hiddenOutput = activationFunction(hiddenSum); + + float outputSum = hiddenOutput * weights[1][0] + biases[1]; + float output = activationFunction(outputSum); + + float outputError = fuzzyRules[targets[i]] - output; + weights[1][0] += learningRate * outputError * hiddenOutput; + biases[1] += learningRate * outputError; + + float hiddenError = outputError * weights[1][0]; + for (size_t j = 0; j < weights[0].size(); ++j) { + weights[0][j] += learningRate * hiddenError * inputs[i][j]; + } + biases[0] += learningRate * hiddenError; + } + } +} + +// Predict +std::string FNN::predictFNN(const std::vector& inputs) { + float hiddenSum = biases[0]; + for (size_t j = 0; j < weights[0].size(); ++j) { + hiddenSum += inputs[j] * weights[0][j]; + } + float hiddenOutput = activationFunction(hiddenSum); + + float outputSum = hiddenOutput * weights[1][0] + biases[1]; + float output = activationFunction(outputSum); + + return defuzzify(output); +} +// Evaluasi Akurasi +float FNN::evaluateAccuracy(const std::vector>& testInputs, const std::vector& expectedOutputs) { + int correctPredictions = 0; + + for (size_t i = 0; i < testInputs.size(); ++i) { + std::string predictedOutput = predictFNN(testInputs[i]); + if (predictedOutput == expectedOutputs[i]) { + correctPredictions++; + } + } + + float accuracy = (float)correctPredictions / testInputs.size(); + return accuracy * 100.0f; // Hasil dalam persen +} + +// Evaluasi Presisi +float FNN::evaluatePrecision(const std::vector>& testInputs, const std::vector& expectedOutputs) { + int truePositives = 0; + int falsePositives = 0; + + for (size_t i = 0; i < testInputs.size(); ++i) { + std::string predictedOutput = predictFNN(testInputs[i]); + + if (predictedOutput == expectedOutputs[i]) { + truePositives++; + } else if (fuzzyRules.find(predictedOutput) != fuzzyRules.end()) { + falsePositives++; + } + } + + if (truePositives + falsePositives == 0) { + return 0.0f; // Hindari pembagian dengan nol + } + + float precision = (float)truePositives / (truePositives + falsePositives); + return precision * 100.0f; // Hasil dalam persen +} diff --git a/src/fnn.h b/src/fnn.h new file mode 100644 index 000000000..262750e3a --- /dev/null +++ b/src/fnn.h @@ -0,0 +1,58 @@ +#ifndef FNN_H +#define FNN_H + +#include +#include +#include +#include +#include + +class FNN { +private: + std::vector> weights; // Bobot untuk tiap layer + std::vector biases; // Bias untuk tiap layer + std::function activationFunction; // Fungsi aktivasi + std::map fuzzyRules; // Aturan fuzzy + + float computeLoss(const std::vector& predicted, const std::vector& expected); + + // Defuzzifikasi + std::string defuzzify(float fuzzyOutput); + +public: + FNN(int inputSize = 3, float bias = 0.1, std::function activation = nullptr); + + // Set bobot + void setWeights(const std::vector& newWeights); + + // Set bias + void setBiases(const std::vector& newBiases); + + // Set fungsi aktivasi + void setActivationFunction(std::function activation); + + // Set fuzzy rules + void setFuzzyRules(const std::map& rules); + + // Prediksi FNN + std::string predictFNN(const std::vector& inputs); + + // Fungsi pelatihan + void train(const std::vector>& inputs, const std::vector& targets, int epochs = 100, float learningRate = 0.01); + + // Evaluasi + // Evaluasi Akurasi + float evaluateAccuracy(const std::vector>& testInputs, const std::vector& expectedOutputs); + + // Evaluasi Presisi + float evaluatePrecision(const std::vector>& testInputs, const std::vector& expectedOutputs); + + // Fungsi aktivasi yang disediakan + static float sigmoid(float x); + static float tanh(float x); + static std::function leakyRelu(float alpha = 0.01); + static std::function elu(float alpha = 1.0); + static float softplus(float x); +}; + +#endif