WenmuZhou / PSENet.pytorch

A pytorch re-implementation of PSENet: Shape Robust Text Detection with Progressive Scale Expansion Network
GNU General Public License v3.0
463 stars 138 forks source link

代码中的一些问题及解决 #39

Open Whu-wxy opened 5 years ago

Whu-wxy commented 5 years ago

作者的代码很棒,但是这几天我在实际的实验中遇到了一些问题并进行了其他几处改进,在这里分享一下。

  1. eval失败。解决:script.py文件中16,17行改为 'GT_SAMPLE_NAME_2_ID': 'gtimg([0-9]+).txt', 'DET_SAMPLE_NAME_2_ID': 'resimg([0-9]+).txt'

  2. 其他python版本编译pse.so出错。我修改makefile文件编译成功了。详情见:https://blog.csdn.net/ab0902cd/article/details/88352417

  3. 训练过程中writer保存了很多图片,但是我感觉用不到,而且保存图片后log文件会很大,可以添加一个if条件。例如添加: if config.display_input_images:

  4. scale设置2或4时报错,尺寸不匹配。原因是模型得到的图是160x160,但是label图是640x640的。 解决:看了一下原作者的代码,train时不设置scale,test时设置scale。

        if self.train:
            x = F.interpolate(x, size=(H, W), mode='bilinear', align_corners=True)
        else:
            x = F.interpolate(x, size=(H // self.scale, W // self.scale), mode='bilinear', align_corners=True)
  5. 加载模型出错。解决:train.py文件,main的 start_epoch = load_checkpoint(config.checkpoint, model, logger, device) ,load_checkpoint的参数optimizer是None时,不加载文件中记录的optimizer,不是None时,加载文件中记录的optimizer,但是文件中保存的不知道是sgd还是adam,在前面设置optimizer时如果不匹配会报错。这里我感觉最好是参数None,就不会报错。 然后后面的MultiStepLR(optimizer, config.lr_decay_step, gamma=config.lr_gamma,last_epoch=-1),最后的参数设置-1,这个是我在其他issue里看到的。

6.保存太多模型文件。main这里我稍微改了一下,改成如果出现test结果更高的,就把以前存的所有文件删除。

               if f1 > best_model['f1']:
                    best_path = glob.glob(config.output_dir + '/Best_*.pth')
                    for b_path in best_path:
                        if os.path.exists(b_path):
                            os.remove(b_path)

                    best_model['recall'] = recall
                    best_model['precision'] = precision
                    best_model['f1'] = f1
                    best_model['models'] = net_save_path

                    best_save_path = '{}/Best_{}_r{:.6f}_p{:.6f}_f1{:.6f}.pth'.format(config.output_dir, epoch,
                                                                                              recall,
                                                                                              precision,
                                                                                              f1)
                    if os.path.exists(net_save_path):
                        shutil.copyfile(net_save_path, best_save_path)
                    else:
                        save_checkpoint(best_save_path, model, optimizer, epoch, logger)

                    pse_path = glob.glob(config.output_dir + '/PSENet_*.pth')
                    for p_path in pse_path:
                        if os.path.exists(p_path):
                            os.remove(p_path)

                writer.add_scalar(tag='Test/recall', scalar_value=recall, global_step=epoch)
                writer.add_scalar(tag='Test/precision', scalar_value=precision, global_step=epoch)
                writer.add_scalar(tag='Test/f1', scalar_value=f1, global_step=epoch)
        writer.close()
    except KeyboardInterrupt:
        save_checkpoint('{}/final.pth'.format(config.output_dir), model, optimizer, epoch, logger)
    finally:
        if best_model['models']:
            # shutil.copy(best_model['models'],
            #             '{}/best_r{:.6f}_p{:.6f}_f1{:.6f}.pth'.format(config.output_dir, best_model['recall'],
            #                                                           best_model['precision'], best_model['f1']))
            logger.info(best_model)
Whu-wxy commented 5 years ago

image

  1. 训练几轮测试一次的结果,与保存的模型文件单独进行测试的结果不一致。解决:train.py的eval里,加了一句“if max(h, w) > long_size:”,但是在eval.py中没有这一句,意思是训练后的test中,图片不进行放大,因此得到的f值较小。把这个if注释掉后f值从60多提高到80多。

    # if max(h, w) > long_size:
    scale = long_size / max(h, w)
    img = cv2.resize(img, None, fx=scale, fy=scale)
  2. pytorch1.1之后,scheduler.step()要放到optimizer.step()之后?改变位置之后没有warning了,效果未知。

  3. epoch信息没有正确保存?加载模型需要手动赋值?

WenmuZhou commented 5 years ago

很赞 有时间提个pr吧

Whu-wxy commented 5 years ago
  1. 调节pse/init.py文件中decode的输入值threshold,可以将F值提高很多,我的实验中提高了至少1%。。。。。话说训练了很长时间都难以提高1%了。。。
WenmuZhou commented 5 years ago

GYxiaOH commented 5 years ago

@Whu-wxy 请问你调节到了多少哦

Whu-wxy commented 5 years ago

@GYxiaOH decode的threshold调到0.58,达到79.x,后来手动调低学习率继续训练,到了80.8。用的optimizer是ranger。

GYxiaOH commented 5 years ago

@Whu-wxy 好的,谢谢。另外我觉得train里那个图片没必要放大,因为validation的时候主要是看看结果好不好,不要求最高结果,train里图片要放大的话validation的速度就变慢了不少

Whu-wxy commented 5 years ago

@GYxiaOH 嗯,主要是我有看最高结果的需要,这个可以在config里设置个开关

GYxiaOH commented 5 years ago

@Whu-wxy python 3.7 重新编译pse在eval的时候会出现段错误,你遇到过这个问题吗

Whu-wxy commented 5 years ago

没有,我编译挺顺利的

GYxiaOH commented 4 years ago

@Whu-wxy 我把decode的阈值调到0.58 f确实涨了,但是召回率掉了好多,这我没想通,理论上更多点了不应该召回率下降精确度升高吗。。。奇了怪了

Debugerss commented 4 years ago

楼主,我在训练了一半之后,停电了,想继续训练,修改如下: #checkpoint = '' checkpoint = '/dahuafs/userdata/01_PDF/01_PSENet/output/psenet_icd2015_resnet152_4gpu_author_crop_adam_MultiStepLR_authorloss/PSENet_36_loss0.055750.pth' restart_training = False

#start_epoch = 0
start_epoch = 37

但是在训练的时候碰到, PermissionError: [Errno 13] Permission denied: 'train_log'

请问怎么解决一下

saonian commented 4 years ago

第八点不能放到optimizer.step()之后,这样每个epoch学习率都会变化,不会按照设定的阶段走。文档上面例子也是在批次训练之后调用。 另外有一点不明,这里###这样没有打标签的不应该设置为False吗,为什么代码里面是True? if label == '*' or label == '###': tags.append(True) else: tags.append(False)