簡體   English   中英

通過子類化創建的自定義層中缺少權重

[英]Missing weights in custom layer created by subclassing

我想在 Tensorflow/Keras 中創建一個自定義層。 我創建了一個由以下 Deepset 層調用的注意力層。

注意層:

class Attention(tf.keras.Model):
def __init__(self, input_shape):
    super(Attention, self).__init__()
    in_features=input_shape
    small_in_features = max(math.floor(in_features/10), 1)
    self.d_k = small_in_features

    query = tf.keras.models.Sequential()
    query.add(tf.keras.layers.Dense(in_features,use_bias=True,trainable=True))
    query.add(tf.keras.layers.Dense(small_in_features,activation="tanh",trainable=True))
    self.query= query
    
    self.key = tf.keras.layers.Dense(small_in_features,use_bias=True,trainable=True)

def call(self, inp):
    # inp.shape should be (B,N,C)
    q = self.query(inp)  # (B,N,C/10)
    k = self.key(inp)     # B,N,C/10
    k = tf.transpose(k,perm=[0,2,1])
    x = tf.linalg.matmul(q, k) / math.sqrt(self.d_k)  # B,N,N
    x = tf.nn.softmax(x)  # over rows
    x = tf.transpose(x)
    x = tf.linalg.matmul(x, inp)  # (B, N, C)
    
    return x

深層:

class DeepSetLayer(tf.keras.Model):
def __init__(self, input_shape, out_features, attention, normalization, second_bias):
    """
    DeepSets single layer
    :param in_features: input's number of features
    :param out_features: output's number of features
    :param attention: Whether to use attention
    :param normalization: normalization method - 'fro' or 'batchnorm'
    :param second_bias: use a bias in second conv1d layer
    """
    super(DeepSetLayer, self).__init__()
    in_features=input_shape[-1]
    self.attention = None
    if attention:
        self.Attention = Attention(in_features)
    self.layer1 = tf.keras.layers.Conv1D(in_features, out_features, 1,trainable=True)
    self.layer2 = tf.keras.layers.Conv1D(in_features, out_features, 1, use_bias=second_bias,trainable=True)

    self.normalization = normalization
    if normalization == 'batchnorm':
        self.bn = tf.keras.layers.BatchNormalization(out_features,trainable=True)

def call(self, x):
    #tf.shape(x) = (B,C,N)
    # attention
    if self.attention:
        x_T = tf.transpose(x,perm=[0,2,1])  # B,C,N -> B,N,C
        x = self.layer1(x) + self.layer2(tf.transpose(self.Attention(x_T),perm=[0,1,2]))
        print(x)
    else:
        x = self.layer1(x) + self.layer2(x - tf.math.reduce_mean(x,axis=2,keepdims=True))

    # normalization
    if self.normalization == 'batchnorm':
        x = self.bn(x)
    else:
        x=tf.transpose(x,perm=[0,2,1])
        print(tf.norm(x,axis=1, keepdims=True,))
        print(x)
        x = x / tf.norm(x, axis=1, keepdims=True)  # BxCxN / Bx1xN

    return x

現在我將使用這些自定義層構建一個 model:

phi=tf.keras.models.Sequential()
phi.add(tf.keras.layers.Input((256,10)))
phi.add(DeepSetLayer((256,10),25,True,True,True))

但是當我使用phi.summary()調用 Layer 結構時,我得到以下我無法解釋的錯誤:

ValueError: Weights for model sequential_84 have not yet been created. Weights are created when the Model is first called on inputs or `build()` is called with an `input_shape`.

我不確定我在那里做錯了什么,但似乎我沒有正確構建我的圖層。

我怎樣才能解決這個問題?

也是 Inputshape=(None,256,10) 但我的 Deepset Layers 將它變成 (None,232,10) 這不是我想要得到的。 我不明白維度在哪里/為什么會減少。

這發生在哪里?

您忘記將輸入層添加到您在注意力層中使用的查詢 model。

請參閱https://colab.research.google.com/drive/174OKxsBr8-G-G7ogXjw-fLsl1Ak4tPcO?usp=sharing

Q1。

在調用 summary() 之前嘗試傳遞任何虛擬數據。 錯誤消息意味着它還不知道 model 的某些部分,或者當您實際“使用”model 和實際數據時會創建一些權重。

Q2。

Conv1D 層的第一個參數是過濾器的數量(這將是輸出的通道號),第二個參數是每個過濾器的大小。

沒有填充(在 keras 中,padding='valid'),如果輸入的形狀是(B,N,C),則 output 形狀將是

(B, (N-kernel_size+1)//(stride) , filters)

因此,在您的情況下, (256 - 25 + 1) // 1 = 232

並且您對過濾器的參數是 input_shape[-1],即 C(在本例中為 10)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM