qqwweee/keras-yolo3模型默认采用的是一块GPU,在直接使用model = multi_gpu_model(model,gpus=N)时,模型会报错tensorflow.python.framework.errors_impl.InvalidArgumentError: Can’t concatenate scalars (use tf.stack instead) for ‘yolo_loss_1/concat’ (op: ‘ConcatV2’) with input shapes: [], [], [], [].,这是因为该模型的设计的loss输出时一个标量,需要多输出进行修改,才能实现并行。具体修改方式如下: yolo_loss函数中的 xy_loss = K.sum(xy_loss) / mf wh_loss = K.sum(wh_loss) / mf confidence_loss = K.sum(confidence_loss) / mf class_loss = K.sum(class_loss) / mf loss += xy_loss + wh_loss + confidence_loss +class_loss 替换成下面的代码 xy_loss = K.sum(K.sum(xy_loss,axis=[2,3,4]),1,keepdims=True) wh_loss = K.sum(K.sum(wh_loss,axis=[2,3,4]),1,keepdims=True) confidence_loss = K.sum(K.sum(confidence_loss,axis=[2,3,4]),1,keepdims=True) class_loss = K.sum(K.sum(class_loss,axis=[2,3,4]),1,keepdims=True) loss += xy_loss + wh_loss + confidence_loss +class_loss 即实现对loss的改进,保证输入N张图片,输出时(N,1)对应的时N张图片的loss
然后将编译语句model.compile(optimizer=Adam(lr=1e-3), loss={ ‘yolo_loss’: lambda y_true, y_pred: y_pred})改为 model.compile(optimizer=Adam(lr=1e-3), loss=totalloss),其中totalloss为下面定义的损失函数: def totalloss(y_true, y_pred): return K.sum(y_pred)/K.cast(K.shape(y_pred)[0],K.dtype(y_pred)) 在将 model_loss = Lambda(yolo_loss, output_shape=(1,),name=‘yolo_loss’,arguments={‘anchors’: anchors, ‘num_classes’: num_classes, ‘ignore_thresh’: 0.5})( [*model_body.output, *y_true])中的, output_shape=(1,)去掉,直接些微model_loss = Lambda(yolo_loss,name=‘yolo_loss’,arguments={‘anchors’: anchors, ‘num_classes’: num_classes, ‘ignore_thresh’: 0.5})( [*model_body.output, *y_true]) 修改完这3处之后,就直接可以使用model = multi_gpu_model(model,gpus=N)进行多gpu训练了。
PS:实现了多gpu训练,batchsize是可以变为原来的两倍,但是训练速度感觉加快,目前还没找到原因,不知道大家能不能加速,目前我使用的windows,有人说在linux下可以实现加速,对此表示半信半疑,希望大家尝试之后能留言下,自己能不能感觉到加速。谢谢 ———————————————— 版权声明:本文为博主「weixin_43938931」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_43938931/article/details/89470878