I currently have a modified resnet50 architecutre that accepts two inputs, selects only the main input, and runs it through resnet. I then am trying to use this additional input in conjunction with an intermediate layer output within a loss function. However, I can't seem to access these intermediate layers at all without getting errors.
The following code runs fine, and I am able to correctly extract the intermediate layer within a loss function.
#imports, load resnet
from keras.applications.resnet50 import ResNet50
import keras
import numpy as np
import keras.backend as K
model = ResNet50(weights=None,input_shape=(64,64,3),classes=10)
#define our loss function, works fine
def demo_loss_works_fine(y_true, y_pred):
return (keras.losses.categorical_crossentropy(y_true, y_pred)
+ K.mean(model.layers[-6].output))
batch_size=16
epochs=8
model.compile(optimizer='adam', loss=demo_loss_works_fine, metrics=['accuracy'])
#generate some fake data
xTrain=np.zeros((100,64,64,3))
yTrain=np.zeros((100,10))
xTest=np.zeros((10,64,64,3))
yTest=np.zeros((10,10))
#datagenerator
from keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(rotation_range=90,horizontal_flip=True,vertical_flip=True)
#train it, works fine
history= model.fit_generator(datagen.flow(xTrain, yTrain, batch_size=batch_size),
steps_per_epoch=int(xTrain.shape[0] / batch_size),
epochs=epochs,
validation_data=(xTest, yTest),
verbose=1,
workers=8)
However, using my modified resnet architecture with 2 inputs, I get a "You must feed a value for placeholder tensor" error. I suspect it may be due to some graph disconnection somewhere or a similar issue, but am not quite sure. Or perhaps an issue with the keras 'pop'. The code below runs when not extracting the intermediate layer in the loss function, and fails when trying to extract the intermediate layer.
##imports
from keras.applications.resnet50 import ResNet50
from keras.layers import Input
from keras.layers import Lambda
from keras.models import Model
from keras.optimizers import Adam
import keras
import keras.backend as K
import numpy as np
#pop off the input
res = ResNet50(weights=None,include_top=True,classes=2,input_shape=(224,224,3))
res.layers.pop(0)
#add two inputs
auxinput= Input(batch_shape=(None,224,224,1), name='aux_input')
main_input = Input(batch_shape=(None,224,224,3), name='main_input')
#use a lambda functon to return just our main input (avoids graph disconnect errors from out auxilary input not being used in resnet50 component)
l_output = Lambda(lambda x: x[0])([main_input, auxinput])
#feed our main input to resnet50 model
data_passed_thru = res(l_output)
#assemble the model with our two inputs, and output from our main input fed through resent
mymodel = Model(inputs=[main_input, auxinput], outputs=[data_passed_thru])
mymodel.summary()
#loss function: this is the cause of the errors. There is some issue accessing the layer output
#change "break_it" to false to run without error
break_it=True
def demo_issue_loss(targ,pred):
classification_loss= keras.losses.poisson(targ,pred)
if break_it==True:
#this is where the issue I'm trying to fix is: extracting the intermediate layer
conv_out= (mymodel.layers[-1].layers[-6].output)
return(K.mean(conv_out)+classification_loss)
else:
return(classification_loss)
batch_size=16
epochs=8
#data generator for some fake data, works fine
def batch_generator_classification(batch_size):
while True:
image_list = []
mask_list = []
label_list=[]
for i in range(batch_size):
img, mask,label = np.random.rand(224,224,3),np.random.rand(224,224,1),np.random.rand(2)
image_list.append(img)
mask_list.append(mask)
label_list.append(label)
image_list = np.array(image_list, dtype=np.float32)
mask_list = np.array(mask_list, dtype=np.float32)
label_list = np.array(label_list, dtype=np.float32)
yield [image_list,mask_list],[label_list]
#compile with our custom loss
mymodel.compile(optimizer='adam',
loss=demo_issue_loss,
metrics=['accuracy'])
#define data augmentation
from keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
rotation_range=90, # randomly rotate images in the range (degrees, 0 to 180)
horizontal_flip=True, # randomly flip images
vertical_flip=True)
#train it: fails when accessing layer output within loss function, runs when not accessing layer output
history= mymodel.fit_generator( generator=batch_generator_classification(batch_size),
samples_per_epoch=100,
nb_epoch=epochs,
nb_val_samples=10,
validation_data=batch_generator_classification(batch_size),
verbose=1)
The error that returns is
InvalidArgumentError: You must feed a value for placeholder tensor 'input_1' with dtype float and shape [?,224,224,3]
[[{{node input_1}}]]
[[{{node metrics/acc/Mean}}]]