簡體   English   中英

在Keras中將多個層添加到自動編碼器

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

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