我制作了自定义的yolo损失函数,基本上与此处的https://github.com/Neerajj9/Text-Detection-using-Yolo-Algorithm-in-keras-tensorflow/blob/master/Yolo.ipynb
相同在训练时,它显示出Nan的损失。为什么会这样?
def yolo_loss_function(y_true,y_pred):
#y_true,y_pred:None,16,16,1,5
l_coords = 5.0
l_noob = 0.5
coords = y_true[:,:,:,:,0]*l_coords
noobs = (-1*(y_true[:,:,:,:,0]-1)*l_noob)
p_pred = y_pred[:,:,:,:,0] #probability that theer is text or not
p_true = y_true[:,:,:,:,0] #Always 1 or 0
x_true = y_true[:,:,:,:,1]
x_pred = y_pred[:,:,:,:,1]
yy_true = y_true[:,:,:,:,2]
yy_pred = y_pred[:,:,:,:,2]
w_true = y_true[:,:,:,:,3]
w_pred = y_pred[:,:,:,:,3]
h_true = y_true[:,:,:,:,4]
h_pred = y_pred[:,:,:,:,4]
#We have different loss value depending on whether text is present or not
p_loss_absent = K.sum(K.square(p_pred-p_true)*noobs)
p_loss_present = K.sum(K.square(p_pred-p_true))
x_loss = K.sum(K.square(x_pred-x_true)*coords)
yy_loss = K.sum(K.square(yy_pred-yy_true)*coords)
xy_loss = x_loss + yy_loss
w_loss = K.sum(K.square(K.sqrt(w_pred)-K.sqrt(w_true))*coords)
h_loss = K.sum(K.square(K.sqrt(h_pred)-K.sqrt(h_true))*coords)
wh_loss = w_loss+h_loss
loss = p_loss_present+p_loss_absent + xy_loss + wh_loss
return loss
#optimizer
opt = Adam(lr=0.0001,beta_1=0.9,beta_2=0.999,epsilon=1e-08,decay=0.0)
#checkpoint
checkpoint = ModelCheckpoint('model/text_detect.h5',monitor='val_loss',verbose =1,save_best_only=True,mode='min',period=1)
model.compile(loss=yolo_loss_function,optimizer=opt,metrics=['accuracy'])
我正在使用通过MobileNetV2架构进行的转移学习。
P.S。 -Loss goes to NAN when training the custom YOLO model如此,我尝试从损失函数中删除sqrt
。那除去了nan
,但我的损失并没有减少。它稳定地增加,然后保持恒定在大约6。上述职位的答案似乎无济于事,因为我在任何地方都看不到0
的“划分”。
编辑:
def yolo_model(input_shape):
inp = Input(input_shape)
model = MobileNetV2( input_tensor= inp , include_top=False, weights='imagenet')
last_layer = model.output
conv = Conv2D(512,(3,3) , activation='relu' , padding='same')(last_layer)
conv = Dropout(0.4)(conv)
bn = BatchNormalization()(conv)
lr = LeakyReLU(alpha=0.1)(bn)
conv = Conv2D(128,(3,3) , activation='relu' , padding='same')(lr)
conv = Dropout(0.4)(conv)
bn = BatchNormalization()(conv)
lr = LeakyReLU(alpha=0.1)(bn)
conv = Conv2D(5,(3,3) , activation='sigmoid' , padding='same')(lr)
final = Reshape((grid_h,grid_w,classes,info))(conv)
model = Model(inp,final)
return model
我正在上传模型。最后一个Conv2D
层的激活是relu
,我将其更改为sigmoid
以响应一个答案。另外,我的图像从(-1,1)归一化。在第1个纪元后,我的程序显示loss:nan accuracy:1.0000
,下面显示一行could not bring down loss from inf
。
答案 0 :(得分:0)
您在最后一层使用relu
,这是不期望的。这可能会导致梯度消失。
在原始的yolo纸中,坐标是有界的,这意味着坐标(高度,宽度)在(0,1)范围内进行了归一化。因此,也许摆脱relu并尝试线性或S型。
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"])