[英]Adding a muplitiply layer to an autoencoder in Keras
我想在LSTM自動編碼器的頂部添加一個乘法層。 乘法層應將張量乘以一個恆定值。 我編寫了以下代碼,這些代碼無需乘法層即可工作。 有誰知道如何調整並使之有效?
import keras
from keras import backend as K
from keras.models import Sequential, Model
from keras.layers import Input, LSTM, RepeatVector, TimeDistributed
from keras.layers.core import Flatten, Dense, Dropout, Lambda
from keras.optimizers import SGD, RMSprop, Adam
from keras import objectives
from keras.engine.topology import Layer
import numpy as np
class LayerKMultiply(Layer):
def __init__(self, output_dim, **kwargs):
self.output_dim = output_dim
self.k = Null
super(LayerKMultiply, self).__init__(**kwargs)
def build(self, input_shape):
# Create a trainable weight variable for this layer.
self.k = self.add_weight(
name='k',
shape=(),
initializer='ones',
dtype='float32',
trainable=True,
)
super(LayerKMultiply, self).build(input_shape) # Be sure to call this at the end
def call(self, x):
#return K.tf.multiply(self.k, x)
return self.k * x
def compute_output_shape(self, input_shape):
return (input_shape[0], self.output_dim)
timesteps, input_dim, latent_dim = 10, 3, 32
inputs = Input(shape=(timesteps, input_dim))
encoded = LSTM(latent_dim, return_sequences=False, activation='linear')(inputs)
decoded = RepeatVector(timesteps)(encoded)
decoded = LSTM(input_dim, return_sequences=True, activation='linear')(decoded)
decoded = TimeDistributed(Dense(input_dim, activation='linear'))(decoded)
#decoded = LayerKMultiply(k = 20)(decoded)
sequence_autoencoder = Model(inputs, decoded)
encoder = Model(inputs, encoded)
autoencoder = Model(inputs, decoded)
autoencoder.compile(optimizer='adam', loss='mse')
X = np.array([[[1,2,3,4,5,6,7,8,9,10],[1,2,3,4,5,6,7,8,9,10],[1,2,3,4,5,6,7,8,9,10]]])
X = X.reshape(1,10,3)
p = autoencoder.predict(x=X, batch_size=1)
print(p)
我收到以下錯誤:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-b2f9497bbf47> in <module>()
7 decoded = LSTM(input_dim, return_sequences=True, activation='linear')(decoded)
8 decoded = TimeDistributed(Dense(input_dim, activation='linear'))(decoded)
----> 9 decoded = LayerKMultiply(k = 20)(decoded)
10
11 sequence_autoencoder = Model(inputs, decoded)
TypeError: __init__() missing 1 required positional argument: 'output_dim'
我要實現的是下圖中描述的體系結構:
https://github.com/mg64ve/SMTDAE/blob/master/images/SMTDAE.png https://github.com/mg64ve/SMTDAE/blob/master/images/REF.png
因此,從這個意義上講,我認為乘法層必須位於TimeDistributed和Dense層之前。 我將代碼修改如下:
import keras
from keras import backend as K
from keras.models import Sequential, Model
from keras.layers import Input, LSTM, RepeatVector, TimeDistributed
from keras.layers.core import Flatten, Dense, Dropout, Lambda
from keras.optimizers import SGD, RMSprop, Adam
from keras import objectives
from keras.engine.topology import Layer
import numpy as np
class LayerKMultiply(Layer):
def __init__(self, output_dim, **kwargs):
self.output_dim = output_dim
self.k = None
super(LayerKMultiply, self).__init__(**kwargs)
def build(self, input_shape):
# Create a trainable weight variable for this layer.
self.k = self.add_weight(
name='k',
shape=(),
initializer='ones',
dtype='float32',
trainable=True,
)
super(LayerKMultiply, self).build(input_shape) # Be sure to call this at the end
def call(self, x):
return self.k * x
def compute_output_shape(self, input_shape):
return (input_shape[0], input_shape[1], self.output_dim)
timesteps, input_dim, latent_dim = 31, 31, 32
inputs = Input(shape=(timesteps, input_dim))
encoded = LSTM(latent_dim, return_sequences=False, activation='linear')(inputs)
decoded = RepeatVector(timesteps)(encoded)
decoded = LSTM(input_dim, return_sequences=True, activation='linear')(decoded)
decoded = LayerKMultiply(20)(decoded)
decoded = TimeDistributed(Dense(input_dim, activation='linear'))(decoded)
autoencoder = Model(inputs, decoded)
batch_size = 100
X = np.zeros([5000,31,31])
autoencoder.fit(X, X, batch_size = batch_size, epochs=3)
autoencoder.compile(optimizer='adam', loss='mse')
但是我仍然收到以下錯誤:
InvalidArgumentError: Incompatible shapes: [155,31,31] vs. [100,31,31]
您正在將位置參數與關鍵字參數混合。 當您定義def __init__(self, output_dim, **kwargs)
類的函數時def __init__(self, output_dim, **kwargs)
output_dim
是位置參數。 你需要:
LayerMultiply(20)(decoded)
傳遞20 def __init__(self, k=10, **kwargs)
output_dim
並使用self.output_dim = kwargs['k']
更多信息在這里 。
我相信解決方案如下:
import keras
from keras import backend as K
from keras.models import Sequential, Model
from keras.layers import Input, LSTM, RepeatVector, TimeDistributed
from keras.layers.core import Flatten, Dense, Dropout, Lambda
from keras.optimizers import SGD, RMSprop, Adam
from keras import objectives
from keras.engine.topology import Layer
import numpy as np
class LayerKMultiply(Layer):
def __init__(self, output_dim, **kwargs):
self.output_dim = output_dim
self.k = None
super(LayerKMultiply, self).__init__(**kwargs)
def build(self, input_shape):
# Create a trainable weight variable for this layer.
self.k = self.add_weight(
name='k',
shape=(),
initializer='ones',
dtype='float32',
trainable=True,
)
super(LayerKMultiply, self).build(input_shape) # Be sure to call this at the end
def call(self, x):
return self.k * x
def compute_output_shape(self, input_shape):
return (input_shape[0], input_shape[1], input_shape[2])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.