Python案例如何用强化学习玩游戏

wen python案例 2

本文目录导读:

Python案例如何用强化学习玩游戏

  1. 基础框架:CartPole游戏(OpenAI Gym)
  2. 经典游戏:打砖块(Breakout)
  3. 自定义游戏:Flappy Bird
  4. 使用预训练模型玩游戏
  5. 进阶:使用Ray实现分布式强化学习
  6. 学习路径建议

我来为你介绍几个Python用强化学习玩游戏的经典案例,从简单到复杂:

基础框架:CartPole游戏(OpenAI Gym)

安装依赖

pip install gym tensorflow keras-rl2
pip install pygame

案例1:使用DQN玩CartPole

import gym
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.optimizers import Adam
from rl.agents import DQNAgent
from rl.policy import BoltzmannQPolicy
from rl.memory import SequentialMemory
# 创建环境
env = gym.make('CartPole-v1')
states = env.observation_space.shape[0]
actions = env.action_space.n
# 构建神经网络模型
def build_model(states, actions):
    model = Sequential()
    model.add(Flatten(input_shape=(1, states)))
    model.add(Dense(24, activation='relu'))
    model.add(Dense(24, activation='relu'))
    model.add(Dense(actions, activation='linear'))
    return model
model = build_model(states, actions)
# 构建DQN代理
def build_agent(model, actions):
    policy = BoltzmannQPolicy()
    memory = SequentialMemory(limit=50000, window_length=1)
    dqn = DQNAgent(model=model, memory=memory, policy=policy,
                   nb_actions=actions, nb_steps_warmup=10,
                   target_model_update=1e-2)
    return dqn
dqn = build_agent(model, actions)
dqn.compile(Adam(lr=1e-3), metrics=['mae'])
# 训练
dqn.fit(env, nb_steps=50000, visualize=False, verbose=1)
# 测试
scores = dqn.test(env, nb_episodes=10, visualize=True)
print(f'平均得分: {np.mean(scores.history["episode_reward"])}')

经典游戏:打砖块(Breakout)

使用深度强化学习

import gym
import tensorflow as tf
from tensorflow.keras import layers
import numpy as np
class BreakoutAgent:
    def __init__(self, env):
        self.env = env
        self.state_size = (84, 84, 4)  # 84x84的灰度图,4帧堆叠
        self.action_size = env.action_space.n
        self.model = self.build_model()
    def build_model(self):
        """构建CNN模型"""
        model = tf.keras.Sequential([
            layers.Conv2D(32, (8, 8), strides=4, activation='relu', 
                         input_shape=self.state_size),
            layers.Conv2D(64, (4, 4), strides=2, activation='relu'),
            layers.Conv2D(64, (3, 3), strides=1, activation='relu'),
            layers.Flatten(),
            layers.Dense(512, activation='relu'),
            layers.Dense(self.action_size, activation='linear')
        ])
        model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(0.00025))
        return model
# 使用现成的强化学习库
from stable_baselines3 import DQN, PPO
from stable_baselines3.common.vec_env import DummyVecEnv
# 更简单的实现方式
def train_breakout():
    # 创建环境
    env = gym.make('Breakout-v4')
    env = DummyVecEnv([lambda: env])
    # 使用PPO算法
    model = PPO('CnnPolicy', env, verbose=1, 
                learning_rate=0.0001,
                n_steps=2048,
                batch_size=64)
    # 训练
    model.learn(total_timesteps=100000)
    # 保存模型
    model.save("breakout_ppo")
    # 测试
    obs = env.reset()
    for _ in range(1000):
        action, _states = model.predict(obs, deterministic=True)
        obs, rewards, dones, info = env.step(action)
        env.render()
    env.close()
# train_breakout()

自定义游戏:Flappy Bird

从零实现强化学习

import pygame
import random
import numpy as np
from collections import deque
import tensorflow as tf
from tensorflow.keras import layers
# 简化的Flappy Bird环境
class FlappyBirdEnv:
    def __init__(self):
        pygame.init()
        self.width = 288
        self.height = 512
        self.screen = pygame.display.set_mode((self.width, self.height))
        self.clock = pygame.time.Clock()
        self.bird_y = self.height // 2
        self.bird_velocity = 0
        self.gravity = 0.5
        self.jump_strength = -8
        self.pipe_width = 52
        self.pipe_gap = 100
        self.pipe_x = self.width
        self.pipe_height = random.randint(100, 400)
        self.score = 0
        self.game_over = False
    def reset(self):
        self.bird_y = self.height // 2
        self.bird_velocity = 0
        self.pipe_x = self.width
        self.pipe_height = random.randint(100, 400)
        self.score = 0
        self.game_over = False
        return self.get_state()
    def get_state(self):
        # 返回状态:相对位置、速度等
        return np.array([
            self.bird_y / self.height,
            self.bird_velocity / 10,
            (self.pipe_x - 50) / self.width,
            (self.pipe_height - 100) / 400
        ])
    def step(self, action):
        # action: 0=不操作, 1=跳跃
        if action == 1:
            self.bird_velocity = self.jump_strength
        # 物理更新
        self.bird_velocity += self.gravity
        self.bird_y += self.bird_velocity
        self.pipe_x -= 3
        # 碰撞检测
        reward = 0.1
        if (self.bird_y < 0 or self.bird_y > self.height or
            (self.pipe_x < 50 < self.pipe_x + self.pipe_width and
             (self.bird_y < self.pipe_height or 
              self.bird_y > self.pipe_height + self.pipe_gap))):
            self.game_over = True
            reward = -10
        # 通过管道
        if self.pipe_x + self.pipe_width < 0:
            self.score += 1
            reward = 10
            self.pipe_x = self.width
            self.pipe_height = random.randint(100, 400)
        return self.get_state(), reward, self.game_over
# DQN代理
class DQNAgent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.memory = deque(maxlen=2000)
        self.gamma = 0.95
        self.epsilon = 1.0
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.995
        self.learning_rate = 0.001
        self.model = self._build_model()
    def _build_model(self):
        model = tf.keras.Sequential([
            layers.Dense(24, input_shape=(self.state_size,), activation='relu'),
            layers.Dense(24, activation='relu'),
            layers.Dense(self.action_size, activation='linear')
        ])
        model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(lr=self.learning_rate))
        return model
    def remember(self, state, action, reward, next_state, done):
        self.memory.append((state, action, reward, next_state, done))
    def act(self, state):
        if np.random.rand() <= self.epsilon:
            return random.randrange(self.action_size)
        act_values = self.model.predict(state)
        return np.argmax(act_values[0])
    def replay(self, batch_size):
        if len(self.memory) < batch_size:
            return
        minibatch = random.sample(self.memory, batch_size)
        for state, action, reward, next_state, done in minibatch:
            target = reward
            if not done:
                target = reward + self.gamma * np.amax(self.model.predict(next_state)[0])
            target_f = self.model.predict(state)
            target_f[0][action] = target
            self.model.fit(state, target_f, epochs=1, verbose=0)
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay
# 训练函数
def train_flappy_bird():
    env = FlappyBirdEnv()
    state_size = 4
    action_size = 2
    agent = DQNAgent(state_size, action_size)
    episodes = 1000
    batch_size = 32
    for e in range(episodes):
        state = env.reset()
        state = np.reshape(state, [1, state_size])
        for time in range(500):
            action = agent.act(state)
            next_state, reward, done = env.step(action)
            next_state = np.reshape(next_state, [1, state_size])
            agent.remember(state, action, reward, next_state, done)
            state = next_state
            if done:
                print(f"Episode {e+1}/{episodes}, Score: {env.score}")
                break
            if len(agent.memory) > batch_size:
                agent.replay(batch_size)
    # 保存模型
    agent.model.save("flappy_bird_dqn.h5")
    print("训练完成!")
# train_flappy_bird()

使用预训练模型玩游戏

# 更实用的方式:使用预训练模型
from stable_baselines3 import DQN
import gym
def play_with_pretrained():
    # 加载预训练模型(需要先下载)
    # 实际使用时可以从网上下载预训练权重
    model = DQN.load("path_to_pretrained_model")
    env = gym.make('CartPole-v1')
    obs = env.reset()
    while True:
        action, _states = model.predict(obs, deterministic=True)
        obs, rewards, dones, info = env.step(action)
        env.render()
        if dones:
            obs = env.reset()
# play_with_pretrained()

进阶:使用Ray实现分布式强化学习

# 安装: pip install ray[rllib]
import ray
from ray import tune
from ray.rllib.agents.ppo import PPOTrainer
ray.init()
# 配置和训练
config = {
    "env": "CartPole-v1",
    "lr": 0.0001,
    "num_workers": 4,
    "train_batch_size": 4000,
}
# 自动调参训练
analysis = tune.run(
    "PPO",
    config=config,
    stop={"episode_reward_mean": 200},
    num_samples=3,
)
print("最佳配置:", analysis.get_best_config(metric="episode_reward_mean", mode="max"))

学习路径建议

  1. 入门顺序

    • 先理解CartPole(最简单的控制问题)
    • 再尝试经典Atari游戏(如Breakout)
    • 最后尝试自定义游戏
  2. 调试技巧

    • 使用TensorBoard监控训练过程
    • 记录奖励曲线
    • 可视化智能体的行为
  3. 资源推荐

    • OpenAI Gym: 标准游戏环境
    • Stable-Baselines3: 成熟的算法库
    • RLlib: 分布式强化学习
    • CleanRL: 简单实现的强化学习算法

这些案例涵盖了从简单到复杂的强化学习应用,建议从CartPole开始,逐步加深理解,强化学习的训练可能需要大量时间和计算资源,可以先使用小规模环境进行测试。

抱歉,评论功能暂时关闭!