【问题标题】:Loss goes to NAN when training the custom YOLO model训练自定义 YOLO 模型时损失到 NAN
【发布时间】:2019-06-03 20:26:34
【问题描述】:

我使用 Keras 为 YOLO 实现了自定义损失函数和模型。我使用 Tensorflow 作为后端。

import pickle
import tensorflow as tf
import numpy as np 
import matplotlib.pyplot as plt 
from keras.models import Sequential,load_model
from keras.layers import Dense,Conv2D,Activation,MaxPooling2D,Flatten
import keras as k
from keras import optimizers
import cv2

batch=12

sess= tf.Session()

#loss function
def yolo_loss(yTrue,yPred):
    coord=5
    noobj=0.5
    L_noobj=1
    L_obj=1
    if yTrue[6] == 1: 
       L_obj=0

    if yTrue[5] == 1:
       L_noobj=0

    w=coord*L_obj*(tf.square([tf.sqrt(yTrue[2])-tf.sqrt(yPred[2])])) 
    h=coord*L_obj*(tf.square([yTrue[3]-yPred[3]]))
    x=coord*L_obj*(tf.square([yTrue[0]-yPred[0]]))
    y=coord*L_obj*(tf.square([yTrue[1]-yPred[1]])) 
    no_obj=noobj*L_noobj*(tf.square([yTrue[6]-yPred[6]])) 
    obj=L_obj*(tf.square([yTrue[5]-yPred[5]])) 
    clss=L_obj*(tf.square([yTrue[4]-yPred[4]]))
    loss=w+h+x+y+no_obj+obj+clss
    return loss

def custom_loss(yTrue,yPred):
    loss=None
    for a in range(batch):
        loss_per_sample=0
        for b in range(4):
            for c in range(4):
                loss_per_sample += yolo_loss(yTrue[a,b,c,0:],yPred[a,b,c,0:])  
        if loss == None:
            loss=tf.stack(loss_per_sample)
        else:
            x=tf.stack(loss_per_sample)
            loss=tf.concat([loss,x],0)

    loss=tf.reshape(loss,[-1,1])      
    return loss 

#load data and labels 
x_train=pickle.load(open('data_image.pickle','rb'))
y_train=pickle.load(open('data_label.pickle','rb'))
test=pickle.load(open('test_image.pickle','rb'))


# model
model=Sequential()

model.add(Conv2D(16,(7,7),input_shape=x_train.shape[1:],padding="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D((2,2)))

model.add(Conv2D(32,(3,3),padding="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D((2,2)))

model.add(Conv2D(64,(3,3),padding="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D((2,2)))

model.add(Conv2D(128,(3,3),padding="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D((2,2)))

model.add(Conv2D(512,(3,3),padding="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D((2,2)))

model.add(Conv2D(512,(3,3),padding="same"))
model.add(Activation("relu"))

model.add(Conv2D(1024,(3,3),padding="same"))
model.add(Activation("relu"))

model.add(Conv2D(7,(3,3),padding="same"))
model.add(Activation("relu"))

adam = optimizers.adam(lr=0.001)
model.compile(loss=custom_loss,optimizer=adam,metrics=["accuracy"]) 


model.fit(x_train,y_train,batch_size=batch,epochs=100)

model.save('yolo.model')

当我训练模型时,损失值变为 NAN。但是在我从自定义损失函数中的“W”和“h”中删除 tf.sqrt() 之后,损失几乎为零。但问题是边界框的“W”和“h”值始终为零。我认为 tf.sqrt() 函数中有一些东西。请有人告诉我这里发生了什么。


【问题讨论】:

    标签: python-3.x tensorflow keras yolo


    【解决方案1】:

    您在最后一层使用relu,这是意料之外的。这可能会导致渐变消失。

    另外,在使用 sqrt 函数之前做一些检查,比如负值。

    model.add(Conv2D(7,(3,3),padding="same"))
    model.add(Activation("relu"))
    
    adam = optimizers.adam(lr=0.001)
    model.compile(loss=custom_loss,optimizer=adam,metrics=["accuracy"]) 
    

    【讨论】:

      【解决方案2】:

      我认为这是某种除以零错误我在使用带有暗流的 Yolo 进行玩家检测时遇到了这个问题我为解决这个问题所做的一件事是对批量大小和学习率进行了一些调整。

      【讨论】:

        猜你喜欢
        • 2020-08-06
        • 1970-01-01
        • 1970-01-01
        • 2023-01-13
        • 2022-10-12
        • 2023-02-26
        • 2017-10-12
        • 2020-12-12
        • 1970-01-01
        相关资源
        最近更新 更多