最近在用DDPG算法解决无人机的轨迹优化问题 遇到了个问题——神经网络不管输入是什么 输出都一模一样 不变
结果一直是(0.5 0.5 0.5 0.5)(输入数据维度是46 输出是4)
研究了好多天了 减少神经元数量,改变优化器、损失函数种类 ,降低输入维度 都试过啦 还是不行 实在是不知道问题出在哪里啦 有知道的可以帮忙解决一下嘛 谢谢大家啦!
这是actor神经网络的模型:
class ActorNetwork(object):
"""
Implements actor network
"""
def __init__(self,sess,state_dim,action_dim,lr,tau):
self.sess = sess
K.set_session(sess)
K.set_learning_phase(1)
self.state_dim = state_dim
self.action_dim = action_dim
self.lr = lr
self.tau = tau
self.mainModel, self.mainModel_weights, self.mainModel_state = self._build_model()
self.targetModel, self.targetModel_weights, _ = self._build_model()
self.action_gradient = tf.placeholder(tf.float32, [None, self.action_dim])
self.params_grad = tf.gradients(self.mainModel.output, self.mainModel_weights, -self.action_gradient)
grads = zip(self.params_grad, self.mainModel_weights)
self.optimize = tf.train.AdamOptimizer(self.lr).apply_gradients(grads)
self.sess.run(tf.global_variables_initializer())
def _build_model(self):
input_obs = Input(shape=(self.state_dim,)) # 输入层 返回一个维度为self.state_dim的张量
h = BatchNormalization()(input_obs)
h = Dense(400, kernel_initializer = 'random_uniform')(h) # 全连接层 400个神经元(即该层的输出维度)
h = LeakyReLU(alpha=0.1)(h)
h = Dense(300, kernel_initializer = 'random_uniform')(h) # 全连接层 输出维度300
h = LeakyReLU(alpha=0.1)(h)
h = Dense(self.action_dim, kernel_initializer = 'random_uniform')(h) # 全连接层 输出维度self.action_dim
h = Activation('tanh')(h) # softmax 改为 tanh
pred = Lambda(lambda h: (h+1)/2)(h)
# RelaxedOneHotCategorical() 函数的作用??? 网络最终输出结果的范围???
# pred = Lambda(lambda h: tf.contrib.distributions.RelaxedOneHotCategorical(0.5, probs=h).sample())(h)
# 给定输入张量和输出张量 生成一个函数型模型 这里包括一个输入层和3个全连接层
model = Model(inputs=input_obs, outputs=pred)
# 用于配置训练模型 优化器:Adam 损失函数:categorical_crossentropy
model.compile(optimizer='Adam'(), loss='categorical_crossentropy')
return model, model.trainable_weights, input_obs
def act(self, state):
act = self.mainModel.predict(state)
return act
这是使用该神经网络获取动作值的部分:
```python
for stp in range(int(args['max_episode_len'])):
a = []
for i in range(env.num_UAVs):
actor = actors[i]
a.append(actor.act(np.reshape(s[i], (-1, actor.state_dim))).reshape(actor.action_dim, )) # 输入状态 输出动作
# reshape 在不改变数据内容的情况下,改变一个数组的格式
# (-1,actor.state_dim) 表示将智能体i的状态信息转化为列数为actor.state_dim的矩阵 行数自适应
# 输入到actor网络的输出结果(动作)再reshape为行数为actor.action_dim的矩阵
for i in range(env.num_UAVs):
# 增加探索扰动, 输出限制在 [0, 1] 范围内
a[i] = np.clip(np.random.normal(a[i], NOISE), 0, 1)
s2, r, done = env.step(a)
replayMemory.add(s, a, r, done, s2)
s = s2
```
检查输入数据是否正确:确保您的输入数据已经被正确地预处理和标准化,使其能够适应网络的要求。还要确保您的输入数据与您的问题域相匹配。
检查网络结构:确认您的神经网络结构是否正确并满足您的问题要求。特别是在使用DDPG算法时,Actor网络通常采用全连接网络或卷积神经网络。您可以尝试增加或减少网络的深度和宽度,以看看是否有任何改善。
检查超参数:确保您的优化器和学习率等超参数已正确设置,尝试使用其他优化器和学习率值,观察是否会对网络性能产生影响。
检查目标函数和奖励函数:请确保您的目标函数和奖励函数与您的问题域相匹配,同时考虑使用不同的目标函数和奖励函数来比较其性能。
调试代码:检查您的代码是否存在错误,可能有语法错误或者实现有误。
如果以上方法都没有解决问题,您可能需要深入分析问题所在,比如可视化激活层的输出和权重,来查找问题的根源。
至于您提供的Actor神经网络的模型,我发现它使用了ReLU激活函数,这是一个常用的激活函数,但在某些情况下可能会导致梯度消失的问题。您可以尝试使用其他激活函数,例如LeakyReLU或ELU,看看是否有任何改善。此外,您的输出层使用了tanh激活函数,这意味着输出值将始终在-1和1之间。
不知道你这个问题是否已经解决, 如果还没有解决的话: