keras-yolo3 icon indicating copy to clipboard operation
keras-yolo3 copied to clipboard

"Gradients do not exist" Warning

Open RadFam opened this issue 2 years ago • 0 comments

I had tried to repeat the train code, just for the network with one class object detection. So I saved the structure of train.py and model.py, except the creation of Yolo network - I built it layer by layer. But, when I've tried to start yolo training, I got the warning: "WARNING:tensorflow:Gradients do not exist for variables ['Layer_Conv_81/kernel:0', 'Layer_Conv_91/kernel:0', 'Layer_Batch_81/gamma:0', 'Layer_Batch_81/beta:0', 'Layer_Batch_91/gamma:0', 'Layer_Batch_91/beta:0', 'Output_1/kernel:0', 'Output_2/kernel:0'] when minimizing the loss. If you're using model.compile(), did you forget to provide a lossargument?". I suppose, that this must be caused in definition of loss argument i.e trainModel.compile(optimizer=Adam(lr=1e-3), loss={'GetLoss': lambda y_train, y_pred: y_pred}, run_eagerly=True)

  • lambda function in loss returns y_pred, and Keras could not connect loss result of Lambda layer (which combines yolo outputs and true ground inputs) with yolo output layers. But original train script had not produce such warning. I'm new to Keras, so can anybody say, what can invoke gradient warning? For convinience, I place a part of my code below:

def MakeYoloMainStructure():

 

    inputImage = Input(shape=(IMAGE_SIDES[0], IMAGE_SIDES[1], 3), name='Main_Input')

 

    # Start placing layers

    layer1_1 = Conv2D(32, (3,3), strides=(1,1), use_bias=False, padding='same', name='Layer_Conv_1')(inputImage) ... layer80_3 = LeakyReLU(alpha=alp, name='Layer_Leaky_80')(layer80_2)

    layer81_1 = Conv2D(1024, (3,3), strides=(1,1), use_bias=False, padding='same', name='Layer_Conv_81')(layer80_3) # From this layer we make fork for first output (!)

    layer81_2 = BatchNormalization(epsilon=eps, name='Layer_Batch_81')(layer81_1)

    layer81_3 = LeakyReLU(alpha=alp, name='Layer_Leaky_81')(layer81_2)

    layer82_1 = Conv2D(3*6, (1,1), strides=(1,1), use_bias=False, padding='same', name='Output_1')(layer81_3) # FIRST output layer (!)

    layer84_1 = layer80_3

    layer85_1 = Conv2D(256, (1,1), strides=(1,1), use_bias=False, padding='same', name='Layer_Conv_83')(layer84_1) ... layer106_1 = Conv2D(3*6, (1,1), strides=(1,1), use_bias=False, padding='same', name='Output_3')(layer105_3)  # THIRD output layer (!)

 

    # Net structure is completed

    yoloBoneModel = Model(inputImage, [layer82_1, layer94_1, layer106_1])

 

    return yoloBoneModel

def MakeYoloTrainStructure(yoloBoneMode): gridInput_all = [Input(shape=(GRID_SIDES[1], GRID_SIDES[1], 3, 6), name='Grid_Input_1'), Input(shape=(GRID_SIDES[2], GRID_SIDES[2], 3, 6), name='Grid_Input_2'), Input(shape=(GRID_SIDES[3], GRID_SIDES[3], 3, 6), name='Grid_Input_3')]

    layer_loss = Lambda(GetLoss, output_shape=(1,), name='GetLoss', arguments={'threshold': thresh})([*yoloBoneModel.output, *gridInput_all])

yoloTrainModel = Model([yoloBoneModel.input, *gridInput_all], layer_loss) return yoloTrainModel

def GetLoss(args, threshold=0.5):

    modelOutputs = args[:3]

    checkInputs = args[3:]

    # ......

    # Numerous manipulations to get loss of objects detection

    # ......

    return loss

def main():

    boneModel = MakeYoloMainStructure()

    trainModel = MakeYoloTrainStructure(boneModel)

 

    trainModel.compile(optimizer=Adam(lr=1e-3), loss={'GetLoss': lambda gridInput_all, y_pred: y_pred}, run_eagerly=True)

    batchSize = 32

    trainModel.fit(GetDataGenerator(batchSize), steps_per_epoch=2000//batchSize, epochs=50, initial_epoch=0)

RadFam avatar Apr 18 '22 11:04 RadFam