DQN理解输入和输出(层)



我有一个关于DQN的输入和输出(层(的问题。

例如

两点:P1(x1,y1(和P2(x2,y2(

P1必须走向P2

我有以下信息:

  • 当前位置P1(x/y(
  • 当前位置P2(x/y(
  • 到P1-P2的距离(x/y(
  • 至P1-P2的方向(x/y(

P1有4种可能的操作:

  • 向上
  • 向下
  • 左侧

我必须如何设置输入和输出层?

  • 4个输入节点
  • 4个输出节点

对吗?我该如何处理输出?我得到了4个数组,每个数组有4个值作为输出。对输出执行argmax是否正确?

编辑:

输入/状态:

# Current position P1
state_pos = [x_POS, y_POS]
state_pos = np.asarray(state_pos, dtype=np.float32)
# Current position P2
state_wp = [wp_x, wp_y]
state_wp = np.asarray(state_wp, dtype=np.float32)
# Distance P1 - P2 
state_dist_wp = [wp_x - x_POS, wp_y - y_POS]
state_dist_wp = np.asarray(state_dist_wp, dtype=np.float32)
# Direction P1 - P2
distance = [wp_x - x_POS, wp_y - y_POS]
norm = math.sqrt(distance[0] ** 2 + distance[1] ** 2)
state_direction_wp = [distance[0] / norm, distance[1] / norm]
state_direction_wp = np.asarray(state_direction_wp, dtype=np.float32)
state = [state_pos, state_wp, state_dist_wp, state_direction_wp]
state = np.array(state)

网络:

def __init__(self):
self.q_net = self._build_dqn_model()
self.epsilon = 1 
def _build_dqn_model(self):
q_net = Sequential()
q_net.add(Dense(4, input_shape=(4,2), activation='relu', kernel_initializer='he_uniform'))
q_net.add(Dense(128, activation='relu', kernel_initializer='he_uniform'))
q_net.add(Dense(128, activation='relu', kernel_initializer='he_uniform'))
q_net.add(Dense(4, activation='linear', kernel_initializer='he_uniform'))
rms = tf.optimizers.RMSprop(lr = 1e-4)
q_net.compile(optimizer=rms, loss='mse')
return q_net
def random_policy(self, state):
return np.random.randint(0, 4)
def collect_policy(self, state):
if np.random.random() < self.epsilon:
return self.random_policy(state)
return self.policy(state)
def policy(self, state):
# Here I get 4 arrays with 4 values each as output
action_q = self.q_net(state)

在第一个密集层中添加input_shape=(4,2)会导致输出形状为(None, 4, 4)。定义q_net的方法如下:

q_net = Sequential()
q_net.add(Reshape(target_shape=(8,), input_shape=(4,2)))
q_net.add(Dense(128,  activation='relu', kernel_initializer='he_uniform'))
q_net.add(Dense(128, activation='relu', kernel_initializer='he_uniform'))
q_net.add(Dense(128, activation='relu', kernel_initializer='he_uniform'))
q_net.add(Dense(4, activation='linear', kernel_initializer='he_uniform'))
rms = tf.optimizers.RMSprop(lr = 1e-4)
q_net.compile(optimizer=rms, loss='mse')
return q_net

这里,q_net.add(Reshape(target_shape=(8,), input_shape=(4,2)))将(None,4,2(输入重塑为(None、8([这里,None表示批次形状]。

要进行验证,请打印q_net.output_shape,它应该是(None, 4)[而在前一种情况下,它是(None, 4, 4)]。

你还需要做一件事。回想一下,input_shape没有考虑批次形状。我的意思是,input_shape=(4,2)期望形状(batch_shape,4,2(的输入。通过打印q_net.input_shape进行验证,应输出(None, 4, 2)。现在,您要做的是在输入中添加一个批处理维度。您可以简单地执行以下操作:

state_with_batch_dim = np.expand_dims(state,0)

并将state_with_batch_dim作为输入传递给q_net。例如,您可以调用像policy(np.expand_dims(state,0))一样编写的policy方法,并获得维度为(batch_shape, 4)的输出[在本例中为(1,4)]。

以下是您最初问题的答案:

  1. 您的输出层应该有4个节点(单位(
  2. 第一个密集层不一定要有4个节点(单位(。如果考虑Reshape层,则节点或单元的概念不适用于此。您可以将Reshape层视为一个占位符,它采用形状为(None,4,2(的张量并输出形状为(None,8(的重塑张量
  3. 现在,您应该得到shape(None,4(的输出——在那里,4个值表示4个相应动作的q值。无需在此处执行argmax来查找q值

向DQN提供一些关于其当前面临的方向的信息也是有意义的。您可以将其设置为(当前位置X、当前位置Y、X来自目标、Y来自目标、方向(。

输出层应该按照您确定的顺序(向上、向左、向下、向右(。Argmax层适用于该问题。确切的代码取决于您是否使用TF/Pythorch。

相关内容

  • 没有找到相关文章

最新更新