蒙特卡洛法的简介以及实战应用(python实现 基于同策略首次访问蒙特卡洛算法 附源码)

简介: 蒙特卡洛法的简介以及实战应用(python实现 基于同策略首次访问蒙特卡洛算法 附源码)

需要源码或数据集请点赞关注收藏后评论区留言

一、蒙特卡洛法的基本概念

在实际问题中,通常不易获得完整的环境知识。蒙特卡洛法(MC)正是基于统计学的思想,通过大量采样获取数据来进行学习的方法称为经验方法。MC正式基于经验方法,在环境模型位置的情况下,采用时间步有限的,完整的情节根据经验进行学习。并通过平均采样回报来解决强化学习问题。

二、蒙特卡洛法(MC)的核心要素

1:经验:经验是从环境交互中获得的序列,它是情节的集合也就是样本集,经验既可以是真实经验也可以是模拟经验

2:情节:一段经验可以分为多个情节,每一个情节都是一个完整的序列,即一定有终止状态。

3:完整回报与目标值:因为只有到达终止状态才能计算回报,所以将情节的回报G称为完整回报,G也称为MC的目标值

三、蒙特卡洛预测

基于首次访问的MC预测算法步骤如下图

部分代码如下

from collections import defaultdict
from my_book_gridworld0406 import GridWorldEnv
import numpy as np
class Agent():
    def __init__(self):
        self.Q = {}  # {state:{action:q_value}} 初始化Q
    def create_epsilon_greedy_policy(self, nA):
        """
        Creates an epsilon-greedy policy based on Q values.
        基于Q值创建贪婪策略
alid_nA
            best_action = max(self.Q[state], key=self.Q[state].get)  # 获取最大value值对应的key,即得到最大动作值函数对应的动作
            A[best_action] += 1.0 - epsilon
            return A
        return policy_fn
    def mc_control_epsilon_greedy(self, env, gamma, max_episode_num):
        # flag = True
        returns_sum = defaultdict(float)
        returns_count = defaultdict(float)
        target_policy = self.create_epsilon_greedy_policy(env.action_space.n)
        num_episode = 0
        for state in range(env.observation_space.n):
            self.initValue(state, env.valid_actions_for_states, randomized=False)
        print("episode:{}".format(num_episode))
        print(epsilon_by_epsiode(num_episode))
        for s in print_states:
            if s in self.Q.keys():
                print("{}_Q:".format(s), end="")
                Q_s = []
                for a in self.Q[s].keys():
                    Q_s.append(round(self.Q[s][a], 3))
                print(Q_s)
                probs = target_policy(env.valid_actions_for_states, s, epsilon_by_epsiode(num_episode))
                action = np.random.choice(np.arange(len(probs)), p=probs)
                p = []
                for a in range(len(probs)):
                    p.append(round(probs[a], 3))
                print(p)
                print(action)
        while num_episode < max_episode_num:
            episode = []
            state = env.reset()
            while True:
                # env.render()
                probs = target_policy(env.valid_actions_for_states, state, epsilon_by_epsiode(num_episode))
                action = np.random.choice(np.arange(len(probs)), p=probs)
                next_state, reward, done, _ = env.step(action)
                episode.append((state, action, reward))
                if done:
                    break
                state = next_state
            num_episode += 1
            # Find all (state, action) pairs we've visited in this episode
            # We convert each state to a tuple so that we can use it as a dict key
            sa_in_episode = set([(x[0], x[1]) for x in episode])
            for state, action in sa_in_episode:
                sa_pair = (state, action)
                # Find the first occurance of the (state, action) pair in the episode
                first_occurence_idx = next(i for i, x in enumerate(episode)
                                           if x[0] == state and x[1] == action)
                # Sum up all rewards since the first occurance
                G = sum([x[2] * (gamma ** i) for i, x in enumerate(episode[first_occurence_idx:])])
                # Calculate average return for this state over all sampled episodes
                returns_sum[sa_pair] += G
                returns_count[sa_pair] += 1.0
                self.__setQValue(state, action, returns_sum[sa_pair] / returns_count[sa_pair])
            if num_episode in print_episodes:
                print("episode:{}".format(num_episode))
                print(epsilon_by_epsiode(num_episode))
                for s in print_states:
                    if s in self.Q.keys():
                        print("{}_Q:".format(s), end="")
                        Q_s = []
                        for a in self.Q[s].keys():
                            Q_s.append(round(self.Q[s][a], 3))
                        print(Q_s)
                        probs = target_policy(env.valid_actions_for_states, s, epsilon_by_epsiode(num_episode))
                        action = np.random.choice(np.arange(len(probs)), p=probs)
                        p = []
                        for a in range(len(probs)):
                            p.append(round(probs[a], 3))
                        print(p)
                        print(action)
        return self.Q
    # return a possible action list for a given state
    # def possibleActionsForstate(self, state):
    #  actions = []
    #  # add your code here
    #  return actions
    # if a state exists in Q dictionary
    def __isStateInQ(self, state):
        # 判断空值。有值则返回值,无值则返回None - None is not None = False
        return self.Q.get(state) is not None  # 因为是实例属性,所以要用self.进行引用
    def initValue(self, s, valid_actions_list, randomized=False):  # 初始化Q和E
        # Q[s]为空值时进入判断
        if not self.__isStateInQ(s):
            self.Q[s] = {}  # 初始化Q
            for a in valid_actions_list[s]:  # 遍历所有action_name
                self.Q[s][
                    a] = np.random().random() / 10 if randomized is True else 0.0  # 初始化Q(s,a);随机一个动作值函数。只有结束状态的Q(s,a) = 0
    """Q的获取与设置方法"""
    def __getQValue(self, s, a):  # ①
        return self.Q[s][a]  # argmax(q)
    def __setQValue(self, s, a, new_q):  # ②
        self.Q[s][a] = new_q
np.random.seed(1)
epsilon_start = 0.5
epsilon_final = 0
epsilon_episodes = 20000
epsilon_by_epsiode = lambda episode_idx: epsilon_start - (epsilon_start - epsilon_final) * min(episode_idx,
                                                                                               epsilon_episodes) / epsilon_episodes
agent = Agent()
env = GridWorldEnv()
print_states = [5, 10, 18, 20, 24]
print_episodes = [1, 7500, 12500, 19999, 20000]
Q = agent.mc_control_epsilon_greedy(env=env, gamma=0.8, max_episode_num=20000)

部分运行效果如下

 

相关文章
|
4天前
|
数据库 Python
Python 应用
Python 应用。
24 4
|
4天前
|
机器学习/深度学习 数据采集 数据可视化
Python在数据科学中的应用:从入门到实践
本文旨在为读者提供一个Python在数据科学领域应用的全面概览。我们将从Python的基础语法开始,逐步深入到数据处理、分析和可视化的高级技术。文章不仅涵盖了Python中常用的数据科学库,如NumPy、Pandas和Matplotlib,还探讨了机器学习库Scikit-learn的使用。通过实际案例分析,本文将展示如何利用Python进行数据清洗、特征工程、模型训练和结果评估。此外,我们还将探讨Python在大数据处理中的应用,以及如何通过集成学习和深度学习技术来提升数据分析的准确性和效率。
|
6天前
|
算法 数据处理 开发者
超越传统:Python二分查找的变种策略,让搜索效率再上新台阶!
本文介绍了二分查找及其几种Python实现的变种策略,包括经典二分查找、查找第一个等于给定值的元素、查找最后一个等于给定值的元素以及旋转有序数组的搜索。通过调整搜索条件和边界处理,这些变种策略能够适应更复杂的搜索场景,提升搜索效率和应用灵活性。
21 5
|
2天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
15 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
2天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
11 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
2天前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
9 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
6天前
|
Python
不容错过!Python中图的精妙表示与高效遍历策略,提升你的编程艺术感
本文介绍了Python中图的表示方法及遍历策略。图可通过邻接表或邻接矩阵表示,前者节省空间适合稀疏图,后者便于检查连接但占用更多空间。文章详细展示了邻接表和邻接矩阵的实现,并讲解了深度优先搜索(DFS)和广度优先搜索(BFS)的遍历方法,帮助读者掌握图的基本操作和应用技巧。
23 4
|
6天前
|
机器学习/深度学习 JSON API
Python编程实战:构建一个简单的天气预报应用
Python编程实战:构建一个简单的天气预报应用
15 1
|
6天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
23 2
|
8天前
|
算法 IDE API
Python编码规范与代码可读性提升策略####
本文探讨了Python编码规范的重要性,并深入分析了如何通过遵循PEP 8等标准来提高代码的可读性和可维护性。文章首先概述了Python编码规范的基本要求,包括命名约定、缩进风格、注释使用等,接着详细阐述了这些规范如何影响代码的理解和维护。此外,文章还提供了一些实用的技巧和建议,帮助开发者在日常开发中更好地应用这些规范,从而编写出更加清晰、简洁且易于理解的Python代码。 ####