【问题标题】:What would be the output from tensorflow dense layer if we assign itself as input and output while making a neural network?如果我们在制作神经网络时将自己指定为输入和输出,那么 tensorflow 密集层的输出会是什么?
【发布时间】:2020-04-11 20:47:12
【问题描述】:

我一直在为任何 Vanilla Policy Gradient 在 openAI 代码中实现神经网络(事实上,这部分几乎在所有地方都使用)。代码看起来像这样:

def mlp_categorical_policy(x, a, hidden_sizes, activation, output_activation, action_space):
    act_dim = action_space.n
    logits = mlp(x, list(hidden_sizes) + [act_dim], activation, None)
    logp_all = tf.nn.log_softmax(logits)
    pi = tf.squeeze(tf.random.categorical(logits, 1), axis=1)
    logp = tf.reduce_sum(tf.one_hot(a, depth=act_dim) * logp_all, axis=1)
    logp_pi = tf.reduce_sum(tf.one_hot(pi, depth=act_dim) * logp_all, axis=1)
    return pi, logp, logp_pi

这个多层感知器网络定义如下:

def mlp(x, hidden_sizes=(32,), activation=tf.tanh, output_activation=None):
    for h in hidden_sizes[:-1]:
        x = tf.layers.dense(inputs=x, units=h, activation=activation)
    return tf.layers.dense(inputs=x, units=hidden_sizes[-1], activation=output_activation)

我的问题是这个 mlp 函数的返回值是什么?我的意思是结构或形状。它是一个 N 维张量吗?如果是这样,它是如何作为tf.random_categorical 的输入提供的?如果不是,它只是形状[hidden_layer2, output],那么其他层发生了什么?根据他们的website description about random_categorical,它只需要一个二维输入。 openAI 的VPG algorithm 的完整代码可以在这里找到。 mlp 实现here。如果有人能告诉我这个mlp_categorical_policy() 在做什么,我将不胜感激?

注意:隐藏大小为[64, 64],动作维度为3

感谢和欢呼

【问题讨论】:

    标签: tensorflow neural-network reinforcement-learning openai-gym


    【解决方案1】:

    请注意,这是一个离散的动作空间 - 每一步都有action_space.n 不同的可能动作,并且代理会选择一个。

    为此,MLP 返回不同操作的 logits(它是概率的函数)。这是由+ [act_dim] 在代码中指定的,它将action_space 的计数附加为最终的MLP 层。请注意,MLP 的最后一层是输出层。 tensorflow中没有指定输入层,是从输入中推断出来的。

    tf.random.categorical 获取 logits 并从中采样策略操作pi,该操作以数字形式返回。

    mlp_categorical_policy 还返回logp,动作a(用于分配信用)的对数概率,以及logp_pi,策略动作pi 的对数概率。


    看来你的问题更多是关于 mlp 的回报。

    mlp 在循环中创建一系列全连接层。在循环的每次迭代中,mlp 使用前一层 x 作为输入创建一个新层,并将其输出分配给覆盖 x,这条线 x = tf.layers.dense(inputs=x, units=h, activation=activation)

    所以输出与输入不同,在每次迭代中,x 都会被新层的值覆盖。这与 x = x + 1 的编码技巧相同,将 x 增加 1。这有效地将层链接在一起。

    tf.layers.dense 的输出是一个大小为[:,h] 的张量,其中: 是批量维度(通常可以忽略)。最后一层的创建发生在循环之外,可以看出这一层的节点数是act_dim(所以shape是[:,3])。您可以通过以下方式检查形状:

    import tensorflow.compat.v1 as tf
    import numpy as np
    
    def mlp(x, hidden_sizes=(32,), activation=tf.tanh, output_activation=None):
        for h in hidden_sizes[:-1]:
            x = tf.layers.dense(x, units=h, activation=activation)
        return tf.layers.dense(x, units=hidden_sizes[-1], activation=output_activation)
    
    obs = np.array([[1.0,2.0]])
    logits = mlp(obs, [64, 64, 3], tf.nn.relu, None)
    print(logits.shape)
    

    结果:TensorShape([1, 3])

    注意,本例中的观察值是[1.,2.],它嵌套在大小为 1 的批次中。

    【讨论】:

    • 我确实通过代码了解了正在发生的事情的要点,但想具体了解 mlp 函数的输出。我的基本疑问是 layers.dense 向网络添加了一个单层,但在这里输出层被分配给它自己。因此,正在发生的事情变得令人困惑(我说的是 mlp 函数的 for 循环)。如果有帮助的话,传递给这个函数的初始状态也就是 x 是一个大小为 [1, 2] 的向量。
    • 我已经在上面回答了。
    • @dilaudid ...感谢内联...最后一件事..关于中间隐藏层的信息会发生什么?他们迷路了吗?它们是否以某种方式存储在内部?由于输出张量的形状为 '[batch size, #output_neurons] 因此很奇怪。'
    • 如果不专门构建 mlp 来执行此操作,您将看不到隐藏(中间)层的激活 - 通常不关心隐藏层,但有时会为此目的绘制激活了解网络正在学习什么。通过调用 tf.trainable_variables() 可以查看层中的变量(权重) - 参见stackoverflow.com/questions/45007823/…
    猜你喜欢
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 2019-07-14
    • 1970-01-01
    相关资源
    最近更新 更多