Custom Loss function error in low light image enhancement model - machine-learning

I'm trying to create a custom loss function for an image enhancement model using SSIM loss.
def mirnet_model(num_rrg, num_mrb, channels):
input_tensor = keras.Input(shape=[None, None, 3])
x1 = layers.Conv2D(channels, kernel_size=(3, 3), padding="same")(input_tensor)
for _ in range(num_rrg):
x1 = recursive_residual_group(x1, num_mrb, channels)
conv = layers.Conv2D(3, kernel_size=(3, 3), padding="same")(x1)
output_tensor = layers.Add()([input_tensor, conv])
return keras.Model(input_tensor, output_tensor)
model = mirnet_model(num_rrg=3, num_mrb=2, channels=64)
Loss function -
def ssim_loss(y_true, y_pred):
return tf.reduce_mean(tf.image.ssim(y_true, y_pred, 2.0))
model training -
model.compile(
# optimizer=optimizer, loss=charbonnier_loss, metrics=[peak_signal_noise_ratio]
optimizer=optimizer, loss=ssim_loss, metrics=[peak_signal_noise_ratio]
)
history = model.fit(
train_dataset,
validation_data=val_dataset,
epochs=50,
callbacks=[
keras.callbacks.ReduceLROnPlateau(
monitor="val_peak_signal_noise_ratio",
factor=0.5,
patience=5,
verbose=1,
min_delta=1e-7,
mode="max",
# callbacks=[cp_callback]
)
],
)
I'm getting good results with charbonnier loss but it might overfit because the LOL dataset is small.
I'm getting this error with the ssim loss -
ValueError: in user code:
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1021, in train_function *
return step_function(self, iterator)
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1010, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1000, in run_step **
outputs = model.train_step(data)
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 859, in train_step
y_pred = self(x, training=True)
File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/usr/local/lib/python3.7/dist-packages/keras/engine/input_spec.py", line 249, in assert_input_compatibility
f'Input {input_index} of layer "{layer_name}" is '
ValueError: Exception encountered when calling layer "sequential" (type Sequential).
Input 0 of layer "conv2d_662" is incompatible with the layer: expected axis -1 of input shape to have value 1, but received input with shape (4, None, None, 3)
Call arguments received:
• inputs=tf.Tensor(shape=(4, None, None, 3), dtype=float32)
• training=True
• mask=None
How to remove this error? And also tell me if there are any good loss functions that I can use in my case.

Related

Layer model_1 expects 2 input but it received 1 tensors received:[<tf.Tensor IteratorGetNext:0 shape=(None, None, None, None, None) dtype=float32>]

Encountered the error while trying to fit model of encoder-decoder using ConvLSTM2D. the x_train is of shape (31567, 7, 210, 203, 1)(batch_size,framelength,H,W,C).
The encoder part works when executed in isolation but the error occurs when i add the decoder part, seems like the problem is in the input part of decoder but not sure.
tried reshaping the encoder_state_c_1 and encoder_state_h_1 to 5D before passing it to the decoder ConvLSTM2D but doesn't help either.
Please find the code and error here:
MODEL
def define_models_1_moving_1(framelength, n_filter, filter_size):
# define training encoder
encoder_inputs = Input(name = "encoder_input",
shape=(x_train.shape[1], x_train.shape[2], x_train.shape[3], x_train.shape[4]))
encoder_1 = ConvLSTM2D(name = "encoder_ConvLSTM",
filters = n_filter, kernel_size=filter_size, padding='same', return_sequences=True, return_state=True,
kernel_regularizer=l2(0.0005), recurrent_regularizer=l2(0.0005), bias_regularizer=l2(0.0005))
# input_shape=(x_train.shape[1], x_train.shape[2], x_train.shape[3], x_train.shape[4]))
encoder_outputs_1, encoder_state_h_1, encoder_state_c_1 = encoder_1(encoder_inputs)
# define training decoder
decoder_inputs = Input(name = "decoder_input",
shape=(x_train.shape[1], x_train.shape[2], x_train.shape[3], x_train.shape[4]))
decoder_1 = ConvLSTM2D(name = "decoder_ConvLSTM",
filters=n_filter, kernel_size=filter_size, padding='same', return_sequences=True, return_state=True,
kernel_regularizer=l2(0.0005), recurrent_regularizer=l2(0.0005), bias_regularizer=l2(0.0005))
decoder_outputs_1, _, _ = decoder_1([decoder_inputs, encoder_state_h_1, encoder_state_c_1]) #### This line is giving Error
model = Model([encoder_inputs, decoder_inputs], decoder_outputs_1)
return model
Error
Traceback (most recent call last):
File "D:\Chintan\Dataset\model.py", line 155, in
training_history = train_1_moving_1.fit(
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "C:\Users\Admin\AppData\Local\Temp_autograph_generated_filernuwcygs.py", line 15, in tf__train_function
retval = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
ValueError: in user code:
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", line 1249, in train_function *
return step_function(self, iterator)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", line 1233, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", line 1222, in run_step **
outputs = model.train_step(data)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", line 1023, in train_step
y_pred = self(x, training=True)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\input_spec.py", line 216, in assert_input_compatibility
raise ValueError(
ValueError: Layer "model_120" expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, None, None, None, None) dtype=float32>]

ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type int)

I am trying to tune the hyperparameters of MLP sequential model but getting an error while performing this task. I have tried degrading/upgrading the scikit-learn version and using np.asarray(X).astype(np.int) and np.asarray(X).astype(np.float32) but still getting the error. Please someone help me with how to fix this error. Thanks.
Error after using np.asarray(X).astype(np.int/float32)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-184-8cee47d11b3d> in <module>
1 x_norm_train=np.asarray(x_norm_train).astype(np.float32)
2
----> 3 y_train=np.asarray(y_train).astype(np.float32)
TypeError: float() argument must be a string or a number, not 'Timestamp'
Below is the code:
def mlp_tune():
def create_model(layers, activation, optimizer):
model = Sequential()
for i, nodes in enumerate(layers):
if i==0:
model.add(Dense(nodes, input_dim = x_norm_train.shape[1]))
model.add(Activation(activation))
else:
model.add(Dense(nodes))
model.add(Activation(activation))
model.add(Dense(1, activation = 'linear')) # Note: no activation beyond this point
model.compile(optimizer = optimizer, loss='mse')
# optimizers.Adam(learning_rate = rate, beta_1 = 0.9, \
# beta_2 = 0.999, amsgrad=False)
return model
model = KerasRegressor(build_fn = create_model, verbose=1)
# specifying layer architecture
optimizer = ['adam', 'rmsprop', 'sgd','adagrad', 'adadelta']
layers = [(3,), (10,), (30,), (10, 10), (10, 20), (20, 20), \
(30, 30), (10, 10, 10), (20, 20, 20), \
(30, 30, 30), (10, 20, 30), (20, 20, 30)]
activations = ['relu', 'tanh', 'sigmoid']
param_grid = dict(layers=layers, optimizer = optimizer, activation=activations, \
batch_size = [10, 50, 100], epochs=[10, 50])
grid = GridSearchCV(estimator = model, param_grid = param_grid,\
scoring='neg_mean_squared_error')
grid_result = grid.fit(x_norm_train, y_train)
[grid_result.best_score_, grid_result.best_params_]
testPredict = grid.predict(x_norm_test)
# model evaluation
print()
print(mean_squared_error(y_test, testPredict))
print()
# list all the data in history
print(history.history.keys())
# summarize history for accuracy
plt.figure(figsize=(12, 8))
plt.plot(grid_result.history['mean_squared_error'])
plt.plot(grid_result.history['val_mean_squared_error'])
plt.title('MLP Model Accuracy (After Hyperparameter tuning)', fontsize=18, y=1.03)
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['train', 'test'], loc='best')
plt.savefig("4 mlp model accuracy after tuning.png", dpi=300)
plt.show()
# summarize history for loss
plt.figure(figsize = (12, 8))
plt.plot(grid_result.history['loss'])
plt.plot(grid_result.history['val_loss'])
plt.title('MLP Model Loss (After Hyperparameter tuning)', fontsize=18, y=1.03)
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['train', 'test'], loc='best')
plt.savefig("5 mlp model loss after tuning.png", dpi=300)
plt.show()
# prepare data for plotting
y = y_test[:]
y.reset_index(inplace=True)
y.drop(['index'], axis = 1, inplace=True)
# plotting the results
sns.set_context('notebook', font_scale= 1.5)
plt.figure(figsize=(20, 10))
plt.plot(y['surge'])
plt.plot(testPredict, color= 'red')
plt.legend(['Observed Surge', 'Predicted Surge'],fontsize = 14)
plt.ylabel('Surge Height (m)')
plt.title("Observed vs. Predicted Storm Surge Height", fontsize=20, y=1.03)
plt.savefig("6 mlp observed vs predicted surge height (after tuning).png", dpi=300)
plt.show()
Error
ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type int).
The error may be faulty data pre processing;make sure that everything is properly formatted.
Below shows what the model expects as inputs:
[print(i.shape, i.dtype) for i in model.inputs]
[print(o.shape, o.dtype) for o in model.outputs]
[print(l.name, l.input_shape, l.dtype) for l in model.layers]
Pass the data to the model as the model expects. Thank You.

Where is this dimension error getting generated in my ADAM algorithm?

I am working on main.py in this BRATS Unet
https://github.com/pykao/Modified-3D-UNet-Pytorch/blob/master/main.py
# create your optimizer
print ("Creating Optimizer")
##optimizer = optim.adam(net.parameteres(), lr=)
optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)
print ("Created! \n")
trainloader = torch.utils.data.DataLoader(train_idx, batch_size=2, shuffle=True)
testloader = torch.utils.data.DataLoader(test_idx, batch_size=2, shuffle=False)
for epoch in range(2): # loop over the dataset multiple times
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
print("inside for")
# get the inputs THIS ERRORS OUT
inputs, labels = data
# zero the parameter gradients
optimizer.zero_grad()
# forward + backward + optimize
outputs = model(inputs)
loss = criterion(outputs, target)
loss.backward()
optimizer.step()
# print statistics
running_loss += loss.item()
if i % 2000 == 1999: # print every 2000 mini-batches
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')
I get this output:
Creating Optimizer
Created!
inside for
Traceback (most recent call last):
File "main.py", line 109, in <module>
outputs = model(inputs)
File "/home/MAHEUNIX/anaconda3/lib/python3.6/site-packages/torch/nn/modules/module.py", line 489, in __call__
result = self.forward(*input, **kwargs)
File "/mnt/c/Users/MAHE/Modified Unet3D Master -TestRun/model.py", line 99, in forward
out = self.conv3d_c1_1(x)
File "/home/MAHEUNIX/anaconda3/lib/python3.6/site-packages/torch/nn/modules/module.py", line 489, in __call__
result = self.forward(*input, **kwargs)
File "/home/MAHEUNIX/anaconda3/lib/python3.6/site-packages/torch/nn/modules/conv.py", line 448, in forward
self.padding, self.dilation, self.groups)
RuntimeError: Expected 5-dimensional input for 5-dimensional weight [16, 4, 3, 3, 3], but got 0-dimensional input of size [] instead
I am unfamiliar with PyTorch, and so trainloader, testloader are probably incorrectly used. Please assume I don't know much while you help me. Thanks.
New error:
Traceback (most recent call last):
File "/mnt/c/Users/MAHE/Modified Unet3D Master -TestRun/main.py", line 91, in <module>
for id, info in enumerate(trainloader,0):
File "/home/MAHEUNIX/anaconda3/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 615, in __next__
batch = self.collate_fn([self.dataset[i] for i in indices])
File "/home/MAHEUNIX/anaconda3/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 615, in <listcomp>
batch = self.collate_fn([self.dataset[i] for i in indices])
KeyError: 0
You should pass the dataset to the data loader API. So, pass train_data and test_data instead of train_idx and test_idx to torch.utils.data.DataLoader.

Input dimension mismatch in Keras

Hi Can anyone help me out with the error, I have seemed to search through the documentation but to no avail.
The aim is to predict a time series. I have used a dummy data shape = (N, timesteps, features). I wish to predict x_2 from x_1, x_3 from x_2 and so on till x_11 from x_10 using LSTM. (Any suggestion to do it better is welcome). The output (below) shows the expected output shapes which seem correct. However, the error mentions an input dimension mismatch. As per documentation, I can't seem to find the problem.
import numpy as np
N = 13*12;
T = 10;
F = 3;
X = np.random.rand(N, T, F);
Y = np.random.rand(N, 1, F);
Y = np.concatenate((X[:,1:T,:], Y), axis=1);
import keras
from keras.models import Model
from keras.layers import Dense, Input, LSTM, Lambda, concatenate, Dropout
from keras.optimizers import Adam, SGD
from keras import regularizers
from keras.metrics import categorical_accuracy
from keras.models import load_model
input_ = Input(shape = (T, F), name ='input');
x = Dense(15, activation='sigmoid', name='fc1')(input_);
x = LSTM(25, return_sequences=True, activation='tanh', name='lstm')(x);
x = Dense(F, activation='sigmoid', name='fc2')(x);
model = Model(input_, x, name='dummy');
model.compile(optimizer='rmsprop', loss='mse', metrics=['accuracy']);
print(model.input_shape); print(X.shape);
print(model.output_shape); print(Y.shape);
print(model.summary());
model.fit(X, Y, batch_size = 13, epochs=30, validation_split=0.20, shuffle=False);
The error comes as
Using Theano backend.
(None, 10, 3)
(156, 10, 3)
(None, 10, 3)
(156, 10, 3)
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input (InputLayer) (None, 10, 3) 0
_________________________________________________________________
fc1 (Dense) (None, 10, 15) 60
_________________________________________________________________
lstm (LSTM) (None, 10, 25) 4100
_________________________________________________________________
fc2 (Dense) (None, 10, 3) 78
=================================================================
Total params: 4,238
Trainable params: 4,238
Non-trainable params: 0
_________________________________________________________________
None
Train on 124 samples, validate on 32 samples
Epoch 1/30
Traceback (most recent call last):
File "C:\Anaconda3\lib\site-packages\theano\compile\function_module.py", line 903, in __call__
self.fn() if output_subset is None else\
ValueError: Input dimension mis-match. (input[0].shape[1] = 10, input[1].shape[1] = 15)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "b.py", line 34, in <module>
model.fit(X, Y, batch_size = 13, epochs=30, validation_split=0.20, shuffle=False);
File "C:\Anaconda3\lib\site-packages\keras\engine\training.py", line 1498, in fit
initial_epoch=initial_epoch)
File "C:\Anaconda3\lib\site-packages\keras\engine\training.py", line 1152, in _fit_loop
outs = f(ins_batch)
File "C:\Anaconda3\lib\site-packages\keras\backend\theano_backend.py", line 1158, in __call__
return self.function(*inputs)
File "C:\Anaconda3\lib\site-packages\theano\compile\function_module.py", line 917, in __call__
storage_map=getattr(self.fn, 'storage_map', None))
File "C:\Anaconda3\lib\site-packages\theano\gof\link.py", line 325, in raise_with_op
reraise(exc_type, exc_value, exc_trace)
File "C:\Anaconda3\lib\site-packages\six.py", line 692, in reraise
raise value.with_traceback(tb)
File "C:\Anaconda3\lib\site-packages\theano\compile\function_module.py", line 903, in __call__
self.fn() if output_subset is None else\
ValueError: Input dimension mis-match. (input[0].shape[1] = 10, input[1].shape[1] = 15)
Apply node that caused the error: Elemwise{Add}[(0, 0)](Reshape{3}.0, InplaceDimShuffle{x,0,x}.0)
Toposort index: 98
Inputs types: [TensorType(float32, 3D), TensorType(float32, (True, False, True))]
Inputs shapes: [(13, 10, 15), (1, 15, 1)]
Inputs strides: [(600, 60, 4), (60, 4, 4)]
Inputs values: ['not shown', 'not shown']
Outputs clients: [[Reshape{2}(Elemwise{Add}[(0, 0)].0, TensorConstant{[-1 15]}), Elemwise{Composite{((i0 + i1 + i2
+ i3) * scalar_sigmoid(i4) * (i5 - scalar_sigmoid(i4)))}}[(0, 0)](Reshape{3}.0, Reshape{3}.0, Reshape{3}.0, Reshape
{3}.0, Elemwise{Add}[(0, 0)].0, TensorConstant{(1, 1, 1) of 1.0})]]
HINT: Re-running with most Theano optimization disabled could give you a back-trace of when this node was created.
This can be done with by setting the Theano flag 'optimizer=fast_compile'. If that does not work, Theano optimizati
ons can be disabled with 'optimizer=None'.
HINT: Use the Theano flag 'exception_verbosity=high' for a debugprint and storage map footprint of this apply node.
I am unable to understand the error as to why the input shape would be (1,15,1) in the error and what are the 2 inputs which theano mentions?
The theano version I use is 0.9.0 and keras version is 2.0.4. If I rather use no features(F), the code runs smoothly.
Edit 1: batch size is 13, just for clarity in error log. Removing it also gives the exact same error.

Viewing layer activations with Keras

In NVIDIA's paper "End to End Learning for Self-Driving Cars" there's an illustration showing the activation of first-layer feature maps:
I'm trying to recreate this with the Comma AI model, but the only visualisation tools I've found are Keras' instructions for gradient ascent and descent, rather than simply viewing activations. what should I be looking for?
EDIT IN RESPONSE TO COMMENT
I tried implementing the code in this answer using the below code:
from keras import backend as K
import json
from keras.models import model_from_json
with open('outputs/steering_model/steering_angle.json', 'r') as jfile:
z = json.load(jfile)
model = model_from_json(z)
print("Loaded model")
model.load_weights('outputs/steering_model/steering_angle.keras')
print("Loaded weights")
img_width = 320
img_height = 160
outputs = [layer.output for layer in model.layers] # all layer outputs
functors = [K.function([inp]+ [K.learning_phase()], [out]) for out in outputs] # evaluation functions
# Testing
test = np.random.random((1, 3, img_width, img_height))
layer_outs = [func([test, 1.]) for func in functors]
print layer_outs
This give the following output error:
Using Theano backend.
Loaded model
Loaded weights
Traceback (most recent call last):
File "vis-layers.py", line 22, in <module>
layer_outs = [func([test, 1.]) for func in functors]
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/backend/theano_backend.py", line 959, in __call__
return self.function(*inputs)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/theano/compile/function_module.py", line 871, in __call__
storage_map=getattr(self.fn, 'storage_map', None))
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/theano/gof/link.py", line 314, in raise_with_op
reraise(exc_type, exc_value, exc_trace)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/theano/compile/function_module.py", line 859, in __call__
outputs = self.fn()
ValueError: Shape mismatch: x has 49152 cols (and 1 rows) but y has 12800 rows (and 512 cols)
Apply node that caused the error: Dot22(Elemwise{Composite{Switch(GT(i0, i1), i0, expm1(i0))}}[(0, 0)].0, dense_1_W)
Toposort index: 50
Inputs types: [TensorType(float32, matrix), TensorType(float32, matrix)]
Inputs shapes: [(1, 49152), (12800, 512)]
Inputs strides: [(196608, 4), (2048, 4)]
Inputs values: ['not shown', 'not shown']
Outputs clients: [[Elemwise{Add}[(0, 0)](Dot22.0, InplaceDimShuffle{x,0}.0)]]
I thought this might be a problem with th vs tf dimensions, so tried changing the test input to:
test = np.random.random((1, img_height, img_width, 3))
which gave the following error:
Using Theano backend.
Loaded model
Loaded weights
Traceback (most recent call last):
File "vis-layers.py", line 22, in <module>
layer_outs = [func([test, 1.]) for func in functors]
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/backend/theano_backend.py", line 959, in __call__
return self.function(*inputs)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/theano/compile/function_module.py", line 871, in __call__
storage_map=getattr(self.fn, 'storage_map', None))
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/theano/gof/link.py", line 314, in raise_with_op
reraise(exc_type, exc_value, exc_trace)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/theano/compile/function_module.py", line 859, in __call__
outputs = self.fn()
ValueError: CorrMM images and kernel must have the same stack size
Apply node that caused the error: CorrMM{half, (4, 4)}(Elemwise{Composite{(i0 + (i1 * i2))}}.0, Subtensor{::, ::, ::int64, ::int64}.0)
Toposort index: 9
Inputs types: [TensorType(float32, 4D), TensorType(float32, 4D)]
Inputs shapes: [(1, 320, 160, 3), (16, 3, 8, 8)]
Inputs strides: [(2250000, 6000, 12, 4), (768, 256, -32, -4)]
Inputs values: ['not shown', 'not shown']
Outputs clients: [[Subtensor{int64:int64:int8, int64:int64:int8, int64:int64:int8, int64:int64:int8}(CorrMM{half, (4, 4)}.0, ScalarFromTensor.0, ScalarFromTensor.0, Constant{1}, Constant{0}, Constant{16}, Constant{1}, ScalarFromTensor.0, ScalarFromTensor.0, Constant{1}, ScalarFromTensor.0, ScalarFromTensor.0, Constant{1})]]
Backtrace when the node is created(use Theano flag traceback.limit=N to make it longer):
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/utils/layer_utils.py", line 43, in layer_from_config
return layer_class.from_config(config['config'])
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/models.py", line 1091, in from_config
model.add(layer)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/models.py", line 332, in add
output_tensor = layer(self.outputs[0])
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/engine/topology.py", line 572, in __call__
self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/engine/topology.py", line 635, in add_inbound_node
Node.create_node(self, inbound_layers, node_indices, tensor_indices)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/engine/topology.py", line 166, in create_node
output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0]))
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/layers/convolutional.py", line 475, in call
filter_shape=self.W_shape)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/backend/theano_backend.py", line 1508, in conv2d
filter_shape=filter_shape)
EDIT: Output of model.summary()
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
lambda_1 (Lambda) (None, 3, 160, 320) 0 lambda_input_1[0][0]
____________________________________________________________________________________________________
convolution2d_1 (Convolution2D) (None, 16, 40, 80) 3088 lambda_1[0][0]
____________________________________________________________________________________________________
elu_1 (ELU) (None, 16, 40, 80) 0 convolution2d_1[0][0]
____________________________________________________________________________________________________
convolution2d_2 (Convolution2D) (None, 32, 20, 40) 12832 elu_1[0][0]
____________________________________________________________________________________________________
elu_2 (ELU) (None, 32, 20, 40) 0 convolution2d_2[0][0]
____________________________________________________________________________________________________
convolution2d_3 (Convolution2D) (None, 64, 10, 20) 51264 elu_2[0][0]
____________________________________________________________________________________________________
flatten_1 (Flatten) (None, 12800) 0 convolution2d_3[0][0]
____________________________________________________________________________________________________
dropout_1 (Dropout) (None, 12800) 0 flatten_1[0][0]
____________________________________________________________________________________________________
elu_3 (ELU) (None, 12800) 0 dropout_1[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 512) 6554112 elu_3[0][0]
____________________________________________________________________________________________________
dropout_2 (Dropout) (None, 512) 0 dense_1[0][0]
____________________________________________________________________________________________________
elu_4 (ELU) (None, 512) 0 dropout_2[0][0]
____________________________________________________________________________________________________
dense_2 (Dense) (None, 1) 513 elu_4[0][0]
====================================================================================================
Total params: 6,621,809
Trainable params: 6,621,809
Non-trainable params: 0
____________________________________________________________________________________________________
EDIT: DEBUGGING WITH SINGLE LAYER
In order to debug the issue with input shapes, I rewrote the script for a single layer:
from keras import backend as K
import numpy as np
import json
from keras.models import model_from_json
with open('outputs/steering_model/steering_angle.json', 'r') as jfile:
z = json.load(jfile)
model = model_from_json(z)
print("Loaded model")
model.load_weights('outputs/steering_model/steering_angle.keras')
print("Loaded weights")
layer_name = 'lambda_1'
img_width = 160
img_height = 320
inp = model.input
layer_idx = [idx for idx, layer in enumerate(model.layers) if layer.name == layer_name][0]
output = model.layers[layer_idx].output
functor = K.function([inp]+ [K.learning_phase()], output) # evaluation function
# Testing
test = np.random.random((1, img_height, img_width, 3))
layer_out = functor([test, 1.])
print layer_out
The output from this is as follows:
Using Theano backend.
Loaded model
Loaded weights
[[[[-0.99223709 -0.99468529 -0.99318016]
[-0.99725926 -0.9924705 -0.9994905 ]
[-0.99380279 -0.99291307 -0.99927235]
...,
[-0.99361622 -0.99258155 -0.99954134]
[-0.99748689 -0.99217939 -0.99918425]
[-0.99475586 -0.99366009 -0.992827 ]]
[[-0.99330682 -0.99756712 -0.99795902]
[-0.99421203 -0.99240923 -0.99438184]
[-0.99222761 -0.99425066 -0.99886942]
...,
[-0.99329156 -0.99460274 -0.99994165]
[-0.99763876 -0.99870259 -0.9998613 ]
[-0.99962425 -0.99702215 -0.9943046 ]]
[[-0.99947125 -0.99577188 -0.99294066]
[-0.99582225 -0.99568367 -0.99345332]
[-0.99823713 -0.99376178 -0.99432898]
...,
[-0.99828976 -0.99264622 -0.99669623]
[-0.99485278 -0.99353015 -0.99411404]
[-0.99832171 -0.99390954 -0.99620205]]
...,
[[-0.9980613 -0.99474132 -0.99680966]
[-0.99378282 -0.99288809 -0.99248403]
[-0.99375945 -0.9966079 -0.99440354]
...,
[-0.99634677 -0.99931824 -0.99611002]
[-0.99781156 -0.99990571 -0.99249381]
[-0.9996115 -0.99991143 -0.99486816]]
[[-0.99839222 -0.99690026 -0.99410695]
[-0.99551272 -0.99262673 -0.99934679]
[-0.99432331 -0.99822938 -0.99294668]
...,
[-0.99515969 -0.99867356 -0.9926796 ]
[-0.99478716 -0.99883151 -0.99760127]
[-0.9982425 -0.99547088 -0.99658638]]
[[-0.99240851 -0.99792403 -0.99360847]
[-0.99226022 -0.99546915 -0.99411654]
[-0.99558711 -0.9960795 -0.9993062 ]
...,
[-0.99745959 -0.99276334 -0.99800634]
[-0.99249429 -0.99748743 -0.99576926]
[-0.99531293 -0.99618822 -0.99997312]]]]
However, attempting the same on the first convolutional layer (convolution2d_1) with an 80x40 image returns the same error:
ValueError: CorrMM images and kernel must have the same stack size
Apply node that caused the error: CorrMM{half, (4, 4)}(Elemwise{Composite{(i0 + (i1 * i2))}}.0, Subtensor{::, ::, ::int64, ::int64}.0)
Toposort index: 9
Inputs types: [TensorType(float32, 4D), TensorType(float32, 4D)]
Inputs shapes: [(1, 40, 80, 3), (16, 3, 8, 8)]
Inputs strides: [(38400, 960, 12, 4), (768, 256, -32, -4)]
Inputs values: ['not shown', 'not shown']
Outputs clients: [[Subtensor{int64:int64:int8, int64:int64:int8, int64:int64:int8, int64:int64:int8}(CorrMM{half, (4, 4)}.0, ScalarFromTensor.0, ScalarFromTensor.0, Constant{1}, Constant{0}, Constant{16}, Constant{1}, ScalarFromTensor.0, ScalarFromTensor.0, Constant{1}, ScalarFromTensor.0, ScalarFromTensor.0, Constant{1})]]
EDIT: OUTPUT LAYER DATA AS IMAGE
The following code replaces the random image with a loaded one, and takes the layer output and saves it as an image:
input_img_data = imread(impath+'.png').astype(np.float32)
# change image to 4d theano array
test = np.expand_dims(input_img_data,axis=0)
print test.shape
layer_out = functor([test, 1.])
img = Image.fromarray(layer_out[0,:,:,:], 'RGB')
img.save('activ_%s_%s.png' % (layer_name,impath))
print("Created Image")
Here is the final code that does what I want it to do, still rough and in need of tidying up:
from keras import backend as K
from PIL import Image
from scipy.misc import imread
from scipy.misc import imsave
import numpy as np
import json
from keras.models import model_from_json
with open('outputs/steering_model/steering_angle.json', 'r') as jfile:
z = json.load(jfile)
model = model_from_json(z)
print("Loaded model")
model.load_weights('outputs/steering_model/steering_angle.keras')
print("Loaded weights")
layer_name = 'lambda_1'
#layer_name = 'convolution2d_1'
#layer_name = 'elu_1'
#layer_name = 'convolution2d_2'
impaths = ['track','road','mway']
img_width = 500
img_height = 375
inp = model.input
layer_idx = [idx for idx, layer in enumerate(model.layers) if layer.name == layer_name][0]
output = model.layers[layer_idx].output
functor = K.function([inp]+ [K.learning_phase()], output) # evaluation function
for impath in impaths:
input_img_data = imread('testimages/'+impath+'.png').astype(np.float32)
input_img_data = np.rollaxis(input_img_data,2,0) # change to (channels,h,w)
test = np.expand_dims(input_img_data,axis=0) # change to (dims,channels,h,w)
print("Test Shape: %s" % (test.shape,)) # check shape
layer_out = functor([test, 1.])
print ("Output Shape: %s" % (layer_out.shape,)) # check output shape
# save multiple greyscale images
layer_out = np.rollaxis(layer_out,0,4)
print ("Output Image Shape: %s" % (layer_out.shape,)) # check output shape
count = 1
for x in layer_out:
x = np.rollaxis(x,2,0)
print ("Final Image Shape: %s" % (x.shape,)) # check output shape
imsave('activationimages/activ_%s_%s_%d.png' % (layer_name,impath,count),x[0,:,:])
count = count + 1
The main issue was wrangling the shapes of the various input and output layers - hence all the print commands in the above code, for debugging.
A second confusion was that I was interpreting an array shape of (3,w,h) as a single RGB (3-channel) image, rather than one greyscale image.
The version above tests an array of images at a time (hardcoded image path). The lambda_1 level outputs a single RGB image per test image, convolution2d_1 and elu_1 output sixteen smaller (25%) greyscale images - one for each filter. And, I hope, so on.
I will add a Github link to a tidied gist with image stitching when I've done this. I've learned a lot.

Resources