I am relatively new to DL and Keras.
I am trying to implement perceptual loss using the pretrained VGG16 in Keras but have some troubles. I already found that question but I am still struggling :/
A short explanation of what my network should do:
I have a CNN (subsequent called mainModel) that gets grayscale images as input (#TrainData, 512, 512, 1) and outputs grayscale images with the same size. The network should reduce artifacts in the images - but I think it is not that important for this question. Instead of using e.g. MSE as loss function, I would like to implement the perceptual loss.
What I want to do (I hope I have properly understood the concept of perceptual loss):
I would like to append a lossModel (pretrained VGG16 with fixed params) to my mainModel. Then I would like to pass the output of the mainModel to the lossModel. In addition I pass the label images (Y_train) to the lossModel. Further on I compare the activations at a specific layer (e.g. block1_conv2) of the lossModel using e.g. MSE and use it as loss function.
What I did so far:
Load in data and create the mainModel:
### Load data ###
with h5py.File('.\train_test_val.h5', 'r') as hf:
X_train = hf['X_train'][:]
Y_train = hf['Y_train'][:]
X_test = hf['X_test'][:]
Y_test = hf['Y_test'][:]
X_val = hf['X_val'][:]
Y_val = hf['Y_val'][:]
### Create Main Model ###
input_1 = Input((512,512,9))
conv0 = Conv2D(64, (3,3), strides=(1,1), activation=relu, use_bias=True, padding='same')(input_1)
.
.
.
mainModel = Model(inputs=input_1, outputs=output)
Create lossModel, append it to mainModel and fix params:
### Create Loss Model (VGG16) ###
lossModel = vgg16.VGG16(include_top=False, weights='imagenet', input_tensor=mainModel.output, input_shape=(512,512, 1))
lossModel.trainable=False
for layer in lossModel.layers:
layer.trainable=False
Create new model including both networks and compile it
### Create new Model ###
fullModel = Model(inputs=mainModel.input, outputs=lossModel.output)
fullModel.compile(loss='mse', optimizer='adam',metrics=['mse','mae'])
fullModel.summary()
Adjust label images by passing them through the lossNetwork:
Y_train_lossModel = lossModel.predict(Y_train)
Fit the fullModel using the perceptual loss:
fullModel.fit(X_train, Y_train_lossModel, batch_size=32, epochs=5, validation_data=[X_val,Y_val])
Problems occurring:
VGG16 wants to get inputs of shape (?,?,3) but my mainModel outputs a grayscale image (?,?,1)
Some issue with appending the lossModel to the mainModel
RuntimeError: Graph disconnected: cannot obtain value for tensor Tensor("conv2d_2/Relu:0", shape=(?, 512, 512, 3), dtype=float32) at layer "input_2". The following previous layers were accessed without issue: []
- How can I calculate the MSE at a specific layers activation and not at the output of the lossModel?
Thank you so much for your help and sorry for the extremely long question :)