【RL】基于迁移学习的强化学习(RL-TL)算法

举报
不去幼儿园 发表于 2024/12/02 20:22:12 2024/12/02
【摘要】 基于迁移学习的强化学习(Reinforcement Learning with Transfer Learning,简称 RL-TL)是将迁移学习(Transfer Learning)的概念应用于强化学习(Reinforcement Learning,简称 RL)中的一种方法。其核心思想是在强化学习的环境中,利用已有的经验或在其他任务中学到的知识来提升学习效率和表现。这样可以减少从零开始学习的时间

        📢本篇文章是博主强化学习RL领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:

       【强化学习】(5)---《基于迁移学习的强化学习(RL-TL)算法》

基于迁移学习的强化学习(RL-TL)算法

目录

1.RL-TL 的基本概念

2.RL-TL 的常见方法

3.RL-TL的优劣

4.应用场景

5.相关论文阅读

6.总结

[Python]基于迁移学习的强化学习实现

[Results] 运行结果

[Notice]  代码说明

[Notice]  结果说明


        基于迁移学习的强化学习Reinforcement Learning with Transfer Learning,简称 RL-TL)是将迁移学习(Transfer Learning)的概念应用于强化学习(Reinforcement Learning,简称 RL)中的一种方法。其核心思想是在强化学习的环境中,利用已有的经验或在其他任务中学到的知识来提升学习效率和表现。这样可以减少从零开始学习的时间和样本需求,尤其在数据稀缺或任务复杂的场景中。


1.RL-TL 的基本概念

  1. 强化学习(RL):
    RL 是通过智能体与环境的交互,学习在不同状态下采取最优动作的技术。智能体通过试错学习,不断优化其策略(policy),以最大化累计奖励(reward)。

  2. 迁移学习(TL):
    TL 的目标是利用在某个源任务(source task)中学到的知识,帮助目标任务(target task)中的学习。通过知识迁移,可以减少目标任务的训练时间,或提升其最终的学习效果。

  3. RL-TL 的结合:
    在 RL-TL 中,智能体不仅依赖于目标任务中的反馈,还从源任务中获取知识。不同于传统的 RL 必须从头开始学习,RL-TL 能够通过迁移已有的策略、模型或者经验来加速学习过程。


2.RL-TL 的常见方法

  1. 策略迁移(Policy Transfer)
    从源任务中获取策略,并将其应用于目标任务中。可以是直接使用,也可以是通过微调(fine-tuning)的方法进行优化。如果目标任务与源任务具有相似性,策略迁移可以显著减少探索的时间。

  2. 值函数迁移(Value Function Transfer)
    强化学习中常使用的值函数(如 Q-learning 的 Q 值)表示状态-动作对的期望奖励。通过迁移源任务的值函数,可以为目标任务提供一个良好的初始估计,从而加速学习过程。

  3. 特征迁移(Feature Transfer)
    一些强化学习任务可能涉及高维度的状态空间,使用源任务中提取的有用特征可以有效降低维度,帮助智能体更快找到最优策略。特征迁移可以包括状态特征、动作特征等。

  4. 经验回放迁移(Experience Replay Transfer)
    在经验回放机制中,智能体存储其与环境交互的历史轨迹数据,供后续学习使用。通过在源任务中收集的轨迹数据,RL-TL 可以利用这些经验来提升目标任务的学习。


3.RL-TL的优劣

RL-TL 的优势

  • 数据高效性:
    通过迁移学习,智能体可以在少量样本的情况下获得较好的表现,尤其是在目标任务中的数据稀缺的情况下。

  • 减少训练时间:
    由于源任务中已有经验的帮助,RL-TL 能够减少探索的时间,快速找到目标任务的最佳策略。

  • 跨任务的泛化能力:
    RL-TL 能够提升智能体在多个任务之间的泛化能力,这使得智能体在面对变化的环境或新任务时,仍能够表现良好。

RL-TL 的挑战

  1. 任务相似性:
    如果源任务和目标任务差异过大,迁移的知识可能会产生负面影响(即“负迁移”),导致目标任务的表现不佳。因此,任务之间的相似性是成功迁移的关键。

  2. 如何选择迁移的内容:
    决定迁移策略、值函数、特征或者经验回放,是需要基于具体任务特点进行的,选择不当会影响学习效果。

  3. 源任务的选择:
    理想的源任务应具备与目标任务相似的环境或动态特性,但在实际场景中,选择适合的源任务可能需要一些额外的工作和判断。


4.应用场景

  • 机器人控制:
    不同机器人任务之间的相似性使得 RL-TL 能有效迁移控制策略,从而实现不同任务的快速适应。

  • 游戏 AI:
    在不同但相关的游戏环境中,游戏 AI 可以通过迁移学习加速学习进程,减少复杂策略的探索时间。

  • 自动驾驶:
    在自动驾驶的应用中,不同道路场景之间的相似性可以通过 RL-TL 来加速驾驶策略的学习,尤其在模拟环境中已有较多经验积累时。


5.相关论文阅读

        下面是一些关于**基于强化学习的迁移学习(Reinforcement Learning with Transfer Learning, RL-TL)**的重要研究论文的详细介绍:

1. "强化学习领域中的迁移学习"(Matthew E. Taylor 和 Peter Stone, 2009)

摘要:
        该论文提供了关于强化学习中迁移学习技术的全面综述。作者对现有的迁移学习方法进行了分类,并讨论了迁移学习在强化学习领域中的理论和实证基础。文章重点探讨了迁移的关键组成部分,如迁移的知识类型(策略、值函数、特征等)以及任务的性质(源任务和目标任务)。

关键概念:

  • 知识迁移: 可以将不同类型的知识(策略、值函数、特征)迁移到新任务中。
  • 任务相似性: 一个关键挑战是如何确定两个任务之间是否足够相似以便有效迁移。
  • 迁移场景: 文章还概述了几种迁移场景,包括任务间映射和领域适应。

应用:

  • 方法被应用于强化学习任务,如机器人导航和模拟控制任务。
  • 通过从较简单任务中迁移学习的策略,显著加快了复杂环境中的学习。

结论:
如果源任务与目标任务足够相关,迁移学习可以显著减少强化学习任务所需的训练量。

引用:
Taylor, M. E., & Stone, P. (2009). Transfer learning for reinforcement learning domains: A survey. Journal of Machine Learning Research, 10, 1633-1685.


2. "深度强化学习中的迁移学习:综述"(Tianjun Zhang 等, 2020)

摘要:
        这篇论文扩展了迁移学习在**深度强化学习(Deep Reinforcement Learning, DRL)**中的应用,重点介绍了在深度强化学习中使用的迁移机制,如网络微调、共享表示以及卷积网络中提取的特征迁移。

关键概念:

  • 表示迁移: 论文解释了如何在深度网络中共享特征提取层,以减少学习时间。
  • 预训练模型: 讨论了如何使用源任务的预训练网络,通过微调加速目标任务学习。
  • 元学习(Meta-learning): 讨论了迁移学习技术与元学习的重叠,元学习的目标是训练能够快速适应新任务的智能体。

挑战:

  • 负迁移: 文章探讨了避免负迁移的策略,负迁移会导致迁移错误知识时,性能受损。
  • 泛化能力: 重点关注如何在不同任务之间泛化知识,即使任务之间差异显著。

应用:

  • 应用于如Atari游戏、机器人操作和多智能体强化学习等环境。
  • 在复杂环境中如Mujoco星际争霸 II中展示了显著的改进。

结论:
        深度强化学习从迁移学习中获益显著,特别是当任务具有结构相似性时。然而,负迁移的防止和稳健性仍是需要进一步解决的挑战。

引用:
Zhang, T., Hsieh, C., Liu, J., & Zhang, C. (2020). A survey on transfer learning for deep reinforcement learning. arXiv preprint arXiv:2009.07888.

        这些论文展示了**基于强化学习的迁移学习(RL-TL)**在传统强化学习到深度学习场景中的各种方法,涵盖了任务间策略迁移、值函数迁移和多任务学习等内容。它们是理解 RL-TL 最新技术的宝贵资源。


6.总结

        基于迁移学习的强化学习(RL-TL)是一种高效的学习方法,通过从源任务中借鉴经验或知识,提升目标任务的学习速度和性能。随着强化学习在复杂环境中的应用日益增多,RL-TL 提供了一种减少训练时间、提高数据效率的途径。然而,RL-TL 的成功实施依赖于任务相似性、迁移策略的合理选择等因素,需要针对具体问题进行设计和优化。


[Python]基于迁移学习的强化学习实现

        以下是一个基于 迁移学习 的强化学习(Reinforcement Learning with Transfer Learning)代码示例,使用 PyTorchOpenAI Gym。我们将先在一个简单的环境中(如 CartPole)训练一个 Q-learning 算法,并将其学到的策略迁移到另一个稍微不同的环境(如 MountainCar),通过微调来适应目标环境。

安装依赖

首先,确保安装了以下依赖:

pip install torch gym numpy

我们使用深度 Q 网络(DQN)算法进行迁移学习。

1. 在源环境中训练模型 (CartPole-v1)

"""《基于迁移学习的强化学习代码示例》
    时间:2024.09.22
    作者:不去幼儿园
"""
import gym
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import random
from collections import deque

# 定义 Q 网络
class QNetwork(nn.Module):
	def __init__(self, state_dim, action_dim):
		super(QNetwork, self).__init__()
		self.fc1 = nn.Linear(state_dim, 128)
		self.fc2 = nn.Linear(128, 128)
		self.fc3 = nn.Linear(128, action_dim)

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

# Replay buffer,用于存储经验
class ReplayBuffer:
	def __init__(self, capacity):
		self.buffer = deque(maxlen=capacity)

	def add(self, transition):
		self.buffer.append(transition)

	def sample(self, batch_size):
		transitions = random.sample(self.buffer, batch_size)

		# 从 transitions 中解压各个元素
		states, actions, rewards, next_states, dones = zip(*transitions)

		# 将 states 和 next_states 转换为 numpy 数组时保持维度一致,使用 np.stack 而不是 np.array
		states = np.stack(states)  # 将状态堆叠为多维数组
		next_states = np.stack(next_states)  # 保证 next_states 也被堆叠为多维数组

		actions = np.array(actions, dtype=np.int64)  # 动作通常是整数
		rewards = np.array(rewards, dtype=np.float32)  # 奖励通常是浮点数
		dones = np.array(dones, dtype=np.float32)  # dones 是布尔值,用浮点数表示

		return states, actions, rewards, next_states, dones

	def size(self):
		return len(self.buffer)

# 选择动作
def select_action(state, policy_net, epsilon, action_dim):
	if random.random() < epsilon:
		return random.choice(np.arange(action_dim))
	else:
		with torch.no_grad():
			state = torch.FloatTensor(state).unsqueeze(0)
			q_values = policy_net(state)
			return q_values.argmax().item()

# Q-learning 更新
def update_model(policy_net, target_net, optimizer, replay_buffer, batch_size, gamma):
	if replay_buffer.size() < batch_size:
		return

	states, actions, rewards, next_states, dones = replay_buffer.sample(batch_size)

	states = torch.FloatTensor(states)
	actions = torch.LongTensor(actions)
	rewards = torch.FloatTensor(rewards)
	next_states = torch.FloatTensor(next_states)
	dones = torch.FloatTensor(dones)

	q_values = policy_net(states).gather(1, actions.unsqueeze(1)).squeeze(1)
	next_q_values = target_net(next_states).max(1)[0]
	target_q_values = rewards + gamma * next_q_values * (1 - dones)

	loss = (q_values - target_q_values.detach()).pow(2).mean()

	optimizer.zero_grad()
	loss.backward()
	optimizer.step()

# 训练模型
def train_dqn(env_name, num_episodes=500, gamma=0.99, epsilon_start=1.0, epsilon_end=0.01, epsilon_decay=0.995, batch_size=64):
	env = gym.make(env_name)
	state_dim = env.observation_space.shape[0]
	action_dim = env.action_space.n

	policy_net = QNetwork(state_dim, action_dim)
	target_net = QNetwork(state_dim, action_dim)
	target_net.load_state_dict(policy_net.state_dict())
	target_net.eval()

	optimizer = optim.Adam(policy_net.parameters())
	replay_buffer = ReplayBuffer(10000)
	epsilon = epsilon_start

	for episode in range(num_episodes):
		state, _ = env.reset()  # 只获取 state,忽略 info
		total_reward = 0

		while True:
			action = select_action(state, policy_net, epsilon, action_dim)
			next_state, reward, done, _, __ = env.step(action)  # 只获取 next_state,忽略其他
			replay_buffer.add((state, action, reward, next_state, done))
			state = next_state
			total_reward += reward

			update_model(policy_net, target_net, optimizer, replay_buffer, batch_size, gamma)

			if done:
				print(f"Episode {episode + 1}/{num_episodes}, Total Reward: {total_reward}")
				break

		epsilon = max(epsilon_end, epsilon_decay * epsilon)

		if episode % 10 == 0:
			target_net.load_state_dict(policy_net.state_dict())

	return policy_net

# 在源环境(CartPole)中训练模型
policy_net_cartpole = train_dqn(env_name='CartPole-v1')

2. 将模型迁移到目标环境 (MountainCar-v0) 并进行微调

        接下来,将在 CartPole-v1 环境中训练的 Q 网络迁移到另一个目标环境 MountainCar-v0,并通过微调适应新环境。

        由于源环境 CartPole-v1 和目标环境 MountainCar-v0 之间的状态空间和动作空间的维度不同,导致模型在迁移时无法直接加载预训练的权重。具体来说:

  1. CartPole-v1 的状态维度是 4,而 MountainCar-v0 的状态维度是 2。这导致模型的输入层权重维度不匹配。
  2. CartPole-v1 的动作维度是 2,而 MountainCar-v0 的动作维度是 3。这导致模型输出层的权重和偏置不匹配。

        需要保留预训练模型中可迁移的部分(如隐藏层的权重),而重新初始化输入层和输出层,以适应目标环境的状态和动作空间。

# 定义函数以匹配网络的结构,进行部分权重的迁移
def transfer_weights(policy_net, target_env_state_dim, target_env_action_dim):
	# 获取预训练的网络
	pretrained_dict = policy_net.state_dict()

	# 创建新网络,适应目标环境的状态和动作维度
	new_policy_net = QNetwork(target_env_state_dim, target_env_action_dim)

	# 获取新网络的权重
	new_dict = new_policy_net.state_dict()

	# 仅保留在预训练网络和新网络中都有的层(即隐藏层的参数)
	pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in new_dict and 'fc1' not in k and 'fc3' not in k}

	# 更新新网络的权重
	new_dict.update(pretrained_dict)

	# 将更新后的字典加载到新模型中
	new_policy_net.load_state_dict(new_dict)

	return new_policy_net


# 微调模型
def fine_tune_dqn(policy_net, env_name, num_episodes=200, gamma=0.99, epsilon_start=0.1, epsilon_end=0.01, epsilon_decay=0.995, batch_size=64):
	env = gym.make(env_name)
	target_state_dim = env.observation_space.shape[0]
	target_action_dim = env.action_space.n

	# 调用 transfer_weights 函数,将权重从 CartPole 模型迁移到新的 MountainCar 模型
	policy_net = transfer_weights(policy_net, target_state_dim, target_action_dim)

	target_net = QNetwork(target_state_dim, target_action_dim)
	target_net.load_state_dict(policy_net.state_dict())
	target_net.eval()

	optimizer = optim.Adam(policy_net.parameters())
	replay_buffer = ReplayBuffer(10000)
	epsilon = epsilon_start

	for episode in range(num_episodes):
		state, _ = env.reset()  # 只获取 state,忽略 info
		total_reward = 0

		while True:
			action = select_action(state, policy_net, epsilon, target_action_dim)
			next_state, reward, done, _, __ = env.step(action)  # 只获取 next_state,忽略其他
			replay_buffer.add((state, action, reward, next_state, done))
			state = next_state
			total_reward += reward

			update_model(policy_net, target_net, optimizer, replay_buffer, batch_size, gamma)

			if done:
				print(f"Episode {episode + 1}/{num_episodes}, Total Reward: {total_reward}")
				break

		epsilon = max(epsilon_end, epsilon_decay * epsilon)

		if episode % 10 == 0:
			target_net.load_state_dict(policy_net.state_dict())

	return policy_net

# 微调源环境训练的策略网络到目标环境 MountainCar
fine_tuned_policy_net = fine_tune_dqn(policy_net_cartpole, env_name='MountainCar-v0')

 3. 测试模型在 MountainCar-v0 环境中的表现

       运行此代码将会显示模型在 MountainCar-v0 环境中的测试表现,你可以根据结果评估模型的迁移学习效果。

# 测试微调后的策略并显示动画
def test_policy_with_animation(policy_net, env_name, num_episodes=5, max_steps=200):
	# 初始化环境并启用动画显示
	env = gym.make(env_name, render_mode="human")
	total_rewards = []

	for episode in range(num_episodes):
		state, _ = env.reset()  # 获取初始状态
		total_reward = 0

		for step in range(max_steps):
			# 选择动作,不使用探索
			action = select_action(state, policy_net, epsilon=0.0, action_dim=env.action_space.n)
			next_state, reward, done, _, __ = env.step(action)  # 执行动作
			total_reward += reward
			state = next_state  # 更新状态

			if done:
				break  # 结束当前回合

		total_rewards.append(total_reward)
		print(f"Episode {episode + 1}/{num_episodes}, Total Reward: {total_reward}")

	# 关闭环境
	env.close()
	print(f"Average Total Reward over {num_episodes} episodes: {np.mean(total_rewards)}")
	return total_rewards


# 测试微调后的策略网络在 MountainCar 环境中的表现
test_rewards = test_policy_with_animation(fine_tuned_policy_net, env_name='MountainCar-v0')

[Results] 运行结果

可直接运行的项目python代码:

 RL基于迁移学习的强化学习(RL-TL)

        🔥若是代码复现困难或者有问题,欢迎评论区留言;需要以整个项目形式的代码,请在评论区留下您的邮箱📌,以便于及时分享给您(私信难以及时回复)。


[Notice]  代码说明

  1. Q 网络定义QNetwork 是一个简单的前馈神经网络,用于估计状态动作值(Q 值)。

  2. Replay Buffer:使用 ReplayBuffer 存储经验,以便进行经验回放,减少样本的相关性。

  3. 训练过程

    • 源环境训练(CartPole):我们首先在 CartPole-v1 环境上使用 DQN 训练模型。
    • 策略迁移:将学到的 QNetwork 模型迁移到 MountainCar-v0 环境,并在新的环境上进行微调,适应新的任务。
  4. 微调过程:微调时,采用较小的 epsilon 值(例如从 0.1 开始),表示我们对新任务有部分知识,并减少探索。随着训练的进行,epsilon 会逐渐衰减。

  5. 测试过程:运行 test_policy_with_animation将会显示模型在 MountainCar-v0 环境中的测试表现,你可以根据结果评估模型的迁移学习效果。

执行步骤

  1. 训练源环境:首先在 CartPole-v1 环境中训练 Q 网络策略,积累源任务的经验。
  2. 迁移并微调:将训练好的模型迁移到新的 MountainCar-v0 环境,通过少量微调适应目标任务。
  3. 新环境中测试:测试模型在 MountainCar-v0 环境中的表现

总结

        这个代码示例展示了如何使用迁移学习的思想,将在一个环境中学到的策略迁移到另一个相关的环境中。我们在 CartPole-v1 中训练了一个深度 Q 网络,并通过迁移学习在 MountainCar-v0 中对其进行微调,使模型能够适应新任务。


[Notice]  结果说明

          迁移学习后在 MountainCar-v0 环境中的奖励值结果较差,并且奖励值为负值,负值奖励是因为 MountainCar 环境本身的设计以及与 CartPole 环境的差异。这种情况常见于迁移学习中的两个任务差异较大时,源任务的学习策略并不适合直接应用于目标任务。

这具体体现在以下几个方面:

1. 源任务和目标任务的本质不同

  • CartPole-v1:任务目标是保持小车的平衡,状态维度为 4,动作空间为 2(向左、向右)。奖励机制是每一步都有正奖励,目标是最大化存活时间。
  • MountainCar-v0:任务目标是驱动车从山谷中爬到山顶,状态维度为 2,动作空间为 3(推车左、推车右、无动作)。奖励机制是每一步都有  奖励(-1),只有当车达到山顶时才会终止。

        因此,CartPole 中学到的策略很难直接应用到 MountainCar,因为两个环境的动力学、目标和奖励机制都有很大差异。

2. 负奖励的来源

        在 MountainCar-v0 环境中,智能体每执行一步就会收到 -1 的奖励,直到车达到目标位置(山顶),奖励累积自然为负数。特别是在迁移初期,智能体没有学会正确的爬坡策略,因此会在山谷中反复移动,得到更多的负奖励。

3. 迁移学习的挑战

        由于源环境(CartPole)和目标环境(MountainCar)的状态、动作空间以及任务目标差异较大,迁移的初期效果往往较差,甚至表现比随机策略还差CartPole 的策略试图通过平衡,而在 MountainCar 中,成功的策略则需要激进的左右移动来获得足够的动能爬到山顶。

4. 可能的解决方案

要提高迁移学习的效果,可以尝试以下方法:

  • 更长时间的微调:微调时间过短可能不足以让智能体学会 MountainCar 环境中的最佳策略。延长微调的训练时间可以帮助智能体逐渐学习如何在目标任务中表现得更好。

  • 调整探索策略:在迁移学习中,减少初期的探索率可能会导致智能体没有足够的探索来适应新环境。可以增加 epsilon 初期值(如 0.5 或 0.9),并减缓其衰减速率,这样智能体可以更多地探索不同的动作。

  • 使用更适合的初始化:仅迁移隐藏层的权重,重新初始化输入层和输出层,这在一定程度上可以帮助智能体在新的环境中从更合适的状态开始微调。

  • 多任务学习:如果目标任务和源任务差异较大,可以通过多任务学习的方法,让智能体同时在两个任务上学习,增加其适应不同任务的能力。

        奖励值较低的情况主要是由于 CartPoleMountainCar 两个环境差异太大,导致迁移学习策略初期表现不好。这是正常的情况,随着更长时间的微调和探索策略的调整,智能体在 MountainCar 中的表现应该会逐渐改善。


        文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者添加VXRainbook_2联系作者。✨

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。