philipperemy / keract

Layers Outputs and Gradients in Keras. Made easy.
MIT License
1.05k stars 186 forks source link

Error when using model.add_loss #124

Closed erik1026 closed 4 years ago

erik1026 commented 4 years ago

I am trying to use keract with a model that has a custom loss function that uses internal model layers. The only way I have found to use internal layers in the loss function is with the keras model.add_loss function. However when using model.add_loss get the following error.

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/keract/keract.py", line 211, in _get_nodes
    key = n_(m.output, output_format_=output_format, nested=nested)
AttributeError: 'dict' object has no attribute 'output'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/akramer/code/src/skywardgitlab.skyward.local/modelsim/adsb_anomaly_detection/adsbAnomalyDetection/samplePINN/pinn.py",
line 38, in <module>
    a=keract.get_activations(model, x[:10])
  File "/usr/local/lib/python3.6/dist-packages/keract/keract.py", line 281, in get_activations
    nodes = _get_nodes(model, output_format, layer_names=layer_names, nested=nested)
  File "/usr/local/lib/python3.6/dist-packages/keract/keract.py", line 213, in _get_nodes
    key = m.name
AttributeError: 'dict' object has no attribute 'name'

Below is a minimal working example.

import keract
import numpy as np
import tensorflow as tf

x = np.random.rand(100).reshape(100, 1)
y = x+1

inputs = tf.keras.layers.Input(shape=(1, ))
d = tf.keras.layers.Dense(11)(inputs)
d = tf.keras.layers.Dense(1)(d)

model = tf.keras.Model(inputs = inputs, outputs = d)

def loss(y_true, y_pred):
    return tf.reduce_mean((y_true - y_pred)**2)

optimizer = tf.keras.optimizers.Adam()
model.add_loss(loss(inputs, d))
model.compile(optimizer)

model.fit(x, y, epochs=20)

a=keract.get_activations(model, x[:0])
philipperemy commented 4 years ago

Working on it right now.

philipperemy commented 4 years ago

Closed with 4.3.3. update and it should work!

https://github.com/philipperemy/keract/commit/1a2846598084f9725499f6978a5f5129f947d7ec

erik1026 commented 4 years ago

Thanks for your quick reply! That did fix the issue in the minimal working example I provided. However there is a new issue when trying to implement my actual model. Here is a new example:

import keract
import numpy as np
import tensorflow as tf

def split_sequence(sequence, n_steps):
    X, y = list(), list()
    for i in range(len(sequence)):
        # find the end of this pattern
        end_ix = i + n_steps
        # check if we are beyond the sequence
        if end_ix > len(sequence) - 1:
            break
        # gather input and output parts of the pattern
        seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
        X.append(seq_x)
        y.append(seq_y)
    return np.array(X), np.array(y)

lam = 0.5

raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90]
n_steps = 3
X, y = split_sequence(raw_seq, n_steps)
n_features = 1
X = X.reshape((X.shape[0], X.shape[1], n_features))

inputs = tf.keras.layers.Input(shape=(n_steps, n_features), name="inp")
outputs = tf.keras.layers.Input(shape=(n_features), name='opt')

d = tf.keras.layers.LSTM(50, activation="relu")(inputs)
d = tf.keras.layers.Dense(1)(d)

model = tf.keras.Model(inputs=[inputs, outputs], outputs=d)

def loss(x, y_true, y_pred):
    return lam*tf.reduce_mean((y_true - y_pred)**2) + (1-lam)*tf.reduce_mean((y_true[-1] + 10 - x)**2)

optimizer = tf.keras.optimizers.Adam()
model.add_loss(loss(inputs, outputs, d))
model.compile(optimizer)
model.fit({"inp":X, "opt":y}, y, epochs=100)

x_extrapolate = np.array([70, 80, 90])
x_extrapolate = x_extrapolate.reshape((1, n_steps, n_features))

a=keract.get_activations(model, x_extrapolate)

and the error is:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/keract/keract.py", line 100, in _evaluate
    return eval_fn(model._feed_inputs + model._feed_targets + model._feed_sample_weights)
AttributeError: 'Functional' object has no attribute '_feed_targets'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  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))
AttributeError: 'Functional' object has no attribute '_standardize_user_data'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/akramer/code/src/skywardgitlab.skyward.local/modelsim/adsb_anomaly_detection/adsbAnomalyDetection/samplePINN/lstm_pinn.
py", line 66, in <module>
    a=keract.get_activations(model, x_extrapolate)
  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 91, in eval_fn
    return K.function(k_inputs, nodes_to_evaluate)(x)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py", line 3940, in func
    outs = model(model_inputs)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/base_layer.py", line 985, in __call__
    outputs = call_fn(inputs, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/functional.py", line 386, in call
    inputs, training=training, mask=mask)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/functional.py", line 517, in _run_internal_graph
    assert x_id in tensor_dict, 'Could not compute output ' + str(x)
AssertionError: Could not compute output Tensor("strided_slice:0", shape=(1,), dtype=float32)
philipperemy commented 4 years ago

@erik1026 can you provide a full snippet that I can run. Your model and y here are not defined. Thanks!

erik1026 commented 4 years ago

@philipperemy I apologize, I have corrected the code above.