Home > database >  'int' object is not subscriptable in vae.fit() function
'int' object is not subscriptable in vae.fit() function

Time:03-29

I am developing a VAE using this: dataset

I have used keras tutorial code and I have developed my own encoder and decoder, the problem is that when I run vae.fit() I get 'int' object is not subscriptable. What am I doing wrong?

df = pd.read_csv('local path')
xtrain, xtest = train_test_split(df, test_size=0.2)

encoder:

def encoder(input_shape):
   inputs = keras.Input(shape=input_shape)
   x = layers.Dense(128, activation='relu')(inputs)
   x = layers.Dense(128, activation='relu')(x)
   z_mean = layers.Dense(2, name='z_mean')(x)
   z_log_var = layers.Dense(2, name='z_log_var')(x)
   z = Sampling()([z_mean, z_log_var])
   encoder = keras.Model(inputs, [z_mean, z_log_var, z], name='encoder')
   encoder.summary()
   return encoder

decoder:

def decoder(input_shape):
   inputs = keras.Input(shape=input_shape)
   x = layers.Dense(128, activation='relu')(inputs)
   x = layers.Dense(128, activation='relu')(x)
   outputs = layers.Dense(input_shape[0], activation='sigmoid')(x)
   decoder = keras.Model(inputs, outputs, name='decoder')
   decoder.summary()
   return decoder

VAE class:

class VAE(keras.Model):
def __init__(self, encoder, decoder, **kwargs):
    super(VAE, self).__init__(**kwargs)
    self.encoder = encoder
    self.decoder = decoder
    self.total_loss_tracker = keras.metrics.Mean(name="total_loss")
    self.reconstruction_loss_tracker = keras.metrics.Mean(
        name="reconstruction_loss"
    )
    self.kl_loss_tracker = keras.metrics.Mean(name="kl_loss")

@property
def metrics(self):
    return [
        self.total_loss_tracker,
        self.reconstruction_loss_tracker,
        self.kl_loss_tracker,
    ]

def train_step(self, data):
    with tf.GradientTape() as tape:
        z_mean, z_log_var, z = self.encoder(data)
        reconstruction = self.decoder(z)
        reconstruction_loss = tf.reduce_mean(
            tf.reduce_sum(
                keras.losses.binary_crossentropy(data, reconstruction), axis=(1, 2)
            )
        )
        kl_loss = -0.5 * (1   z_log_var - tf.square(z_mean) - tf.exp(z_log_var))
        kl_loss = tf.reduce_mean(tf.reduce_sum(kl_loss, axis=1))
        total_loss = reconstruction_loss   kl_loss
    grads = tape.gradient(total_loss, self.trainable_weights)
    self.optimizer.apply_gradients(zip(grads, self.trainable_weights))
    self.total_loss_tracker.update_state(total_loss)
    self.reconstruction_loss_tracker.update_state(reconstruction_loss)
    self.kl_loss_tracker.update_state(kl_loss)
    return {
        "loss": self.total_loss_tracker.result(),
        "reconstruction_loss": self.reconstruction_loss_tracker.result(),
        "kl_loss": self.kl_loss_tracker.result(),
    }

This is where I get the error:

data = np.concatenate([xtrain.values, xtest.values])

vae = VAE(encoder(data.shape[1]), 
decoder(data.shape[1]))
vae.compile(optimizer="adam", 
loss="binary_crossentropy")
vae.fit(data, epochs=10, batch_size=32, 
validation_split=0.2)

Full traceback:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
c:\Users\User\Documents\Github\Generative-Models\TFG\VAE.ipynb Cell 9' in <cell line: 3>()
  1 data = np.concatenate([xtrain.values, xtest.values])
  ----> 3 vae = VAE(encoder(data.shape[1]), decoder(data.shape[1]))
  4 vae.compile(optimizer="adam", loss="binary_crossentropy")
  5 vae.fit(data, epochs=10, batch_size=32, validation_split=0.2)

  c:\Users\User\Documents\Github\Generative-Models\TFG\VAE.ipynb Cell 7' in 
  decoder(input_shape)
  3 x = layers.Dense(128, activation='relu')(inputs)
  4 x = layers.Dense(128, activation='relu')(x)
  ----> 5 outputs = layers.Dense(input_shape[0], activation='sigmoid')(x)
  6 decoder = keras.Model(inputs, outputs, name='decoder')
  7 decoder.summary()

  TypeError: 'int' object is not subscriptable

What should I change? help is much appreciated.

CodePudding user response:

The encoder and decoder functions expect an input_shape sequence. But with

vae = VAE(
    encoder(data.shape[1]), 
    decoder(data.shape[1])
)

you are passing int values.

You can fix this by passing in a sequence of int values. For example with

vae = VAE(
    encoder(data.shape[1:]), 
    decoder(data.shape[1:])
)

This assumes that the shape of data is (samples, features). Then your input_shape will be (features,).

  • Related