В настоящее время у меня есть измененный архитектор resnet50, который принимает два входа, выбирает только основной вход и запускает его через реснет. Затем я пытаюсь использовать этот дополнительный вход в сочетании с выходом промежуточного слоя в функции потерь. Однако я не могу получить доступ к этим промежуточным слоям вообще без ошибок.
Следующий код работает нормально, и я могу правильно извлечь промежуточный слой в функции потерь.
#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)
Однако, используя мою модифицированную архитектуру повторной сети с 2 входами, я получаю ошибку «Вы должны указать значение для тензора заполнителя». Я подозреваю, что это может быть связано с некоторым отключением графа или похожей проблемой, но я не совсем уверен. Или, возможно, проблема с керасом «поп». Приведенный ниже код выполняется, когда не извлекается промежуточный уровень в функции потерь, и завершается неудачно при попытке извлечь промежуточный уровень.
##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)
Возвращаемая ошибка:
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}}]]