Ошибка при извлечении вывода слоя keras в функции потерь - «Вы должны указать значение для тензора-заполнителя» - PullRequest
0 голосов
/ 01 июня 2019

В настоящее время у меня есть измененный архитектор 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}}]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...