我一直在使用 tensorflow 和一个非常简单的深度 Q 神经网络 (NN) 来玩一个非常简单的游戏。
游戏在一个数组 [0, 0, 0, 0] 中,通过选择位置 0, 1, 2, 3 中的一个,选择的数字在 0 和 1 之间交换,所以如果我在开始游戏看起来像 [0, 0, 1, 0]。当数组为 [1, 1, 1, 1] 时,游戏结束。因此,对于人类和神经网络来说,这是一个非常容易玩的游戏。
我希望能够做的不是每次想要添加新层时都复制和粘贴我的代码部分。我对此的尝试是迭代的:
W = []
b = []
hidden_outputs = []
shape = [4, 8, 4]
input_ = tf.placeholder(tf.float32, [None, shape[0]], name='input_')
for i in range(len(shape) - 1):
print("i: " + str(i))
## Create the W and b variables for this layer of my network and add them to the list
W.append(tf.Variable(tf.random_normal([shape[i], shape[i + 1]], stddev=0.03)))
b.append(tf.Variable(tf.random_normal([shape[i + 1]])))
## Multiply the previous output by the current W and then add b
if i == len(shape) - 2:
if len(shape) > 2:
Qout_new = tf.add(tf.matmul(hidden_outputs[i - 1], W[i]), b[i])
sig_out_new = tf.sigmoid(Qout_new)
else:
Qout_new = tf.add(tf.matmul(input_, W[i]), b[i])
sig_out_new = tf.sigmoid(Qout_new)
elif i == 0:
hidden_outputs.append(tf.nn.relu(tf.add(tf.matmul(input_, W[i]), b[i])))
else:
hidden_outputs.append(tf.nn.relu(tf.add(tf.matmul(hidden_outputs[i - 1], W[i]), b[i])))
我的逻辑是,这将允许我改变形状并且神经网络的形状会随之改变。
这确实有效,并且神经网络确实学会了玩我非常基本的游戏,shape = [4, 4] 或 [4, 4, 4] 或 [4, 50, 4],其中shape[0] 是输入层的维度,shape[-1] 是输出层的维度。
但是,它不会学习使用 2 个隐藏层(例如 shape = [4, 50, 50, 4])正确播放,我知道您不需要 2 个隐藏层游戏,但我这样做是作为一个更大项目的垫脚石。
回顾代码可以看到,这只会在使用 else 语句时发生。
我不知道的是 NN 是否无法学习是因为游戏和两个隐藏层 NN 之间存在一些根本差异,或者我的 else 语句中的代码是否存在问题,或者我没有训练得足够多(游戏中有 200 次尝试,每次尝试 4 步),或者我的学习率太高或太低(y = 0.05)。
基本上,是什么导致它失败?