Python-DQN代码阅读(8)

目录

1.代码

1.1 代码总括

1.2 代码分解

1.2.1 action = np.random.choice(np.arange(len(action_probs)), p=action_probs)

1.2.2 env.render()

1.2.3 next_state_img, reward, done, info = env.step(VALID_ACTIONS[action])

1.2.4 info_ale_lives = int(info['ale.lives'])

1.2.5 next_state_img = state_processor.process(sess, next_state_img)

1.2.6 next_state = np.zeros((84, 84, 4), dtype=np.uint8)

1.2.7 episode_rewards += reward

1.2.8 time_steps += 1

1.2.9 reward = np.sign(reward)


1.代码

1.1 代码总括

# 初始化变量
time_to_fire = False
steps_in_this_life = 0
num_no_ops_this_life = np.random.randint(low=0, high=7)
ale_lives = info_ale_lives

# 根据时间步数和生命数判断是否需要执行新的游戏或新的生命
if time_steps == 0 or ale_lives != info_ale_lives:
    steps_in_this_life = 0
    num_no_ops_this_life = np.random.randint(low=0, high=7)
    action_probs = [0.0, 1.0, 0.0, 0.0]  # 执行 fire 动作
    time_to_fire = True
    if ale_lives != info_ale_lives:
        ale_lives = info_ale_lives
else:
    action_probs = policy(sess, state, epsilon)  # 根据策略网络获取动作概率

# 根据生命数和时间步数判断是否执行无操作
steps_in_this_life += 1
if steps_in_this_life < num_no_ops_this_life and not time_to_fire:
    action_probs = [1.0, 0.0, 0.0, 0.0]  # 执行 no-op 动作

# 从动作概率分布中选择动作
action = np.random.choice(np.arange(len(action_probs)), p=action_probs)

# 渲染当前环境状态
env.render()

# 执行选择的动作并获取下一个时间步的状态、奖励、完成状态和其他信息
next_state_img, reward, done, info = env.step(VALID_ACTIONS[action])

# 获取当前生命数
info_ale_lives = int(info['ale.lives'])

# rewards = -1,0,+1 as done in the paper
# reward = np.sign(reward)

# 预处理下一个时间步的状态  注意state_processor有降维tf.squeeze()的过程
next_state_img = state_processor.process(sess, next_state_img)

# state is of size [84,84,4]; next_state_img is of size[84,84]
# next_state = np.append(state[:,:,1:], np.expand_dims(next_state, 2), axis=2)

# 创建新的状态,将预处理后的状态添加到状态序列的末尾
next_state = np.zeros((84, 84, 4), dtype=np.uint8)
next_state[:, :, 0] = state[:, :, 1]
next_state[:, :, 1] = state[:, :, 2]
next_state[:, :, 2] = state[:, :, 3]
next_state[:, :, 3] = next_state_img

# 累加当前时间步的奖励
episode_rewards += reward

# 更新时间步数
time_steps += 1

1.2 代码分解

1.2.1 action = np.random.choice(np.arange(len(action_probs)), p=action_probs)

action = np.random.choice(np.arange(len(action_probs)), p=action_probs)

从概率分布 action_probs 中根据概率选择一个动作,将其索引赋值给 action 变量,表示当前时间步选择的动作。

这行代码使用 np.random.choice 函数根据动作概率分布 action_probs 来随机选择一个动作,并将选中的动作赋值给 action。

具体解释如下:

np.random.choice 函数用于从给定的一维数组中进行随机采样,并返回一个随机选中的元素。
np.arange(len(action_probs)) 生成了一个从 0 到 len(action_probs)-1 的整数数组,用于作为随机采样的候选动作。
p=action_probs 参数指定了每个候选动作的选择概率,即动作概率分布。
action 是从候选动作中随机选中的动作,作为智能体当前时刻的动作选择。
这段代码的作用是根据动作概率分布 action_probs 来随机选择一个动作,并将选中的动作赋值给 action 变量,作为智能体在当前时刻的动作选择。选中的动作会用于后续的环境交互和经验存储。

1.2.2 env.render()

env.render()

调用环境的 render() 方法,将当前环境状态渲染到屏幕上,以便可视化。

  • 注意,在实际训练过程中,由于渲染操作可能会消耗较多的计算资源,通常会在训练时禁用渲染以提高训练效率,仅在需要可视化时才会启用渲染。

1.2.3 next_state_img, reward, done, info = env.step(VALID_ACTIONS[action])

next_state_img, reward, done, info = env.step(VALID_ACTIONS[action])

通过调用环境的 step() 方法,传入 action 变量作为当前时间步选择的动作,获取下一个时间步的状态 next_state_img、奖励 reward、完成状态 done 和其他信息 info

env.step(VALID_ACTIONS[action]) 是在 OpenAI Gym 环境中执行动作 VALID_ACTIONS[action],并返回执行该动作后的下一个状态 next_state_img,奖励值 reward,结束标志 done,以及其他环境信息 info这里的 VALID_ACTIONS[action] 是根据之前选择的动作索引 action 在动作空间 VALID_ACTIONS 中选取对应的动作。next_state_img 表示执行动作后的图像状态,reward 表示执行动作后获得的奖励值,done 表示环境是否结束,info 包含了其他与环境相关的信息。

1.2.4 info_ale_lives = int(info['ale.lives'])

info_ale_lives = int(info['ale.lives'])

info 字典中获取 'ale.lives' 键对应的值,表示当前生命中剩余的生命数,并将其转换为整数类型,赋值给 info_ale_lives 变量。

info['ale.lives'] 是从环境信息 info 中获取当前游戏中剩余生命值的属性值。通过 int() 函数将其转换为整数类型,并赋值给 info_ale_lives 变量,用于后续的比较和判断。这里的 'ale.lives' 是一种常见的属性名称,可能是在使用 Atari 游戏环境时,环境信息中记录了游戏的生命值信息,并以 'ale.lives' 进行命名。

1.2.5 next_state_img = state_processor.process(sess, next_state_img)

next_state_img = state_processor.process(sess, next_state_img)

通过调用 state_processor 对象的 process() 方法,将获取到的下一个时间步的状态 next_state_img 进行预处理。

这行代码调用了 state_processor.process() 方法,用于处理环境返回的下一步状态。

具体解释如下:

state_processor 是一个用于处理状态的对象,可能包含了对状态进行预处理或者特征提取的逻辑。
sess 是 TensorFlow 会话,用于执行 TensorFlow 计算图中的操作。
next_state_img 是从环境中获得的下一步状态,通过 env.step() 函数返回。
state_processor.process(sess, next_state_img) 是对下一步状态进行处理的方法,它接受 TensorFlow 会话和下一步状态作为输入,并返回处理后的状态。
处理后的状态会被赋值给 next_state_img 变量,供后续使用。

1.2.6 next_state = np.zeros((84, 84, 4), dtype=np.uint8)

next_state = np.zeros((84, 84, 4), dtype=np.uint8)
next_state[:, :, 0] = state[:, :, 1]
next_state[:, :, 1] = state[:, :, 2]
next_state[:, :, 2] = state[:, :, 3]
next_state[:, :, 3] = next_state_img

这部分代码是为了更新状态 next_state 的四个通道,实现滑动窗口的效果。具体操作如下:

  1. 创建一个全零数组 next_state,形状为 (84, 84, 4),数据类型为 np.uint8,表示每个像素的取值范围在 0 到 255 之间。

  2. 将当前状态 state 中的通道 1 到 3 的数据赋值给 next_state 中的通道 0 到 2,相当于将通道 1 到 3 的数据往前滑动了一位。

  3. next_state_img(从环境中获取的下一状态的图像数据)赋值给 next_state 中的通道 3,作为滑动窗口后的最新状态。

这样,next_state 中的四个通道分别表示当前状态和前三个状态的图像数据,实现了滑动窗口的效果,用于构建状态序列。

1.2.7 episode_rewards += reward

episode_rewards += reward

将当前时间步的奖励 reward 累加到 episode_rewards 变量中,用于记录当前回合的总奖励。

1.2.8 time_steps += 1

time_steps += 1

time_steps 变量的值递增1,用于记录当前回合中已经经过的时间步数。

1.2.9 reward = np.sign(reward)

reward = np.sign(reward)

这行代码将原始的奖励值 reward 转换为其符号的值,即将正数映射为 1,将负数映射为 -1,将零映射为 0。这种处理常用于强化学习中,旨在将奖励值标准化为固定的取值范围,使得算法在处理不同任务时具有一定的一致性。在这段代码中,通过 np.sign() 函数来实现奖励值的符号映射操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的DQN(Deep Q-Network)的Python实现,使用TensorFlow 2.0框架: ```python import gym import tensorflow as tf import numpy as np class DQNAgent: def __init__(self, env): # 初始化环境和神经网络参数 self.env = env self.input_shape = env.observation_space.shape self.output_shape = env.action_space.n self.learning_rate = 0.001 self.gamma = 0.95 self.epsilon = 1.0 self.epsilon_decay = 0.995 self.epsilon_min = 0.01 self.memory = [] self.batch_size = 32 self.model = self.build_model() def build_model(self): # 构建神经网络模型 model = tf.keras.models.Sequential() model.add(tf.keras.layers.Dense(24, input_shape=self.input_shape, activation='relu')) model.add(tf.keras.layers.Dense(24, activation='relu')) model.add(tf.keras.layers.Dense(self.output_shape, activation='linear')) model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(lr=self.learning_rate)) return model def act(self, state): # 选择行动 if np.random.rand() <= self.epsilon: return self.env.action_space.sample() else: return np.argmax(self.model.predict(state)) def remember(self, state, action, reward, next_state, done): # 存储经验 self.memory.append((state, action, reward, next_state, done)) def replay(self): # 经验回放 if len(self.memory) < self.batch_size: return batch = np.random.choice(self.memory, self.batch_size) for state, action, reward, next_state, done in batch: 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(self, episodes): # 开始训练 for i in range(episodes): state = self.env.reset() state = np.reshape(state, [1, self.input_shape[0]]) done = False score = 0 while not done: action = self.act(state) next_state, reward, done, info = self.env.step(action) next_state = np.reshape(next_state, [1, self.input_shape[0]]) self.remember(state, action, reward, next_state, done) state = next_state score += reward self.replay() print('Episode: %d, Score: %d, Epsilon: %.2f' % (i, score, self.epsilon)) if __name__ == "__main__": env = gym.make('CartPole-v0') agent = DQNAgent(env) agent.train(1000) ``` 这个代码实现了一个DQN智能体,用于在OpenAI Gym的CartPole任务中学习。 该智能体使用经验回放来训练其神经网络,以使其能够预测最佳行动,并且逐渐减小其随机探索率,以便更多地依赖于其神经网络的输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天寒心亦热

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值