我想在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]
答案 0 :(得分:1)
您正在将位置参数与关键字参数混合。当您定义类似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']
更多信息here。
答案 1 :(得分:0)
我相信解决方法如下:
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])