diff --git a/.gitignore b/.gitignore index 63649e64c6c6e62adfd72e7b568f1300ebbc4740..45755846413dd3cfa8c5f8237cc10e65c801b9ab 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ image/* _pycache_/* plotting.py image-classification/ +cifar.PNG diff --git a/README.md b/README.md index 3ec3bb7af0298dcd9745890dbd9db3afd6b8bcc7..77c08a88a1e81fab607f233d3710d3b7037883cd 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,99 @@ -# Image Classification +# Image Classification Project +This project aims to implement an image classification program using two successive models: k-nearest neighbors (KNN) and artificial neural networks (ANN). +## CIFAR-10 Dataset -## Getting started +The CIFAR-10 dataset is a commonly used database in computer vision for image classification. It consists of 60,000 color images of 32x32 pixels, distributed across 10 distinct classes, representing different objects or animals. -To make it easy for you to get started with GitLab, here's a list of recommended next steps. + +### CIFAR-10 Dataset Classes: -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! +1. airplane +2. automobile +3. bird +4. cat +5. deer +6. dog +7. frog +8. horse +9. ship +10. truck -## Add your files +## Accomplished Steps -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: +### CIFAR Database Preparation -``` -cd existing_repo -git remote add origin https://gitlab.ec-lyon.fr/selalimi/image-classification.git -git branch -M main -git push -uf origin main -``` +#### Database Download: +The CIFAR-10 database was downloaded from [Dataset_Cifar-10](https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz). -## Integrate with your tools +#### Creating the data Folder: +A folder named data was created to store the CIFAR-10 database files. -- [ ] [Set up project integrations](https://gitlab.ec-lyon.fr/selalimi/image-classification/-/settings/integrations) +#### Writing the read_cifar.py Script: +A Python file named read_cifar.py was created, including the following functions: +- `read_cifar_batch` +- `read_cifar` +- `split_dataset` -## Collaborate with your team +## Implementation of k-nearest neighbors (KNN) -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) +### Writing the knn.py Script: +A Python file named knn.py was created, including the following functions: +- `distance_matrix` +- `knn_predict` +- `evaluate_knn` +- `plot_KNN` -## Test and Deploy +### Performance Study +The effectiveness of the KNN algorithm was evaluated based on the number of neighbors (k) for `split_factor=0.9`. -Use the built-in continuous integration in GitLab. +### Running the KNN Code -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** +1. Run the script to split data +```bash +import read_cifar as rc +X, y = rc.read_cifar('data') +# Split the Dataset +X_train, y_train, X_test, y_test = rc.split_dataset(X, y, split=0.9) +``` -# Editing this README +## Results : +### Generating the Graph +1. Results using KNN: -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. +A graph showing the accuracy variation with k was generated using matplotlib and saved as "knn.png" in the "Results" folder. : -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. -## Name -Choose a self-explaining name for your project. + -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. +2. Results using ANN : -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. +A graph showing the accuracy variation with the number of epochs was generated using matplotlib and saved as "mlp.png" in the "Results" folder. -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. + -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. +## Analysis of KNN Results +Unfortunately, the performance of the KNN algorithm was disappointing, with accuracy ranging between 0.33 and 0.34 for different values of k (up to k=20). Several reasons may explain these mixed results: -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. +1. **High Dimensionality of Data**: CIFAR-10 dataset images are 32x32 pixels, resulting in high-dimensional data. This can make Euclidean distance less discriminative, affecting KNN's performance. -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. +2. **Scale Sensitivity**: KNN is sensitive to different feature scales. Pixels in an image can have different values, and KNN may be influenced by these disparities. -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. +3. **Choice of k**: The choice of the number of neighbors (k) can significantly influence results. An inappropriate k value can lead to underestimation or overestimation of the model's complexity. -## Contributing -State if you are open to contributions and what your requirements are for accepting them. +4. **Lack of Feature Abstraction**: KNN directly uses pixels as features. More advanced feature extraction techniques could improve performance -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. + ## Analysis of ANN Results +The deep learning algorithm (ANN) used for our dataset has relatively low performance, with test set accuracy plateauing around 0.098 over 100 epochs. -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. +These results suggest that adjustments to certain aspects of the model, such as complexity, hyperparameters, or weight initialization, may be necessary to improve its ability to generalize to new data. Further exploration of these aspects could be beneficial in optimizing model performance. -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. + ## Conculsion + The best accuracy is achieved with the KNN model, reaching 36%. However, it could be further improved by using Convolutional Neural Networks (CNN) instead of Artificial Neural Networks (ANN). CNNs are particularly recognized for their effectiveness in image recognition, analysis, and classification of images and videos. -## License -For open source projects, say how it is licensed. +## Author +Sara EL ALIMI -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +## Licence +Ce projet est sous licence MIT. diff --git a/Results/knn.png b/Results/knn.png new file mode 100644 index 0000000000000000000000000000000000000000..93ce23e5896f4bd9604d96a8349e8c56a1e0e0ec Binary files /dev/null and b/Results/knn.png differ diff --git a/Results/mlp.png b/Results/mlp.png new file mode 100644 index 0000000000000000000000000000000000000000..b68ffa5438c8c26397c7be686d998e7166bc5f5c Binary files /dev/null and b/Results/mlp.png differ diff --git a/main.ipynb b/main.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..04aa675cec429e135d1349890fb63c031028a691 --- /dev/null +++ b/main.ipynb @@ -0,0 +1,623 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare the Dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import read_cifar as rc\n", + "X,y=rc.read_cifar('data') \n", + "# Split the Dataset\n", + "X_train,y_train,X_test,y_test=rc.split_dataset(X,y,split=0.9) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## k-nearest neighbors" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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QLcivFYLXL2qbF2IiIhcEQOQAnx85A1gNxgREZESGIAUwnFAREREymEAUggDEBERkXIYgBTCAERERKQcBiCFcD0wIiIi5TAAKYQtQERERMphAFII1wMjIiJSDgOQQtgCREREpBwGIIUwABERESmHAUghDEBERETKYQBSCAMQERGRchiAFMIAREREpBwGIIWUDUBCKFsXIiIiV8MApBBdACopAQoLla0LERGRq2EAUkitWoCnp3zMbjAiIiL7YgBSiErFcUBERERKYQBSEAMQERGRMhiAFMQFUYmIiJTBAKQgtgAREREpgwFIQVwQlYiISBkMQApiCxAREZEyGIAUxABERESkDAYgBTEAERERKYMBSEEMQERERMpgAFIQAxAREZEyGIAUxABERESkDAYgBTEAERERKYMBSEG6AHTzJnDjhrJ1ISIiciUMQAry8wPc3eVjtgIRERHZDwOQgrgiPBERkTIYgBTGAERERGR/DEAK43pgRERE9scApDC2ABEREdkfA5DCGICIiIjsjwFIYQxARERE9scApDAGICIiIvtjAFIYAxAREZH9MQApjAGIiIjI/hiAFMYAREREZH8MQApjACIiIrI/BiCFMQARERHZHwOQwurWlfeFhUBRkbJ1ISIichUMQArz9wfc/ncWrlxRti5ERESuggFIYW5uQJ068jHXAyMiIrIPBiAHwHFARERE9sUA5AAYgIiIiOyLAcgBMAARERHZFwOQA2AAIiIisi8GIAfAAERERGRfDEAOgAGIiIjIvhiAHAADEBERkX0xADkABiAiIiL7YgByAAxARERE9sUA5AAYgIiIiOyLAcgB6BZEZQAiIiKyDwYgB6BrASooAEpKlK0LERGRK2AAcgCBgaWPuSI8ERGR7TlEAJo/fz4iIyPh7e2NuLg47N6922TZlJQUxMbGIjAwEL6+voiJicGyZcsMyowZMwYqlcrg1rt3b1sfRpWp1aUhiN1gREREtueudAXWrFmDpKQkLFy4EHFxcZgzZw569eqFzMxM1K9fv1z5oKAgTJs2DdHR0fD09MSPP/6IxMRE1K9fH7169dKX6927N7766iv9z15eXnY5nqoKCgLy8hiAiIiI7EHxFqCPPvoITz/9NBITE3HnnXdi4cKFqFWrFhYvXmy0fLdu3TBw4EC0bNkSTZs2xcSJE9GmTRts27bNoJyXlxca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/9mcz3p1MQDVUACM3r766it9mfvuu0+MHj1a//OkSZNEo0aNhKenpwgJCREPPfSQyMjIsH/lq2DYsGEiNDRUeHp6ivDwcDFs2DBx/Phx/fO3H6sQQnz99dfijjvuEJ6enqJVq1biv//9r51rXXUbNmwQAERmZma555z5vG7evNnov1vd8Wi1WjF9+nQREhIivLy8xAMPPFDud9C4cWMxc+ZMg23z5s3T/w46deokdu7caacjqlhFx3vy5EmTn+PNmzfr93H78Vb2WVBKRcd6/fp18eCDD4p69eoJDw8P0bhxY/H000+XCzLOcm4r+3cshBCLFi0SPj4+Ii8vz+g+nOW8mvNdc+PGDTF27FhRp04dUatWLTFw4EBx7ty5cvsp+xpzPuvVpfrfGxMRERG5DI4BIiIiIpfDAEREREQuhwGIiIiIXA4DEBEREbkcBiAiIiJyOQxARERE5HIYgIiIiMjlMAARERGRy2EAIiKXMGbMGAwYMMBg2zfffANvb298+OGHylSKiBTjrnQFiIiU8MUXX2DcuHFYuHAhEhMTla4OEdkZW4CIyOXMnj0b48ePx+rVqxl+iFwUW4CIyKVMnToVn332GX788Uc88MADSleHiBTCAERELuOnn37CunXrkJqaivvvv1/p6hCRgtgFRkQuo02bNoiMjMTMmTNx7do1patDRApiACIilxEeHo60tDRkZ2ejd+/euHr1qtJVIiKFMAARkUtp3LgxtmzZgvPnzzMEEbkwBiAicjkRERFIS0vDhQsX0KtXLxQUFChdJSKyMwYgInJJDRs2RFpaGnJzcxmCiFyQSgghlK4EERERkT2xBYiIiIhcDgMQERERuRwGICIiInI5DEBERETkchiAiIiIyOUwABEREZHLYQAiIiIil8MARERERC6HAYiIiIhcDgMQERERuRwGICIiInI5DEBERETkcv4fnWkth3i6zJEAAAAASUVORK5CYII=", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "import read_cifar as rc\n", + "import knn\n", + "X,y=rc.read_cifar('data') \n", + "# Split the Dataset\n", + "X_train,y_train,X_test,y_test=rc.split_dataset(X,y,split=0.9) \n", + "# Plot the accuracy of the model KNN\n", + "knn.plot_KNN(X_train,y_train,X_test,y_test) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Artificial Neural Network" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\HP\\Desktop\\Deep_learning_BE\\image-classification\\mlp.py:29: RuntimeWarning: overflow encountered in exp\n", + " return 1 / (1 + np.exp(-x))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/100\n", + "Train Accuracy: 0.093370 Test Accuracy: 0.069000\n", + "Epoch 2/100\n", + "Train Accuracy: 0.073167 Test Accuracy: 0.073833\n", + "Epoch 3/100\n", + "Train Accuracy: 0.074981 Test Accuracy: 0.078000\n", + "Epoch 4/100\n", + "Train Accuracy: 0.076926 Test Accuracy: 0.076667\n", + "Epoch 5/100\n", + "Train Accuracy: 0.078741 Test Accuracy: 0.076000\n", + "Epoch 6/100\n", + "Train Accuracy: 0.079537 Test Accuracy: 0.076000\n", + "Epoch 7/100\n", + "Train Accuracy: 0.078704 Test Accuracy: 0.076500\n", + "Epoch 8/100\n", + "Train Accuracy: 0.079852 Test Accuracy: 0.077000\n", + "Epoch 9/100\n", + "Train Accuracy: 0.079944 Test Accuracy: 0.078000\n", + "Epoch 10/100\n", + "Train Accuracy: 0.079722 Test Accuracy: 0.078667\n", + "Epoch 11/100\n", + "Train Accuracy: 0.080241 Test Accuracy: 0.077667\n", + "Epoch 12/100\n", + "Train Accuracy: 0.080463 Test Accuracy: 0.077500\n", + "Epoch 13/100\n", + "Train Accuracy: 0.080500 Test Accuracy: 0.076167\n", + "Epoch 14/100\n", + "Train Accuracy: 0.080870 Test Accuracy: 0.076333\n", + "Epoch 15/100\n", + "Train Accuracy: 0.081204 Test Accuracy: 0.075333\n", + "Epoch 16/100\n", + "Train Accuracy: 0.081352 Test Accuracy: 0.076167\n", + "Epoch 17/100\n", + "Train Accuracy: 0.081389 Test Accuracy: 0.075667\n", + "Epoch 18/100\n", + "Train Accuracy: 0.082185 Test Accuracy: 0.075333\n", + "Epoch 19/100\n", + "Train Accuracy: 0.081981 Test Accuracy: 0.076167\n", + "Epoch 20/100\n", + "Train Accuracy: 0.081741 Test Accuracy: 0.075667\n", + "Epoch 21/100\n", + "Train Accuracy: 0.081741 Test Accuracy: 0.076833\n", + "Epoch 22/100\n", + "Train Accuracy: 0.082111 Test Accuracy: 0.075667\n", + "Epoch 23/100\n", + "Train Accuracy: 0.082259 Test Accuracy: 0.075333\n", + "Epoch 24/100\n", + "Train Accuracy: 0.082315 Test Accuracy: 0.074667\n", + "Epoch 25/100\n", + "Train Accuracy: 0.082370 Test Accuracy: 0.076833\n", + "Epoch 26/100\n", + "Train Accuracy: 0.082852 Test Accuracy: 0.074833\n", + "Epoch 27/100\n", + "Train Accuracy: 0.082926 Test Accuracy: 0.075833\n", + "Epoch 28/100\n", + "Train Accuracy: 0.083185 Test Accuracy: 0.075833\n", + "Epoch 29/100\n", + "Train Accuracy: 0.083370 Test Accuracy: 0.075833\n", + "Epoch 30/100\n", + "Train Accuracy: 0.083667 Test Accuracy: 0.076500\n", + "Epoch 31/100\n", + "Train Accuracy: 0.083741 Test Accuracy: 0.076833\n", + "Epoch 32/100\n", + "Train Accuracy: 0.083778 Test Accuracy: 0.078500\n", + "Epoch 33/100\n", + "Train Accuracy: 0.084185 Test Accuracy: 0.079167\n", + "Epoch 34/100\n", + "Train Accuracy: 0.084148 Test Accuracy: 0.079000\n", + "Epoch 35/100\n", + "Train Accuracy: 0.084407 Test Accuracy: 0.079500\n", + "Epoch 36/100\n", + "Train Accuracy: 0.085037 Test Accuracy: 0.079500\n", + "Epoch 37/100\n", + "Train Accuracy: 0.085037 Test Accuracy: 0.080000\n", + "Epoch 38/100\n", + "Train Accuracy: 0.084778 Test Accuracy: 0.079667\n", + "Epoch 39/100\n", + "Train Accuracy: 0.084593 Test Accuracy: 0.079833\n", + "Epoch 40/100\n", + "Train Accuracy: 0.084519 Test Accuracy: 0.080167\n", + "Epoch 41/100\n", + "Train Accuracy: 0.084852 Test Accuracy: 0.079500\n", + "Epoch 42/100\n", + "Train Accuracy: 0.084815 Test Accuracy: 0.079167\n", + "Epoch 43/100\n", + "Train Accuracy: 0.084574 Test Accuracy: 0.079000\n", + "Epoch 44/100\n", + "Train Accuracy: 0.084685 Test Accuracy: 0.078500\n", + "Epoch 45/100\n", + "Train Accuracy: 0.084481 Test Accuracy: 0.079000\n", + "Epoch 46/100\n", + "Train Accuracy: 0.084833 Test Accuracy: 0.079333\n", + "Epoch 47/100\n", + "Train Accuracy: 0.085130 Test Accuracy: 0.079500\n", + "Epoch 48/100\n", + "Train Accuracy: 0.085185 Test Accuracy: 0.080667\n", + "Epoch 49/100\n", + "Train Accuracy: 0.085389 Test Accuracy: 0.080833\n", + "Epoch 50/100\n", + "Train Accuracy: 0.085944 Test Accuracy: 0.081667\n", + "Epoch 51/100\n", + "Train Accuracy: 0.086111 Test Accuracy: 0.079000\n", + "Epoch 52/100\n", + "Train Accuracy: 0.086648 Test Accuracy: 0.079667\n", + "Epoch 53/100\n", + "Train Accuracy: 0.086963 Test Accuracy: 0.080833\n", + "Epoch 54/100\n", + "Train Accuracy: 0.087278 Test Accuracy: 0.081833\n", + "Epoch 55/100\n", + "Train Accuracy: 0.087648 Test Accuracy: 0.082500\n", + "Epoch 56/100\n", + "Train Accuracy: 0.088352 Test Accuracy: 0.084167\n", + "Epoch 57/100\n", + "Train Accuracy: 0.088519 Test Accuracy: 0.083500\n", + "Epoch 58/100\n", + "Train Accuracy: 0.089019 Test Accuracy: 0.085167\n", + "Epoch 59/100\n", + "Train Accuracy: 0.089000 Test Accuracy: 0.086333\n", + "Epoch 60/100\n", + "Train Accuracy: 0.089500 Test Accuracy: 0.086000\n", + "Epoch 61/100\n", + "Train Accuracy: 0.089833 Test Accuracy: 0.086333\n", + "Epoch 62/100\n", + "Train Accuracy: 0.090056 Test Accuracy: 0.088000\n", + "Epoch 63/100\n", + "Train Accuracy: 0.090370 Test Accuracy: 0.087833\n", + "Epoch 64/100\n", + "Train Accuracy: 0.090185 Test Accuracy: 0.087667\n", + "Epoch 65/100\n", + "Train Accuracy: 0.090741 Test Accuracy: 0.087167\n", + "Epoch 66/100\n", + "Train Accuracy: 0.091444 Test Accuracy: 0.087833\n", + "Epoch 67/100\n", + "Train Accuracy: 0.091667 Test Accuracy: 0.088500\n", + "Epoch 68/100\n", + "Train Accuracy: 0.092315 Test Accuracy: 0.090167\n", + "Epoch 69/100\n", + "Train Accuracy: 0.091963 Test Accuracy: 0.090667\n", + "Epoch 70/100\n", + "Train Accuracy: 0.092093 Test Accuracy: 0.091167\n", + "Epoch 71/100\n", + "Train Accuracy: 0.091833 Test Accuracy: 0.091833\n", + "Epoch 72/100\n", + "Train Accuracy: 0.091870 Test Accuracy: 0.090333\n", + "Epoch 73/100\n", + "Train Accuracy: 0.092148 Test Accuracy: 0.091833\n", + "Epoch 74/100\n", + "Train Accuracy: 0.092481 Test Accuracy: 0.091667\n", + "Epoch 75/100\n", + "Train Accuracy: 0.092315 Test Accuracy: 0.093000\n", + "Epoch 76/100\n", + "Train Accuracy: 0.092852 Test Accuracy: 0.093333\n", + "Epoch 77/100\n", + "Train Accuracy: 0.093389 Test Accuracy: 0.093500\n", + "Epoch 78/100\n", + "Train Accuracy: 0.093852 Test Accuracy: 0.095500\n", + "Epoch 79/100\n", + "Train Accuracy: 0.094167 Test Accuracy: 0.095500\n", + "Epoch 80/100\n", + "Train Accuracy: 0.094685 Test Accuracy: 0.096333\n", + "Epoch 81/100\n", + "Train Accuracy: 0.095111 Test Accuracy: 0.097000\n", + "Epoch 82/100\n", + "Train Accuracy: 0.095537 Test Accuracy: 0.097667\n", + "Epoch 83/100\n", + "Train Accuracy: 0.095685 Test Accuracy: 0.096833\n", + "Epoch 84/100\n", + "Train Accuracy: 0.096167 Test Accuracy: 0.098000\n", + "Epoch 85/100\n", + "Train Accuracy: 0.095685 Test Accuracy: 0.097833\n", + "Epoch 86/100\n", + "Train Accuracy: 0.096000 Test Accuracy: 0.097333\n", + "Epoch 87/100\n", + "Train Accuracy: 0.096481 Test Accuracy: 0.097667\n", + "Epoch 88/100\n", + "Train Accuracy: 0.096611 Test Accuracy: 0.098167\n", + "Epoch 89/100\n", + "Train Accuracy: 0.096519 Test Accuracy: 0.098667\n", + "Epoch 90/100\n", + "Train Accuracy: 0.096519 Test Accuracy: 0.098500\n", + "Epoch 91/100\n", + "Train Accuracy: 0.096519 Test Accuracy: 0.096500\n", + "Epoch 92/100\n", + "Train Accuracy: 0.096704 Test Accuracy: 0.097667\n", + "Epoch 93/100\n", + "Train Accuracy: 0.096815 Test Accuracy: 0.098167\n", + "Epoch 94/100\n", + "Train Accuracy: 0.096685 Test Accuracy: 0.099000\n", + "Epoch 95/100\n", + "Train Accuracy: 0.096796 Test Accuracy: 0.098833\n", + "Epoch 96/100\n", + "Train Accuracy: 0.096815 Test Accuracy: 0.099167\n", + "Epoch 97/100\n", + "Train Accuracy: 0.097241 Test Accuracy: 0.098833\n", + "Epoch 98/100\n", + "Train Accuracy: 0.097333 Test Accuracy: 0.099500\n", + "Epoch 99/100\n", + "Train Accuracy: 0.097389 Test Accuracy: 0.098833\n", + "Epoch 100/100\n", + "Train Accuracy: 0.097556 Test Accuracy: 0.098167\n", + "Test Set Accuracy: 0.09816666666666667\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import mlp\n", + "mlp.plot_ANN(X_train,y_train,X_test,y_test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test de la fonction read_cifar " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import read_cifar as rc\n", + "from read_cifar import read_cifar_batch\n", + "from read_cifar import read_cifar\n", + "\n", + "def test_read_cifar_batch():\n", + " # Test read_cifar_batch function\n", + " batch_path = \"data\\data_batch_1\"\n", + " data, labels = read_cifar_batch(batch_path)\n", + "\n", + " # Check that data has the right shape and type\n", + " assert data.shape == (10000, 3072)\n", + " assert data.dtype == np.float32\n", + "\n", + " # Check that labels has the right shape and type\n", + " assert labels.shape == (10000,)\n", + " assert labels.dtype == np.int64\n", + " print(\"All tests passed successfully.\")\n", + " \n", + "def test_read_cifar():\n", + " # Test read_cifar function\n", + " data, labels = read_cifar('data')\n", + "\n", + " # Check that data has the right shape and type\n", + " assert data.shape == (60000, 3072)\n", + " assert data.dtype == np.float32\n", + "\n", + " # Check that labels has the right shape and type\n", + " assert labels.shape == (60000,)\n", + " assert labels.dtype == np.int64\n", + " print(\"All tests passed successfully.\")\n", + "\n", + "def test_split_dataset():\n", + " data = np.random.randn(150, 4)\n", + " labels = np.random.randn(150)\n", + " split = 0.8\n", + " data_train, labels_train, data_test, labels_test = rc.split_dataset(data, labels, split)\n", + "\n", + " total_size = data_train.shape[0] + data_test.shape[0]\n", + "\n", + " assert total_size == len(data)\n", + " assert len(labels_train) == len(data_train)\n", + " assert len(labels_test) == len(data_test)\n", + " \n", + " print(\"All tests passed successfully.\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All tests passed successfully.\n" + ] + } + ], + "source": [ + "test_read_cifar_batch()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All tests passed successfully.\n" + ] + } + ], + "source": [ + "test_read_cifar()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All tests passed successfully.\n" + ] + } + ], + "source": [ + "test_split_dataset()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test de la fonction knn" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import knn \n", + "\n", + "# Test de la fonction distance_matrix :\n", + "def test_distance_matrix():\n", + " X = np.array([[1, 2], [3, 4]])\n", + " Y = np.array([[2, 2], [1, 1]])\n", + " dists = knn.distance_matrix(X, Y)\n", + " assert dists.shape == (2, 2)\n", + " print(\"Test for distance_matrix passed.\")\n", + " \n", + "\n", + "# Test de la fonction knn_predict :\n", + "def test_knn_predict():\n", + " dists = np.array([[2, 5], [10, 1]])\n", + " labels_train = np.array([0, 1])\n", + " k = 1\n", + " y_pred = knn.knn_predict(dists, labels_train, k)\n", + " assert y_pred.shape == (2,)\n", + " assert np.array_equal(y_pred, np.array([0, 1]))\n", + " print(\"Test for knn_predict passed.\")\n", + "\n", + "# Test de la fonction evaluate_knn :\n", + "def test_evaluate_knn_accuracy():\n", + " data_train = np.array([[1, 2], [3, 4], [5, 6], [1, 1], [2, 2]])\n", + " labels_train = np.array([0, 1, 2, 0, 1])\n", + " data_test = np.array([[2, 2], [1, 1], [3, 3]])\n", + " labels_test = np.array([1, 0, 1])\n", + " k = 2\n", + " accuracy = knn.evaluate_knn(data_train, labels_train, data_test, labels_test, k)\n", + " assert 0 <= accuracy <= 1\n", + " print(\"Test for evaluate_knn accuracy passed.\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test for distance_matrix passed.\n" + ] + } + ], + "source": [ + "test_distance_matrix()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test for knn_predict passed.\n" + ] + } + ], + "source": [ + "test_knn_predict()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test for evaluate_knn accuracy passed.\n" + ] + } + ], + "source": [ + "test_evaluate_knn_accuracy()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test de la fonction mlp" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "from mlp import initialization, train_mlp, calculate_accuracy, run_mlp_training\n", + "\n", + "def test_mlp_training():\n", + " #Paramètres du test\n", + " num_samples = 200\n", + " num_features = 3\n", + " num_classes = 2\n", + " num_hidden_units = 3\n", + " learning_rate = 0.1\n", + " num_epochs = 10\n", + "\n", + " # Générez des données factices pour le test\n", + " X_train = np.random.randn(num_samples, num_features)\n", + " y_train = np.random.randint(0, num_classes, num_samples)\n", + " X_test = np.random.randn(num_samples, num_features)\n", + " y_test = np.random.randint(0, num_classes, num_samples)\n", + "\n", + " # Initialisez les poids et les biais\n", + " W1, b1, W2, b2 = initialization(num_features, num_hidden_units, num_classes)\n", + "\n", + " # Entraînez le modèle\n", + " train_accuracies, test_accuracy = run_mlp_training(X_train, y_train, X_test, y_test, num_hidden_units, learning_rate, num_epochs)\n", + "\n", + " # Vérifiez si l'accuracy sur l'ensemble de test est un nombre entre 0 et 1\n", + " assert 0 <= test_accuracy <= 1\n", + "\n", + " # Vérifiez si la longueur de la liste des accuracies d'entraînement correspond au nombre d'époques\n", + " assert len(train_accuracies) == num_epochs\n", + "\n", + " # Vérifiez si les accuracies d'entraînement sont des nombres entre 0 et 1\n", + " for accuracy in train_accuracies:\n", + " assert 0 <= accuracy <= 1\n", + "\n", + " print(\"Tous les tests ont réussi avec succès.\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/10\n", + "Train Accuracy: 0.490000 Test Accuracy: 0.555000\n", + "Epoch 2/10\n", + "Train Accuracy: 0.490000 Test Accuracy: 0.535000\n", + "Epoch 3/10\n", + "Train Accuracy: 0.505000 Test Accuracy: 0.540000\n", + "Epoch 4/10\n", + "Train Accuracy: 0.505000 Test Accuracy: 0.540000\n", + "Epoch 5/10\n", + "Train Accuracy: 0.500000 Test Accuracy: 0.545000\n", + "Epoch 6/10\n", + "Train Accuracy: 0.500000 Test Accuracy: 0.545000\n", + "Epoch 7/10\n", + "Train Accuracy: 0.500000 Test Accuracy: 0.545000\n", + "Epoch 8/10\n", + "Train Accuracy: 0.500000 Test Accuracy: 0.545000\n", + "Epoch 9/10\n", + "Train Accuracy: 0.500000 Test Accuracy: 0.545000\n", + "Epoch 10/10\n", + "Train Accuracy: 0.500000 Test Accuracy: 0.545000\n", + "Tous les tests ont réussi avec succès.\n" + ] + } + ], + "source": [ + "test_mlp_training()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mlp.py b/mlp.py index 7812729f50be812fcc4370346eca45aabe63b553..7fa9b88cedc561c0a344be830268fc7b3d0e97a8 100644 --- a/mlp.py +++ b/mlp.py @@ -32,7 +32,7 @@ def sigmoid(x,derivate): # Define the softmax activation function def softmax(x,derivate): if derivate == False : - return np.exp(x) / np.exp(np.array(x)).sum(axis=-1, keepdims=True) + return np.exp(x) / np.exp(np.array(x)).sum(axis=1, keepdims=True) else : return x*(1-x) @@ -94,7 +94,7 @@ def learn_once_mse(W1, b1, W2, b2, data, targets, learning_rate): # Update weights and biases of the output layer W2 = W2 - learning_rate * np.dot(hidden_layer_output.T, output_layer_gradients) / data.shape[0] - b2 = b2 - learning_rate * (1 / hidden_layer_output.shape[1]) * output_layer_gradients.sum(axis=0, keepdims=True) + b2 = b2 - learning_rate * (1 / hidden_layer_output.shape[1]) * output_layer_gradients.sum(axis=0) # Calculate the error at the hidden layer hidden_layer_error = np.dot(output_layer_gradients, W2.T) @@ -104,7 +104,7 @@ def learn_once_mse(W1, b1, W2, b2, data, targets, learning_rate): # Update weights and biases of the hidden layer W1 = W1 - learning_rate * np.dot(data.T, hidden_layer_gradients) / data.shape[0] - b1 = b1 - learning_rate * (1 / data.shape[1]) * hidden_layer_gradients.sum(axis=0, keepdims=True) + b1 = b1 - learning_rate * (1 / data.shape[1]) * hidden_layer_gradients.sum(axis=0) # Calculate the loss using the specified metric loss = loss_metrics(output_layer_output, targets,metric="MSE",status="forward") diff --git a/test/__pycache__/read_cifar.cpython-312.pyc b/test/__pycache__/read_cifar.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..998b9339c4bd361ea0c214803f363c7d9a563bc2 Binary files /dev/null and b/test/__pycache__/read_cifar.cpython-312.pyc differ diff --git a/test/__pycache__/test_read_cifar.cpython-312.pyc b/test/__pycache__/test_read_cifar.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e59a03bb7d0607acc6662e7dc4edcd909da2b9f Binary files /dev/null and b/test/__pycache__/test_read_cifar.cpython-312.pyc differ diff --git a/test/test_knn.py b/test/test_knn.py new file mode 100644 index 0000000000000000000000000000000000000000..9368c502d898a364c9954e895d462c1da3f454e0 --- /dev/null +++ b/test/test_knn.py @@ -0,0 +1,33 @@ +import numpy as np +import knn + +# Test de la fonction distance_matrix : +def test_distance_matrix(): + X = np.array([[1, 2], [3, 4]]) + Y = np.array([[2, 2], [1, 1]]) + dists = knn.distance_matrix(X, Y) + assert dists.shape == (2, 2) + assert np.allclose(dists, np.array([[2, 5], [10, 1]])) + print("Test for distance_matrix passed.") + + +# Test de la fonction knn_predict : +def test_knn_predict(): + dists = np.array([[2, 5], [10, 1]]) + labels_train = np.array([0, 1]) + k = 1 + y_pred = knn.knn_predict(dists, labels_train, k) + assert y_pred.shape == (2,) + assert np.array_equal(y_pred, np.array([0, 1])) + print("Test for knn_predict passed.") + +# Test de la fonction evaluate_knn : +def test_evaluate_knn_accuracy(): + data_train = np.array([[1, 2], [3, 4], [5, 6], [1, 1], [2, 2]]) + labels_train = np.array([0, 1, 2, 0, 1]) + data_test = np.array([[2, 2], [1, 1], [3, 3]]) + labels_test = np.array([1, 0, 1]) + k = 2 + accuracy = knn.evaluate_knn(data_train, labels_train, data_test, labels_test, k) + assert 0 <= accuracy <= 1 + print("Test for evaluate_knn accuracy passed.") diff --git a/test/test_mlp.py b/test/test_mlp.py new file mode 100644 index 0000000000000000000000000000000000000000..546d9f3f1959693a52f8de88f4f53f961af72415 --- /dev/null +++ b/test/test_mlp.py @@ -0,0 +1,39 @@ +import numpy as np + +# Importez les fonctions +from mlp import initialization, train_mlp, calculate_accuracy + +def test_mlp_training(): + # Paramètres du test + num_samples = 200 + num_features = 10 + num_classes = 3 + num_hidden_units = 5 + learning_rate = 0.1 + num_epochs = 10 + + # Générez des données factices pour le test + X_train = np.random.randn(num_samples, num_features) + y_train = np.random.randint(0, num_classes, num_samples) + X_test = np.random.randn(num_samples, num_features) + y_test = np.random.randint(0, num_classes, num_samples) + + # Initialisez les poids et les biais + W1, b1, W2, b2 = initialization(num_features, num_hidden_units, num_classes) + + # Entraînez le modèle + train_accuracies, test_accuracy = train_mlp(W1, b1, W2, b2, X_train, y_train, learning_rate, num_epochs) + + # Vérifiez si l'accuracy est un nombre entre 0 et 1 + assert 0 <= test_accuracy <= 1 + + # Vérifiez si la longueur de la liste des accuracies d'entraînement correspond au nombre d'époques + assert len(train_accuracies) == num_epochs + + # Vérifiez si les accuracies d'entraînement sont des nombres entre 0 et 1 + for accuracy in train_accuracies: + assert 0 <= accuracy <= 1 + + print("Tous les tests ont réussi avec succès.") + + diff --git a/test/test_read_cifar.py b/test/test_read_cifar.py new file mode 100644 index 0000000000000000000000000000000000000000..13080e1c90fb8307fb16d9c4776301c0995efded --- /dev/null +++ b/test/test_read_cifar.py @@ -0,0 +1,46 @@ +import numpy as np +import read_cifar as rc +from read_cifar import read_cifar_batch +from read_cifar import read_cifar +def test_read_cifar_batch(): + # Test read_cifar_batch function + batch_path = "data\data_batch_1" + data, labels = read_cifar_batch(batch_path) + + # Check that data has the right shape and type + assert data.shape == (10000, 3072) + assert data.dtype == np.float32 + + # Check that labels has the right shape and type + assert labels.shape == (10000,) + assert labels.dtype == np.int64 + print("All tests passed successfully.") + + + +def test_read_cifar(): + # Test read_cifar function + data, labels = read_cifar('data') + + # Check that data has the right shape and type + assert data.shape == (60000, 3072) + assert data.dtype == np.float32 + + # Check that labels has the right shape and type + assert labels.shape == (60000,) + assert labels.dtype == np.int64 + print("All tests passed successfully.") + +def test_split_dataset(): + data = np.random.randn(150, 4) + labels = np.random.randn(150) + split = 0.8 + data_train, labels_train, data_test, labels_test = rc.split_dataset(data, labels, split) + + total_size = data_train.shape[0] + data_test.shape[0] + + assert total_size == len(data) + assert len(labels_train) == len(data_train) + assert len(labels_test) == len(data_test) + + print("All tests passed successfully.")