0

I want to do some processes on one of my layer in autoencoder and then send it to next layer but I can not use the predefined functions in Keras like add ,... and I think I should use lambda with function. the output of my autoencoder is a tensor with shape (1,28,28,1)named encoder and I have an input tensor with shape (1,4,4,1) named wtm. now, I want to consider 7x7 blocks in encoder and I add the middle value of each 7x7 block with one value of wtm respectively ( each block of encoder with one value of wtm) I write two functions to do this but it produced this error:

TypeError: 'Tensor' object does not support item assignment

I am a beginner in python and Keras and I search for the reason but unfortunately, I could not understand why it happened and what should I do? please guide me how do I write my lambda layer? I attached the code here. I can do some simple thing like this with lambda

add_const = Kr.layers.Lambda(lambda x: x[0] + x[1])
encoded_merged = add_const([encoded,wtm])

but if wtm has the different shape with encoded or sompe complicated things on layer, I do not know what should I do?

from keras.layers import Input, Concatenate, GaussianNoise,Dropout,BatchNormalization,MaxPool2D,AveragePooling2D
from keras.layers import Conv2D, AtrousConv2D
from keras.models import Model
from keras.datasets import mnist
from keras.callbacks import TensorBoard
from keras import backend as K
from keras import layers
import matplotlib.pyplot as plt
import tensorflow as tf
import keras as Kr
from keras.optimizers import SGD,RMSprop,Adam
from keras.callbacks import ReduceLROnPlateau
from keras.callbacks import EarlyStopping
from keras.callbacks import ModelCheckpoint
import numpy as np
import pylab as pl
import matplotlib.cm as cm
import keract
from matplotlib import pyplot
from keras import optimizers
from keras import regularizers

from tensorflow.python.keras.layers import Lambda;
#-----------------building w train---------------------------------------------
    def grid_w(args):
    Enc, W = args
#    Ex,Ey,Ez=Enc.shape

#    Wx,Wy,Wz=W.shape
    Enc=tf.reshape(Enc,[28,28])
    W=tf.reshape(W,[4,4])
    Enc[3::7, 3::7] += W
    Enc=tf.reshape(Enc,[1,28,28,1])
    W=tf.reshape(W,[1,4,4,1])
#    Enc[:, 3::7, 3::7]=K.sum(W,axis=1)

    return Enc

    def grid_w_output_shape(shapes):
        shape1, shape2 = shapes
        return (shape1[0], 1)
    wt_random=np.random.randint(2, size=(49999,4,4))
    w_expand=wt_random.astype(np.float32)
    wv_random=np.random.randint(2, size=(9999,4,4))
    wv_expand=wv_random.astype(np.float32)
    x,y,z=w_expand.shape
    w_expand=w_expand.reshape((x,y,z,1))
    x,y,z=wv_expand.shape
    wv_expand=wv_expand.reshape((x,y,z,1))

    #-----------------building w test---------------------------------------------
    w_test = np.random.randint(2,size=(1,4,4))
    w_test=w_test.astype(np.float32)
    w_test=w_test.reshape((1,4,4,1))
    #-----------------------encoder------------------------------------------------
    #------------------------------------------------------------------------------
    wtm=Input((4,4,1))
    image = Input((28, 28, 1))
    conv1 = Conv2D(64, (5, 5), activation='relu', padding='same', name='convl1e')(image)
    conv2 = Conv2D(64, (5, 5), activation='relu', padding='same', name='convl2e')(conv1)
    conv3 = Conv2D(64, (5, 5), activation='relu', padding='same', name='convl3e')(conv2)
    #conv3 = Conv2D(8, (3, 3), activation='relu', padding='same', name='convl3e', kernel_initializer='Orthogonal',bias_initializer='glorot_uniform')(conv2)
    BN=BatchNormalization()(conv3)
    #DrO1=Dropout(0.25,name='Dro1')(BN)
    encoded =  Conv2D(1, (5, 5), activation='relu', padding='same',name='encoded_I')(BN)

    #-----------------------adding w---------------------------------------
    encoded_merged=Kr.layers.Lambda(grid_w, output_shape=grid_w_output_shape)([encoded, wtm])

    #-----------------------decoder------------------------------------------------
    #------------------------------------------------------------------------------

    deconv1 = Conv2D(64, (5, 5), activation='elu', padding='same', name='convl1d')(encoded_merged)
    deconv2 = Conv2D(64, (5, 5), activation='elu', padding='same', name='convl2d')(deconv1)
    deconv3 = Conv2D(64, (5, 5), activation='elu',padding='same', name='convl3d')(deconv2)
    deconv4 = Conv2D(64, (5, 5), activation='elu',padding='same', name='convl4d')(deconv3)
    BNd=BatchNormalization()(deconv3)  
    decoded = Conv2D(1, (5, 5), activation='sigmoid', padding='same', name='decoder_output')(BNd) 

    model=Model(inputs=[image,wtm],outputs=decoded)

    decoded_noise = GaussianNoise(0.5)(decoded)

    #----------------------w extraction------------------------------------
    convw1 = Conv2D(64, (3,3), activation='relu', name='conl1w')(decoded_noise)
    convw2 = Conv2D(64, (3, 3), activation='relu', name='convl2w')(convw1)
    Avw1=AveragePooling2D(pool_size=(2,2))
    convw3 = Conv2D(64, (3, 3), activation='relu', padding='same', name='conl3w')(convw2)
    convw4 = Conv2D(64, (3, 3), activation='relu', padding='same', name='conl4w')(convw3)
    Avw2=AveragePooling2D(pool_size=(2,2))
    convw5 = Conv2D(64, (3, 3), activation='relu', name='conl5w')(convw4)
    convw6 = Conv2D(64, (3, 3), activation='relu', padding='same', name='conl6w')(convw5)
    BNed=BatchNormalization()(convw6)
    #DrO3=Dropout(0.25, name='DrO3')(BNed)
    pred_w = Conv2D(1, (1, 1), activation='sigmoid', padding='same', name='reconstructed_W')(BNed)  
    watermark_extraction=Model(inputs=[image,wtm],outputs=[decoded,pred_w])

    watermark_extraction.summary()
david
  • 1,255
  • 4
  • 13
  • 26
  • You need to use Keras backend / tensorflow functions in your custom function because you are operating on Tensors, not NumPy arrays. – Luke DeLuccia Feb 27 '19 at 17:08
  • how can I do this?:( I really can not understand these concepts. is it possible for you to explain more with sample code? – david Feb 27 '19 at 17:28
  • I used this add_const = Kr.layers.Lambda(lambda x: x[0][:,3::7,3::7] + x[1]) encoded_merged = add_const([encoded,wtm]) but the output shape is (1,4,4,1) while it should be (1,28,28,1] and I am also not sure it di the things I want:(( – david Feb 27 '19 at 18:24
  • Instead of using NumPy functions, you would use the tensorflow equivalents. For example, `np.reshape` would become `tf.reshape`, and so on. Before you do this, though, you should test your current `grid_w` with dummy NumPy array inputs to make sure it does what you want. Then, you can translate to tensorflow. – Luke DeLuccia Feb 27 '19 at 18:45
  • I change my grid_w to new code that I put above but it produces new error: ValueError: Index out of range using input dim 2; input has only 2 dims for 'lambda_19/strided_slice' (op: 'StridedSlice') with input shapes: [28,28], [3], [3], [3] and with computed input tensors: input[3] = <1 7 7>. – david Feb 27 '19 at 19:22
  • I use tensorflow but it produced a new error. the problem is that I really do not know how do I use these concepts you said:( if possible put here a sample code or link a document that completely explains these. – david Feb 27 '19 at 19:25
  • You reshaped `Enc` to `[28,28]` and then tried to access `Enc[:, 3::7, 3::7]`, but `Enc` only has 2 dimensions after your reshape. If you don't understand this, you should probably brush up on your list and NumPy indexing. I can't put sample code to explain every last detail, and this is not a code-writing service. My advice is simply what I said before: create a function using NumPy, test with dummy arrays, and then convert to tensorflow. – Luke DeLuccia Feb 27 '19 at 19:54
  • I know this work with arrays but I do not know how can I work with tensors that have a different shape. if anyone can guide me please answer me. – david Feb 27 '19 at 20:53
  • this thread might help: https://stackoverflow.com/questions/15572288/general-decorator-to-wrap-try-except-in-python – Roy learns to code Oct 28 '22 at 11:36

0 Answers0