【问题标题】:What is reason behind different keras layers initialization?不同的keras层初始化背后的原因是什么?
【发布时间】:2019-07-13 13:39:02
【问题描述】:

我在 keras 中见过这种类型的层初始化

from keras.models import Model
from keras.layers import Input, Dense

a = Input(shape=(32,))
b = Dense(32)(a)
c = Dense(b)

它的第 c_th 层的初始化令人困惑。我有一个像这样的类对象

class Attention(tf.keras.Model):
    def __init__(self, units):
        super(Attention, self).__init__()
        self.W1 = tf.keras.layers.Dense(units)
        self.W2 = tf.keras.layers.Dense(units)
        self.V = tf.keras.layers.Dense(1)

    def call(self, features, hidden):
        hidden_with_time_axis = tf.expand_dims(hidden, 1)
        score = tf.nn.tanh(self.W1(features) + self.W2(hidden_with_time_axis))
        attention_weights = tf.nn.softmax(self.V(score), axis=1)
        context_vector = attention_weights * features
        context_vector = tf.reduce_sum(context_vector, axis=1)

        return context_vector, attention_weights

查看self.W1(features),它采用前一层的特征并将其传递给已经初始化的权重W1 密集层,x units。这一步发生了什么以及我们为什么要这样做?

编辑:

class Foo:
    def __init__(self, units):
        self.units=units
    def __call__(self):
        print ('called '+self.units)


a=Foo(3)
b=Foo(a)

为什么我们需要调用函数?

【问题讨论】:

    标签: python class oop keras tf.keras


    【解决方案1】:

    初始化层和调用层是有区别的。

    b = Dense(32)(a) 初始化具有 32 个隐藏单元的密集层,然后立即在输入 a 上调用该层。为此,您需要了解 Python 中可调用对象的概念;基本上任何定义了__call__ 函数的对象(keras 基础Layer 类就是这样做的)都可以在输入上调用,即像函数一样使用。

    c = Dense(b) 肯定行不通,如果你真的在某个教程或某段代码中看到过这个,我以后会避免使用那个源...这将尝试用@987654326 创建一个层如果b 是另一个密集层的输出,@units 就没有意义。最有可能的是,您所看到的实际上是 c = Dense(n_units)(b)

    话虽如此,在Attention 代码段中发生的所有事情都是self.W1 层在之前在__init__ 中初始化之后在features(W2 相同)上被调用。

    【讨论】:

    • 嘿,谢谢你的回答,但我在调用函数时还有一些疑问。我在上一个问题中添加了一个简单的类对象来模拟调用函数。你能解释一下call的应用是什么吗?
    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 2018-08-31
    • 2020-01-26
    • 2016-03-31
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多