Search code examples
keraskeras-layer

How to solve the problem: "'Tensor' object does not support item assignment"


I tried to sum up element-wise two tensors but, failed. My code is as below. I want to assign elements of 'a' as [x[0]*y[0]-x[1]*y[1], x[0]*y[1]+x[1]*y[0], x[2]*y[2]-x[3]*y[3], x[2]*y[3]+x[3]*y[2]]. Since I'm a beginner in Keras and tensorflow, I don't wanna use 'session' in tensorflow. How can I assign the above value merely using keras backend?

from keras import backend as K
def rayleigh_fading(x):
    global noise_std, n_channel
    y = K.random_normal((2*n_channel,), mean=0, stddev=1.0)*(1/np.sqrt(2))
    a = K.placeholder(shape=(4,))
    a[0] = x[0]*y[0]-x[1]*y[1]
    a[1] = x[0]*y[1]+x[1]*y[0] 
    a[2] = x[2]*y[2]-x[3]*y[3]
    a[3] = x[2]*y[3]+x[3]*y[2]
    z = a + K.random_normal((2*n_channel,), mean=0, sttdev=noise_std)
return z

Solution

  • Try something like the following:

    import tensorflow as tf
    import numpy as np
    
    keras = tf.keras
    
    from tensorflow.keras import backend as K
    
    noise_std = 1
    n_channel = 2
    
    def rayleigh_fading(x):
        global noise_std, n_channel
        y = K.random_normal((K.shape(x)[0], 2*n_channel,), mean=0, stddev=1.0)*(1/np.sqrt(2))
        a0 = x[:, 0]*y[:, 0]-x[:, 1]*y[:, 1]
        a1 = x[:, 0]*y[:, 1]+x[:, 1]*y[:, 0] 
        a2 = x[:, 2]*y[:, 2]-x[:, 3]*y[:, 3]
        a3 = x[:, 2]*y[:, 3]+x[:, 3]*y[:, 2]
        a_tensors = [K.expand_dims(t) for t in [a0, a1, a2, a3]]
        a = K.concatenate(a_tensors, axis=1)
        z = a + K.random_normal((2*n_channel,), mean=0, stddev=noise_std)
        return z
    
    def make_model():
      inp = keras.layers.Input(shape=(4,))
      rf = keras.layers.Lambda(rayleigh_fading)(inp)
      out = keras.layers.Dense(1)(rf)
      model = keras.models.Model(inp, out)
      model.compile('adam', 'mse')
      return model
    
    model = make_model()
    model.summary()
    

    I assume that y should sample from a random variable on a per batch basis; z should most likely have a shape (batch_size, 2*n_channel) also... where batch_size is K.shape(x)[0].

    The main issue with your attempt is that a placeholder is not a variable that can be modified. It is a placeholder for input data to the model. Also you should take into account that at the tensor level x has a batch dimension. So to access the first column of x across all batches you need to use x[:, 0].

    I avoided creating a variable for a by just concatenating the vectors in your equation.