Pytorch强化学习初学者笔记 -- 使用强化学习(Reinforcement Learning)来让程序自动学习玩乒乓小游戏

前言

  • 本文暂时并未完全实现,我还在努力学习中,这篇文章后续会随着我的学习进度,再来改进
  • 目前只是记录下暂时写下的代码而已
  • (边工作边学习个人爱好,所以经常会暂时性写下一些未完成的笔记,有意者看到的话请见谅哈)
  • *(若期待本文最终结果的话,可以持续关注)

案例功能描述

  • 有一个简易的打乒乓小游戏是这样的:一个小球会从顶部随机位置开始往下掉落,底部有个一定长度的横线,需要通过左右方向按键左右移动这顶部的横线来接住小球,如果没接住小球就算游戏失败,失败了再重新开始。
  • 我们可以使用强化学习(Reinforcement Learning)来让程序自动学习玩这个简单的小游戏。

代码在此

  • 下面是一个基于 PyTorch 和 OpenAI Gym 的示例实现
    • (【注】:以下代码暂时记录而已,我还没为实践证实,只是个思路,其中一定存在很多问题,待后续抽空学习并实践之后再来修改)
python 复制代码
import gym
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim

# 定义游戏环境
class BallCatchingEnv(gym.Env):
    def __init__(self):
        super(BallCatchingEnv, self).__init__()
        self.action_space = gym.spaces.Discrete(3)  # 左移、不动、右移
        self.observation_space = gym.spaces.Box(low=np.array([0, 0]), high=np.array([100, 100]), dtype=np.float32)
        self.bar_position = 50
        self.ball_position = np.random.randint(0, 100)
        self.ball_velocity = np.random.uniform(-5, 5)

    def step(self, action):
        # 根据动作更新bar位置
        if action == 0:
            self.bar_position = max(0, self.bar_position - 5)
        elif action == 1:
            pass
        else:
            self.bar_position = min(100, self.bar_position + 5)

        # 更新球位置
        self.ball_position += self.ball_velocity
        if self.ball_position <= 0 or self.ball_position >= 100:
            self.ball_velocity = -self.ball_velocity

        # 检查是否接住球
        reward = 0
        done = False
        if self.ball_position >= self.bar_position and self.ball_position <= self.bar_position + 10:
            reward = 1
        else:
            reward = -1
            done = True

        return np.array([self.bar_position, self.ball_position]), reward, done, {}

    def reset(self):
        self.bar_position = 50
        self.ball_position = np.random.randint(0, 100)
        self.ball_velocity = np.random.uniform(-5, 5)
        return np.array([self.bar_position, self.ball_position])

# 定义 Q 网络
class QNetwork(nn.Module):
    def __init__(self, input_size, output_size):
        super(QNetwork, self).__init__()
        self.fc1 = nn.Linear(input_size, 64)
        self.fc2 = nn.Linear(64, output_size)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 定义 DQN 代理
class DQNAgent:
    def __init__(self, env, lr=0.001, gamma=0.99, epsilon=1.0, epsilon_decay=0.995, epsilon_min=0.01):
        self.env = env
        self.q_network = QNetwork(env.observation_space.shape[0], env.action_space.n)
        self.optimizer = optim.Adam(self.q_network.parameters(), lr=lr)
        self.gamma = gamma
        self.epsilon = epsilon
        self.epsilon_decay = epsilon_decay
        self.epsilon_min = epsilon_min

    def select_action(self, state):
        if np.random.rand() < self.epsilon:
            return self.env.action_space.sample()
        else:
            state = torch.from_numpy(state).float().unsqueeze(0)
            q_values = self.q_network(state)
            return q_values.argmax().item()

    def train(self, num_episodes):
        for episode in range(num_episodes):
            state = self.env.reset()
            done = False
            while not done:
                action = self.select_action(state)
                next_state, reward, done, _ = self.env.step(action)
                target = reward + self.gamma * self.q_network(torch.from_numpy(next_state).float().unsqueeze(0)).max()
                loss = (self.q_network(torch.from_numpy(state).float().unsqueeze(0))[0][action] - target) ** 2
                self.optimizer.zero_grad()
                loss.backward()
                self.optimizer.step()
                state = next_state
            self.epsilon = max(self.epsilon_min, self.epsilon * self.epsilon_decay)
            print(f"Episode {episode}, Epsilon: {self.epsilon:.2f}")

# 训练代理
env = BallCatchingEnv()
agent = DQNAgent(env)
agent.train(1000)
  • 这个示例使用了深度 Q 网络(DQN)算法来学习玩这个简单的小游戏。我们首先定义了游戏环境 BallCatchingEnv,然后创建了一个 Q 网络 QNetwork 和一个 DQN 代理 DQNAgent

在训练过程中,代理会探索环境并学习如何选择最佳动作来接住下落的小球。它使用 epsilon-greedy 策略,在训练初期更倾向于探索(随机选择动作),而在训练后期更倾向于利用(选择预测的最佳动作)。

通过运行 agent.train(1000),代理会在 1000 个回合中学习如何玩这个游戏。你可以观察代理的表现,并根据需要调整训练参数,如学习率、折扣因子和 epsilon 衰减率等。

总结

  • 这只是一个简单的示例,我感觉是比较适合初学者入门的。我也是为了逐步迈入机器学习这个领域而想到的这个小案例,如果我能现在掌握这个小案例,再逐步扩展的话,这样学习会更有趣更有动力更合理一些;毕竟一下子去实现太大的目标或者直接去看一整套乏味的学习资料或教学视频的话,会很容易产生迷茫甚至厌烦;
  • 后续可以根据需求再进行慢慢扩展和优化,比如添加更复杂的游戏规则、调整网络结构、尝试其他强化学习算法等。通过实践和探索,可以慢慢掌握深度学习在游戏AI中的应用
相关推荐
Envyᥫᩣ8 分钟前
Python中的自然语言处理:从基础到高级
python·自然语言处理·easyui
哪 吒8 分钟前
华为OD机试 - 几何平均值最大子数(Python/JS/C/C++ 2024 E卷 200分)
javascript·python·华为od
我是陈泽11 分钟前
一行 Python 代码能实现什么丧心病狂的功能?圣诞树源代码
开发语言·python·程序员·编程·python教程·python学习·python教学
hakesashou12 分钟前
python全栈开发是什么?
python
创作小达人31 分钟前
家政服务|基于springBoot的家政服务平台设计与实现(附项目源码+论文+数据库)
开发语言·python
ZPC821041 分钟前
Python使用matplotlib绘制图形大全(曲线图、条形图、饼图等)
开发语言·python·matplotlib
镜花照无眠43 分钟前
Python爬虫使用实例-mdrama
开发语言·爬虫·python
aaasssdddd961 小时前
python和c
c语言·开发语言·python
爱写代码的小朋友1 小时前
Python的几个高级特性
python
Eric.Lee20211 小时前
数据集-目标检测系列- 螃蟹 检测数据集 crab >> DataBall
python·深度学习·算法·目标检测·计算机视觉·数据集·螃蟹检测