From 23fdbccff1a0ab84f8785391d774a35cc69f668f Mon Sep 17 00:00:00 2001 From: Ojaswi Chopra Date: Sun, 9 Jun 2024 13:12:13 +0530 Subject: [PATCH] Added Reinforcement Learning --- .../machine-learning/assets/rl-components.png | Bin 0 -> 62544 bytes contrib/machine-learning/index.md | 1 + .../reinforcement-learning.md | 327 ++++++++++++++++++ 3 files changed, 328 insertions(+) create mode 100644 contrib/machine-learning/assets/rl-components.png create mode 100644 contrib/machine-learning/reinforcement-learning.md diff --git a/contrib/machine-learning/assets/rl-components.png b/contrib/machine-learning/assets/rl-components.png new file mode 100644 index 0000000000000000000000000000000000000000..cb359cf455ebd9fdf83221d1b97c6bbb05810543 GIT binary patch literal 62544 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 Bzg7SM literal 0 HcmV?d00001 diff --git a/contrib/machine-learning/index.md b/contrib/machine-learning/index.md index 0bf39f9..f6d988f 100644 --- a/contrib/machine-learning/index.md +++ b/contrib/machine-learning/index.md @@ -20,3 +20,4 @@ - [Grid Search](grid-search.md) - [Transformers](transformers.md) - [K-nearest neighbor (KNN)](knn.md) +- [Reinforcement Learning](reinforcement-learning.md) diff --git a/contrib/machine-learning/reinforcement-learning.md b/contrib/machine-learning/reinforcement-learning.md new file mode 100644 index 0000000..b470ed3 --- /dev/null +++ b/contrib/machine-learning/reinforcement-learning.md @@ -0,0 +1,327 @@ +# Reinforcement Learning: A Comprehensive Guide + +Reinforcement Learning (RL) is a field of Machine Learing which focuses on goal-directed learning from interaction with the environment. In RL, an agent learns to make decisions by performing actions in an environment to maximize cumulative numerical reward signal. This README aims to provide a thorough understanding of RL, covering key concepts, algorithms, applications, and resources. + +## Table of Contents + +
+Click to expand + +1. [What is Reinforcement Learning?](#what-is-reinforcement-learning) +2. [Key Concepts and Terminology](#key-concepts-and-terminology) + - [Agent](#agent) + - [Environment](#environment) + - [State](#state) + - [Action](#action) + - [Reward](#reward) + - [Policy](#policy) + - [Value Function](#value-function) + - [Model](#model) + - [Exploration vs. Exploitation](#exploration-vs-exploitation) +3. [Types of Reinforcement Learning](#types-of-reinforcement-learning) + - [Model-Based vs Model-Free](#model-based-vs-model-free) + - [Value-Based Methods](#value-based-methods) + - [Policy-Based Methods](#policy-based-methods) + - [Actor-Critic Methods](#actor-critic-methods) +4. [Important Algorithms](#important-algorithms) + - [Q-Learning](#q-learning) + - [Deep Q-Networks](#deep-q-networks-dqn) + - [SARSA](#sarsa) + - [REINFORCE Algorithm](#reinforce-algorithm) + - [Proximal Policy Optimization (PPO)](#proximal-policy-optimization-ppo) + - [A2C/A3C](#a2ca3c) +5. [Mathematical Background](#mathematical-background) + - [Markov Decision Processes (MDP)](#markov-decision-processes-mdps) + - [Bellman Equations](#bellman-equations) +6. [Applications of Reinforcement Learning](#applications-of-reinforcement-learning) + - [Gaming](#gaming) + - [Robotics](#robotics) + - [Finance](#finance) + - [Healthcare](#healthcare) +7. [Tools and Libraries](#tools-and-libraries) +8. [Resources for Further Learning](#resources-for-further-learning) + - [Books](#books) + - [Online Courses](#online-courses) + - [Research Papers](#research-papers) + - [Blogs and Websites](#blogs-and-websites) +9. [How to Start with Reinforcement Learning](#how-to-start-with-reinforcement-learning) + - [Prerequisites](#prerequisites) + - [Beginner Project](#beginner-project) +10. [Conclusion](#conclusion) + +
+ +## What is Reinforcement Learning? + +Reinforcement learning involves determining the best actions to take in various situations to maximize a numerical reward signal. Instead of being instructed on which actions to take, the learner must explore and identify the actions that lead to the highest rewards through trial and error. After each action performed in its environment, a trainer may give feedback in the form of rewards or penalties to indicate the desirability of the resulting state. Unlike supervised learning, reinforcement learning does not depend on labeled data but instead learns from the outcomes of its actions. + +## Key Concepts and Terminology + +![image](assets/rl-components.png) + +### Agent +Agent is a system or entity that learns to make decisions by interacting with an environment. The agent improves its performance by trial and error, receiving feedback from the environment in the form of rewards or punishments. + +### Environment +Environment is the setting or world in which the agent operates and interacts with. It provides the agent with states and feedback based on the agent's actions. + +### State +State represents the current situation of the environment, encapsulating all the relevant information needed for decision-making. + +### Action +Action represents a move that can be taken by the agent, which would affect the state of the environment. The set of all possible actions is called the action space. + +### Reward +Reward is the feedback from the environment in response to the agent’s action, thereby defining what are good and bad actions. Agent aims to maximize the total reward over time. + +### Policy +Policy is a strategy used by the agent to determine its actions based on the current state. In some cases the policy may be a simple function or lookup table, whereas in others it may involve extensive computation such as a search process. + +### Value Function +The value function of a state is the expected total amount of reward an agent can expect to accumulate over the future, starting from that state. There are two main types of value functions: + - **State Value Function (V)**: The expected reward starting from a state and following a certain policy thereafter. + - **Action Value Function (Q)**: The expected reward starting from a state, taking a specific action, and following a certain policy thereafter. + +### Model +Model mimics the behavior of the environment, or more generally, that allows inferences to be made about how the environment will behave. + +### Exploration vs. Exploitation +To accumulate substantial rewards, a reinforcement learning agent needs to favor actions that have previously yielded high rewards. However, to identify these effective actions, the agent must also attempt actions it hasn't tried before. This means the agent must *exploit* its past experiences to gain rewards, while also *exploring* new actions to improve its future decision-making. + +## Types of Reinforcement Learning + +### Model-Based vs Model-Free + +**Model-Based Reinforcement Learning:** Model-based methods involve creating a model of the environment to predict future states and rewards, allowing the agent to plan its actions by simulating various scenarios. These methods often involve two main components: + +**Model-Free Reinforcement Learning:** Model-free methods do not explicitly learn a model of the environment. Instead, they learn a policy or value function directly from the interactions with the environment. These methods can be further divided into two categories: value-based and policy-based methods. + +### Value-Based Methods: +Value-based methods focus on estimating the value function, and the policy is indirectly derived from the value function. + +### Policy-Based Methods: +Policy-based methods directly optimize the policy by maximizing the expected cumulative rewardto find the optimal parameters. + +### Actor-Critic Methods: +Actor-Critic methods combine the strengths of both value-based and policy-based methods. Actor learns the policy that maps states to actions and Critic learns the value function that evaluates the action chosen by the actor. + +## Important Algorithms + +### Q-Learning +Q-Learning is a model-free algorithm used in reinforcement learning to learn the value of an action in a particular state. It aims to find the optimal policy by iteratively updating the Q-values, which represent the expected cumulative reward of taking a particular action in a given state and following the optimal policy thereafter. + +#### Algorithm: +1. Initialize Q-values arbitrarily for all state-action pairs. +2. Repeat for each episode: + - Choose an action using an exploration strategy (e.g., epsilon-greedy). + - Take the action, observe the reward and the next state. + - Update the Q-value of the current state-action pair using the Bellman equation: + \[ Q(s, a) \leftarrow Q(s, a) + \alpha \left( r + \gamma \max_{a'} Q(s', a') - Q(s, a) \right) \] + where: + - \( Q(s, a) \) is the Q-value of state \( s \) and action \( a \). + - \( r \) is the observed reward. + - \( s' \) is the next state. + - \( \alpha \) is the learning rate. + - \( \gamma \) is the discount factor. +3. Until convergence or a maximum number of episodes. + +### Deep Q-Networks (DQN) +Deep Q-Networks (DQN) extend Q-learning to high-dimensional state spaces using deep neural networks to approximate the Q-function. It uses experience replay and target networks to improve stability and convergence. + +#### Algorithm: +1. Initialize the Q-network with random weights. +2. Initialize a target network with the same weights as the Q-network. +3. Repeat for each episode: + - Initialize the environment state \( s \). + - Repeat for each timestep: + - With probability \( \epsilon \), choose a random action. Otherwise, select the action with the highest Q-value according to the Q-network. + - Take the chosen action, observe the reward \( r \) and the next state \( s' \). + - Store the transition \( (s, a, r, s') \) in the replay memory. + - Sample a minibatch of transitions from the replay memory. + - Compute the target Q-value for each transition: + \[ y_j = \begin{cases} r_j & \text{if episode terminates at step } j+1 \\ + r_j + \gamma \max_{a'} Q(s', a'; \theta^-) & \text{otherwise} \end{cases} \] + where: + - \( \theta^- \) represents the parameters of the target network. + - \( y_j \) is the target Q-value for the \( j \)th transition. + - Update the Q-network parameters by minimizing the temporal difference loss: + \[ \mathcal{L}(\theta) = \frac{1}{N} \sum_{j} (y_j - Q(s_j, a_j; \theta))^2 \] +4. Until convergence or a maximum number of episodes. + +### SARSA +SARSA (State-Action-Reward-State-Action) is an on-policy temporal difference algorithm used for learning the Q-function. Unlike Q-learning, SARSA directly updates the Q-values based on the current policy. + +#### Algorithm: +1. Initialize Q-values arbitrarily for all state-action pairs. +2. Repeat for each episode: + - Initialize the environment state \( s \). + - Choose an action \( a \) using the current policy (e.g., epsilon-greedy). + - Repeat for each timestep: + - Take action \( a \), observe the reward \( r \) and the next state \( s' \). + - Choose the next action \( a' \) using the current policy. + - Update the Q-value of the current state-action pair using the SARSA update rule: + \[ Q(s, a) \leftarrow Q(s, a) + \alpha \left( r + \gamma Q(s', a') - Q(s, a) \right) \] +3. Until convergence or a maximum number of episodes. + +### REINFORCE Algorithm: +REINFORCE (Monte Carlo policy gradient) is a simple policy gradient method that updates the policy parameters in the direction of the gradient of expected rewards. + +### Proximal Policy Optimization (PPO): +PPO is an advanced policy gradient method that improves stability by limiting the policy updates within a certain trust region. + +### A2C/A3C: +Advantage Actor-Critic (A2C) and Asynchronous Advantage Actor-Critic (A3C) are variants of actor-critic methods that utilize multiple parallel agents to improve sample efficiency. + +## Mathematical Background + +### Markov Decision Processes (MDPs) +A Markov Decision Process (MDP) is a mathematical framework used to model decision-making problems. It consists of states, actions, rewards and transition probabilities. + +### Bellman Equations +Bellman equations are fundamental recursive equations in dynamic programming and reinforcement learning. They express the value of a decision at one point in time in terms of the expected value of the subsequent decisions. + +## Applications of Reinforcement Learning + +### Gaming +Reinforcement learning is extensively used in gaming for developing AI agents capable of playing complex games like AlphaGo, Chess, and video games. RL algorithms enable these agents to learn optimal strategies by interacting with the game environment and receiving feedback in the form of rewards. + +### Robotics +In robotics, reinforcement learning is employed to teach robots various tasks such as navigation, manipulation, and control. RL algorithms allow robots to learn from their interactions with the environment, enabling them to adapt and improve their behavior over time without explicit programming. + +### Finance +Reinforcement learning plays a crucial role in finance, particularly in algorithmic trading and portfolio management. RL algorithms are utilized to optimize trading strategies, automate decision-making processes, and manage investment portfolios dynamically based on changing market conditions and objectives. + +### Healthcare +In healthcare, reinforcement learning is utilized for various applications such as personalized treatment, drug discovery, and optimizing healthcare operations. RL algorithms can assist in developing personalized treatment plans for patients, identifying effective drug candidates, and optimizing resource allocation in hospitals to improve patient care and outcomes. + +## Tools and Libraries +- **OpenAI Gym:** A toolkit for developing and comparing RL algorithms. +- **TensorFlow/TF-Agents:** A library for RL in TensorFlow. +- **PyTorch:** Popular machine learning library with RL capabilities. +- **Stable Baselines3:** A set of reliable implementations of RL algorithms in PyTorch. + +## Resources for Further Learning +### Books +- "Reinforcement Learning: An Introduction" by Sutton and Barto +- "Deep Reinforcement Learning Hands-On" by Maxim Lapan + +### Online Courses +- "Reinforcement Learning" by Udacity +- "Fundamentals of Reinforcement Learning" by Coursera +- "Master Reinforcement Learning and Deep RL with Python" by Udemy + +### Research Papers +- [Reinforcement learning model, algorithms and its application](https://ieeexplore.ieee.org/abstract/document/6025669) +- [A Concise Introduction to Reinforcement Learning](https://www.researchgate.net/publication/323178749_A_Concise_Introduction_to_Reinforcement_Learning) + +### Blogs and Websites +- [OpenAI Blog](https://spinningup.openai.com/en/latest/) +- [Geeks for Geeks](https://www.geeksforgeeks.org/what-is-reinforcement-learning/) +- [Medium Blog](https://gordicaleksa.medium.com/how-to-get-started-with-reinforcement-learning-rl-4922fafeaf8c) + +## How to Start with Reinforcement Learning + +### Prerequisites +- Basic knowledge of machine learning and neural networks. +- Proficiency in Python. + +### Beginner Project +The provided Python code implements the Q-learning algorithm for a basic grid world environment. It defines the grid world, actions, and parameters such as discount factor and learning rate. The algorithm iteratively learns the optimal action-value function (Q-values) by updating them based on rewards obtained from actions taken in each state. Finally, the learned Q-values are printed for each state-action pair. + +```python +import numpy as np + +# Define the grid world environment +# 'S' represents the start state +# 'G' represents the goal state +# 'H' represents the hole (negative reward) +# '.' represents empty cells (neutral reward) +# 'W' represents walls (impassable) +grid_world = np.array([ + ['S', '.', '.', '.', '.'], + ['.', 'W', '.', 'H', '.'], + ['.', '.', '.', 'W', '.'], + ['.', 'W', '.', '.', 'G'] +]) + +# Define the actions (up, down, left, right) +actions = ['UP', 'DOWN', 'LEFT', 'RIGHT'] + +# Define parameters +gamma = 0.9 # discount factor +alpha = 0.1 # learning rate +epsilon = 0.1 # exploration rate + +# Initialize Q-values +num_rows, num_cols = grid_world.shape +num_actions = len(actions) +Q = np.zeros((num_rows, num_cols, num_actions)) + +# Define helper function to get possible actions in a state +def possible_actions(state): + row, col = state + possible_actions = [] + for i, action in enumerate(actions): + if action == 'UP' and row > 0 and grid_world[row - 1, col] != 'W': + possible_actions.append(i) + elif action == 'DOWN' and row < num_rows - 1 and grid_world[row + 1, col] != 'W': + possible_actions.append(i) + elif action == 'LEFT' and col > 0 and grid_world[row, col - 1] != 'W': + possible_actions.append(i) + elif action == 'RIGHT' and col < num_cols - 1 and grid_world[row, col + 1] != 'W': + possible_actions.append(i) + return possible_actions + +# Q-learning algorithm +num_episodes = 1000 +for episode in range(num_episodes): + # Initialize the starting state + state = (0, 0) # start state + while True: + # Choose an action using epsilon-greedy policy + if np.random.uniform(0, 1) < epsilon: + action = np.random.choice(possible_actions(state)) + else: + action = np.argmax(Q[state[0], state[1]]) + + # Perform the action and observe the next state and reward + if actions[action] == 'UP': + next_state = (state[0] - 1, state[1]) + elif actions[action] == 'DOWN': + next_state = (state[0] + 1, state[1]) + elif actions[action] == 'LEFT': + next_state = (state[0], state[1] - 1) + elif actions[action] == 'RIGHT': + next_state = (state[0], state[1] + 1) + + # Get the reward + if grid_world[next_state] == 'G': + reward = 1 # goal state + elif grid_world[next_state] == 'H': + reward = -1 # hole + else: + reward = 0 + + # Update Q-value using the Bellman equation + best_next_action = np.argmax(Q[next_state[0], next_state[1]]) + Q[state[0], state[1], action] += alpha * ( + reward + gamma * Q[next_state[0], next_state[1], best_next_action] - Q[state[0], state[1], action]) + + # Move to the next state + state = next_state + + # Check if the episode is terminated + if grid_world[state] in ['G', 'H']: + break + +# Print the learned Q-values +print("Learned Q-values:") +for i in range(num_rows): + for j in range(num_cols): + print(f"State ({i}, {j}):", Q[i, j]) +``` + +### Conclusion +Congratulations on completing your journey through this comprehensive guide to reinforcement learning! Armed with this knowledge, you are well-equipped to dive deeper into the exciting world of RL, whether it's for gaming, robotics, finance, healthcare, or any other domain. Keep exploring, experimenting, and learning, and remember, the only limit to what you can achieve with reinforcement learning is your imagination. + +*Happy coding, and may your RL adventures be rewarding!* \ No newline at end of file