[英]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.