philipperemy/keract

Regression CNN

zepmck opened this issue · 19 comments

Hi, is it possible to use keract for a regression problem instead of classification?

Thanks!

Yes definitely possible.

Hi @philipperemy, thanks for your reply. I am trying to get activations out of a custom 3D CNN without success so far. The last layers of my net are (simplified version):

        net = keras.layers.MaxPooling3D()(net)
        net = keras.layers.Flatten()(net)
        net = self.DropoutLayer()(net)
        net = keras.layers.Dense()(net)
        net = keras.layers.Dense()(net)
        net = keras.layers.Dense(2**4)(net)
        net = keras.layers.Dense(2**2)(net)
        net = keras.layers.Dense(4)(x)

I am currently getting this error:

tensorflow.python.framework.errors_impl.UnimplementedError: Cast variant to float is not supported [Op:Cast] name: Cast/ threw by the keract eval_fn function.

The input of my net is a:
<class 'tensorflow.python.data.ops.dataset_ops.PrefetchDataset'> object.

Any suggestion on how to address this?

Thanks!

@zepmck upload the full code so that I can run it and see why it does not work.

@philipperemy this is the error that I get:

Traceback (most recent call last):
  File "/workspace/dl-pipeline/utilities.py", line 325, in predict
    activations = get_activations(model, keract_inputs)
  File "/usr/local/lib/python3.6/dist-packages/keract/keract.py", line 313, in get_activations
    activations = _evaluate(model, layer_outputs.values(), x, y=None, auto_compile=auto_compile)
  File "/usr/local/lib/python3.6/dist-packages/keract/keract.py", line 102, in _evaluate
    return eval_fn(model._feed_inputs)
  File "/usr/local/lib/python3.6/dist-packages/keract/keract.py", line 88, in eval_fn
    return K.function(k_inputs, nodes_to_evaluate)(model._standardize_user_data(x, y))
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/backend.py", line 3725, in __call__
    value = math_ops.cast(value, tensor.dtype)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/util/dispatch.py", line 180, in wrapper
    return target(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/math_ops.py", line 707, in cast
    x = gen_math_ops.cast(x, base_type, name=name)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/gen_math_ops.py", line 1971, in cast
    _ops.raise_from_not_ok_status(e, name)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/framework/ops.py", line 6606, in raise_from_not_ok_status
    six.raise_from(core._status_to_exception(e.code, message), None)
  File "<string>", line 3, in raise_from
tensorflow.python.framework.errors_impl.UnimplementedError: Cast variant to float is not supported [Op:Cast] name: Cast/

Since the code is quite complex as well as the input data, may I drop you an email?

@zepmck try to make it easier and paste your snippet.

@philipperemy this is the full net

        img_input = keras.layers.Input(shape=self.InputShape)
        x = keras.layers.Conv3D(128, (8, 8, 8), **self.ActivationFunction[1])(img_input)
        x = keras.layers.MaxPooling3D(pool_size=(2, 2, 4), strides=(2, 2, 4))(x)
        if self.AuxHP.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)
        x = keras.layers.Conv3D(128, (4, 4, 1), **self.ActivationFunction[1])(x)
        x = keras.layers.MaxPooling3D(pool_size=(2, 2, 1), strides=(2, 2, 1))(x)
        if self.AuxHP.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)
        x = keras.layers.Conv3D(128, (1, 1, 4), **self.ActivationFunction[1])(x)
        x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
        if self.AuxHP.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)
        x = keras.layers.Conv3D(128, (3, 3, 1), **self.ActivationFunction[1])(x)
        if self.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)
    
        x = keras.layers.Conv3D(128, (1, 1, 4), **self.ActivationFunction[1])(x)
        x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
        if self.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)
        x = keras.layers.Conv3D(128, (1, 1, 4), **self.ActivationFunction[1])(x)
        x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
        if self.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)        
        x = keras.layers.Conv3D(128, (1, 1, 4), **self.ActivationFunction[1])(x)
        x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
        if self.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)
 
        x = keras.layers.Flatten()(x)
        x = self.DropoutLayer(self.AuxHP.Dropout)(x)
        x = keras.layers.Dense(2**9, **self.AuxHP.ActivationFunction[1])(x)
        if self.AuxHP.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)
        x = keras.layers.Dense(2**8, **self.AuxHP.ActivationFunction[1])(x)
        if self.AuxHP.BatchNormalization == True:
            x = keras.layers.BatchNormalization()(x)

        x = keras.layers.Dense(2**6, **self.AuxHP.ActivationFunction[1])(x)
        x = keras.layers.Dense(2**4, **self.AuxHP.ActivationFunction[1])(x)
        x = keras.layers.Dense(4)(x)

and then:

    pred = ctx.predict(
        data,
        verbose = False,
        workers = 1,
        use_multiprocessing = False,
        )

    activations = get_activations(model, keract_inputs)
    display_activations(activations, cmap="gray", save=False)     

@zepmck great we're making progress. Can you add a full code with imports that I can run locally and check why it fails and solve the problem?

@philipperemy I managed to make some progresses.

This is the output of the get_activations function:

input_1 (1, 25, 25, 526, 1) 
conv3d (1, 18, 18, 519, 128) 
max_pooling3d (1, 9, 9, 129, 128) 
batch_normalization (1, 9, 9, 129, 128) 
conv3d_1 (1, 6, 6, 129, 128) 
max_pooling3d_1 (1, 3, 3, 129, 128) 
batch_normalization_1 (1, 3, 3, 129, 128) 
conv3d_2 (1, 3, 3, 126, 128) 
max_pooling3d_2 (1, 3, 3, 63, 128) 
batch_normalization_2 (1, 3, 3, 63, 128) 
conv3d_3 (1, 1, 1, 63, 128) 
batch_normalization_3 (1, 1, 1, 63, 128) 
conv3d_4 (1, 1, 1, 60, 128) 
max_pooling3d_3 (1, 1, 1, 30, 128) 
batch_normalization_4 (1, 1, 1, 30, 128) 
conv3d_5 (1, 1, 1, 27, 128) 
max_pooling3d_4 (1, 1, 1, 13, 128) 
batch_normalization_5 (1, 1, 1, 13, 128) 
conv3d_6 (1, 1, 1, 10, 128) 
max_pooling3d_5 (1, 1, 1, 5, 128) 
batch_normalization_6 (1, 1, 1, 5, 128) 
flatten (1, 640) 
dropout (1, 640) 
dense (1, 512) 
batch_normalization_7 (1, 512) 
dense_1 (1, 256) 
batch_normalization_8 (1, 256) 
dense_2 (1, 64)
dense_3 (1, 16)
dense_4 (1, 4)

however, since the nrows and ncols are equal to 1, at least for the first layer, the hmap doesn't get create throwing an error.

AttributeError: 'NoneType' object has no attribute 'get_array'

@zepmck great. I think we are doing some progress. What is the shape of the np array you give to visualize activations that produces the error?

@philipperemy this is the shape of the input I provide to the get_activations function

(1, 25, 25, 526, 1)

@zepmck what is ActivationFunction?

I am using the leakyrelu.

@philipperemy do you have any suggestion on how to move forward? thanks.

import numpy as np
from tensorflow import keras

InputShape = (25, 25, 526, 1)

ActivationFunction = 'relu'
BatchNormalization = True
dropout = 0.5
DropoutLayer = keras.layers.Dropout

img_input = keras.layers.Input(shape=InputShape)
x = keras.layers.Conv3D(128, (8, 8, 8), activation=ActivationFunction)(img_input)
x = keras.layers.MaxPooling3D(pool_size=(2, 2, 4), strides=(2, 2, 4))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (4, 4, 1), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(2, 2, 1), strides=(2, 2, 1))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (1, 1, 4), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (3, 3, 1), activation=ActivationFunction)(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)

x = keras.layers.Conv3D(128, (1, 1, 4), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (1, 1, 4), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (1, 1, 4), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)

x = keras.layers.Flatten()(x)
x = DropoutLayer(dropout)(x)
x = keras.layers.Dense(2 ** 9, activation=ActivationFunction)(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Dense(2 ** 8, activation=ActivationFunction)(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)

x = keras.layers.Dense(2 ** 6, activation=ActivationFunction)(x)
x = keras.layers.Dense(2 ** 4, activation=ActivationFunction)(x)
x = keras.layers.Dense(4)(x)

m = keras.Model(inputs=[img_input], outputs=[x])

m.summary()

m.predict(np.ones(shape=InputShape))

Please provide me a code like this that I can run on my machine and reproduce your error. That's the best way to move forward. I'm trying to guess but it's not easy here. @zepmck

But regarding your error I think your input is of type int and you should provide float. Try something like:

np.array(my_numpy_input, dtype=float)

Hi @philipperemy
I am working to prepare a code bundle to reproduce the error. However, if I execute the following sample code:

import numpy as np
from tensorflow import keras
# from src.py21cnn.keract.keract import get_activations, display_activations

from keract import get_activations, display_activations

InputShape = (25, 25, 526, 1)

ActivationFunction = 'relu'
BatchNormalization = True
dropout = 0.5
DropoutLayer = keras.layers.Dropout

img_input = keras.layers.Input(shape=InputShape)
x = keras.layers.Conv3D(128, (8, 8, 8), activation=ActivationFunction)(img_input)
x = keras.layers.MaxPooling3D(pool_size=(2, 2, 4), strides=(2, 2, 4))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (4, 4, 1), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(2, 2, 1), strides=(2, 2, 1))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (1, 1, 4), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (3, 3, 1), activation=ActivationFunction)(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)

x = keras.layers.Conv3D(128, (1, 1, 4), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (1, 1, 4), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Conv3D(128, (1, 1, 4), activation=ActivationFunction)(x)
x = keras.layers.MaxPooling3D(pool_size=(1, 1, 2), strides=(1, 1, 2))(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)

x = keras.layers.Flatten()(x)
x = DropoutLayer(dropout)(x)
x = keras.layers.Dense(2 ** 9, activation=ActivationFunction)(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)
x = keras.layers.Dense(2 ** 8, activation=ActivationFunction)(x)
if BatchNormalization == True:
    x = keras.layers.BatchNormalization()(x)

x = keras.layers.Dense(2 ** 6, activation=ActivationFunction)(x)
x = keras.layers.Dense(2 ** 4, activation=ActivationFunction)(x)
x = keras.layers.Dense(4)(x)

m = keras.Model(inputs=[img_input], outputs=[x])

m.summary()

inputs = np.ones(shape=(1, 25, 25, 526, 1))

m.predict(inputs)

activations = get_activations(m, inputs)
display_activations(activations, cmap="gray", save=True, data_format='channels_last')  

I get the same error:

AttributeError: 'NoneType' object has no attribute 'get_array'

What I am doing wrong?

Thanks!

I fix an error but in your case, you can't display the activations. Look at the shape of your activations:

image

How can you plot that in 2D? You have 4/5D!

Just fetch your activations with activations = get_activations(m, inputs) but do not display them. Just do some processing with them instead.

Let me know if it is more clear to you now. I'll close this issue for now.