# ReservoirChat: Interactive Documentation Enhanced with LLM and Knowledge Graph for ReservoirPy

Virgile Boraud, Yannis Bendi-Ouis, Paul Bernard, Xavier Hinaut

► To cite this version:

Virgile Boraud, Yannis Bendi-Ouis, Paul Bernard, Xavier Hinaut. ReservoirChat: Interactive Documentation Enhanced with LLM and Knowledge Graph for ReservoirPy. 2025. hal-05132988

HAL Id: hal-05132988

https://hal.science/hal-05132988v1

Preprint submitted on 3 Jul 2025

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_1.png" /></figure>

Distributed under a Creative Commons Attribution 4.0 International License
# ReservoirChat: Interactive Documentation Enhanced with LLM and Knowledge Graph for ReservoirPy

Virgile Boraud*

Mnemosyne

Inria

Bordeaux, France

virgile.boraud@yahoo.fr

Yannis Bendi-Ouis*

Mnemosyne

Inria

Bordeaux, France

yannis.bendi-ouis@inria.fr

Paul Bernard

Mnemosyne

Inria

Bordeaux, France

paul.bernard@inria.fr

Xavier Hinaut†

Mnemosyne

Inria

Bordeaux, France

xavier.hinaut@inria.fr

**Abstract**—We introduce a tool designed to improve the capabilities of Large Language Models (LLMs) in assisting with code development using the ReservoirPy library, as well as in answering complex questions in the field of Reservoir Computing. By incorporating external knowledge through Retrieval-Augmented Generation (RAG) and knowledge graphs, our approach aims to reduce hallucinations and increase the factual accuracy of generated responses. The system provides an interactive experience similar to ChatGPT, tailored specifically for ReservoirPy, enabling users to write, debug, and understand Python code while accessing reliable domain-specific insights. In our evaluation, while proprietary models such as ChatGPT-4o and NotebookLM performed slightly better on general knowledge questions, our model outperformed them on coding tasks and showed a significant improvement over its base model, Codestral-22B.

**Index Terms**—Large Language Model, Knowledge Graph, Retrieval Augmented Generation, Reservoir Computing, Code Generation, Question Answering, LLM, RAG, QA

## I. INTRODUCTION

Large Language Models (LLMs) are transformer-based models [1] designed to generate text, that users interact with using natural language. These models are pre-trained on a large quantity of data covering a variety of domains and linguistic styles [2]. Training data is usually imported from web pages, newspaper articles, books, documentation or literature [3] [4] [5]. Llama3 [6] was trained on 15 trillion (1.5 × 10¹³) tokens. However, training on such large datasets requires significant computational resources, raising concerns about time, cost, and energy consumption [7].

Training these models on large code datasets enables them to assist users and developers, showing strong potential for code generation. A notable example is *GitHub Copilot* [8], an assistant designed to provide suggestions, error corrections, and autocompletions of code. It is powered by OpenAI's *Codex* model [9], a general purpose programming model. Copilot analyzes the context in which code is written, and generates contextually relevant suggestions in real-time, potentially accelerating the coding process.

However, one major problem with LLMs is when the model generates incorrect or unfounded information. This phenomenon is called hallucination [10]. It is a particularly

concerning problem in specialized or underrepresented domains in the training dataset, like Reservoir Computing [11]. As such, even if ChatGPT-4o [12] knows what a reservoir is, it could first confuse it with a water reservoir. Even when clarified within the context of machine learning, it will not always give an accurate answer, and it could provide answers that seems plausible but are actually incorrect.

Reservoir Computing models are not mainstream, despite their performance in different tasks, particularly those involving small sequential datasets or challenging corpora with complex non-linear variable interactions such as COVID hospitalization predictions [13]. This under-representation can make it difficult for users, especially those new to the field, to fully appreciate and harness the potential of Reservoir Computing, and in fact to efficiently parametrize reservoir models.

ReservoirPy [14]–[16] is a Python library that allows users to easily create and manipulate Reservoir Computing models. But, ReservoirPy users can face challenges when trying to configure reservoir models to understand the underlying intuitions and correctly parametrize the models. Moreover, reading the full documentation can be time-consuming, especially for new users. An interactive assistant may offer a more intuitive and accessible alternative to static documentation, helping users efficiently locate specific features without getting lost in the API. More generally, Reservoir Computing needs some expertise to properly set up a model. For instance, hyperparameter tuning could be a challenge for some tasks<fnref n="1" />, and ReservoirPy propose hyperparameter tutorials [17].

In the following, we propose various versions of an improved LLM augmented with code and documents. Then, we compare its performance with its base model and other mainstream models. Finally, we discuss the strengths and limitations of this approach.

## II. METHODS

### A. Embeddings and Simple ChatBot

ReservoirChat development began with a simple chatbot designed to answer 245 predefined questions (see GitHub

<footnote n="1">¹For instance, there is the misconception that values above 1 should not be explored for the *spectral radius* because of theoretical insights that are not well understood on the echo state property.</footnote>

<footnote>* These authors are co-first authors. † Corresponding author.</footnote>
repo), with their corresponding answers. The goal was to determine if a simple application, without the involvement of text generator (LLM decoder), could be sufficient. The entire database was converted into vectors using text embeddings, in our case according to the *nomic-embed-text-v1.5* [18] model (LLM encoder) from Nomic-AI with *LM Studio*. Each user-submitted question was vectorized and compared with the database through a cosine similarity process, in order to make correlations between the questions and the database. Based on the closest match, a response would be selected and delivered to the user. This basic approach becomes more effective as the database grows.

When a user submitted a query, the chatbot retrieved the top five most similar embeddings based on cosine similarity between the query embedding and the database of prepared questions.

The system's limitations became apparent when users asked questions that were not explicitly covered in the database. This issue was exacerbated when handling coding-related questions, where even a slight variation in the code or phrasing of the question could result in the chatbot failing to find a suitable match. This revealed the need for a more sophisticated system capable of handling a wider range of queries, including those that required deeper contextual understanding or more complex reasoning challenges. This preliminary model served as a baseline, limited to simple, predictable questions.

## B. Retrieval-Augmented Generation and ReservoirRag

A more elaborate approach consists in enhancing an LLM with a database. As stated previously, hallucination occurs when LLMs generate incorrect, but sometimes plausible answers, due to a lack of factual basis. Retrieval-Augmented Generation (RAG) [19] [20] can mitigate this issue without requiring additional model training by dynamically retrieving relevant information from external documentation sources before generating a response, provided the retrieved data has been properly validated. However, if incorrect sources are introduced, RAG will propagate these errors, hence making careful conservation of the knowledge base essential. Assuming the database remains up-to-date, RAG can be easily adjusted with new information at a significantly lower computational cost compared to retraining an entire model. Since RAG influences the accuracy and reliability of responses, selecting an appropriate LLM remains a critical decision, as some models offer superior multilingual capabilities while others excel in coding assistance.

RAG requires the database to be prepared and cut into chunks. These chunks of text provide a basis for generating responses, treated as text embeddings, and correlated according to the previous model. Chunk size is defined by the user depending on the context and parameters. It is possible, for example, to choose segments of 10 lines, entire paragraphs, or even complete portions of code. In addition, it is sometimes appropriate to overlap chunks to maintain context coherence.

Thus, the chatbot evolved into ReservoirRAG, when we decided to connect Codestral-22B [21] to a RAG. Codestral

is a multilingual model developed by Mistral, known for its effective handling of coding queries. The base data consists of documents, including the ReservoirPy documentation, relevant papers about Reservoir Computing, and code samples. After processing, embeddings are generated from these documents and stored in a CSV file alongside their content. These pre-computed embeddings are then loaded using the *pandas* library and organized into a *Frame*. Some additional documents were processed in the same manner, but reserved as external data for RAG.

Again, embedding relevance was based on the same test as before, with a 0.75 correlation threshold. This implementation ensures that only the most relevant data is considered, enhancing response accuracy. Once the relevant documents are identified, they are incorporated into the LLM's response generation process as part of the contextual information, alongside the conversation history, enabling the model to retain memory of previous queries and responses. For queries related to coding, the additional custom document codes.md, is added to the database, containing various code snippets and samples from the ReservoirPy GitHub. This feature is particularly important for coding-related queries, as even minor errors in generated code could lead to incorrect answers.

## C. Knowledge graph, GraphRAG and ReservoirChat

A Knowledge Graph (Figure 1) [22] is a structured representation of a dataset that organizes information into entities and their relationships, represented respectively as nodes and edges. Knowledge graphs allow LLMs to associate different concepts in a more qualitative manner, improving the contextual and semantic accuracy of answers. Unlike simply implementing RAG, this method requires preprocessing the documents during the initial creation of a graph, which can become time and resource intensive for a complete and thorough result. It is nevertheless lighter than retraining the entire model.

The GraphRAG [23] method, developed by Microsoft, stands out for its ability to handle a large and complex volume of data, in the form of corpora, such as scientific papers. Where traditional RAG shines when it comes to specific questions, GraphRAG is more versatile, and if effective at answering both specific questions, and broader queries about the general theme of a corpus.

According to the methodology (Figure 3) described by [23], the knowledge graph is constructed starting from a database of documents, which are cut into chunks as detailed before. Using LLM-driven prompts, the system identifies named entities and the relationships between them. This is repeated in several rounds to ensure that all relevant entities are captured. Each individual element is summarized according to a domain-tailored summarizing process. Then, the system builds an undirected graph in which each node represents an entity, and each edge captures the relationship between two entities. The edges are weighted based on the frequency and strength of the relationships. Algorithms like Leiden [24] are used to partition the newly created graph, detecting clusters of
<figure><img src="image_2.png" /><figcaption>Fig. 2. Zoom of the graph. We can see the links between reservoirpy and other entities</figcaption></figure>

<figure><img src="image_3.png" /></figure>

closely related nodes within the graph. These clusters, also known as communities, reflect topics or themes that are highly interconnected (Figure 2). A summary is later generated for each community, helping to create partial answers to user queries by drawing from multiple related entities. These partial or local answers may be relevant on their own, or summarized even further into a so-called global answer. In the case of ReservoirChat and its final version, it was more appropriate to mainly utilize local answers, as they provide more focused and detailed information than a global response. While more comprehensive, global responses tend to be less precise, which is intuitively less desirable for the scientific and educational objectives of ReservoirChat.

Several versions of ReservoirChat were created with varying content and database sizes (Figure 4). The Basic version includes resolved issues related to ReservoirPy, its complete documentation and code, along with code samples, resulting in a corpus of 70 documents. The Little version includes

<figure><img src="image_4.png" /><figcaption>Fig. 4. Comparison of training documents used for each ReservoirChat and NotebookLM versions</figcaption></figure>

<figure><img src="image_5.png" /></figure>

10 additional research papers about Reservoir Computing. Medium has 10 more research documents appended to its database, including a PhD thesis. Finally, Big includes all previous resources with 10 additional scientific papers, and a compilation of 245 prepared questions and answers, including 55 code-related questions, and 195 about various concepts related to Reservoir Computing and ReservoirPy. The Big version is the one currently available on the website.

However, GraphRAG also has its limitations. The construction of the permanent knowledge graph requires the precise extraction of entities and relations from the source documents. This requires additional data preprocessing to guarantee the quality of the graph. It also needs to be regularly updated with new information to stay relevant, which can be computationally expensive.

## D. Model and web interface implementations

The user interface (Figure 5) can be accessed at https://chat.reservoirpy.inria.fr/). In addition, code and most documents to create the various versions of ReservoirChat models can be found in the following GitHub repository: https://github.com/Naowak/ReservoirChat/. Some documents that can be freely accessed elsewhere (such as scientific publications content) were not included. An Appendix with benchmark questions is also available at the same URL.
<figure><img src="image_6.png" /><figcaption>Fig. 5. ReservoirChat<sub>Big</sub> Interface</figcaption></figure>

## E. Evaluation method

Response quality in natural language is complex to evaluate, hence the need to consider a systematic approach. Human evaluation is not preferred, as it would both be highly time-consuming and require expertise, which is costly, in addition to being vulnerable to subjectivity and cognitive bias. LLM-based evaluation was also excluded, as there are currently no LLM specifically trained about ReservoirPy and Reservoir Computing, therefore leading to potential imprecision and unreliability.

Benchmarking was the chosen method, being the most objective one. A set of questions, written by a Reservoir Computing expert, were given to the LLM. The model was tasked with selecting the correct answer from 4 suggestions.

In the following experiment, we compared every model of ReservoirChat we created with ChatGPT-4o, Llama3, Codestral and NotebookLM [25] (based on Gemini 1.5 [26]). Only ReservoirChat and NotebookLM were fed with documents about Reservoir Computing and ReservoirPy. ChatGPT-4o, Llama3 and Codestral relied only on their own knowledge and training methods to answer. We tried different sets of documents for NotebookLM. NotebookLM<sub>Core</sub> includes the same documents as ReservoirChat<sub>Basic</sub> except the documentation. NotebookLM<sub>Other</sub> includes every document not included in the core version, this was added to test the influence of the core model compared to the other model. The NotebookLM<sub>Big</sub> represents all the documents like ReservoirChat<sub>Big</sub>. For every model a temperature of 0.1 was used to minimize stochastic effects, as preliminary tests showed it was a good compromise and close to a temperature of 0<sup>2</sup> which is often preferred [27]. However, ChatGPT-4o does not offer the possibility to change temperature, nor does NotebookLM.

The benchmark consisted of 20 knowledge-based questions and 14 coding-related questions, including 8 debugging tasks. To minimize bias, each question was asked independently, without prior context. A standardized prompt designed to reduce any disparity was provided to ensure fair comparison across all models :

"You will be given a question with four answer options labeled A, B, C, and D. Please respond using the library ReservoirPy with only the letter (A, B, C, or D) that is the correct answer."

Each question were asked 3 times, therefore a score of 0, 0.33, 0.66, or 1 respectively indicates that the model gave the correct answer zero, once, twice or three times out of three attempts. The total score of a model is the addition of the individual score for each question, respectively on a scale from 0 to 20 for the first benchmark, then from 0 to 14 for the second, with 0 indicating the lowest possible performance.

# III. RESULTS

## A. Brief Recapitulation

<figure><img src="image_7.png" /><figcaption>Fig. 7. Results of code and debug questions from the 14 questions benchmark for ChatGPT 4o (GPT 4o), Llama3, Codestral, NotebookLM (NLM) and ReservoirChat (RC).</figcaption></figure>

<figure><img src="image_8.png" /></figure>

In this section, we aim to compare ReservoirChat, which is based on the Codestral architecture, to various classical models such as LLaMA3 and GPT-4o, as well as other models capable of learning from external databases, such as NotebookLM. Specifically, the results focus on evaluating

<footnote n="2">²Temperature in an LLM controls freedom in responses, on a scale from 0 to 1, 0 resulting in more deterministic answers with no variation. This setting influences the model's creativity in generating answers.</footnote>
two important aspects: knowledge-based questions related to Reservoir Computing concepts and coding/debugging tasks involving the ReservoirPy library. We also examine how incorporating external resources, such as scientific papers and documentation, impacts the performance of several models. The evaluation uses a custom-made benchmark developed to assess the accuracy and consistency of responses in the context of Reservoir Computing (see Methods).

## B. Analysis of Knowledge-Based Performance

Regarding knowledge questions (Figure 6), Llama3 and Codestral have comparable score of 12.66 and 11, respectively. All ReservoirChat models output higher scores than the default Codestral, increasing with each addition of documents from a score of 15 for the Basic model, up to a score of 18.66 with the ReservoirChat<sub>Big</sub>. Performance improves proportionally with the number of documents added to ReservoirChat's database. Further improvements could be achieved by adding more documents and fine-tuning the model. Also ChatGPT-4o and all NotebookLM versions obtain a score of 20. This perfect score highlights a superior ability to answer knowledge-based questions compared to other models.

## C. Analysis of Code and Debug Performance

On the other hand, code and debug questions (Figure 7) have an overall much lower performance for all models, with none having or approaching a perfect score. ChatGPT-4o performed moderately at 7. NotebookLM ranges from 7.66 to 8.66. It is interesting to note that the Core version, trained on resolved issues, has a worse score than the Other version which includes ReservoirPy documentation and scientific papers about reservoirs and the library. The difference, slightly in favor of NotebookLM<sub>Other</sub>, equals to 8.33 - 7.66 = 0.67, or 4.8%, could indicate that an LLM trained on a whole language documentation is more reliable in coding assistance than one only trained on resolved issues. NotebookLM<sub>Big</sub> outputs a similar score of 8.66. These results may be biased, as in real-world scenarios, developers often face novel issues not covered by existing resolved cases, potentially lowering NotebookLM<sub>Core</sub>'s performance.

Llama3 yields better results than Codestral, with a score of 6 against 5. Given that Codestral is known for its reliability in coding assistance, this result surprising, and suggest that as ReservoirPy is a recent library, the model may not have been trained on a lot of data apart from the documentation in itself. Codestral's usual reliability must then be founded on training with larger or different type of dataset. This discrepancy may also be due to how the questions were posed, or the fact that Codestral's training corpus may focus less on English and more on other languages.

ReservoirChat models also outperform Codestral, obtaining a score of 9.66 for the Basic and Little Models, 7 for Medium, and 8.66 for Big. These results may be indicative of the influence of other non-code related documents on the Knowledge Graph. The larger the database, the more complex and numerous the connections between entities are, potentially

affecting some answers. Also, Medium having the lowest score for coding questions, out of all the ReservoirChat versions tested, could indicate that there is a limit up to which more data confuses the model but there is not enough data to adjust its own performance yet.

Finally, it is interesting to note when asked three times, ChatGPT-4o's provided different answers to 50% of the coding questions, suggesting that it has a high temperature. In comparison, when asked three times, ReservoirChat<sub>Big</sub> provided different answers to only 21.4% of the coding questions. Also, questions were arranged into categories and levels of difficulty, but no evident differences were observed.

ReservoirChat<sub>Big</sub> is slightly outperformed (Table I and II) by ChatGPT 4o and NotebookLM<sub>Big</sub> in the case of knowledge questions, with a 6.70% lower score in both cases. However, its coding score remains comparable to NotebookLM<sub>Big</sub>, with no difference, and is better by 23.71% in favor of ReservoirChat<sub>Big</sub> in the case of ChatGPT 4o. In other cases, ReservoirChat<sub>Big</sub> significantly outperforms other major models, achieving up to a 43.54% increase in knowledge scores and a 73.20% improvement in coding compared to Codestral. These results show that even if ReservoirChat doesn't achieve a perfect score, it clearly improves upon Codestral when responding to Reservoir specific questions. These performance differences were calculated as percentage rates based on the total score of each model compared to each ReservoirChat models.

## D. Correlation Analysis Across Models

<figure><img src="image_9.png" /><figcaption>Fig. 8. Pearson correlation matrix of every model for the knowledge related questions</figcaption></figure>

For each model, we respectively concatenated the 3 answers they gave for the knowledge-related and the code-related questions into two vectors, and we computed the Pearson correlation between all of them. We can see those results
<table><caption>TABLE I
SCORE DIFFERENCE TABLE OF EVERY RESERVOIRCHAT MODELS COMPARED TO CODESTRAL, NOTEBOOKLM<sub>Core</sub>, NOTEBOOKLM<sub>Other</sub> AND NOTEBOOKLM<sub>Big</sub>. HOW TO READ: GIVEN AN EXISTING SOLUTION (OTHER MODELS IN COLUMNS), HOW MUCH DO WE GAIN/LOOSE (IN SCORE POINTS) IF WE CHANGE FOR OUR SOLUTION (OUR MODELS IN LINES). FORMULA: OUR-MODEL[LINES] - OTHER-MODELS[COLUMNS].</caption><thead><tr><th rowspan="2">Model</th><th colspan="2">Codestral</th><th colspan="2">ChatGPT 4o</th><th colspan="2">NotebookLM<sub>Core</sub></th><th colspan="2">NotebookLM<sub>Other</sub></th><th colspan="2">NotebookLM<sub>Big</sub></th></tr><tr><th>Knowledge</th><th>Coding</th><th>Knowledge</th><th>Coding</th><th>Knowledge</th><th>Coding</th><th>Knowledge</th><th>Coding</th><th>Knowledge</th><th>Coding</th></tr></thead><tbody><tr><td>ReservoirChat<sub>Basic</sub></td><td>2,00</td><td>4,66</td><td>-5,00</td><td>2,66</td><td>-5,00</td><td>2,00</td><td>-5,00</td><td>1,33</td><td>-5,00</td><td>1,00</td></tr><tr><td>ReservoirChat<sub>Little</sub></td><td>3,33</td><td>4,66</td><td>-3,67</td><td>2,66</td><td>-3,67</td><td>2,00</td><td>-3,67</td><td>1,33</td><td>-3,67</td><td>1,00</td></tr><tr><td>ReservoirChat<sub>Medium</sub></td><td>5,00</td><td>2,00</td><td>-2,00</td><td>0,00</td><td>-2,00</td><td>-0,66</td><td>-2,00</td><td>-1,33</td><td>-2,00</td><td>-1,66</td></tr><tr><td>ReservoirChat<sub>Big</sub></td><td>5,66</td><td>3,66</td><td>-1,34</td><td>1,66</td><td>-1,34</td><td>1,00</td><td>-1,34</td><td>0,33</td><td>-1,34</td><td>0,00</td></tr></tbody></table>

<table><caption>TABLE II
PERFORMANCE TABLE OF EVERY RESERVOIRCHAT MODELS COMPARED TO CODESTRAL, NOTEBOOKLM<sub>Core</sub>, NOTEBOOKLM<sub>Other</sub> AND NOTEBOOKLM<sub>Big</sub>. HOW TO READ: GIVEN AN EXISTING SOLUTION (OTHER MODELS IN COLUMNS), HOW MUCH DO WE GAIN/LOOSE (IN PERCENTAGE) IF WE CHANGE FOR OUR SOLUTION (OUR MODELS IN LINES). FORMULA: 100 * (OUR-MODEL[LINES] - OTHER-MODELS[COLUMNS]) / OTHER-MODELS[COLUMNS].</caption><thead><tr><th rowspan="2">Model</th><th colspan="2">Codestral</th><th colspan="2">ChatGPT 4o</th><th colspan="2">NotebookLM<sub>Core</sub></th><th colspan="2">NotebookLM<sub>Other</sub></th><th colspan="2">NotebookLM<sub>Big</sub></th></tr><tr><th>Knowledge (%)</th><th>Coding (%)</th><th>Knowledge (%)</th><th>Coding (%)</th><th>Knowledge (%)</th><th>Coding (%)</th><th>Knowledge (%)</th><th>Coding (%)</th><th>Knowledge (%)</th><th>Coding (%)</th></tr></thead><tbody><tr><td>ReservoirChat<sub>Basic</sub></td><td>15,38</td><td>93,20</td><td>-25,00</td><td>38,00</td><td>-25,00</td><td>26,11</td><td>-25,00</td><td>15,97</td><td>-25,00</td><td>11,55</td></tr><tr><td>ReservoirChat<sub>Little</sub></td><td>25,62</td><td>93,20</td><td>-18,35</td><td>38,00</td><td>-18,35</td><td>26,11</td><td>-18,35</td><td>15,97</td><td>-18,35</td><td>11,55</td></tr><tr><td>ReservoirChat<sub>Medium</sub></td><td>38,46</td><td>40,00</td><td>-10,00</td><td>0,00</td><td>-10,00</td><td>-8,62</td><td>-10,00</td><td>-15,97</td><td>-10,00</td><td>-19,17</td></tr><tr><td>ReservoirChat<sub>Big</sub></td><td>43,54</td><td>73,20</td><td>-6,70</td><td>23,71</td><td>-6,70</td><td>13,05</td><td>-6,70</td><td>3,96</td><td>-6,70</td><td>0,00</td></tr></tbody></table>

<figure><img src="image_10.png" /><figcaption>Fig. 9. Pearson correlation matrix of every model for the code related questions</figcaption></figure>

in the Figure 8 and 9 that respectively show the knowledge-related and code-related correlation matrices. You can find the correlation matrix on the whole questions in the Appendix (available on our repository).

As we can expect, models that perform well are correlated together, because there is only one good answer per question. So, for the knowledge part where lots of models obtained good results, it is not a surprise to see that a lot of models are well correlated together, as we can see with GPT-4o, and all NotebookLM versions which have a correlation score of 1, as

they all answered perfectly on all the knowledge questions. Conversely, the less a model performs, the less it will be correlated with the others, as we can see with Codestral. One exception is Llama3, which does not perform well on the knowledge related questions, but is a bit correlated with other high-performing models.

On the other hand, when we look at the code-related matrix correlation, we can observe two major groups of models: those related to NotebookLM and those related to ReservoirChat. In both groups, models are well correlated together, which is expected, because they respectively derive from the same base. We can also observe this with Codestral that is a bit correlated to ReservoirChat but not at all to other models. In fact, Codestral appears a bit isolated, with correlation score close to 0 with every model except ReservoirChat and Llama3. This might be due to the fact that Codestral is the only model specifically trained for coding tasks. As an unexpected results, we also observe a correlation between Llama3 and NotebookLM Other which might be due to the documents there were fed with, and the near-zero correlation between ReservoirChat Medium and Codestral.

## E. Summary of Findings and Future Directions

These results are encouraging for RAG based knowledge graph methods. Despite the base model's limitations, our approach improves its performance in domain-specific tasks, particularly in Reservoir Computing.

## IV. USER DATA COLLECTION WITH BIG RESERVOIRCHAT

Over three months, 130 users interacted with ReservoirChatBig. Some questions were directly related to the ReservoirPy library, while others required broader coding knowledge beyond the preloaded database, relying on
Codestral’s base model. On average, people asked between two to five questions, indicating that while the tool raises curiosity, it’s not yet fully utilized as an assistant.

We analyzed data collected to get inspiration on which Q&A we could put in the benchmark. In the following section, we present a selection of two representative user questions and the corresponding responses given by ReservoirChat<sub>Big</sub> between August and November.

### A. Example of knowledge question

**User:**

How can a random matrix make such results? Why does it work? How can it store such an amount of information?

**ReservoirChat:**

A random matrix can make such results because it is a matrix that is generated using random values. This randomness can lead to the creation of complex patterns and structures that can capture and store a significant amount of information.

The ability of a random matrix to store information is a result of its dimensionality and the distribution of its values. A high-dimensional random matrix can potentially have a large number of unique configurations, which can be used to represent a wide range of data. The distribution of values in the matrix also plays a role, as certain distributions can lead to more efficient packing of information.

However, it's important to note that the effectiveness of a random matrix in storing information can vary depending on the specific characteristics of the data and the task at hand. While random matrices can be powerful tools, they may not always be the best choice for every situation.

### B. Example of code question

**User:**

Code me the initialization of a reservoir

**ReservoirChat:**

Sure, I can help you with that.

```python
from reservoirpy.nodes import Reservoir, Ridge

# Define the reservoir size and input
dimension
reservoir_size = 100
inputDimension = 1

# Initialize the reservoir with random weights
reservoir = Reservoir(reservoir_size,
                       input_dim, 42)

# Initialize the readout with Ridge regression
readout = Ridge(ridge=1e-5)
```

<caption>Fig. 10. Simple code produced by ReservoirChat Big for the prompt “Code me the initialization of a reservoir”.</caption>

In Figure 10, on can see a simple example of how you might initialize a reservoir using the ReservoirPy library in Python. This example uses random initialization. In this code, we first import the necessary classes from the ReservoirPy library.

We then define the size of the reservoir and the dimension of the input. Next, we initialize the reservoir with random weights using the 'Reservoir' class. Finally, we initialize the readout with Ridge regression using the 'Ridge' class.

## V. DISCUSSION

To summarize, there is a clear need for a tool capable of assisting users working with Reservoir Computing, an underrepresented technology in the literature. While traditional LLMs can partially fulfill this task, they tend to hallucinate and provide incorrect results on their own, especially in specialized areas such as Reservoir Computing. Moreover, even though the ReservoirPy library is acknowledged by the community, there is not as much code available online as for other mainstream libraries such as scikit-learn. Thus, general LLMs do not have enough examples to train on for domain-specific libraries.

We had to make choices during tool development, beginning with Microsoft's GraphRAG library, which was not originally designed to be used with LLMs other than ChatGPT. As a result, we had to identify LLMs and embeddings that match our project. This included requirements such as code generation, answering questions about RCs, available computational power, and support for European languages. In this context, Codestral emerged as a suitable choice [28] [29]. However, running these models locally requires high computing power, and even though Codestral can be considered as a small model with its 22 billions parameters, it still required the use of a GPU (NVIDIA V100 16Go) [30].

ReservoirChat has shown better results on the benchmark in both knowledge-based and coding tasks compared to Codestral, the model on which it is based. Moreover, a larger database intuitively tends to provide an acceptable tradeoff between reliability in answering knowledge-based and code-related questions. Additionally, methods implemented in ReservoirChat<sub>Big</sub> do not produce aberrant outputs, nor responses entirely different from those of other models. Finally, ReservoirChat<sub>Big</sub> fulfills its objective, by being able to relevantly answer both knowledge and coding questions towards Reservoir Computing and ReservoirPy, with higher reliability than other tested commonly used LLMs.

It is important to note that GraphRAG was originally developed to extract concepts and relationships from narrative texts. However, the concepts involved in the challenges we encountered, such as code related tasks or technical knowledge in Reservoir Computing, are significantly different and may require prompts tailored to these domains, rather than those originally designed for GraphRAG. A potential improvement could be to refine GraphRAG's prompts to better extract the concepts and relationships relevant to our areas of interest.

This approach could serve as a model for making technical documentation more interactive. It could represents a significant advancement in how users engage with specialized libraries and apply them in their own projects. With further refinements, ReservoirChat could become a reliable and practical solution for every Reservoir Computing developer. Fine-tuning hyperparameters and system settings could help optimize
response time and quality. Furthermore, careful selection of
the LLM remains a critical component of system performance.

Additional testing should also be considered to ensure
safety, no inappropriate response should be generated even
in unanticipated use cases. Data fairness should be verified, as
always, to avoid any misuse of intellectual property, as it is an
important concern for LLM pretraining. The knowledge graph
method could also be compared to alternative approaches in
terms of answer interpretability, server resource requirements,
and cost of minimal configuration for acceptable user experi-
ence.

The ReservoirChat tool, based on a GraphRAG approach
combined with a specialized knowledge base, addresses the
practical needs of the Reservoir Computing community. It
currently simplifies the learning and application of libraries
like ReservoirPy, notably by assisting with debugging and
suggesting relevant hyperparameters (e.g., spectral radius, leak
rate). For instance, a Phd student tackling their first Echo
State Network project can turn to ReservoirChat as a technical
partner for configuring and optimizing their network, while an
engineer seeking to deploy Reservoir Computing modules in a
production environment can quickly resolve compatibility and
performance issues.

Moving forward, continuously adding new scientific pub-
lications to the knowledge graph will allow ReservoirChat
to stay aligned with advances in the field (e.g., hybrid ar-
chitectures, photonic or spintronic physical reservoirs, and
Deep RC). This would enable researchers to interactively
consult recent papers and code prototypes to identify promis-
ing configurations more efficiently. Moreover, the graph-based
approach offers improved traceability and interpretability: by
retracing inference paths, users can not only obtain more
reliable responses but also deepen their understanding of key
Reservoir Computing concepts. These developments position
ReservoirChat as a versatile tool that supports research, fosters
innovation, and serves as an interactive documentation and
educational resource for the Reservoir Computing community.

REFERENCES

[1] A. Vaswani, N. Shazeer, N. Parmar, J. Uszkoreit, L. Jones, A. N. Gomez, Ł. Kaiser, and I. Polosukhin, "Attention is all you need," *Advances in neural information processing systems*, vol. 30, 2017.

[2] J. Achiam, S. Adler, S. Agarwal, L. Ahmad, I. Akkaya, F. L. Aleman, D. Almeida, J. Altenschmidt, S. Altman, S. Anadkat et al., "Gpt-4 technical report," arXiv preprint arXiv:2303.08774, 2023.

[3] A. Radford, "Improving language understanding by generative pre-training," 2018.

[4] A. Radford, J. Wu, R. Child, D. Luan, D. Amodei, I. Sutskever et al., "Language models are unsupervised multitask learners," *OpenAI blog*, vol. 1, no. 8, p. 9, 2019.

[5] T. Brown, B. Mann, N. Ryder, M. Subbiah, J. D. Kaplan, P. Dhariwal, A. Neelakantan, P. Shyam, G. Sastry, A. Askell et al., "Language models are few-shot learners," *Advances in neural information processing systems*, vol. 33, pp. 1877-1901, 2020.

[6] A. Dubey, A. Jauhri, A. Pandey, A. Kadian, A. Al-Dahle, A. Letman, A. Mathur, A. Schelten, A. Yang, A. Fan et al., "The llama 3 herd of models," arXiv preprint arXiv:2407.21783, 2024.

[7] A. Singh, N. P. Patel, A. Ehtesham, S. Kumar, and T. T. Khoei, "A survey of sustainability in large language models: Applications, economics, and challenges," arXiv preprint arXiv:2412.04782, 2024.

[8] S. Peng, E. Kalliamvakou, P. Cihon, and M. Demirer, "The impact of ai on developer productivity: Evidence from github copilot," arXiv preprint arXiv:2302.06590, 2023.

[9] M. Chen, J. Tworek, H. Jun, Q. Yuan, H. P. D. O. Pinto, J. Kaplan, H. Edwards, Y. Burda, N. Joseph, G. Brockman et al., "Evaluating large language models trained on code," arXiv preprint arXiv:2107.03374, 2021.

[10] L. Huang, W. Yu, W. Ma, W. Zhong, Z. Feng, H. Wang, Q. Chen, W. Peng, X. Feng, B. Qin et al., "A survey on hallucination in large language models: Principles, taxonomy, challenges, and open questions," arXiv preprint arXiv:2311.05232, 2023.

[11] H. Jaeger, “The “echo state” approach to analysing and training recurrent neural networks-with an erratum note,” *Bonn, Germany: German National Research Center for Information Technology GMD Technical Report*, vol. 148, no. 34, p. 13, 2001.

[12] A. Hurst, A. Lerer, A. P. Goucher, A. Perelman, A. Ramesh, A. Clark, A. Ostrow, A. Welihinda, A. Hayes, A. Radford et al., “Gpt-4o system card,” arXiv preprint arXiv:2410.21276, 2024.

[13] T. Ferté and et al., "Reservoir Computing for Short High-Dimensional Time Series: an Application to SARS-CoV-2 Hospitalization Forecast," in *ICML'24: Proceedings of the 41st International Conference on Machine Learning*, ser. Proceedings of Machine Learning Research, vol. 235, Vienna, Austria, Jul. 2024, pp. 13 570–13 591.

[14] N. Trouvain, L. Pedrelli, T. T. Dinh, and X. Hinaut, "Reservoirpy: an efficient and user-friendly library to design echo state networks," in *International Conference on Artificial Neural Networks*. Springer, 2020, pp. 494–505.

[15] N. Trouvain, N. Rougier, and X. Hinaut, "Create efficient and complex reservoir computing architectures with reservoirpy," in *International Conference on Simulation of Adaptive Behavior*. Springer, 2022, pp. 91–102.

[16] N. Trouvain and X. Hinaut, “reservoirpy: A Simple and Flexible Reservoir Computing Tool in Python,” Jun. 2022, working paper or preprint.

[17] X. Hinaut and N. Trouvain, “Which hype for my new task? hints and random search for echo state networks hyperparameters,” in *International Conference on Artificial Neural Networks*. Springer, 2021, pp. 83–97.

[18] Z. Nussbaum, J. X. Morris, B. Duderstadt, and A. Mulyar, “Nomic embed: Training a reproducible long context text embedder,” arXiv preprint arXiv:2402.01613, 2024.

[19] P. Lewis and et al., "Retrieval-augmented generation for knowledge-intensive nlp tasks," in *Advances in Neural Information Processing Systems*, H. Larochelle and et al., Eds., vol. 33. Curran Associates, Inc., 2020, pp. 9459–9474.

[20] Y. Gao, Y. Xiong, X. Gao, K. Jia, J. Pan, Y. Bi, Y. Dai, J. Sun, and H. Wang, "Retrieval-augmented generation for large language models: A survey," arXiv preprint arXiv:2312.10997, 2023.

[21] A. Mistral, “Codestral: Hello, world,” *Section: news*, 2024.

[22] Z. Chen, Y. Wang, B. Zhao, J. Cheng, X. Zhao, and Z. Duan, "Knowledge graph completion: A review," *Ieee Access*, vol. 8, pp. 192 435–192 456, 2020.

[23] D. Edge and et al., "From local to global: A graph rag approach to query-focused summarization," 2024.

[24] V. A. Traag, L. Waltman, and N. J. van Eck, "From louvain to leiden: guaranteeing well-connected communities," *Scientific Reports*, vol. 9, no. 1, Mar. 2019.

[25] Google, "Introducing notebooklm," *Section: news*, 2024.

[26] G. Team, P. Georgiev, V. I. Lei, R. Burnell, L. Bai, A. Gulati, G. Tanzer, D. Vincent, Z. Pan, S. Wang et al., "Gemini 1.5: Unlocking multimodal understanding across millions of tokens of context," arXiv preprint arXiv:2403.05530, 2024.

[27] M. Renze and E. Guven, "The effect of sampling temperature on problem solving in large language models," arXiv preprint arXiv:2402.05201, 2024.

[28] A. Q. Jiang, A. Sablayrolles, A. Mensch, C. Bamford, D. S. Chaplot, D. d. I. Casas, F. Bressand, G. Lengyel, G. Lample, L. Saulnier et al., "Mistral 7b," arXiv preprint arXiv:2310.06825, 2023.

[29] A. Q. Jiang, A. Sablayrolles, A. Roux, A. Mensch, B. Savary, C. Bamford, D. S. Chaplot, D. d. I. Casas, E. B. Hanna, F. Bressand et al., "Mixtral of experts," arXiv preprint arXiv:2401.04088, 2024.

[30] Y. Bendi-Ouis, D. Dutarte, and X. Hinaut, "Deploying open-source large language models: A performance analysis," arXiv preprint arXiv:2409.14887, 2024.
ACKNOWLEDGMENTS

We thank the following grants: the Inria AEx BrainGPT project (https://www.inria.fr/en/braingpt) and the ANR DeepPool ANR-21-CE23-0009 project (https://anr.fr/Projet-ANR-21-CE23-0009).

Experiments presented in this paper were carried out using the PlaFRIM experimental testbed, supported by Inria, CNRS (LABRI and IMB), Université de Bordeaux, Bordeaux INP and Conseil Régional d'Aquitaine (see https://www.plafrim.fr).

APPENDIX

<figure><img src="image_11.png" /><figcaption>Fig. 11. Pearson correlation matrix of every model for the whole questions</figcaption></figure>

For each model, we concatenated the 3 answers they made for all questions of the benchmark into one vector, and we computed the Pearson correlation between all of them, giving us the Heatmat of correlation that we can see in Figure 11.

<caption>Similarity Rate</caption>

<table><caption>Fig. 12. Similarity Rate Table between the answers of ReservoirChat<sub>Big</sub> and ChatGPT-4o, Llama3, Codestral and NotebookLM<sub>Big</sub></caption><thead><tr><th>%</th><th>Knowledge</th><th>Code</th></tr></thead><tbody><tr><td>Mean</td><td>81,5</td><td>62,8</td></tr><tr><td>Median</td><td>75,0</td><td>66,8</td></tr></tbody></table>

Big ReservoirChat outputs answers significantly similar to the other models, with a correlation rate ranging from 62.8% to 81.5%, with coherent medians, not generating any remarkable aberrant error that no other models generated. Therefore, Even though, it has overall best performance than the other models, it seems to give the same good answers and errors than the others. For each question, the mean of the 4 other models answers were divided by the ReservoirChat<sub>Big</sub> score. Then, each value were put into a series to calculate its mean and median.
## RESERVOIRCHAT: Q&A BENCHMARK

Important: there is only one unique correct answer for each question.

### Knowledge questions (Beginner)

#### 1. What is an echo state network?

* A. A place where anything is kept in store.

* B. A recurrent neural network in which usually only the output neurons are trained.

* C. A black box component that receives an input signal to be read out and mapped by another process.

* D. A large natural or artificial lake used as a source of water supply.

Correct: B

#### 2. What is Reservoir Computing?

* A. A machine learning paradigm for timeseries.

* B. The construction of a computer model of a petroleum reservoir.

* C. A branch of fluid dynamics that studies the design of tank trucks to reduce rollover accidents.

* D. It is only a computational framework in which all the computations are done by a pool of water.

#### 3. What is call the readout? (in the context of Reservoir Computing)

* A. A linear regression that models the Markovian process of a support vector machine.

* B. An efficient way for input processing in order to read only part of the inputs.

* C. A black box component that receives an input signal to be read out and mapped back to the input for predictive coding.

* D. A trainable layer that extracts the dynamics of a reservoir to produce some desired outputs.

Correct: D

#### 4. On which task is Reservoir Computing known to compete with the state-of-the-art?

* A. Video segmentation.

* B. Natural language processing.

* C. Image recognition.

* D. Chaotic timeseries prediction.

Correct: D

#### 5. On which task is it challenging to apply Reservoir Computing compared to other state-of-the-art methods?

* A. A task with small univariate dataset.

* B. Video segmentation.

* C. Chaotic timeseries prediction.

* D. Classification of timeseries with few classes.

Correct: B

#### 6. Approximately how many neurons are used inside an echo state network?

* A. Around 1 thousand neurons.

* B. Around 100 thousand neurons.

* C. Around 10 neurons.

* D. Around 1 million neurons.

Correct: A

#### 7. What is the purpose of using ridge regression instead of linear regression for the readout?

* A. Reduce the computational cost.

* B. Improve numerical stability.

* C. Improve explainability of the model.

* D. Avoid the exploding/vanishing gradient problem.

Correct: B

#### 8. How are the weights most often initialized in an echo state network?

* A. They can be randomly initialized and then scaled to have a specific spectral radius.

* B. They are tuned according to an autocorrelation Hebbian learning rule.

* C. Trained using a linear regression.

* D. Each neuron is connected to only one input.

Correct: A

### Knowledge questions (Intermediate)

#### 9. What is the difference between 'echo state network' and 'Reservoir Computing'?

* A. Reservoir Computing is a type of recurrent neural network model based on the philosophy of the echo state network.

* B. There is no difference, we can use the terms Reservoir Computing and echo state network indistinctly.

* C. An echo state network is a type of recurrent neural network model based on the Reservoir Computing paradigm.

* D. In Reservoir Computing, the reservoir part is a physical system, in echo state networks, the reservoir part is a recurrent neural network.

Correct: C

#### 10. Are there other forms of Reservoir Computing than echo state networks?

* A. No, an echo state network is not even a form of Reservoir Computing.

* B. Yes, any random kernel method, even those who don't apply to timeseries, are considered to be a form of Reservoir Computing.

* C. No, Reservoir Computing only refers to the philosophy behind echo state networks.

* D. Yes, there are for instance physical reservoirs or liquid state machines, in which the reservoir is a spiking neural network.

Correct: D
11. What is a liquid state machine?

* A. An architecture in which the reservoir part is a pool of spiking neurons.

* B. A physical reservoir in which the reservoir is a reservoir of liquid, usually water.

* C. Liquid state machine and Reservoir Computing designate the same concept.

* D. A computational model of the hippocampus using the Reservoir Computing paradigm.

Correct: A

12. Why is it called 'computing at the edge of chaos'?

* A. Because it is common to add noise (and thus chaos) to the reservoir in order to stabilize its activity.

* B. Because Reservoir Computing works best for chaotic timeseries forecasting.

* C. Because Reservoir Computing often works best when the dynamics of the reservoir are approaching chaotic dynamics, but are not chaotic.

* D. It requires computers to be physically placed at the edge of a chaotic environment, such as a volcano or a kindergarten.

Correct: C

13. What is the 'echo state property'?

* A. The echo state property allows the reservoir to operate with chaotic behavior to enhance computational power.

* B. The ability to memorize past activity and cycle over it (the echo).

* C. The ability to perfectly reconstruct any input signal from the reservoir activity.

* D. The influence of initial states on the reservoir dynamics decays over time, ensuring that the current state primarily reflects recent inputs.

Correct: D

14. What are some of the most important hyper-parameters?

* A. The spectral radius of the recurrent weight matrix, the leak rate, the input scaling.

* B. The spectral radius of the recurrent weight matrix, the reservoir connectivity, the weight distribution.

* C. The spectral radius of the recurrent weight matrix, the reservoir connectivity, the encoding of the input.

* D. The activation function, the reservoir connectivity, the regularization parameter.

Correct: A

Knowledge questions (Advanced)

15. How explainable are Reservoir Computing models?

* A. Reservoir Computing models are generally less explainable due to their reliance on complex, nonlinear dynamics within the reservoir, making it difficult to trace the exact path of information processing.

* B. Reservoir Computing models are fully explainable because they rely on predefined, static patterns that do not change over time.

* C. Reservoir Computing models are highly explainable because they use simple linear transformations that can be easily interpreted.

* D. Reservoir Computing models are completely explainable due to their deterministic nature, which allows for perfect traceability of every computation.

Correct: A

16. To what extent do the results vary between two differently initialized reservoirs?

* A. The results between two differently initialized reservoirs are completely unpredictable and random, regardless of the input data.

* B. The results between two differently initialized reservoirs are always identical because the initialization has no impact on the reservoir's dynamics.

* C. The results between two differently initialized reservoirs can vary somewhat, but the overall performance and behavior of the reservoir are generally robust to different initialisations, provided the reservoir is sufficiently large and well-designed.

* D. The results between two differently initialized reservoirs vary significantly because the initialization determines the exact sequence of outputs.

Correct: C

Knowledge questions (Expert)

17. What is the effective spectral radius?

* A. The real spectral radius of the matrix W, that is always a bit different from the specified spectral radius.

* B. A weighted sum of all eigenvalues norms, that takes into account the distribution of the spectrum.

* C. A value that has similar properties to the spectral radius of a matrix, taking into account the full reservoir equation.

* D. The norm of the singular values for each neuron. It is a way to evaluate the impact of each neuron on the reservoir.

Correct: C

18. What is a deep reservoir?

* A. A deep reservoir is a Reservoir Computing architecture that consists of multiple layers of interconnected reservoirs, allowing for hierarchical processing and the capture of more complex temporal dynamics.

* B. An underground gas or petroleum reservoir that cannot be reached using traditional tools and infrastructure.

* C. A deep reservoir is a reservoir that employs deep learning techniques, such as backpropagation, to train the weights within the reservoir, enhancing its ability to learn from data.

* D. A deep reservoir is a reservoir that uses extremely large and dense weight matrices to store vast amounts of data.

Correct: A
19. What is the use of an orthogonal matrix in the reservoir equation?

* A. An orthogonal matrix can be represented in a condensed form, improving matrix multiplication computation time.

* B. An orthogonal matrix in the reservoir equation is used to prevent any interaction between neurons, maintaining independence.

* C. This is a trick question, there is no point in using an orthogonal matrix.

* D. It augments the memory capacity of the reservoir.

Correct: D

20. What is a Conceptor?

* A. A conceptor is a mathematical function used to compress the data within a reservoir, reducing its dimensionality for faster processing.

* B. A conceptor is a hardware component that accelerates the computation of reservoir dynamics by offloading calculations to a dedicated processor.

* C. A derivation of Reservoir Computing which can store and recall patterns.

* D. A conceptor is a specialized type of neuron within a reservoir that is designed to store and retrieve specific concepts or patterns.

Correct: C

Code questions (not debug)

1. I want to train my echo state network on multiple timeseries that have different lengths. I have seen in the documentation that you can put a 3D numpy array with shape (timeseries, timesteps, dimensions), but it wouldn't work in my case as the timeseries have different lengths.

* A. There is no way to do that in ReservoirPy as it is most probably not a good idea to train a model with different lengths and it would induce unexpected results.

* B. You can pass a list of 2D numpy arrays that represents timeseries. As lists can contain numpy arrays of different shapes, you can specify timeseries with different lengths.

* C. You would have to pad every timeseries with zeros and then concatenate them.

* D. As NumPy doesn't support sparse arrays, it is best to use xarray for this use-case.

Correct: B

2. Make me a reservoir, with 1000 neurons, and with a uniform distribution of weights, and a sparsity of 95%.

* A.

```python
from reservoirpy as rpy
reservoir = rpy.nodes.Reservoir(neurons=1
                                _000, connectivity=0.05, weights="
                                uniform")
```

* B.

```python
from reservoirpy as rpy
reservoir = rpy.nodes.Reservoir(units=1
                                _000, sparsity=0.95, W=rpy.mat_gen.
                                uniform)
```

* C.

```python
from reservoirpy as rpy
reservoir = rpy.Reservoir(units=1_000,
                          rc_connectivity=0.05, distr="uniform")
```

* D.

```python
from reservoirpy as rpy
reservoir = rpy.nodes.Reservoir(units=1
                                _000, rc_connectivity=0.05, W=rpy.
                                mat_gen/uniform)
```

Correct: D

3. Create a model in which there are several reservoirs connected in a chain, and a readout at the end.

* A.

```python
from reservoirpy.nodes import Reservoir,
                          Ridge
model = [Reservoir(100, name="1"),
        Reservoir(100, name="2"),
        Reservoir(100, name="3"),
        Reservoir(100, name="4"),
        Reservoir(100, name="5"), Ridge(
            ridge=1e-5)]
```

* B.

```python
from reservoirpy.nodes import Reservoir,
                          Ridge
model = Reservoir(100, name="1") >>
        Reservoir(100, name="2")
        >> Reservoir(100, name="3") >>
        Reservoir(100, name="4")
        >> Reservoir(100, name="5") >>
        Ridge(ridge=1e-5)
```

* C.

```python
from reservoirpy.nodes import Reservoir,
                          Ridge
model = Reservoir(100) > Reservoir(100) >
        Reservoir(100)
        > Reservoir(100) > Reservoir(100)
        > Ridge(ridge=1e-5)
```

* D.

```python
from reservoirpy.nodes import Reservoir,
                          Ridge
model = Ridge(ridge=1e-5, previous=
                Reservoir(100, name="5",
                    previous=Reservoir(100, name="4",
                    previous=Reservoir(100, name="3",
                    previous=Reservoir(100, name="2",
                    previous=Reservoir(100, name="1")
                ))))
```

Correct: B
4. Write me an echo state network that can efficiently use the many CPU cores my machine has.

* A.

```python
import reservoirpy as rpy
rpy.set_param("backend", "parallel")

from reservoirpy.nodes import ESN
model = ESN(units=100)
model.fit(train_data, train_data)
```

* B.

```python
from reservoirpy.utils import parallel
from reservoirpy.nodes import ESN
model = ESN(units=100)
with parallel(n_jobs=-1):
    model.fit(train_data, train_data)
```

* C.

```python
from reservoirpy.nodes import ESN
model = ESN(units=100, workers=-1)
model.fit(train_data, train_data)
```

* D. ReservoirPy already parallelizes computation by default to ensure the best performance.

Correct: C

5. I have a model with several trainable readouts inside as such:

```python
from reservoirpy.nodes import Reservoir,
Ridge

model = Reservoir(100, name="R1") >> Ridge
(name="readout1")
model >>= Reservoir(100, name="R2") >>
Ridge(name="readout2")
model >>= Reservoir(100, name="R3") >>
Ridge(name="readout3")
```

How can I fit the model, by specifying the Y values to each Ridge node?

* A. It is not possible to do such a thing in ReservoirPy as it wouldn't make sense.

* B. You can pass a dict as a y parameter: `model.fit(X, "readout1": Y1, "readout2": Y2, "readout3": Y3, )`.

* C. You would have to fit each part separately before concatenating them.

* D. You can specify the node names as parameters and ReservoirPy will dispatch them correctly: `model.fit(X, readout1=Y1, readout2=Y2, readout3=Y3)`.

Correct: B

6. I have a NumPy array X of shape (timeseries, timesteps, dimensions) and I want to classify them according to my Y array of shape (timeseries, ) which contains numbers from 0 to 9 according to the class the timeseries belongs to. How can I do that in ReservoirPy?

* A.

```python
from reservoirpy.nodes import Reservoir,
ScikitLearnNode, Ridge
from sklearn.linear_model import
RidgeClassifier

Y_ = Y.reshape(-1, 1, 1).repeat(X.shape
[1], 1)

model = Reservoir(1000, lr=0.9, sr=1.0) >>
ScikitLearnNode(RidgeClassifier,
model_hypers=dict(alpha=1e-8))
model.fit(X, Y_)
```

* B. Reservoir Computing is only a framework for time-series forecasting, it is not suited for classification.

* C.

```python
from reservoirpy.nodes import Reservoir,
ScikitLearnNode, Ridge
from sklearn.linear_model import
RidgeClassifier

model = Reservoir(1000, lr=0.9, sr=1.0) >>
RidgeClassifier(alpha=1e-8)
model.fit(X, Y)
```

* D.

```python
from reservoirpy.nodes import Reservoir,
ScikitLearnNode, Ridge
from sklearn.linear_model import
RidgeClassifier

Y_ = Y.reshape(-1, 1, 1).repeat(X.shape
[1], 1)

model = Reservoir(1000, lr=0.9, sr=1.0) >>
ScikitLearnNode(RidgeClassifier)
model.fit(X, Y_)
```

Correct: A

Code questions (debug)

7. Here is my code:

```python
from reservoirpy.nodes import Reservoir,
Ridge

model = Reservoir(units=200, lr=0.2, sr
=1.0) >> Ridge(ridge=1e-4)

for x_series, y_series in zip(X_train,
Y_train):
    model.fit(x_series, y_series, warmup
=10)

y_pred = model.run(X_test[0])
```

Is that correct?

* A. Calling `.fit` on a model erases the previous trained results. You can instead call `.fit` once by passing the lists `X_train` and `Y_train` as parameters.

* B. Everything is correct!

* C. `.fit` method is not suited for online training. Use `.train` instead.
* D. Reservoir parameters should be written in full form: `leak_rate`, `spectral_range`.

Correct: A

8. Here is my code:

```python
from reservoirpy.nodes import Reservoir,
Ridge

model = Reservoir(units=200, lr=0.2, sr
                  =1.0, iss=0.2) >> Ridge(ridge=1e-4)

model.fit(X_train, Y_train, warmup=200)
Y_pred = model.run(X_test)
```

I have an error. What's wrong?

* A. `iss` is not a parameter. For scaling the input, the correct parameter is `scale_factor`.

* B. Reservoir parameters should be written in full form: `leak_rate`, `spectral_range`, `inputScaling`.

* C. You must first create the reservoir and readout nodes, and then connect them, in three separate lines.

* D. `iss` is not a parameter. For scaling the input, the correct parameter is `inputScaling`.

Correct: D

9. Here is my code:

```python
from reservoirpy.nodes import Reservoir,
RLS

model = Reservoir(units=200, lr=0.2, sr
                  =1.0) >> RLS(alpha=1e-4)

for x_series, y_series in zip(X_train,
                           Y_train):
    model.fit(x_series, y_series, warmup
              =10)

y_pred = model.run(X_test[0])
```

I have an error. What's wrong?

* A. The `RLS` node can only be trained online, but the `.fit` method is for offline training. You should use `.train` instead.

* B. The model has been trained on a list of timeseries but is run on a single timeseries.

* C. There are not enough units inside the reservoir. For this task, having at least 1000 neurons is recommended.

* D. Wrong import path: to import the `Reservoir` node, use `from reservoirpy.nodes.reservoirs import Reservoir`.

Correct: A

10. Here's my code:

```python
from reservoirpy.nodes import Input,
Output, Reservoir, Ridge

R1 = Reservoir(100, lr=0.01, sr=1.)
R2 = Reservoir(100, lr=0.03, sr=1.)
```

```python
R3 = Reservoir(100, lr=0.09, sr=1.)
R4 = Reservoir(100, lr=0.3, sr=1.)
R5 = Reservoir(100, lr=0.9, sr=1.)
R6 = Reservoir(100, lr=0.01, sr=1.)
readout = Ridge(ridge=1e-5, name="readout")

path1, path2 = R1 >> R6, R2 >> R5
path3 = Input(name="input") >> [R1, R2, R3]
path4 = R1 >> R2 >> R3 >> R4 >> R5 >> R6
>> readout >> Output()
model = path1 & path2 & path3 & path4

model.fit({"input": X_train}, {"readout":
    Y_train}, warmup=10)
model.run({"input": X_test})
```

Is that correct?

* A. The `.fit` and `.run` methods only take `numpy` arrays or list of ` numpy` arrays, not dictionaries.

* B. Yes, everything is correct!

* C. There is a circular connection in the model.

* D. `path2` is not defined.

Correct: B

11. Is this the correct usage of the method `partial_fit`?

```python
reservoir, readout = Reservoir(100, sr=1),
Ridge(ridge=1e-8)

for x, y in zip(X, Y):
    states = reservoir.run(x)
    readoutpartial_fit
    readout.fit()
    model = reservoir >> readout
```

* A. By calling the method `.fit`, the readout forgets its previous training.

* B. The created model won't be fitted.

* C. While it works, it can be simplified by creating the model and calling `partial_fit` on it.

* D. Yes, everything is correctly coded.

Correct: D

12. Here is my code:

```python
reservoir, readout = Reservoir(100, sr=1),
Ridge(ridge=1e-8)

model = reservoir >> readout

model.fit(X[:800], Y[:800], warmup=10)

steps = 1000
results = np.zeros((steps, 1))

last_output = X[800]

for i in range(steps):
    last_output = model(last_output)
    results[i] = last_output
```
Is that the best way to have a model that generates new values by looping on itself?

* A. No, you can connect the readout to the reservoir in order to loop the results back as an input after training: `readout >> reservoir`.

* B. No, it won't work as the reservoir has an input dimension of 100 and the `results` array containing the results only has its feature dimension set to 1.

* C. You can call the `.autoregress(n=1000)` Model method.

* D. Yes, this is probably the best solution.

Correct: D

13. Here is my code:

```python
weights = np.random.choice([1, -1], p
                          =[0.6, 1 - 0.6], replace=True, size
                          =(200, 200))
reservoir = Reservoir(W=weights, sr=0.9,
                      lr=0.6)
```

I created my reservoir this way, but it seems the reservoir has a very chaotic behavior, even though the spectral radius is below 1.

* A. The rule of the spectral radius $\lambda$1 holds for matrices with a normal distribution, not a Bernoulli one, which explains why you have a chaotic behavior with a spectral radius of only 1.

* B. The rule of the spectral radius $\lambda$1 only holds when there is no leak rate, so that explains why you have a chaotic behavior with a spectral radius of only 1.

* C. The parameter `sr` is only valid when no weight matrix has been specified. If a matrix is already specified, this argument is ignored.

* D. The reservoir argument names are incorrect. You should use `spectralRadius` and `leak_rate`.

Correct: C

14. Here's my code:

```python
from reservoirpy.nodes import Input,
                          Output, Reservoir, Ridge
R1 = Reservoir(100, lr=0.01, sr=1.)
R2 = Reservoir(100, lr=0.03, sr=1.)
R3 = Reservoir(100, lr=0.09, sr=1.)
R4 = Reservoir(100, lr=0.3, sr=1.)
R5 = Reservoir(100, lr=0.9, sr=1.)
R6 = Reservoir(100, lr=0.01, sr=1.)
readout = Ridge(ridge=1e-5, name="readout")

path1, path2 = R1 >> R6, R2 >> R5
path3 = Input(name="input") >> [R1, R2, R3]
path4 = R1 >> R2 >> R4 >> R3 >> R5 >> R6
>> readout >> Output()
model = path1 & path2 & path3 & path4

model.fit({"input": X_train}, {"readout":
    Y_train}, warmup=10)
model.run({"input": X_test})
```

Is that correct?

* A. The `.fit` and `.run` methods only take ` numpy arrays` or list of ` numpy arrays`, not ` dictionaries`.

* B. Yes, everything is correct!

* C. There is a circular connection in the model.

* D. `path2` is not defined.

Correct: B