Search code examples
pythonlisttensorflowarraylistnumpy-ndarray

How to convert the weights to 1D array?


I have the following weights of my keras model.


x_train_mnist = np.expand_dims(x_train_mnist, axis=-1)     
x_train_mnist = np.repeat(x_train_mnist, 3, axis=-1)        

x_train_mnist = x_train_mnist.astype('float32') / 255

x_train_mnist = tf.image.resize(x_train_mnist, [75,75]) 

x_test_mnist = np.expand_dims(x_test_mnist, axis=-1)

x_test_mnist = np.repeat(x_test_mnist, 3, axis=-1)         


x_test_mnist = x_test_mnist.astype('float32') / 255

x_test_mnist = tf.image.resize(x_test_mnist, [75,75])

model=tf.keras.applications.InceptionV3(
 include_top=True,
    pooling=None,
    classes=10,
    weights=None,
    input_shape=(75,75,3)
) 

Now the weights of the model is a list of lists as can be observed from the following snippet

weights=model.weights
print(type(weights))
weights_np=np.array(weights)
print(type(weights_np))
weights_npfloat_32=np.float32(weights_np)
print(weights_np.size) 

Output

<class 'list'>
<class 'numpy.ndarray'>
/tmp/ipykernel_3796671/1208296518.py:3: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  weights_np=np.array(weights)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~/miniconda3/lib/python3.9/site-packages/tensorflow/python/ops/resource_variable_ops.py:1456, in BaseResourceVariable.__float__(self)
   1455 def __float__(self):
-> 1456   return float(self.value().numpy())

TypeError: only size-1 arrays can be converted to Python scalars

The above exception was the direct cause of the following exception:

ValueError                                Traceback (most recent call last)
Cell In [42], line 5
      3 weights_np=np.array(weights)
      4 print(type(weights_np))
----> 5 weights_npf=np.float32(weights_np)
      6 print(weights_np.size)

ValueError: setting an array element with a sequence.

I want to convert these weights into 1D array, i.e., a row vector. I have used np.flatten, np.ravel, np.reshape but am not able to get the required output. For all the np methods described, the shape of the weights and type remains same.


Solution

  • model.weights will give you a list of the weights tensors. If you want to covert them to numpy I would suggest to use list comprehension:

    weights=model.weights    
    weights_np = [i.numpy() for i in weights]
    

    If you want to convert all of these to a 1D array one way to do is with .flatten(), then you could concatenate them if that is what you want.

    flatten_w = [i.flatten() for i in weights_np]
    np.concatenate(flatten_w)
    

    You could do it in one step as well

    flatten_w = [i.numpy().flatten() for i in weights]
    

    Also if you want to change the type use .astype(np.float32)