From 5275d667f4fdfb64d2c4c841933a8b4239b18bca Mon Sep 17 00:00:00 2001 From: NYH <175484793@qq.com> Date: Wed, 27 Dec 2023 14:48:56 +0800 Subject: [PATCH] V1.0 --- LICENSE | 21 + README.md | 119 ++- __pycache__/decoder.cpython-38.pyc | Bin 0 -> 3304 bytes __pycache__/eval.cpython-38.pyc | Bin 0 -> 1927 bytes __pycache__/func_utils.cpython-38.pyc | Bin 0 -> 3603 bytes __pycache__/loss.cpython-38.pyc | Bin 0 -> 4241 bytes __pycache__/test.cpython-38.pyc | Bin 0 -> 6121 bytes __pycache__/train.cpython-38.pyc | Bin 0 -> 5435 bytes __pycache__/train.cpython-39.pyc | Bin 0 -> 5467 bytes change_jpg_2_png.py | 15 + decoder.py | 97 ++ draw_loss.py | 61 ++ eval.py | 57 ++ eval_for_resnet18_101.py | 42 + func_utils.py | 101 ++ image_filename_to_txtlist.py | 13 + loss.py | 132 +++ main.py | 83 ++ main_for_test.py | 84 ++ main_for_val.py | 83 ++ models/__pycache__/ctrbox_net.cpython-38.pyc | Bin 0 -> 2077 bytes models/__pycache__/model_parts.cpython-38.pyc | Bin 0 -> 1646 bytes models/__pycache__/resnet.cpython-38.pyc | Bin 0 -> 11093 bytes models/ctrbox_net.py | 89 ++ models/model_parts.py | 37 + models/resnet.py | 356 +++++++ my.log | 64 ++ my20230603.log | 949 ++++++++++++++++++ my520.log | 909 +++++++++++++++++ myenlarge.log | 397 ++++++++ nms.py | 119 +++ resize_image.py | 42 + split_txt.py | 26 + test.py | 225 +++++ test20230320.py | 220 ++++ train.py | 194 ++++ 必看.log | 17 + 37 files changed, 4550 insertions(+), 2 deletions(-) create mode 100644 LICENSE create mode 100644 __pycache__/decoder.cpython-38.pyc create mode 100644 __pycache__/eval.cpython-38.pyc create mode 100644 __pycache__/func_utils.cpython-38.pyc create mode 100644 __pycache__/loss.cpython-38.pyc create mode 100644 __pycache__/test.cpython-38.pyc create mode 100644 __pycache__/train.cpython-38.pyc create mode 100644 __pycache__/train.cpython-39.pyc create mode 100644 change_jpg_2_png.py create mode 100644 decoder.py create mode 100644 draw_loss.py create mode 100644 eval.py create mode 100644 eval_for_resnet18_101.py create mode 100644 func_utils.py create mode 100644 image_filename_to_txtlist.py create mode 100644 loss.py create mode 100644 main.py create mode 100644 main_for_test.py create mode 100644 main_for_val.py create mode 100644 models/__pycache__/ctrbox_net.cpython-38.pyc create mode 100644 models/__pycache__/model_parts.cpython-38.pyc create mode 100644 models/__pycache__/resnet.cpython-38.pyc create mode 100644 models/ctrbox_net.py create mode 100644 models/model_parts.py create mode 100644 models/resnet.py create mode 100644 my.log create mode 100644 my20230603.log create mode 100644 my520.log create mode 100644 myenlarge.log create mode 100644 nms.py create mode 100644 resize_image.py create mode 100644 split_txt.py create mode 100644 test.py create mode 100644 test20230320.py create mode 100644 train.py create mode 100644 必看.log diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4ef8446 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 yijingru + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index ea09dd1..c02cb21 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,118 @@ -# Ship_Tilt_Detection +Update (10-10-2021) My email has been changed to yijingru321@gmail.com. +# BBAVectors-Oriented-Object-Detection +[WACV2021] Oriented Object Detection in Aerial Images with Box Boundary-Aware Vectors ([arXiv](https://arxiv.org/pdf/2008.07043.pdf)) -船舶倾斜框检测 \ No newline at end of file +Please cite the article in your publications if it helps your research: + + @inproceedings{yi2021oriented, + title={Oriented object detection in aerial images with box boundary-aware vectors}, + author={Yi, Jingru and Wu, Pengxiang and Liu, Bo and Huang, Qiaoying and Qu, Hui and Metaxas, Dimitris}, + booktitle={Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision}, + pages={2150--2159}, + year={2021} + } + + +# Introduction + +Oriented object detection in aerial images is a challenging task as the objects in aerial images are displayed in arbitrary directions and are usually densely packed. Current oriented object detection methods mainly rely on two-stage anchor-based detectors. However, the anchor-based detectors typically suffer from a severe imbalance issue between the positive and negative anchor boxes. To address this issue, in this work we extend the horizontal keypoint-based object detector to the oriented object detection task. In particular, we first detect the center keypoints of the objects, based on which we then regress the box boundary-aware vectors (BBAVectors) to capture the oriented bounding boxes. The box boundary-aware vectors are distributed in the four quadrants of a Cartesian coordinate system for all arbitrarily oriented objects. To relieve the difficulty of learning the vectors in the corner cases, we further classify the oriented bounding boxes into horizontal and rotational bounding boxes. In the experiment, we show that learning the box boundary-aware vectors is superior to directly predicting the width, height, and angle of an oriented bounding box, as adopted in the baseline method. Besides, the proposed method competes favorably with state-of-the-art methods. + +

+ +

+ +# Evaluation Results on [DOTA-v1.0](https://captain-whu.github.io/DOTA/evaluation.html) + +When training the BBAVectors+rh on 4 RTX6000 GPUs with a larger batch size```--batch_size 48```, we get a higher mAP (75.36) than the reported mAP (72.32) in the paper. We add the result to our final version. We thank the public visitors for their effort. The model weights can be downloaded from the following links: [GoogleDrive](https://drive.google.com/drive/folders/1a5LirNJ9-jc21JV11WBGqDYKpur95sno?usp=sharing) and [Dropbox](https://www.dropbox.com/sh/p7pz6silvy56f1a/AADHGlBKmdf5-7GBq2q7XBTua?dl=0). + + +```ruby +## model_50.pth +mAP: 0.7536283690546086 +ap of each class: plane:0.8862514770737425, baseball-diamond:0.8406009896282075, bridge:0.521285610860641, ground-track-field:0.6955552280263699, small-vehicle:0.7825702607967113, large-vehicle:0.8040010247209182, ship:0.8805575982076236, tennis-court:0.9087489402165854, basketball-court:0.8722663525600673, storage-tank:0.8638699841268725, soccer-ball-field:0.5610545208583243, roundabout:0.6562139014619145, harbor:0.6709747110284013, swimming-pool:0.7208480121858474, helicopter:0.6396269240669054 + +## model_43.pth +mAP: 0.7492727335105831 +ap of each class: plane:0.8859121197958046, baseball-diamond:0.8483251642688572, bridge:0.5214374843409882, ground-track-field:0.6560710395759289, small-vehicle:0.7773671634218439, large-vehicle:0.7427879633964128, ship:0.8804625721887132, tennis-court:0.908816372618596, basketball-court:0.862399364058993, storage-tank:0.8670730838290734, soccer-ball-field:0.5987801663737911, roundabout:0.6401450110418495, harbor:0.6698206063852568, swimming-pool:0.7071826121359568, helicopter:0.672510279226682 +``` + + +# Dependencies +Ubuntu 18.04, Python 3.6.10, PyTorch 1.6.0, OpenCV-Python 4.3.0.36 + +# How To Start + +Download and install the DOTA development kit [DOTA_devkit](https://github.com/CAPTAIN-WHU/DOTA_devkit) and put it under datasets folder. +Please uncomment the ```nn.BatchNorm2d(head_conv)``` in ```ctrbox_net.py``` to avoid ```NAN``` loss when training with a smaller batch size. Note that the current version of ```ctrbox_net.py``` matches the uploaded weights. + +## About DOTA +### Split Image +Split the DOTA images from [DOTA_devkit](https://github.com/CAPTAIN-WHU/DOTA_devkit) before training, testing and evaluation. + +The dota ```trainval``` and ```test``` datasets are cropped into ```600×600``` patches with a stride of `100` and two scales `0.5` and `1`. + +## Remove Images That Do Not Have Objects [Relate to NAN Loss] +For Issue [About Loss NaN](https://github.com/yijingru/BBAVectors-Oriented-Object-Detection/issues/15), @navidasj96 has found that removing images that do not have any objects inside will help resolve the NAN loss issue. + +### About Split TXT Files +The `trainval.txt` and `test.txt` used in `datasets/dataset_dota.py` contain the list of image names without suffix, example: +``` +P0000__0.5__0___0 +P0000__0.5__0___1000 +P0000__0.5__0___1500 +P0000__0.5__0___2000 +P0000__0.5__0___2151 +P0000__0.5__0___500 +P0000__0.5__1000___0 +``` +Some people would be interested in the format of the ground-truth, I provide some examples for DOTA dataset: +Format: `x1, y1, x2, y2, x3, y3, x4, y4, category, difficulty` + +Examples: +``` +275.0 463.0 411.0 587.0 312.0 600.0 222.0 532.0 tennis-court 0 +341.0 376.0 487.0 487.0 434.0 556.0 287.0 444.0 tennis-court 0 +428.0 6.0 519.0 66.0 492.0 108.0 405.0 50.0 bridge 0 +``` +## Data Arrangment +### DOTA +``` +data_dir/ + images/*.png + labelTxt/*.txt + trainval.txt + test.txt +``` +you may modify `datasets/dataset_dota.py` to adapt code to your own data. +### HRSC +``` +data_dir/ + AllImages/*.bmp + Annotations/*.xml + train.txt + test.txt + val.txt +``` +you may modify `datasets/dataset_hrsc.py` to adapt code to your own data. + + +## Train Model +```ruby +python main.py --data_dir dataPath --epochs 80 --batch_size 16 --dataset dota --phase train +``` + +޸磬ʱresnet101 +## Test Model +```ruby +python main.py --data_dir dataPath --batch_size 16 --dataset dota --phase test +``` + + +## Evaluate Model +```ruby +python main.py --data_dir dataPath --conf_thresh 0.1 --batch_size 16 --dataset dota --phase eval +``` + +You may change `conf_thresh` to get a better `mAP`. + +Please zip and upload the generated `merge_dota` for DOTA [Task1](https://captain-whu.github.io/DOTA/evaluation.html) evaluation. diff --git a/__pycache__/decoder.cpython-38.pyc b/__pycache__/decoder.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b3a9115ee67d0eae2acfd24cf4cc6961907faaf GIT binary patch literal 3304 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 literal 0 HcmV?d00001 diff --git a/__pycache__/loss.cpython-38.pyc b/__pycache__/loss.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61f978a5b6186f21dfdf3ff7399542d95edb1b47 GIT binary patch literal 4241 zcmd50#~T}U zhTlJ4udAb182cx6R(}pUzedRl5XBT9uvS^~p=b$Sw&hR=#@WzmxtzVvlu+^oQ!*CE z-kEIq;5fRK4K2T_)R z$^P}*W-lGa&AgY5o1c8xOrH0e51+jEs5v=qhetE=RA+ae=zg5!vAX-@ z=oqZK@5MQ)ews7~IP1NW=i0@VJ{^ztW_+?$-Q(Wk6bEg3!o`ng^pgO1+VxD`)0R`K-KksU_$_xuw2l9J+(eOrfDlccc&Rz^X!T zV5xIjTyGM&1u}Py4`UjR^4QedX_EK5qjZ$%Z_ofhlo~VXmX( zB+cRw>Ri>sHb!Rw2;T#qMO|s5`xnxq?*099CJ?V(at%YK% zu?>DO56D9#(J&4}QxC&oszw89uZQ8YQ8Xwe7T5Nn?Jf0vI@CtxMcVOT5QZz~p~uu@ z@YVwnzU}+Mwq?B@c$V7+_tKB7j(%UxZ{B*+=^PHzH1F--|04cV(=i%SlatavCqkB` z=?>an%bK;l8wtLLvT$`fSGN9Yxjem2S0Hzz?-02RPy4iY=`uGuq}Q%p?f>MM^tb4& z-y!nG4W}l=(IZ`UAB}6L{c5-o{T7Z|`3e19y3W#1=(nlc05O}HHQ#V>KeRCaK1qH+ zmOZS?*g!-O*+P9z!LZ6fTe5QnCKuDA%${mTH_+EaZT-U z+KvWa8koPpj-L~rh4D50?dtKl0FKQnG;kRmw| zgWR~tBOCS#@0oKbjUe3NgAE#Zi7^EU)VsXzq0F1GmOm5aBk%ysVRA7hIC z36Y-?u^ySMUsH;`veShblY#7`WTX#@JDNDxl4&xKhct|47WhAvhs=fmyDB0*|8!-2 zo5Q*NEQyksW|j7(AEEs}L5EMkcy}MsAPoO%SnGO&v5S0$z5A}Rqf}2?bj%O zDT7+Q3~GJ_WE~p%7jhvT|kd0fF;2LXq2!#Wbu$VmVz^L@O{AWWq`c)nj9R+ zUC5FDEAN^d9LT-gDdZW?{)F18YWIxmzvZq11d%-QGtL=$03yB|7QGsJNFYg8$ie{( zT@>#QfL_q2Tm8U@-q46~uN7z@h7!Cohm+`<+ESmBjoxsNFtgXs_WpP}*%#C}ev%sxfEh+P0u1RENxKeJ+y*$id3Y4%?Ox084Q)(m z`Qu*M2(U}p+FTy23_FDIE2eL=zGvWPl(JK{zQ^~(p4cHc^UVP8y|sAv3cQ-owX)0w zLdgvKC<}!8nmCPhOdPJUO5I?t4&Z%@XIpceTRHzMlO`Tz;4UiZ{oijIR6C~p@X0R literal 0 HcmV?d00001 diff --git a/__pycache__/test.cpython-38.pyc b/__pycache__/test.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e1b9b190f0c952a09737727e0de159b20c4b776 GIT binary patch literal 6121 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 b|C%~;mh)X)Aikuz0}M|a9o-om!zuk26+l5f literal 0 HcmV?d00001 diff --git a/__pycache__/train.cpython-39.pyc b/__pycache__/train.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2098cfe3277e630cf4a575e229dfd81d63f06d36 GIT binary patch literal 5467 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 literal 0 HcmV?d00001 diff --git a/change_jpg_2_png.py b/change_jpg_2_png.py new file mode 100644 index 0000000..0245bc7 --- /dev/null +++ b/change_jpg_2_png.py @@ -0,0 +1,15 @@ +import os + +# 想要更改图片所在的根目录 +rootdir = "/home/thsw/WJ/nyh/CODE/zjc_bba/BBAVectors-Oriented-Object-Detection/dataPath/images" +# 获取目录下文件名清单 +files = os.listdir(rootdir) + +# 对文件名清单里的每一个文件名进行处理 +for filename in files: + portion = os.path.splitext(filename) # portion为名称和后缀分离后的列表 #os.path.splitext()将文件名和扩展名分开 + if portion[1] == ".jpg": # 如果为tiff则更改名字 + newname = portion[0] + ".png" # 要改的新后缀 #改好的新名字 + print(filename) # 打印出要更改的文件名 + os.chdir(rootdir) # 修改工作路径 + os.rename(filename, newname) # 在工作路径下对文件名重新命名 \ No newline at end of file diff --git a/decoder.py b/decoder.py new file mode 100644 index 0000000..eb2e365 --- /dev/null +++ b/decoder.py @@ -0,0 +1,97 @@ +import torch.nn.functional as F +import torch + +class DecDecoder(object): + def __init__(self, K, conf_thresh, num_classes): + self.K = K + self.conf_thresh = conf_thresh + self.num_classes = num_classes + + def _topk(self, scores): + batch, cat, height, width = scores.size() + + topk_scores, topk_inds = torch.topk(scores.view(batch, cat, -1), self.K) + + topk_inds = topk_inds % (height * width) + topk_ys = (topk_inds // width).int().float() + topk_xs = (topk_inds % width).int().float() + + topk_score, topk_ind = torch.topk(topk_scores.view(batch, -1), self.K) + topk_clses = (topk_ind // self.K).int() + topk_inds = self._gather_feat( topk_inds.view(batch, -1, 1), topk_ind).view(batch, self.K) + topk_ys = self._gather_feat(topk_ys.view(batch, -1, 1), topk_ind).view(batch, self.K) + topk_xs = self._gather_feat(topk_xs.view(batch, -1, 1), topk_ind).view(batch, self.K) + + return topk_score, topk_inds, topk_clses, topk_ys, topk_xs + + + def _nms(self, heat, kernel=3): + hmax = F.max_pool2d(heat, (kernel, kernel), stride=1, padding=(kernel - 1) // 2) + keep = (hmax == heat).float() + return heat * keep + + def _gather_feat(self, feat, ind, mask=None): + dim = feat.size(2) + ind = ind.unsqueeze(2).expand(ind.size(0), ind.size(1), dim) + feat = feat.gather(1, ind) + if mask is not None: + mask = mask.unsqueeze(2).expand_as(feat) + feat = feat[mask] + feat = feat.view(-1, dim) + return feat + + def _tranpose_and_gather_feat(self, feat, ind): + feat = feat.permute(0, 2, 3, 1).contiguous() + feat = feat.view(feat.size(0), -1, feat.size(3)) + feat = self._gather_feat(feat, ind) + return feat + + def ctdet_decode(self, pr_decs): + heat = pr_decs['hm'] + wh = pr_decs['wh'] + reg = pr_decs['reg'] + cls_theta = pr_decs['cls_theta'] + + batch, c, height, width = heat.size() + heat = self._nms(heat) + + scores, inds, clses, ys, xs = self._topk(heat) + reg = self._tranpose_and_gather_feat(reg, inds) + reg = reg.view(batch, self.K, 2) + xs = xs.view(batch, self.K, 1) + reg[:, :, 0:1] + ys = ys.view(batch, self.K, 1) + reg[:, :, 1:2] + clses = clses.view(batch, self.K, 1).float() + scores = scores.view(batch, self.K, 1) + wh = self._tranpose_and_gather_feat(wh, inds) + wh = wh.view(batch, self.K, 10) + # add + cls_theta = self._tranpose_and_gather_feat(cls_theta, inds) + cls_theta = cls_theta.view(batch, self.K, 1) + mask = (cls_theta>0.8).float().view(batch, self.K, 1) + # + tt_x = (xs+wh[..., 0:1])*mask + (xs)*(1.-mask) + tt_y = (ys+wh[..., 1:2])*mask + (ys-wh[..., 9:10]/2)*(1.-mask) + rr_x = (xs+wh[..., 2:3])*mask + (xs+wh[..., 8:9]/2)*(1.-mask) + rr_y = (ys+wh[..., 3:4])*mask + (ys)*(1.-mask) + bb_x = (xs+wh[..., 4:5])*mask + (xs)*(1.-mask) + bb_y = (ys+wh[..., 5:6])*mask + (ys+wh[..., 9:10]/2)*(1.-mask) + ll_x = (xs+wh[..., 6:7])*mask + (xs-wh[..., 8:9]/2)*(1.-mask) + ll_y = (ys+wh[..., 7:8])*mask + (ys)*(1.-mask) + # + detections = torch.cat([xs, # cen_x + ys, # cen_y + tt_x, + tt_y, + rr_x, + rr_y, + bb_x, + bb_y, + ll_x, + ll_y, + scores, + clses], + dim=2) + + index = (scores>self.conf_thresh).squeeze(0).squeeze(1) + detections = detections[:,index,:] + return detections.data.cpu().numpy() \ No newline at end of file diff --git a/draw_loss.py b/draw_loss.py new file mode 100644 index 0000000..8a93ae7 --- /dev/null +++ b/draw_loss.py @@ -0,0 +1,61 @@ +import matplotlib.pyplot as plt +import numpy as np +import os + +def load_data(filename): + pts = [] + f = open(filename, "rb") + for line in f: + pts.append(float(line.strip())) + f.close() + return pts + +dataset = 'hrsc' +weights_path = 'weights_'+dataset+'' + +############################################### +# Load data +train_pts = load_data(os.path.join(weights_path, 'train_loss.txt')) +# val_pts = load_data(os.path.join(weights_path, 'val_loss.txt')) + +def draw_loss(): + x = np.linspace(0, len(train_pts), len(train_pts)) + plt.plot(x,train_pts,'ro-',label='train') + # plt.plot(x,val_pts,'bo-',label='val') + # plt.axis([0,len(train_pts), 0.02, 0.08]) + plt.legend(loc='upper right') + + plt.xlabel('Epochs') + plt.ylabel('Loss') + + plt.show() + + +def draw_loss_ap(): + ap05_pts = load_data(os.path.join(weights_path, 'ap_list.txt')) + + x = np.linspace(0,len(train_pts),len(train_pts)) + x1 = np.linspace(0, len(train_pts), len(ap05_pts)) + + fig, ax1 = plt.subplots() + + color = 'tab:red' + ax1.set_xlabel('Epochs') + ax1.set_ylabel('Loss', color=color) + ax1.plot(x, train_pts, 'ro-',label='train') + ax1.tick_params(axis='y', labelcolor=color) + plt.legend(loc = 'lower right') + ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis + color = 'tab:blue' + ax2.set_ylabel('AP', color=color) # we already handled the x-label with ax1 + ax2.plot(x1, ap05_pts, 'go-',label='AP@05') + ax2.tick_params(axis='y', labelcolor=color) + + fig.tight_layout() # otherwise the right y-label is slightly clipped + plt.legend(loc = 'upper right') + plt.show() + + +if __name__ == '__main__': + # draw_loss() + draw_loss_ap() \ No newline at end of file diff --git a/eval.py b/eval.py new file mode 100644 index 0000000..b1ea49e --- /dev/null +++ b/eval.py @@ -0,0 +1,57 @@ +import torch +import os +import func_utils + + +class EvalModule(object): + def __init__(self, dataset, num_classes, model, decoder): + torch.manual_seed(317) + self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.dataset = dataset + self.num_classes = num_classes + self.model = model + self.decoder = decoder + + + def load_model(self, model, resume): + checkpoint = torch.load(resume, map_location=lambda storage, loc: storage) + print('loaded weights from {}, epoch {}'.format(resume, checkpoint['epoch'])) + state_dict_ = checkpoint['model_state_dict'] + model.load_state_dict(state_dict_, strict=False) + return model + + def evaluation(self, args, down_ratio): + save_path = 'weights_'+args.dataset + self.model = self.load_model(self.model, os.path.join(save_path, args.resume)) + self.model = self.model.to(self.device) + self.model.eval() + + result_path = 'result_'+args.dataset + if not os.path.exists(result_path): + os.mkdir(result_path) + + dataset_module = self.dataset[args.dataset] + dsets = dataset_module(data_dir=args.data_dir, + phase='test', + input_h=args.input_h, + input_w=args.input_w, + down_ratio=down_ratio) + + func_utils.write_results(args, + self.model, + dsets, + down_ratio, + self.device, + self.decoder, + result_path, + print_ps=True) + + if args.dataset == 'dota': + merge_path = 'merge_'+args.dataset + if not os.path.exists(merge_path): + os.mkdir(merge_path) + dsets.merge_crop_image_results(result_path, merge_path) + return None + else: + ap = dsets.dec_evaluation(result_path) + return ap \ No newline at end of file diff --git a/eval_for_resnet18_101.py b/eval_for_resnet18_101.py new file mode 100644 index 0000000..2150f9c --- /dev/null +++ b/eval_for_resnet18_101.py @@ -0,0 +1,42 @@ + + +from .DOTA_devkit.ResultMerge_multi_process import mergebypoly + + +result_path, merge_path='result_dota','merge_dota' +dsets = dataset_module('./dataPath', + phase='test', + input_h=608, + input_w=608, + down_ratio=4) + +dsets.merge_crop_image_results(result_path, merge_path) + +func_utils.write_results(args, + self.model, + dsets, + down_ratio, + self.device, + self.decoder, + result_path, + print_ps=True) + + +def merge_crop_image_results(self, result_path, merge_path): + mergebypoly(result_path, merge_path) + + +def mergebypoly(srcpath, dstpath): + """ + srcpath: result files before merge and nms + dstpath: result files after merge and nms + """ + # srcpath = r'/home/dingjian/evaluation_task1/result/faster-rcnn-59/comp4_test_results' + # dstpath = r'/home/dingjian/evaluation_task1/result/faster-rcnn-59/testtime' + + # mergebase(srcpath, + # dstpath, + # py_cpu_nms_poly) + mergebase_parallel(srcpath, + dstpath, + py_cpu_nms_poly_fast) \ No newline at end of file diff --git a/func_utils.py b/func_utils.py new file mode 100644 index 0000000..817b4f1 --- /dev/null +++ b/func_utils.py @@ -0,0 +1,101 @@ +import os +import torch +import numpy as np +from datasets.DOTA_devkit.ResultMerge_multi_process import py_cpu_nms_poly_fast, py_cpu_nms_poly + + +def decode_prediction(predictions, dsets, args, img_id, down_ratio): + predictions = predictions[0, :, :] + ori_image = dsets.load_image(dsets.img_ids.index(img_id)) + h, w, c = ori_image.shape + + pts0 = {cat: [] for cat in dsets.category} + scores0 = {cat: [] for cat in dsets.category} + for pred in predictions: + cen_pt = np.asarray([pred[0], pred[1]], np.float32) + tt = np.asarray([pred[2], pred[3]], np.float32) + rr = np.asarray([pred[4], pred[5]], np.float32) + bb = np.asarray([pred[6], pred[7]], np.float32) + ll = np.asarray([pred[8], pred[9]], np.float32) + tl = tt + ll - cen_pt + bl = bb + ll - cen_pt + tr = tt + rr - cen_pt + br = bb + rr - cen_pt + score = pred[10] + clse = pred[11] + pts = np.asarray([tr, br, bl, tl], np.float32) + pts[:, 0] = pts[:, 0] * down_ratio / args.input_w * w + pts[:, 1] = pts[:, 1] * down_ratio / args.input_h * h + pts0[dsets.category[int(clse)]].append(pts) + scores0[dsets.category[int(clse)]].append(score) + return pts0, scores0 + + +def non_maximum_suppression(pts, scores): + nms_item = np.concatenate([pts[:, 0:1, 0], + pts[:, 0:1, 1], + pts[:, 1:2, 0], + pts[:, 1:2, 1], + pts[:, 2:3, 0], + pts[:, 2:3, 1], + pts[:, 3:4, 0], + pts[:, 3:4, 1], + scores[:, np.newaxis]], axis=1) + nms_item = np.asarray(nms_item, np.float64) + keep_index = py_cpu_nms_poly_fast(dets=nms_item, thresh=0.1) + return nms_item[keep_index] + + +def write_results(args, + model, + dsets, + down_ratio, + device, + decoder, + result_path, + print_ps=False): + results = {cat: {img_id: [] for img_id in dsets.img_ids} for cat in dsets.category} + for index in range(len(dsets)): + data_dict = dsets.__getitem__(index) + image = data_dict['image'].to(device) + img_id = data_dict['img_id'] + image_w = data_dict['image_w'] + image_h = data_dict['image_h'] + + with torch.no_grad(): + pr_decs = model(image) + + + decoded_pts = [] + decoded_scores = [] + torch.cuda.synchronize(device) + predictions = decoder.ctdet_decode(pr_decs) + pts0, scores0 = decode_prediction(predictions, dsets, args, img_id, down_ratio) + decoded_pts.append(pts0) + decoded_scores.append(scores0) + + # nms + for cat in dsets.category: + if cat == 'background': + continue + pts_cat = [] + scores_cat = [] + for pts0, scores0 in zip(decoded_pts, decoded_scores): + pts_cat.extend(pts0[cat]) + scores_cat.extend(scores0[cat]) + pts_cat = np.asarray(pts_cat, np.float32) + scores_cat = np.asarray(scores_cat, np.float32) + if pts_cat.shape[0]: + nms_results = non_maximum_suppression(pts_cat, scores_cat) + results[cat][img_id].extend(nms_results) + if print_ps: + print('testing {}/{} data {}'.format(index+1, len(dsets), img_id)) + + for cat in dsets.category: + if cat == 'background': + continue + with open(os.path.join(result_path, 'Task1_{}.txt'.format(cat)), 'w') as f: + for img_id in results[cat]: + for pt in results[cat][img_id]: + f.write('{} {:.12f} {:.1f} {:.1f} {:.1f} {:.1f} {:.1f} {:.1f} {:.1f} {:.1f}\n'.format( + img_id, pt[8], pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], pt[6], pt[7])) diff --git a/image_filename_to_txtlist.py b/image_filename_to_txtlist.py new file mode 100644 index 0000000..4ce2cc1 --- /dev/null +++ b/image_filename_to_txtlist.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +import os +import random + +#./testimages ͼƬtest.txtڼ⡣./dataPath/test.txt +paths = r'./testimages' # ͼƬļ· +f = open('./dataPath/test.txt', 'w') +filenames = os.listdir(paths) # ȡͼƬ +for filename in filenames: + out = filename.split('.jpg')[0] + f.write(out + '\n') +f.close() \ No newline at end of file diff --git a/loss.py b/loss.py new file mode 100644 index 0000000..9758c08 --- /dev/null +++ b/loss.py @@ -0,0 +1,132 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class BCELoss(nn.Module): + def __init__(self): + super(BCELoss, self).__init__() + + def _gather_feat(self, feat, ind, mask=None): + dim = feat.size(2) + ind = ind.unsqueeze(2).expand(ind.size(0), ind.size(1), dim) + feat = feat.gather(1, ind) + if mask is not None: + mask = mask.unsqueeze(2).expand_as(feat) + feat = feat[mask] + feat = feat.view(-1, dim) + return feat + + def _tranpose_and_gather_feat(self, feat, ind): + feat = feat.permute(0, 2, 3, 1).contiguous() + feat = feat.view(feat.size(0), -1, feat.size(3)) + feat = self._gather_feat(feat, ind) + return feat + + def forward(self, output, mask, ind, target): + # torch.Size([1, 1, 152, 152]) + # torch.Size([1, 500]) + # torch.Size([1, 500]) + # torch.Size([1, 500, 1]) + pred = self._tranpose_and_gather_feat(output, ind) # torch.Size([1, 500, 1]) + if mask.sum(): + mask = mask.unsqueeze(2).expand_as(pred).bool() + loss = F.binary_cross_entropy(pred.masked_select(mask), + target.masked_select(mask), + reduction='mean') + return loss + else: + return 0. + +class OffSmoothL1Loss(nn.Module): + def __init__(self): + super(OffSmoothL1Loss, self).__init__() + + def _gather_feat(self, feat, ind, mask=None): + dim = feat.size(2) + ind = ind.unsqueeze(2).expand(ind.size(0), ind.size(1), dim) + feat = feat.gather(1, ind) + if mask is not None: + mask = mask.unsqueeze(2).expand_as(feat) + feat = feat[mask] + feat = feat.view(-1, dim) + return feat + + def _tranpose_and_gather_feat(self, feat, ind): + feat = feat.permute(0, 2, 3, 1).contiguous() + feat = feat.view(feat.size(0), -1, feat.size(3)) + feat = self._gather_feat(feat, ind) + return feat + + def forward(self, output, mask, ind, target): + # torch.Size([1, 2, 152, 152]) + # torch.Size([1, 500]) + # torch.Size([1, 500]) + # torch.Size([1, 500, 2]) + pred = self._tranpose_and_gather_feat(output, ind) # torch.Size([1, 500, 2]) + if mask.sum(): + mask = mask.unsqueeze(2).expand_as(pred).bool() + loss = F.smooth_l1_loss(pred.masked_select(mask), + target.masked_select(mask), + reduction='mean') + return loss + else: + return 0. + +class FocalLoss(nn.Module): + def __init__(self): + super(FocalLoss, self).__init__() + + def forward(self, pred, gt): + pos_inds = gt.eq(1).float() + neg_inds = gt.lt(1).float() + + neg_weights = torch.pow(1 - gt, 4) + + loss = 0 + + pos_loss = torch.log(pred) * torch.pow(1 - pred, 2) * pos_inds + neg_loss = torch.log(1 - pred) * torch.pow(pred, 2) * neg_weights * neg_inds + + num_pos = pos_inds.float().sum() + pos_loss = pos_loss.sum() + neg_loss = neg_loss.sum() + + if num_pos == 0: + loss = loss - neg_loss + else: + loss = loss - (pos_loss + neg_loss) / num_pos + return loss + +def isnan(x): + return x != x + + +class LossAll(torch.nn.Module): + def __init__(self): + super(LossAll, self).__init__() + self.L_hm = FocalLoss() + self.L_wh = OffSmoothL1Loss() + self.L_off = OffSmoothL1Loss() + self.L_cls_theta = BCELoss() + + def forward(self, pr_decs, gt_batch): + hm_loss = self.L_hm(pr_decs['hm'], gt_batch['hm']) + wh_loss = self.L_wh(pr_decs['wh'], gt_batch['reg_mask'], gt_batch['ind'], gt_batch['wh']) + off_loss = self.L_off(pr_decs['reg'], gt_batch['reg_mask'], gt_batch['ind'], gt_batch['reg']) + ## add + cls_theta_loss = self.L_cls_theta(pr_decs['cls_theta'], gt_batch['reg_mask'], gt_batch['ind'], gt_batch['cls_theta']) + + if isnan(hm_loss) or isnan(wh_loss) or isnan(off_loss): + print('hm loss is {}'.format(hm_loss)) + print('wh loss is {}'.format(wh_loss)) + print('off loss is {}'.format(off_loss)) + + # print(hm_loss) + # print(wh_loss) + # print(off_loss) + # print(cls_theta_loss) + # print('-----------------') + + loss = hm_loss + wh_loss + off_loss + cls_theta_loss + return loss diff --git a/main.py b/main.py new file mode 100644 index 0000000..08d4bae --- /dev/null +++ b/main.py @@ -0,0 +1,83 @@ +import argparse +import train +import test +import eval +from datasets.dataset_dota import DOTA +from datasets.dataset_hrsc import HRSC +from models import ctrbox_net +import decoder +import os +import time + + +def parse_args(): + parser = argparse.ArgumentParser(description='BBAVectors Implementation') + parser.add_argument('--num_epoch', type=int, default=300, help='Number of epochs') + parser.add_argument('--batch_size', type=int, default=32, help='Number of batch size') + parser.add_argument('--num_workers', type=int, default=4, help='Number of workers') + parser.add_argument('--init_lr', type=float, default=1.25e-4, help='Initial learning rate') + parser.add_argument('--input_h', type=int, default=608, help='Resized image height') + parser.add_argument('--input_w', type=int, default=608, help='Resized image width') + parser.add_argument('--K', type=int, default=500, help='Maximum of objects') + parser.add_argument('--conf_thresh', type=float, default=0.18, help='Confidence threshold, 0.1 for general evaluation') + parser.add_argument('--ngpus', type=int, default=1, help='Number of gpus, ngpus>1 for multigpu') + parser.add_argument('--resume_train', type=str, default='', help='Weights resumed in training') # default='weights_dota/model_last.pth' + parser.add_argument('--resume', type=str, default='model_last_resnet18_20230323.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_last_resnet34_20230322.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_last_resnet50_20230321.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_last_resnet50_20230321.pth', help='Weights resumed in testing and evaluation') # weight path + # parser.add_argument('--resume', type=str, default='model_last_resnet101_20230315.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_resnet101_20230315.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_last.pth', help='Weights resumed in testing and evaluation') # weight path + parser.add_argument('--dataset', type=str, default='dota', help='Name of dataset') + parser.add_argument('--data_dir', type=str, default='./dataPath', help='Data directory') + # parser.add_argument('--data_dir', type=str, default='../Datasets/dota', help='Data directory') + parser.add_argument('--phase', type=str, default='train', help='Phase choice= {train, test, eval}') + #parser.add_argument('--phase', type=str, default='test', help='Phase choice= {train, test, eval}') + #parser.add_argument('--phase', type=str, default='eval', help='Phase choice= {train, test, eval}') + parser.add_argument('--wh_channels', type=int, default=8, help='Number of channels for the vectors (4x2)') #yuan 8 + args = parser.parse_args() + return args + +if __name__ == '__main__': + args = parse_args() + dataset = {'dota': DOTA, 'hrsc': HRSC} + num_classes = {'dota': 1, 'hrsc': 1} + #num_classes = {'dota': 15, 'hrsc': 1} + heads = {'hm': num_classes[args.dataset], + 'wh': 10, + 'reg': 2, + 'cls_theta': 1 + } + down_ratio = 4 + model = ctrbox_net.CTRBOX(heads=heads, + pretrained=True, + down_ratio=down_ratio, + final_kernel=1, + head_conv=256) + + decoder = decoder.DecDecoder(K=args.K, + conf_thresh=args.conf_thresh, + num_classes=num_classes[args.dataset]) + import time + + #T1 = time.time() + + if args.phase == 'train': + ctrbox_obj = train.TrainModule(dataset=dataset, + num_classes=num_classes, + model=model, + decoder=decoder, + down_ratio=down_ratio) + + ctrbox_obj.train_network(args) + elif args.phase == 'test': + ctrbox_obj = test.TestModule(dataset=dataset, num_classes=num_classes, model=model, decoder=decoder) + T1 = time.time() + ctrbox_obj.test(args, down_ratio=down_ratio) + else: + ctrbox_obj = eval.EvalModule(dataset=dataset, num_classes=num_classes, model=model, decoder=decoder) + ctrbox_obj.evaluation(args, down_ratio=down_ratio) + + T2 = time.time() + print('程序总运行时间:%s毫秒' % ((T2 - T1) * 1000)) \ No newline at end of file diff --git a/main_for_test.py b/main_for_test.py new file mode 100644 index 0000000..7505232 --- /dev/null +++ b/main_for_test.py @@ -0,0 +1,84 @@ +import argparse +import train +import test +import eval +from datasets.dataset_dota import DOTA +from datasets.dataset_hrsc import HRSC +from models import ctrbox_net +import decoder +import os +import time + + +def parse_args(): + parser = argparse.ArgumentParser(description='BBAVectors Implementation') + parser.add_argument('--num_epoch', type=int, default=300, help='Number of epochs') + parser.add_argument('--batch_size', type=int, default=8, help='Number of batch size') + parser.add_argument('--num_workers', type=int, default=4, help='Number of workers') # 原来是 + parser.add_argument('--init_lr', type=float, default=1.25e-4, help='Initial learning rate') + parser.add_argument('--input_h', type=int, default=608, help='Resized image height') + parser.add_argument('--input_w', type=int, default=608, help='Resized image width') + parser.add_argument('--K', type=int, default=500, help='Maximum of objects') + parser.add_argument('--conf_thresh', type=float, default=0.18, help='Confidence threshold, 0.1 for general evaluation') + parser.add_argument('--ngpus', type=int, default=1, help='Number of gpus, ngpus>1 for multigpu') + parser.add_argument('--resume_train', type=str, default='', help='Weights resumed in training') + parser.add_argument('--resume', type=str, default='weights_dota/model_last_resnet18_20230421_10K495dataset.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='weights_dota/model_last_resnet18_20230409_10Kdataset.pth', help='Weights resumed in testing and evaluation') # weight path + + #parser.add_argument('--resume', type=str, default='weights_dota/model_last_resnet50_20230406_10Kdataset.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='weights_dota/model_last_resnet34_20230326_10Kdataset.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='weights_dota/model_last_resnet101_20230315.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_last_resnet18_20230421_10K495dataset.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_last.pth', help='Weights resumed in testing and evaluation') # weight path + parser.add_argument('--dataset', type=str, default='dota', help='Name of dataset') + parser.add_argument('--data_dir', type=str, default='./dataPath', help='Data directory') + # parser.add_argument('--data_dir', type=str, default='../Datasets/dota', help='Data directory') + #parser.add_argument('--phase', type=str, default='train', help='Phase choice= {train, test, eval}') + parser.add_argument('--phase', type=str, default='test', help='Phase choice= {train, test, eval}') + #parser.add_argument('--phase', type=str, default='eval', help='Phase choice= {train, test, eval}') + parser.add_argument('--wh_channels', type=int, default=8, help='Number of channels for the vectors (4x2)') #yuan 8 + args = parser.parse_args() + return args + +if __name__ == '__main__': + args = parse_args() + dataset = {'dota': DOTA, 'hrsc': HRSC} + # num_classes = {'dota': 15, 'hrsc': 1} + num_classes = {'dota': 1, 'hrsc': 1} + heads = {'hm': num_classes[args.dataset], + 'wh': 10, + 'reg': 2, + 'cls_theta': 1 + } + down_ratio = 4 + model = ctrbox_net.CTRBOX(heads=heads, + pretrained=True, + down_ratio=down_ratio, + final_kernel=1, + head_conv=256) + + decoder = decoder.DecDecoder(K=args.K, + conf_thresh=args.conf_thresh, + num_classes=num_classes[args.dataset]) + import time + + #T1 = time.time() + + if args.phase == 'train': + ctrbox_obj = train.TrainModule(dataset=dataset, + num_classes=num_classes, + model=model, + decoder=decoder, + down_ratio=down_ratio) + + ctrbox_obj.train_network(args) + elif args.phase == 'test': + ctrbox_obj = test.TestModule(dataset=dataset, num_classes=num_classes, model=model, decoder=decoder) + T1 = time.time() + ctrbox_obj.test(args, down_ratio=down_ratio) + else: + ctrbox_obj = eval.EvalModule(dataset=dataset, num_classes=num_classes, model=model, decoder=decoder) + ctrbox_obj.evaluation(args, down_ratio=down_ratio) + + T2 = time.time() + print('程序总运行时间:%s毫秒' % ((T2 - T1) * 1000)) \ No newline at end of file diff --git a/main_for_val.py b/main_for_val.py new file mode 100644 index 0000000..987ac15 --- /dev/null +++ b/main_for_val.py @@ -0,0 +1,83 @@ +import argparse +import train +import test +import eval +from datasets.dataset_dota import DOTA +from datasets.dataset_hrsc import HRSC +from models import ctrbox_net +import decoder +import os +import time + + +def parse_args(): + parser = argparse.ArgumentParser(description='BBAVectors Implementation') + parser.add_argument('--num_epoch', type=int, default=300, help='Number of epochs') + parser.add_argument('--batch_size', type=int, default=8, help='Number of batch size') + parser.add_argument('--num_workers', type=int, default=4, help='Number of workers') # 原来是 + parser.add_argument('--init_lr', type=float, default=1.25e-4, help='Initial learning rate') + parser.add_argument('--input_h', type=int, default=608, help='Resized image height') + parser.add_argument('--input_w', type=int, default=608, help='Resized image width') + parser.add_argument('--K', type=int, default=500, help='Maximum of objects') + parser.add_argument('--conf_thresh', type=float, default=0.18, help='Confidence threshold, 0.1 for general evaluation') + parser.add_argument('--ngpus', type=int, default=1, help='Number of gpus, ngpus>1 for multigpu') + parser.add_argument('--resume_train', type=str, default='', help='Weights resumed in training') + parser.add_argument('--resume', type=str, default='model_last_resnet18_20230421_10K495dataset.pth', help='Weights resumed in testing and evaluation') # weight path + + #parser.add_argument('--resume', type=str, default='weights_dota/model_last_resnet50_20230406_10Kdataset.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='weights_dota/model_last_resnet34_20230326_10Kdataset.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='weights_dota/model_last_resnet101_20230315.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_resnet101_20230315.pth', help='Weights resumed in testing and evaluation') # weight path + #parser.add_argument('--resume', type=str, default='model_last.pth', help='Weights resumed in testing and evaluation') # weight path + parser.add_argument('--dataset', type=str, default='dota', help='Name of dataset') + parser.add_argument('--data_dir', type=str, default='./dataPath', help='Data directory') + # parser.add_argument('--data_dir', type=str, default='../Datasets/dota', help='Data directory') + #parser.add_argument('--phase', type=str, default='train', help='Phase choice= {train, test, eval}') + #parser.add_argument('--phase', type=str, default='test', help='Phase choice= {train, test, eval}') + parser.add_argument('--phase', type=str, default='eval', help='Phase choice= {train, test, eval}') + parser.add_argument('--wh_channels', type=int, default=8, help='Number of channels for the vectors (4x2)') #yuan 8 + args = parser.parse_args() + return args + +if __name__ == '__main__': + args = parse_args() + dataset = {'dota': DOTA, 'hrsc': HRSC} + # num_classes = {'dota': 15, 'hrsc': 1} + num_classes = {'dota': 1, 'hrsc': 1} + heads = {'hm': num_classes[args.dataset], + 'wh': 10, + 'reg': 2, + 'cls_theta': 1 + } + down_ratio = 4 + model = ctrbox_net.CTRBOX(heads=heads, + pretrained=True, + down_ratio=down_ratio, + final_kernel=1, + head_conv=256) + + decoder = decoder.DecDecoder(K=args.K, + conf_thresh=args.conf_thresh, + num_classes=num_classes[args.dataset]) + import time + + #T1 = time.time() + + if args.phase == 'train': + ctrbox_obj = train.TrainModule(dataset=dataset, + num_classes=num_classes, + model=model, + decoder=decoder, + down_ratio=down_ratio) + + ctrbox_obj.train_network(args) + elif args.phase == 'test': + ctrbox_obj = test.TestModule(dataset=dataset, num_classes=num_classes, model=model, decoder=decoder) + T1 = time.time() + ctrbox_obj.test(args, down_ratio=down_ratio) + else: + ctrbox_obj = eval.EvalModule(dataset=dataset, num_classes=num_classes, model=model, decoder=decoder) + ctrbox_obj.evaluation(args, down_ratio=down_ratio) + + T2 = time.time() + print('程序总运行时间:%s毫秒' % ((T2 - T1) * 1000)) \ No newline at end of file diff --git a/models/__pycache__/ctrbox_net.cpython-38.pyc b/models/__pycache__/ctrbox_net.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..efc7abb0cad44dae28bb68f40fe78410c0e4c4a4 GIT binary patch literal 2077 zcmb7F+io015bd7(j@Q?iB!-B)B5g#n#EBph5lU=FL=o7^4WgA$Yj%3g>bu@sQ!U`^ya( zPcrr!87ChH#tpp19SF%J&sdMQI3MX&%dUJ*%aN9}Gq>lpJj_|r$^2f>3OM_WNmqLN zOnM3L*7odHDEWQX@P~-UmWLd&!Oiqyzt>LlNT>b$i@w~-5;#4T6nUa!`tsys9~s35 zP!iVSlC`X7Y?Vtct^EKw+0xl($f?@7Ex9077r7gX6uehM?@3?lfJAmhq?_q`TbZ7wgbz{Xh(n^1h?FOYU!*xsjs;36ida659 zdYHpZ=_0!^M5rIQ@SlPv9W9x~^lS~xpPGbCx zNXj%{Gfq2=3M}%|d?SnEMA0=j95s!>c!gG}Ow6ERxpC^O~oDC##; zUq$0(VpK#^qXa~Z?Mx7Nq8x=Sj6+W2$617Q1rU z{OV3Kf6{3#t}NYZ?sQ|(Zb!|9g_~a{vF@wl;)+UfszhE~X?NkexRhuNC}*?Rm)NZt zYt`;Qrg~l4c%tTzFJYqi5Q6cEH>P-G<|y!p!kQI$hNw-r@p;W+m6WYwcO;e95~YxAmGj505i&E1MIbD>z%rs^Tus zglUoHg^qGy?0p1L=SftcatJb}hHBEh77a@gXBpm8AJIpZ_?R@>y-K4ZCY&(jJExCw z|IgjNas(gi2%pv3@1dacaEL>`3oaS(5}XK@0E5l3Lu=Q9&nhk0c4dQ=26kz~b}HLR z*{%y_alk*72bY(`eYx~#RJXM^@M#9CkG|NvUAn}y%jyiW8UBTq z8onU$Cxki;pRwbtXawpl=;~b(?~r(#1R<2LyLOCS;{r2r$M{9M*6XLT;U87-aVw0k z0;lx1kwCw4LZ5%B2h?UV1)?rf_*aW={MEkNj+DHOxndTA@z9?oSXmA(UUP3EYZ$8e=A?if}2f*pbjDw6d$ZxYYLF@-s6aj>D{`kkBR5GVcSBB&C9+jtHKTF>UljsVh9;KOw32lz1fdL08AVwqMRhx#Cq`sxL~h zDC8gu8a*w*a|FK&zxkOGQjv<*nuUTOZlT`RNbsS{oAG7Kdek+5rURz>HK#~SIR`{m)d_u z^_?rNb-`A={2#BHzFZk8 z+RmH{k*gycm`dkDew9$$$<@5znLKw;z|lTzx`P_F8-k71V#bbixtJTff#+<(6{s{I z+~8x$tA&;(*|5G@%%#?-%7%>PDz6x`j#4(hCm$@Ns&Zb~V82w~e<*Bsk5}1bSn3%d z-k0+3ed{ddHq3a%GGMXMZ8VDvcJp&(Dy}lwvL}J{j4Z~fpRuAmPQ8qQWIRHJOrb#B zxZIw5`AWD!pHmw#mKEF>#-5WuzU@!Sne0~+bKL*tPG3Em^!E=BKI@-MGd3FW{@&iF zU(2j2wb?n;IlMuNox{--NIM6zf(`nnKPv@&ooTAL&;h5ZFHE005zz)T7sE zNaH^P_jbpD6x>5M07|@~;2wH_{}njb0iL}5LbL8(#5u#fUo1Ss5F-2Vn~wn0 zR^jbU1(DBqqEhF7vU|vGx`IxG&He~Em+gBBm6UHT_~tvsImKPILeD$Nv;Qp zV?BJY?eQW%QjjYsF>N%CpQNMTLT);+-5f%t=View36(M7P#V|p&WBiL6YD~r6IX8m zDfJ(=X?zH2)b9YL1>4Bp8JGH)Yw;c+rWtYcU3#+hVjxz0i8~k!pg^Di6`x5cz?d=c z7X}-gHyC@c;6;1WBuFP{rMD`HOcn)WYd+k7TfL0{%NpCGaU!IfHyTP3rf)P4+Er?I zyiiR&@It=|oHkw~+(bfn!Kyz%G-wBIqiD@$6M^l9|5oey$JoyXYw2|;m(ckeI_szL literal 0 HcmV?d00001 diff --git a/models/__pycache__/resnet.cpython-38.pyc b/models/__pycache__/resnet.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..676bc0a448232f7bf14bb07a45c0c95cb723b4dd GIT binary patch literal 11093 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 P+PZG!NB?PK+L-$z`Tes3 literal 0 HcmV?d00001 diff --git a/models/ctrbox_net.py b/models/ctrbox_net.py new file mode 100644 index 0000000..4239393 --- /dev/null +++ b/models/ctrbox_net.py @@ -0,0 +1,89 @@ +import torch.nn as nn +import numpy as np +import torch +from .model_parts import CombinationModule +from . import resnet + +class CTRBOX(nn.Module): + def __init__(self, heads, pretrained, down_ratio, final_kernel, head_conv): + super(CTRBOX, self).__init__() + + #channels = [3, 64, 256, 512, 1024, 2048] + #assert down_ratio in [2, 4, 8, 16] + #self.l1 = int(np.log2(down_ratio)) + #self.base_network = resnet.resnet101(pretrained=pretrained) + #self.dec_c2 = CombinationModule(512, 256, batch_norm=True) + #self.dec_c3 = CombinationModule(1024, 512, batch_norm=True) + #self.dec_c4 = CombinationModule(2048, 1024, batch_norm=True) + + #channels = [3, 64, 256, 512, 1024, 2048] + #assert down_ratio in [2, 4, 8, 16] + #self.l1 = int(np.log2(down_ratio)) + #self.base_network = resnet.resnet50(pretrained=pretrained) + #self.dec_c2 = CombinationModule(512, 256, batch_norm=True) + #self.dec_c3 = CombinationModule(1024, 512, batch_norm=True) + #self.dec_c4 = CombinationModule(2048, 1024, batch_norm=True) + + + #channels = [3, 64, 64, 128, 256, 512] + #assert down_ratio in [2, 4, 8, 16] + #self.l1 = int(np.log2(down_ratio)) + #self.base_network = resnet.resnet34(pretrained=pretrained) + #self.dec_c2 = CombinationModule(128, 64, batch_norm=True) + #self.dec_c3 = CombinationModule(256, 128, batch_norm=True) + #self.dec_c4 = CombinationModule(512, 256, batch_norm=True) + + channels = [3, 64, 64, 128, 256, 512] + assert down_ratio in [2, 4, 8, 16] + self.l1 = int(np.log2(down_ratio)) + self.base_network = resnet.resnet18(pretrained=pretrained) + self.dec_c2 = CombinationModule(128, 64, batch_norm=True) + self.dec_c3 = CombinationModule(256, 128, batch_norm=True) + self.dec_c4 = CombinationModule(512, 256, batch_norm=True) + + + self.heads = heads + + for head in self.heads: + classes = self.heads[head] + if head == 'wh': + fc = nn.Sequential(nn.Conv2d(channels[self.l1], head_conv, kernel_size=3, padding=1, bias=True), + # nn.BatchNorm2d(head_conv), # BN not used in the paper, but would help stable training + nn.ReLU(inplace=True), + nn.Conv2d(head_conv, classes, kernel_size=3, padding=1, bias=True)) + else: + fc = nn.Sequential(nn.Conv2d(channels[self.l1], head_conv, kernel_size=3, padding=1, bias=True), + # nn.BatchNorm2d(head_conv), # BN not used in the paper, but would help stable training + nn.ReLU(inplace=True), + nn.Conv2d(head_conv, classes, kernel_size=final_kernel, stride=1, padding=final_kernel // 2, bias=True)) + if 'hm' in head: + fc[-1].bias.data.fill_(-2.19) + else: + self.fill_fc_weights(fc) + + self.__setattr__(head, fc) + + + def fill_fc_weights(self, m): + if isinstance(m, nn.Conv2d): + if m.bias is not None: + nn.init.constant_(m.bias, 0) + + def forward(self, x): + x = self.base_network(x) + # import matplotlib.pyplot as plt + # import os + # for idx in range(x[1].shape[1]): + # temp = x[1][0,idx,:,:] + # temp = temp.data.cpu().numpy() + # plt.imsave(os.path.join('dilation', '{}.png'.format(idx)), temp) + c4_combine = self.dec_c4(x[-1], x[-2]) + c3_combine = self.dec_c3(c4_combine, x[-3]) + c2_combine = self.dec_c2(c3_combine, x[-4]) + + dec_dict = {} + for head in self.heads: + dec_dict[head] = self.__getattr__(head)(c2_combine) + if 'hm' in head or 'cls' in head: + dec_dict[head] = torch.sigmoid(dec_dict[head]) + return dec_dict diff --git a/models/model_parts.py b/models/model_parts.py new file mode 100644 index 0000000..a9e6d97 --- /dev/null +++ b/models/model_parts.py @@ -0,0 +1,37 @@ +import torch.nn.functional as F +import torch.nn as nn +import torch + +class CombinationModule(nn.Module): + def __init__(self, c_low, c_up, batch_norm=False, group_norm=False, instance_norm=False): + super(CombinationModule, self).__init__() + if batch_norm: + self.up = nn.Sequential(nn.Conv2d(c_low, c_up, kernel_size=3, padding=1, stride=1), + nn.BatchNorm2d(c_up), + nn.ReLU(inplace=True)) + self.cat_conv = nn.Sequential(nn.Conv2d(c_up*2, c_up, kernel_size=1, stride=1), + nn.BatchNorm2d(c_up), + nn.ReLU(inplace=True)) + elif group_norm: + self.up = nn.Sequential(nn.Conv2d(c_low, c_up, kernel_size=3, padding=1, stride=1), + nn.GroupNorm(num_groups=32, num_channels=c_up), + nn.ReLU(inplace=True)) + self.cat_conv = nn.Sequential(nn.Conv2d(c_up * 2, c_up, kernel_size=1, stride=1), + nn.GroupNorm(num_groups=32, num_channels=c_up), + nn.ReLU(inplace=True)) + elif instance_norm: + self.up = nn.Sequential(nn.Conv2d(c_low, c_up, kernel_size=3, padding=1, stride=1), + nn.InstanceNorm2d(num_features=c_up), + nn.ReLU(inplace=True)) + self.cat_conv = nn.Sequential(nn.Conv2d(c_up * 2, c_up, kernel_size=1, stride=1), + nn.InstanceNorm2d(num_features=c_up), + nn.ReLU(inplace=True)) + else: + self.up = nn.Sequential(nn.Conv2d(c_low, c_up, kernel_size=3, padding=1, stride=1), + nn.ReLU(inplace=True)) + self.cat_conv = nn.Sequential(nn.Conv2d(c_up*2, c_up, kernel_size=1, stride=1), + nn.ReLU(inplace=True)) + + def forward(self, x_low, x_up): + x_low = self.up(F.interpolate(x_low, x_up.shape[2:], mode='bilinear', align_corners=False)) + return self.cat_conv(torch.cat((x_up, x_low), 1)) \ No newline at end of file diff --git a/models/resnet.py b/models/resnet.py new file mode 100644 index 0000000..e21e2bf --- /dev/null +++ b/models/resnet.py @@ -0,0 +1,356 @@ +import torch +import torch.nn as nn + +try: + from torch.hub import load_state_dict_from_url +except ImportError: + from torch.utils.model_zoo import load_url as load_state_dict_from_url + + +__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101', + 'resnet152', 'resnext50_32x4d', 'resnext101_32x8d', + 'wide_resnet50_2', 'wide_resnet101_2'] + + +model_urls = { + 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth', + 'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth', + 'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth', + 'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth', + 'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth', + 'resnext50_32x4d': 'https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pth', + 'resnext101_32x8d': 'https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pth', + 'wide_resnet50_2': 'https://download.pytorch.org/models/wide_resnet50_2-95faca4d.pth', + 'wide_resnet101_2': 'https://download.pytorch.org/models/wide_resnet101_2-32ee1156.pth', +} + + +def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1): + """3x3 convolution with padding""" + return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, + padding=dilation, groups=groups, bias=False, dilation=dilation) + + +def conv1x1(in_planes, out_planes, stride=1): + """1x1 convolution""" + return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False) + + +class BasicBlock(nn.Module): + expansion = 1 + __constants__ = ['downsample'] + + def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, + base_width=64, dilation=1, norm_layer=None): + super(BasicBlock, self).__init__() + if norm_layer is None: + norm_layer = nn.BatchNorm2d + if groups != 1 or base_width != 64: + raise ValueError('BasicBlock only supports groups=1 and base_width=64') + if dilation > 1: + raise NotImplementedError("Dilation > 1 not supported in BasicBlock") + # Both self.conv1 and self.downsample layers downsample the input when stride != 1 + self.conv1 = conv3x3(inplanes, planes, stride) + self.bn1 = norm_layer(planes) + self.relu = nn.ReLU(inplace=True) + self.conv2 = conv3x3(planes, planes) + self.bn2 = norm_layer(planes) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + identity = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out += identity + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + expansion = 4 + __constants__ = ['downsample'] + + def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, + base_width=64, dilation=1, norm_layer=None): + super(Bottleneck, self).__init__() + if norm_layer is None: + norm_layer = nn.BatchNorm2d + width = int(planes * (base_width / 64.)) * groups + # Both self.conv2 and self.downsample layers downsample the input when stride != 1 + self.conv1 = conv1x1(inplanes, width) + self.bn1 = norm_layer(width) + self.conv2 = conv3x3(width, width, stride, groups, dilation) + self.bn2 = norm_layer(width) + self.conv3 = conv1x1(width, planes * self.expansion) + self.bn3 = norm_layer(planes * self.expansion) + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + identity = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out += identity + out = self.relu(out) + + return out + + +class ResNet(nn.Module): + + def __init__(self, block, layers, num_classes=1000, zero_init_residual=False, + groups=1, width_per_group=64, replace_stride_with_dilation=None, + norm_layer=None): + super(ResNet, self).__init__() + if norm_layer is None: + norm_layer = nn.BatchNorm2d + self._norm_layer = norm_layer + + self.inplanes = 64 + self.dilation = 1 + if replace_stride_with_dilation is None: + # each element in the tuple indicates if we should replace + # the 2x2 stride with a dilated convolution instead + replace_stride_with_dilation = [False, False, False] + if len(replace_stride_with_dilation) != 3: + raise ValueError("replace_stride_with_dilation should be None " + "or a 3-element tuple, got {}".format(replace_stride_with_dilation)) + self.groups = groups + self.base_width = width_per_group + self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3, + bias=False) + self.bn1 = norm_layer(self.inplanes) + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + self.layer1 = self._make_layer(block, 64, layers[0]) + self.layer2 = self._make_layer(block, 128, layers[1], stride=2, + dilate=replace_stride_with_dilation[0]) + self.layer3 = self._make_layer(block, 256, layers[2], stride=2, + dilate=replace_stride_with_dilation[1]) + self.layer4 = self._make_layer(block, 512, layers[3], stride=2, + dilate=replace_stride_with_dilation[2]) + # self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) + # self.fc = nn.Linear(512 * block.expansion, num_classes) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') + elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)): + nn.init.constant_(m.weight, 1) + nn.init.constant_(m.bias, 0) + + # Zero-initialize the last BN in each residual branch, + # so that the residual branch starts with zeros, and each residual block behaves like an identity. + # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677 + if zero_init_residual: + for m in self.modules(): + if isinstance(m, Bottleneck): + nn.init.constant_(m.bn3.weight, 0) + elif isinstance(m, BasicBlock): + nn.init.constant_(m.bn2.weight, 0) + + def _make_layer(self, block, planes, blocks, stride=1, dilate=False): + norm_layer = self._norm_layer + downsample = None + previous_dilation = self.dilation + if dilate: + self.dilation *= stride + stride = 1 + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + conv1x1(self.inplanes, planes * block.expansion, stride), + norm_layer(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, downsample, self.groups, + self.base_width, previous_dilation, norm_layer)) + self.inplanes = planes * block.expansion + for _ in range(1, blocks): + layers.append(block(self.inplanes, planes, groups=self.groups, + base_width=self.base_width, dilation=self.dilation, + norm_layer=norm_layer)) + + return nn.Sequential(*layers) + + def forward(self, x): + feat = [] + feat.append(x) # C0 + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + feat.append(x) # C1 + x = self.maxpool(x) + + x = self.layer1(x) + feat.append(x) # C2 + x = self.layer2(x) + feat.append(x) # C3 + x = self.layer3(x) + feat.append(x) # C4 + x = self.layer4(x) + feat.append(x) # C5 + + + # x = self.avgpool(x) + # x = torch.flatten(x, 1) + # x = self.fc(x) + # + return feat + + +def _resnet(arch, block, layers, pretrained, progress, **kwargs): + model = ResNet(block, layers, **kwargs) + if pretrained: + state_dict = load_state_dict_from_url(model_urls[arch], progress=progress) + model.load_state_dict(state_dict, strict=False) + return model + + +def resnet18(pretrained=False, progress=True, **kwargs): + r"""ResNet-18 model from + `"Deep Residual Learning for Image Recognition" `_ + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + return _resnet('resnet18', BasicBlock, [2, 2, 2, 2], pretrained, progress, + **kwargs) + + +def resnet34(pretrained=False, progress=True, **kwargs): + r"""ResNet-34 model from + `"Deep Residual Learning for Image Recognition" `_ + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + return _resnet('resnet34', BasicBlock, [3, 4, 6, 3], pretrained, progress, + **kwargs) + + +def resnet50(pretrained=False, progress=True, **kwargs): + r"""ResNet-50 model from + `"Deep Residual Learning for Image Recognition" `_ + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + return _resnet('resnet50', Bottleneck, [3, 4, 6, 3], pretrained, progress, + **kwargs) + + +def resnet101(pretrained=False, progress=True, **kwargs): + r"""ResNet-101 model from + `"Deep Residual Learning for Image Recognition" `_ + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + return _resnet('resnet101', Bottleneck, [3, 4, 23, 3], pretrained, progress, + **kwargs) + + +def resnet152(pretrained=False, progress=True, **kwargs): + r"""ResNet-152 model from + `"Deep Residual Learning for Image Recognition" `_ + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + return _resnet('resnet152', Bottleneck, [3, 8, 36, 3], pretrained, progress, + **kwargs) + + +def resnext50_32x4d(pretrained=False, progress=True, **kwargs): + r"""ResNeXt-50 32x4d model from + `"Aggregated Residual Transformation for Deep Neural Networks" `_ + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + kwargs['groups'] = 32 + kwargs['width_per_group'] = 4 + return _resnet('resnext50_32x4d', Bottleneck, [3, 4, 6, 3], + pretrained, progress, **kwargs) + + +def resnext101_32x8d(pretrained=False, progress=True, **kwargs): + r"""ResNeXt-101 32x8d model from + `"Aggregated Residual Transformation for Deep Neural Networks" `_ + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + kwargs['groups'] = 32 + kwargs['width_per_group'] = 8 + return _resnet('resnext101_32x8d', Bottleneck, [3, 4, 23, 3], + pretrained, progress, **kwargs) + + +def wide_resnet50_2(pretrained=False, progress=True, **kwargs): + r"""Wide ResNet-50-2 model from + `"Wide Residual Networks" `_ + + The model is the same as ResNet except for the bottleneck number of channels + which is twice larger in every block. The number of channels in outer 1x1 + convolutions is the same, e.g. last block in ResNet-50 has 2048-512-2048 + channels, and in Wide ResNet-50-2 has 2048-1024-2048. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + kwargs['width_per_group'] = 64 * 2 + return _resnet('wide_resnet50_2', Bottleneck, [3, 4, 6, 3], + pretrained, progress, **kwargs) + + +def wide_resnet101_2(pretrained=False, progress=True, **kwargs): + r"""Wide ResNet-101-2 model from + `"Wide Residual Networks" `_ + + The model is the same as ResNet except for the bottleneck number of channels + which is twice larger in every block. The number of channels in outer 1x1 + convolutions is the same, e.g. last block in ResNet-50 has 2048-512-2048 + channels, and in Wide ResNet-50-2 has 2048-1024-2048. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + kwargs['width_per_group'] = 64 * 2 + return _resnet('wide_resnet101_2', Bottleneck, [3, 4, 23, 3], + pretrained, progress, **kwargs) \ No newline at end of file diff --git a/my.log b/my.log new file mode 100644 index 0000000..6dd0ab7 --- /dev/null +++ b/my.log @@ -0,0 +1,64 @@ +nohup: ignoring input +Setting up data... +Starting training... +---------- +Epoch: 1/300 +train loss: 3.4244043734789633 +---------- +Epoch: 2/300 +/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/optim/lr_scheduler.py:154: UserWarning: The epoch parameter in `scheduler.step()` was not necessary and is being deprecated where possible. Please use `scheduler.step()` to step the scheduler. During the deprecation, if epoch is different from None, the closed form is used instead of the new chainable form, where available. Please open an issue if you are unable to replicate your use case: https://github.com/pytorch/pytorch/issues/new/choose. + warnings.warn(EPOCH_DEPRECATION_WARNING, UserWarning) +train loss: 1.9177124688499851 +---------- +Epoch: 3/300 +train loss: 1.622521436620423 +---------- +Epoch: 4/300 +train loss: 1.4714328696484167 +---------- +Epoch: 5/300 +train loss: 1.3505059377327793 +---------- +Epoch: 6/300 +train loss: 1.2887507426111322 +---------- +Epoch: 7/300 +train loss: 1.1910065563839656 +---------- +Epoch: 8/300 +train loss: 1.170240322502774 +---------- +Epoch: 9/300 +train loss: 1.1249810649145497 +---------- +Epoch: 10/300 +train loss: 1.100411476365553 +---------- +Epoch: 11/300 +train loss: 1.0680593386892194 +---------- +Epoch: 12/300 +train loss: 1.0271114858311396 +---------- +Epoch: 13/300 +train loss: 1.0196107995030312 +---------- +Epoch: 14/300 +train loss: 0.997023107835752 +---------- +Epoch: 15/300 +train loss: 0.9820298757346422 +---------- +Epoch: 16/300 +train loss: 0.9564395314399672 +---------- +Epoch: 17/300 +train loss: 0.9323030086493713 +---------- +Epoch: 18/300 +train loss: 0.9327782955332068 +---------- +Epoch: 19/300 +train loss: 0.8958315594646584 +---------- +Epoch: 20/300 diff --git a/my20230603.log b/my20230603.log new file mode 100644 index 0000000..32c4756 --- /dev/null +++ b/my20230603.log @@ -0,0 +1,949 @@ +nohup: ignoring input +Setting up data... +Starting training... +---------- +Epoch: 1/300 +nohup: ignoring input +Setting up data... +Starting training... +---------- +Epoch: 1/300 +nohup: ignoring input +Traceback (most recent call last): + File "main.py", line 73, in + ctrbox_obj.train_network(args) + File "/home/thsw/WJ/nyh/CODE/bba_vector/BBAVectors-Oriented-Object-Detection/train.py", line 101, in train_network + self.model.to(self.device) + File "/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/nn/modules/module.py", line 852, in to + return self._apply(convert) + File "/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/nn/modules/module.py", line 530, in _apply + module._apply(fn) + File "/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/nn/modules/module.py", line 530, in _apply + module._apply(fn) + File "/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/nn/modules/module.py", line 552, in _apply + param_applied = fn(param) + File "/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/nn/modules/module.py", line 850, in convert + return t.to(device, dtype if t.is_floating_point() or t.is_complex() else None, non_blocking) +RuntimeError: CUDA error: out of memory +CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect. +For debugging consider passing CUDA_LAUNCH_BLOCKING=1. +Traceback (most recent call last): + File "main.py", line 73, in + ctrbox_obj.train_network(args) + File "/home/thsw/WJ/nyh/CODE/bba_vector/BBAVectors-Oriented-Object-Detection/train.py", line 130, in train_network + epoch_loss = self.run_epoch(phase='train', + File "/home/thsw/WJ/nyh/CODE/bba_vector/BBAVectors-Oriented-Object-Detection/train.py", line 166, in run_epoch + pr_decs = self.model(data_dict['input']) + File "/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl + return forward_call(*input, **kwargs) + File "/home/thsw/WJ/nyh/CODE/bba_vector/BBAVectors-Oriented-Object-Detection/models/ctrbox_net.py", line 81, in forward + c3_combine = self.dec_c3(c4_combine, x[-3]) + File "/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl + return forward_call(*input, **kwargs) + File "/home/thsw/WJ/nyh/CODE/bba_vector/BBAVectors-Oriented-Object-Detection/models/model_parts.py", line 37, in forward + return self.cat_conv(torch.cat((x_up, x_low), 1)) +RuntimeError: CUDA out of memory. Tried to allocate 182.00 MiB (GPU 0; 23.69 GiB total capacity; 5.63 GiB already allocated; 30.12 MiB free; 5.85 GiB reserved in total by PyTorch) +train loss: 3.3678845995809974 +---------- +Epoch: 2/300 +/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/optim/lr_scheduler.py:154: UserWarning: The epoch parameter in `scheduler.step()` was not necessary and is being deprecated where possible. Please use `scheduler.step()` to step the scheduler. During the deprecation, if epoch is different from None, the closed form is used instead of the new chainable form, where available. Please open an issue if you are unable to replicate your use case: https://github.com/pytorch/pytorch/issues/new/choose. + warnings.warn(EPOCH_DEPRECATION_WARNING, UserWarning) +train loss: 1.8854694141120445 +---------- +Epoch: 3/300 +train loss: 1.5767962481917404 +---------- +Epoch: 4/300 +train loss: 1.4255406602126797 +---------- +Epoch: 5/300 +train loss: 1.3310559519180438 +---------- +Epoch: 6/300 +train loss: 1.2327631359420173 +---------- +Epoch: 7/300 +train loss: 1.179566274510651 +---------- +Epoch: 8/300 +train loss: 1.1194112766079787 +---------- +Epoch: 9/300 +train loss: 1.0934214072256554 +---------- +Epoch: 10/300 +train loss: 1.0598071190278704 +---------- +Epoch: 11/300 +train loss: 1.0322292461627867 +---------- +Epoch: 12/300 +train loss: 1.0056840393964837 +---------- +Epoch: 13/300 +train loss: 0.978235443009109 +---------- +Epoch: 14/300 +train loss: 0.9646336492605325 +---------- +Epoch: 15/300 +train loss: 0.9264216072312216 +---------- +Epoch: 16/300 +train loss: 0.9201980442172144 +---------- +Epoch: 17/300 +train loss: 0.9013974646606097 +---------- +Epoch: 18/300 +train loss: 0.8931510070475136 +---------- +Epoch: 19/300 +train loss: 0.872543891755546 +---------- +Epoch: 20/300 +train loss: 0.8504351748198997 +---------- +Epoch: 21/300 +train loss: 0.8342699241347429 +---------- +Epoch: 22/300 +train loss: 0.8266373327592524 +---------- +Epoch: 23/300 +train loss: 0.8242110590018877 +---------- +Epoch: 24/300 +train loss: 0.7909619433850776 +---------- +Epoch: 25/300 +train loss: 0.7895614755589787 +---------- +Epoch: 26/300 +train loss: 0.7839372414277821 +---------- +Epoch: 27/300 +train loss: 0.7723920864121216 +---------- +Epoch: 28/300 +train loss: 0.7776255176925078 +---------- +Epoch: 29/300 +train loss: 0.7548159630742015 +---------- +Epoch: 30/300 +train loss: 0.7567941827199808 +---------- +Epoch: 31/300 +train loss: 0.7433899990850832 +---------- +Epoch: 32/300 +train loss: 0.7302218635634679 +---------- +Epoch: 33/300 +train loss: 0.7302329011443185 +---------- +Epoch: 34/300 +train loss: 0.7236013530594546 +---------- +Epoch: 35/300 +train loss: 0.7173745734844266 +---------- +Epoch: 36/300 +train loss: 0.6950798584375439 +---------- +Epoch: 37/300 +train loss: 0.7018409407720333 +---------- +Epoch: 38/300 +train loss: 0.6869057262452637 +---------- +Epoch: 39/300 +train loss: 0.6841795565333308 +---------- +Epoch: 40/300 +train loss: 0.6794473394388105 +---------- +Epoch: 41/300 +train loss: 0.6790968551323181 +---------- +Epoch: 42/300 +train loss: 0.6754620320549826 +---------- +Epoch: 43/300 +train loss: 0.665113363687585 +---------- +Epoch: 44/300 +train loss: 0.667056881618209 +---------- +Epoch: 45/300 +train loss: 0.6623089440712114 +---------- +Epoch: 46/300 +train loss: 0.6524794242549233 +---------- +Epoch: 47/300 +train loss: 0.6567894975404914 +---------- +Epoch: 48/300 +train loss: 0.6450830041090163 +---------- +Epoch: 49/300 +train loss: 0.6330659195053868 +---------- +Epoch: 50/300 +train loss: 0.6390185023589832 +---------- +Epoch: 51/300 +train loss: 0.6335206407054168 +---------- +Epoch: 52/300 +train loss: 0.6487786481838401 +---------- +Epoch: 53/300 +train loss: 0.6242503134034029 +---------- +Epoch: 54/300 +train loss: 0.629002622987439 +---------- +Epoch: 55/300 +train loss: 0.6285576712249256 +---------- +Epoch: 56/300 +train loss: 0.6151385171020903 +---------- +Epoch: 57/300 +train loss: 0.618396897959273 +---------- +Epoch: 58/300 +train loss: 0.6186871595862435 +---------- +Epoch: 59/300 +train loss: 0.6152329195926829 +---------- +Epoch: 60/300 +train loss: 0.6118716762923613 +---------- +Epoch: 61/300 +train loss: 0.6106682838644923 +---------- +Epoch: 62/300 +train loss: 0.605608502084889 +---------- +Epoch: 63/300 +train loss: 0.6064907143392214 +---------- +Epoch: 64/300 +train loss: 0.6069014861998034 +---------- +Epoch: 65/300 +train loss: 0.608613460256559 +---------- +Epoch: 66/300 +train loss: 0.6001394573689961 +---------- +Epoch: 67/300 +train loss: 0.6002942952441006 +---------- +Epoch: 68/300 +train loss: 0.5860573515841146 +---------- +Epoch: 69/300 +train loss: 0.5889460247282575 +---------- +Epoch: 70/300 +train loss: 0.5920564295133439 +---------- +Epoch: 71/300 +train loss: 0.5855444338081813 +---------- +Epoch: 72/300 +train loss: 0.5848859441353054 +---------- +Epoch: 73/300 +train loss: 0.5868136161347715 +---------- +Epoch: 74/300 +train loss: 0.593527490772852 +---------- +Epoch: 75/300 +train loss: 0.5777589420719844 +---------- +Epoch: 76/300 +train loss: 0.5826347842812538 +---------- +Epoch: 77/300 +train loss: 0.5838093518665651 +---------- +Epoch: 78/300 +train loss: 0.5841529097680639 +---------- +Epoch: 79/300 +train loss: 0.5777867313746999 +---------- +Epoch: 80/300 +train loss: 0.5788609479076978 +---------- +Epoch: 81/300 +train loss: 0.5771293887277928 +---------- +Epoch: 82/300 +train loss: 0.5715940859077907 +---------- +Epoch: 83/300 +train loss: 0.5743454047819463 +---------- +Epoch: 84/300 +train loss: 0.5756655906940379 +---------- +Epoch: 85/300 +train loss: 0.5661546761488042 +---------- +Epoch: 86/300 +train loss: 0.5686924996354231 +---------- +Epoch: 87/300 +train loss: 0.572288849731771 +---------- +Epoch: 88/300 +train loss: 0.5718413282458376 +---------- +Epoch: 89/300 +train loss: 0.5705293969410222 +---------- +Epoch: 90/300 +train loss: 0.5671022519832705 +---------- +Epoch: 91/300 +train loss: 0.5707364989126601 +---------- +Epoch: 92/300 +train loss: 0.567001880759873 +---------- +Epoch: 93/300 +train loss: 0.5718449552248164 +---------- +Epoch: 94/300 +train loss: 0.5605094927113231 +---------- +Epoch: 95/300 +train loss: 0.5588691746134583 +---------- +Epoch: 96/300 +train loss: 0.563779655571391 +---------- +Epoch: 97/300 +train loss: 0.5727203829986293 +---------- +Epoch: 98/300 +train loss: 0.5606645670060705 +---------- +Epoch: 99/300 +train loss: 0.5655639344235746 +---------- +Epoch: 100/300 +train loss: 0.5642829932635878 +---------- +Epoch: 101/300 +train loss: 0.5613318870707256 +---------- +Epoch: 102/300 +train loss: 0.559509095985715 +---------- +Epoch: 103/300 +train loss: 0.5671124627313963 +---------- +Epoch: 104/300 +train loss: 0.5616818245772909 +---------- +Epoch: 105/300 +train loss: 0.5619957823215461 +---------- +Epoch: 106/300 +train loss: 0.5567884017236349 +---------- +Epoch: 107/300 +train loss: 0.5557383496950312 +---------- +Epoch: 108/300 +train loss: 0.5642311291360274 +---------- +Epoch: 109/300 +train loss: 0.5662872087119556 +---------- +Epoch: 110/300 +train loss: 0.5590864852434252 +---------- +Epoch: 111/300 +train loss: 0.5648398053173612 +---------- +Epoch: 112/300 +train loss: 0.5580323726483961 +---------- +Epoch: 113/300 +train loss: 0.5567497580153186 +---------- +Epoch: 114/300 +train loss: 0.5630400580603901 +---------- +Epoch: 115/300 +train loss: 0.5538424374308528 +---------- +Epoch: 116/300 +train loss: 0.5580180316436582 +---------- +Epoch: 117/300 +train loss: 0.556875641026148 +---------- +Epoch: 118/300 +train loss: 0.5678275541016241 +---------- +Epoch: 119/300 +train loss: 0.560026458850721 +---------- +Epoch: 120/300 +train loss: 0.5611625352828968 +---------- +Epoch: 121/300 +train loss: 0.551834630530055 +---------- +Epoch: 122/300 +train loss: 0.5544438309422354 +---------- +Epoch: 123/300 +train loss: 0.5569952729998565 +---------- +Epoch: 124/300 +train loss: 0.5532170316976744 +---------- +Epoch: 125/300 +train loss: 0.5545102213395805 +---------- +Epoch: 126/300 +train loss: 0.5570076818509799 +---------- +Epoch: 127/300 +train loss: 0.5552769386913718 +---------- +Epoch: 128/300 +train loss: 0.555146463942237 +---------- +Epoch: 129/300 +train loss: 0.5533929106484099 +---------- +Epoch: 130/300 +train loss: 0.5599716932671827 +---------- +Epoch: 131/300 +train loss: 0.5522712502719426 +---------- +Epoch: 132/300 +train loss: 0.5526935269192952 +---------- +Epoch: 133/300 +train loss: 0.5498186174507548 +---------- +Epoch: 134/300 +train loss: 0.558319001663022 +---------- +Epoch: 135/300 +train loss: 0.567952715678186 +---------- +Epoch: 136/300 +train loss: 0.5496662398118798 +---------- +Epoch: 137/300 +train loss: 0.5459267346233856 +---------- +Epoch: 138/300 +train loss: 0.5548020657606241 +---------- +Epoch: 139/300 +train loss: 0.5581261336621715 +---------- +Epoch: 140/300 +train loss: 0.555513132272697 +---------- +Epoch: 141/300 +train loss: 0.5425212532281876 +---------- +Epoch: 142/300 +train loss: 0.554408071335496 +---------- +Epoch: 143/300 +train loss: 0.5611961568455871 +---------- +Epoch: 144/300 +train loss: 0.5497159719830607 +---------- +Epoch: 145/300 +train loss: 0.553985515291371 +---------- +Epoch: 146/300 +train loss: 0.552209698027227 +---------- +Epoch: 147/300 +train loss: 0.5482723026922564 +---------- +Epoch: 148/300 +train loss: 0.5597864095030761 +---------- +Epoch: 149/300 +train loss: 0.5535240913854866 +---------- +Epoch: 150/300 +train loss: 0.5547397449249174 +---------- +Epoch: 151/300 +train loss: 0.5516444017610899 +---------- +Epoch: 152/300 +train loss: 0.5467582678467762 +---------- +Epoch: 153/300 +train loss: 0.5556213542273859 +---------- +Epoch: 154/300 +train loss: 0.5559055385429684 +---------- +Epoch: 155/300 +train loss: 0.5527037072290735 +---------- +Epoch: 156/300 +train loss: 0.5595959684834247 +---------- +Epoch: 157/300 +train loss: 0.5552922378226024 +---------- +Epoch: 158/300 +train loss: 0.5588282246778651 +---------- +Epoch: 159/300 +train loss: 0.5568678265482914 +---------- +Epoch: 160/300 +train loss: 0.5509358892535291 +---------- +Epoch: 161/300 +train loss: 0.55544380798209 +---------- +Epoch: 162/300 +train loss: 0.5503908054130834 +---------- +Epoch: 163/300 +train loss: 0.5490232755134745 +---------- +Epoch: 164/300 +train loss: 0.55477098148407 +---------- +Epoch: 165/300 +train loss: 0.5499786233938322 +---------- +Epoch: 166/300 +train loss: 0.5489160029626474 +---------- +Epoch: 167/300 +train loss: 0.5535752333518935 +---------- +Epoch: 168/300 +train loss: 0.5517634667637872 +---------- +Epoch: 169/300 +train loss: 0.5544024943941976 +---------- +Epoch: 170/300 +train loss: 0.5567889806882638 +---------- +Epoch: 171/300 +train loss: 0.5537487953537847 +---------- +Epoch: 172/300 +train loss: 0.5505024468208232 +---------- +Epoch: 173/300 +train loss: 0.5541055284258796 +---------- +Epoch: 174/300 +train loss: 0.5564219584552254 +---------- +Epoch: 175/300 +train loss: 0.5509056932315594 +---------- +Epoch: 176/300 +train loss: 0.5506802266690789 +---------- +Epoch: 177/300 +train loss: 0.5518694978843375 +---------- +Epoch: 178/300 +train loss: 0.5442488067215536 +---------- +Epoch: 179/300 +train loss: 0.5474909305027346 +---------- +Epoch: 180/300 +train loss: 0.5438729580946084 +---------- +Epoch: 181/300 +train loss: 0.5497829824140886 +---------- +Epoch: 182/300 +train loss: 0.5528207572131623 +---------- +Epoch: 183/300 +train loss: 0.5478700979090319 +---------- +Epoch: 184/300 +train loss: 0.5556103761603193 +---------- +Epoch: 185/300 +train loss: 0.5493665297583836 +---------- +Epoch: 186/300 +train loss: 0.5469489639125219 +---------- +Epoch: 187/300 +train loss: 0.5473163739391943 +---------- +Epoch: 188/300 +train loss: 0.5498563008519207 +---------- +Epoch: 189/300 +train loss: 0.5418999908355678 +---------- +Epoch: 190/300 +train loss: 0.5562262407890181 +---------- +Epoch: 191/300 +train loss: 0.5534045947034184 +---------- +Epoch: 192/300 +train loss: 0.5485934589694186 +---------- +Epoch: 193/300 +train loss: 0.5419396719918018 +---------- +Epoch: 194/300 +train loss: 0.5514212181655372 +---------- +Epoch: 195/300 +train loss: 0.5535368068007435 +---------- +Epoch: 196/300 +train loss: 0.5464842418526731 +---------- +Epoch: 197/300 +train loss: 0.5495766509415173 +---------- +Epoch: 198/300 +train loss: 0.5532617549888972 +---------- +Epoch: 199/300 +train loss: 0.5452990282054354 +---------- +Epoch: 200/300 +train loss: 0.553361903966927 +---------- +Epoch: 201/300 +train loss: 0.5432001394106121 +---------- +Epoch: 202/300 +train loss: 0.550419543574496 +---------- +Epoch: 203/300 +train loss: 0.5534595720833395 +---------- +Epoch: 204/300 +train loss: 0.5453232568575115 +---------- +Epoch: 205/300 +train loss: 0.5451060552604314 +---------- +Epoch: 206/300 +train loss: 0.5556593400130911 +---------- +Epoch: 207/300 +train loss: 0.557492576721238 +---------- +Epoch: 208/300 +train loss: 0.5553175620734692 +---------- +Epoch: 209/300 +train loss: 0.5433410697775644 +---------- +Epoch: 210/300 +train loss: 0.5517896733632902 +---------- +Epoch: 211/300 +train loss: 0.5420230569817671 +---------- +Epoch: 212/300 +train loss: 0.553179111422562 +---------- +Epoch: 213/300 +train loss: 0.5532874674877015 +---------- +Epoch: 214/300 +train loss: 0.5513115395314809 +---------- +Epoch: 215/300 +train loss: 0.5477715160061674 +---------- +Epoch: 216/300 +train loss: 0.5524102382180167 +---------- +Epoch: 217/300 +train loss: 0.5583272420960229 +---------- +Epoch: 218/300 +train loss: 0.5493520412866663 +---------- +Epoch: 219/300 +train loss: 0.5505585817665588 +---------- +Epoch: 220/300 +train loss: 0.5513288827567566 +---------- +Epoch: 221/300 +train loss: 0.5509700740619403 +---------- +Epoch: 222/300 +train loss: 0.5471859193611436 +---------- +Epoch: 223/300 +train loss: 0.5479258945802363 +---------- +Epoch: 224/300 +train loss: 0.5468155258312458 +---------- +Epoch: 225/300 +train loss: 0.5532922947370424 +---------- +Epoch: 226/300 +train loss: 0.5509961512757511 +---------- +Epoch: 227/300 +train loss: 0.5566592513606315 +---------- +Epoch: 228/300 +train loss: 0.5468720855509362 +---------- +Epoch: 229/300 +train loss: 0.5485118084200998 +---------- +Epoch: 230/300 +train loss: 0.5553761393558688 +---------- +Epoch: 231/300 +train loss: 0.5538774156352368 +---------- +Epoch: 232/300 +train loss: 0.5535862693881116 +---------- +Epoch: 233/300 +train loss: 0.559648928482358 +---------- +Epoch: 234/300 +train loss: 0.5566149992732013 +---------- +Epoch: 235/300 +train loss: 0.5537716771771268 +---------- +Epoch: 236/300 +train loss: 0.5482096226840485 +---------- +Epoch: 237/300 +train loss: 0.5522753771667074 +---------- +Epoch: 238/300 +train loss: 0.553921124738891 +---------- +Epoch: 239/300 +train loss: 0.5568602827445763 +---------- +Epoch: 240/300 +train loss: 0.5509852958706821 +---------- +Epoch: 241/300 +train loss: 0.5503496584914079 +---------- +Epoch: 242/300 +train loss: 0.5573272326188844 +---------- +Epoch: 243/300 +train loss: 0.5485873044264026 +---------- +Epoch: 244/300 +train loss: 0.5551095642149448 +---------- +Epoch: 245/300 +train loss: 0.555719885429958 +---------- +Epoch: 246/300 +train loss: 0.5547739392737063 +---------- +Epoch: 247/300 +train loss: 0.5579677987389449 +---------- +Epoch: 248/300 +train loss: 0.5550545382245284 +---------- +Epoch: 249/300 +train loss: 0.5540565562139197 +---------- +Epoch: 250/300 +train loss: 0.5495907050989023 +---------- +Epoch: 251/300 +train loss: 0.5591612574530811 +---------- +Epoch: 252/300 +train loss: 0.5526787800396361 +---------- +Epoch: 253/300 +train loss: 0.5496814871524892 +---------- +Epoch: 254/300 +train loss: 0.5540165307863456 +---------- +Epoch: 255/300 +train loss: 0.5507408661268106 +---------- +Epoch: 256/300 +train loss: 0.5493098404712793 +---------- +Epoch: 257/300 +train loss: 0.5516996947912182 +---------- +Epoch: 258/300 +train loss: 0.5472092830189844 +---------- +Epoch: 259/300 +train loss: 0.5510950345636868 +---------- +Epoch: 260/300 +train loss: 0.5474240792597213 +---------- +Epoch: 261/300 +train loss: 0.5587661537091907 +---------- +Epoch: 262/300 +train loss: 0.5486958720153425 +---------- +Epoch: 263/300 +train loss: 0.555758919476009 +---------- +Epoch: 264/300 +train loss: 0.5515954894263569 +---------- +Epoch: 265/300 +train loss: 0.5496930155630518 +---------- +Epoch: 266/300 +train loss: 0.5465638443100743 +---------- +Epoch: 267/300 +train loss: 0.5538034867040995 +---------- +Epoch: 268/300 +train loss: 0.5515833862307595 +---------- +Epoch: 269/300 +train loss: 0.5496920899647039 +---------- +Epoch: 270/300 +train loss: 0.550315346841405 +---------- +Epoch: 271/300 +train loss: 0.5523107038220254 +---------- +Epoch: 272/300 +train loss: 0.5502457329776229 +---------- +Epoch: 273/300 +train loss: 0.5546982049396852 +---------- +Epoch: 274/300 +train loss: 0.5525404347515688 +---------- +Epoch: 275/300 +train loss: 0.5541610901312131 +---------- +Epoch: 276/300 +train loss: 0.5573831272379655 +---------- +Epoch: 277/300 +train loss: 0.549906870759115 +---------- +Epoch: 278/300 +train loss: 0.5567150217730824 +---------- +Epoch: 279/300 +train loss: 0.5559126037831713 +---------- +Epoch: 280/300 +train loss: 0.5517111808606764 +---------- +Epoch: 281/300 +train loss: 0.552947857757894 +---------- +Epoch: 282/300 +train loss: 0.5567048276524719 +---------- +Epoch: 283/300 +train loss: 0.5521830897323969 +---------- +Epoch: 284/300 +train loss: 0.5454606041312218 +---------- +Epoch: 285/300 +train loss: 0.5507395709978371 +---------- +Epoch: 286/300 +train loss: 0.5518143521394672 +---------- +Epoch: 287/300 +train loss: 0.5519008437489591 +---------- +Epoch: 288/300 +train loss: 0.5451099986165036 +---------- +Epoch: 289/300 +train loss: 0.5455087039892267 +---------- +Epoch: 290/300 +train loss: 0.545345228528831 +---------- +Epoch: 291/300 +train loss: 0.5585307433474355 +---------- +Epoch: 292/300 +train loss: 0.5500989946105131 +---------- +Epoch: 293/300 +train loss: 0.5457923505000952 +---------- +Epoch: 294/300 +train loss: 0.5575511342868572 +---------- +Epoch: 295/300 +train loss: 0.5508520018036772 +---------- +Epoch: 296/300 +train loss: 0.5536141810802425 +---------- +Epoch: 297/300 +train loss: 0.5538290936227251 +---------- +Epoch: 298/300 +train loss: 0.5453163091911049 +---------- +Epoch: 299/300 +train loss: 0.5550332332893115 +---------- +Epoch: 300/300 +train loss: 0.5472247938557369 +Traceback (most recent call last): + File "main.py", line 83, in + print('程序总运行时间:%s毫秒' % ((T2 - T1) * 1000)) +NameError: name 'T1' is not defined diff --git a/my520.log b/my520.log new file mode 100644 index 0000000..5a384db --- /dev/null +++ b/my520.log @@ -0,0 +1,909 @@ +nohup: ignoring input +Setting up data... +Starting training... +---------- +Epoch: 1/300 +train loss: 3.4394320607554434 +---------- +Epoch: 2/300 +/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/optim/lr_scheduler.py:154: UserWarning: The epoch parameter in `scheduler.step()` was not necessary and is being deprecated where possible. Please use `scheduler.step()` to step the scheduler. During the deprecation, if epoch is different from None, the closed form is used instead of the new chainable form, where available. Please open an issue if you are unable to replicate your use case: https://github.com/pytorch/pytorch/issues/new/choose. + warnings.warn(EPOCH_DEPRECATION_WARNING, UserWarning) +train loss: 1.930078529721074 +---------- +Epoch: 3/300 +train loss: 1.633405933439178 +---------- +Epoch: 4/300 +train loss: 1.4825877442079431 +---------- +Epoch: 5/300 +train loss: 1.3513453146990608 +---------- +Epoch: 6/300 +train loss: 1.284238253584587 +---------- +Epoch: 7/300 +train loss: 1.1909992801884748 +---------- +Epoch: 8/300 +train loss: 1.1763500916330438 +---------- +Epoch: 9/300 +train loss: 1.1247926802827108 +---------- +Epoch: 10/300 +train loss: 1.0886840263018298 +---------- +Epoch: 11/300 +train loss: 1.0634160527134828 +---------- +Epoch: 12/300 +train loss: 1.031403729605601 +---------- +Epoch: 13/300 +train loss: 1.0176705832451858 +---------- +Epoch: 14/300 +train loss: 0.9851431567971551 +---------- +Epoch: 15/300 +train loss: 0.9842541802778333 +---------- +Epoch: 16/300 +train loss: 0.9521809052387628 +---------- +Epoch: 17/300 +train loss: 0.9335779822647756 +---------- +Epoch: 18/300 +train loss: 0.9177891434899794 +---------- +Epoch: 19/300 +train loss: 0.89844102848425 +---------- +Epoch: 20/300 +train loss: 0.8756160040388904 +---------- +Epoch: 21/300 +train loss: 0.867238417313933 +---------- +Epoch: 22/300 +train loss: 0.8499307780073893 +---------- +Epoch: 23/300 +train loss: 0.842164253302772 +---------- +Epoch: 24/300 +train loss: 0.8305777697002187 +---------- +Epoch: 25/300 +train loss: 0.8163966628789163 +---------- +Epoch: 26/300 +train loss: 0.8109905509387746 +---------- +Epoch: 27/300 +train loss: 0.8094634806777671 +---------- +Epoch: 28/300 +train loss: 0.7870301117099845 +---------- +Epoch: 29/300 +train loss: 0.7851962270935992 +---------- +Epoch: 30/300 +train loss: 0.7699445513748902 +---------- +Epoch: 31/300 +train loss: 0.7692669129962153 +---------- +Epoch: 32/300 +train loss: 0.7567083329977266 +---------- +Epoch: 33/300 +train loss: 0.7474709262050712 +---------- +Epoch: 34/300 +train loss: 0.748934083678774 +---------- +Epoch: 35/300 +train loss: 0.7352799732618657 +---------- +Epoch: 36/300 +train loss: 0.7257756930386688 +---------- +Epoch: 37/300 +train loss: 0.7222192510731819 +---------- +Epoch: 38/300 +train loss: 0.7172380039935511 +---------- +Epoch: 39/300 +train loss: 0.7211404704826166 +---------- +Epoch: 40/300 +train loss: 0.7054665542608444 +---------- +Epoch: 41/300 +train loss: 0.6915910904621562 +---------- +Epoch: 42/300 +train loss: 0.6871611627262812 +---------- +Epoch: 43/300 +train loss: 0.688079390178893 +---------- +Epoch: 44/300 +train loss: 0.6753499621392772 +---------- +Epoch: 45/300 +train loss: 0.6777258363117006 +---------- +Epoch: 46/300 +train loss: 0.6820033273829764 +---------- +Epoch: 47/300 +train loss: 0.6689407763650912 +---------- +Epoch: 48/300 +train loss: 0.6597786256034308 +---------- +Epoch: 49/300 +train loss: 0.6596399033586308 +---------- +Epoch: 50/300 +train loss: 0.6629376999180383 +---------- +Epoch: 51/300 +train loss: 0.6641064552884353 +---------- +Epoch: 52/300 +train loss: 0.6577023321260977 +---------- +Epoch: 53/300 +train loss: 0.6460512635693092 +---------- +Epoch: 54/300 +train loss: 0.6521802763267198 +---------- +Epoch: 55/300 +train loss: 0.636500123853654 +---------- +Epoch: 56/300 +train loss: 0.6382356001865753 +---------- +Epoch: 57/300 +train loss: 0.6377618587792104 +---------- +Epoch: 58/300 +train loss: 0.6327137644445933 +---------- +Epoch: 59/300 +train loss: 0.6347541431708971 +---------- +Epoch: 60/300 +train loss: 0.629689353722906 +---------- +Epoch: 61/300 +train loss: 0.629009592182496 +---------- +Epoch: 62/300 +train loss: 0.6273051674705541 +---------- +Epoch: 63/300 +train loss: 0.6193134883424446 +---------- +Epoch: 64/300 +train loss: 0.6325272070734125 +---------- +Epoch: 65/300 +train loss: 0.6154070925601864 +---------- +Epoch: 66/300 +train loss: 0.6071137105901913 +---------- +Epoch: 67/300 +train loss: 0.6189665371788544 +---------- +Epoch: 68/300 +train loss: 0.6039990106418774 +---------- +Epoch: 69/300 +train loss: 0.6081831483833561 +---------- +Epoch: 70/300 +train loss: 0.6164965122107751 +---------- +Epoch: 71/300 +train loss: 0.6093785233172839 +---------- +Epoch: 72/300 +train loss: 0.6064768053429783 +---------- +Epoch: 73/300 +train loss: 0.6042170901047555 +---------- +Epoch: 74/300 +train loss: 0.607218999980773 +---------- +Epoch: 75/300 +train loss: 0.6010280915827205 +---------- +Epoch: 76/300 +train loss: 0.6088563133688534 +---------- +Epoch: 77/300 +train loss: 0.5960819613269239 +---------- +Epoch: 78/300 +train loss: 0.5995096006076033 +---------- +Epoch: 79/300 +train loss: 0.6007698672843791 +---------- +Epoch: 80/300 +train loss: 0.5952687222891179 +---------- +Epoch: 81/300 +train loss: 0.603035535513432 +---------- +Epoch: 82/300 +train loss: 0.5906850624564263 +---------- +Epoch: 83/300 +train loss: 0.5875769174504945 +---------- +Epoch: 84/300 +train loss: 0.5973145653588853 +---------- +Epoch: 85/300 +train loss: 0.5833648518881193 +---------- +Epoch: 86/300 +train loss: 0.5883274316418651 +---------- +Epoch: 87/300 +train loss: 0.5961968240907687 +---------- +Epoch: 88/300 +train loss: 0.5970893593579992 +---------- +Epoch: 89/300 +train loss: 0.5811341264668632 +---------- +Epoch: 90/300 +train loss: 0.5812809775488296 +---------- +Epoch: 91/300 +train loss: 0.5839183432029866 +---------- +Epoch: 92/300 +train loss: 0.5849279689345935 +---------- +Epoch: 93/300 +train loss: 0.5826380343260041 +---------- +Epoch: 94/300 +train loss: 0.5840902419835791 +---------- +Epoch: 95/300 +train loss: 0.5825643528356641 +---------- +Epoch: 96/300 +train loss: 0.5778747019199395 +---------- +Epoch: 97/300 +train loss: 0.5842624517048106 +---------- +Epoch: 98/300 +train loss: 0.5786413823487958 +---------- +Epoch: 99/300 +train loss: 0.5854276273826328 +---------- +Epoch: 100/300 +train loss: 0.5831200461084998 +---------- +Epoch: 101/300 +train loss: 0.5781117375052012 +---------- +Epoch: 102/300 +train loss: 0.5853699297174212 +---------- +Epoch: 103/300 +train loss: 0.5790560357157291 +---------- +Epoch: 104/300 +train loss: 0.5730563790621034 +---------- +Epoch: 105/300 +train loss: 0.5763303658726046 +---------- +Epoch: 106/300 +train loss: 0.5797402464752965 +---------- +Epoch: 107/300 +train loss: 0.5812801884792906 +---------- +Epoch: 108/300 +train loss: 0.5763228203490054 +---------- +Epoch: 109/300 +train loss: 0.5762089939309347 +---------- +Epoch: 110/300 +train loss: 0.5756880531185552 +---------- +Epoch: 111/300 +train loss: 0.5692944096706969 +---------- +Epoch: 112/300 +train loss: 0.5768693202973888 +---------- +Epoch: 113/300 +train loss: 0.5789581728239915 +---------- +Epoch: 114/300 +train loss: 0.5717335509441954 +---------- +Epoch: 115/300 +train loss: 0.5798303593792045 +---------- +Epoch: 116/300 +train loss: 0.5730079361713338 +---------- +Epoch: 117/300 +train loss: 0.5750909528865165 +---------- +Epoch: 118/300 +train loss: 0.5771061666425168 +---------- +Epoch: 119/300 +train loss: 0.5824603371944959 +---------- +Epoch: 120/300 +train loss: 0.5709850619267384 +---------- +Epoch: 121/300 +train loss: 0.5749542965054881 +---------- +Epoch: 122/300 +train loss: 0.5685901321678338 +---------- +Epoch: 123/300 +train loss: 0.5765443899129566 +---------- +Epoch: 124/300 +train loss: 0.5766789385408809 +---------- +Epoch: 125/300 +train loss: 0.575109283898268 +---------- +Epoch: 126/300 +train loss: 0.5734074563249346 +---------- +Epoch: 127/300 +train loss: 0.5787333538842275 +---------- +Epoch: 128/300 +train loss: 0.5745735660241484 +---------- +Epoch: 129/300 +train loss: 0.5669669184153294 +---------- +Epoch: 130/300 +train loss: 0.5708108556344413 +---------- +Epoch: 131/300 +train loss: 0.5693512706564676 +---------- +Epoch: 132/300 +train loss: 0.569030460742974 +---------- +Epoch: 133/300 +train loss: 0.5710507141362772 +---------- +Epoch: 134/300 +train loss: 0.5748469328548148 +---------- +Epoch: 135/300 +train loss: 0.5773823523299982 +---------- +Epoch: 136/300 +train loss: 0.5693722617330935 +---------- +Epoch: 137/300 +train loss: 0.567474852220931 +---------- +Epoch: 138/300 +train loss: 0.5759126903841001 +---------- +Epoch: 139/300 +train loss: 0.5726324898355147 +---------- +Epoch: 140/300 +train loss: 0.5715209749460959 +---------- +Epoch: 141/300 +train loss: 0.5773299010730011 +---------- +Epoch: 142/300 +train loss: 0.566016223962093 +---------- +Epoch: 143/300 +train loss: 0.5756766654943165 +---------- +Epoch: 144/300 +train loss: 0.5762189758635896 +---------- +Epoch: 145/300 +train loss: 0.5703497758775303 +---------- +Epoch: 146/300 +train loss: 0.5751561454206059 +---------- +Epoch: 147/300 +train loss: 0.5723920575236389 +---------- +Epoch: 148/300 +train loss: 0.5694741011588567 +---------- +Epoch: 149/300 +train loss: 0.5725228538269598 +---------- +Epoch: 150/300 +train loss: 0.5694768740665802 +---------- +Epoch: 151/300 +train loss: 0.5667742189054519 +---------- +Epoch: 152/300 +train loss: 0.5780753946341228 +---------- +Epoch: 153/300 +train loss: 0.5716342858670297 +---------- +Epoch: 154/300 +train loss: 0.5683843594032914 +---------- +Epoch: 155/300 +train loss: 0.5782360846044109 +---------- +Epoch: 156/300 +train loss: 0.5695936934497703 +---------- +Epoch: 157/300 +train loss: 0.5644589573975318 +---------- +Epoch: 158/300 +train loss: 0.5699425021376772 +---------- +Epoch: 159/300 +train loss: 0.5675014005541432 +---------- +Epoch: 160/300 +train loss: 0.5726423774710381 +---------- +Epoch: 161/300 +train loss: 0.5736665025399565 +---------- +Epoch: 162/300 +train loss: 0.5683291724222732 +---------- +Epoch: 163/300 +train loss: 0.5703395354120355 +---------- +Epoch: 164/300 +train loss: 0.5666843002241093 +---------- +Epoch: 165/300 +train loss: 0.5642050609869116 +---------- +Epoch: 166/300 +train loss: 0.5783111298047352 +---------- +Epoch: 167/300 +train loss: 0.5688314526442773 +---------- +Epoch: 168/300 +train loss: 0.5649547326860044 +---------- +Epoch: 169/300 +train loss: 0.5662805891996566 +---------- +Epoch: 170/300 +train loss: 0.5690607213568023 +---------- +Epoch: 171/300 +train loss: 0.5693840228551682 +---------- +Epoch: 172/300 +train loss: 0.5664498788468978 +---------- +Epoch: 173/300 +train loss: 0.5662287851974322 +---------- +Epoch: 174/300 +train loss: 0.5706901245811037 +---------- +Epoch: 175/300 +train loss: 0.5746730549416675 +---------- +Epoch: 176/300 +train loss: 0.5749756673541231 +---------- +Epoch: 177/300 +train loss: 0.5743117327845133 +---------- +Epoch: 178/300 +train loss: 0.5589386003305299 +---------- +Epoch: 179/300 +train loss: 0.5710129630823991 +---------- +Epoch: 180/300 +train loss: 0.5704299873058272 +---------- +Epoch: 181/300 +train loss: 0.5674120885299825 +---------- +Epoch: 182/300 +train loss: 0.559411147338318 +---------- +Epoch: 183/300 +train loss: 0.5742758797602757 +---------- +Epoch: 184/300 +train loss: 0.5652756291461802 +---------- +Epoch: 185/300 +train loss: 0.5745003632163116 +---------- +Epoch: 186/300 +train loss: 0.5711110114313132 +---------- +Epoch: 187/300 +train loss: 0.5659535459874215 +---------- +Epoch: 188/300 +train loss: 0.574384407823669 +---------- +Epoch: 189/300 +train loss: 0.5667811529739722 +---------- +Epoch: 190/300 +train loss: 0.5642454672154996 +---------- +Epoch: 191/300 +train loss: 0.5740268274726513 +---------- +Epoch: 192/300 +train loss: 0.5629734715256529 +---------- +Epoch: 193/300 +train loss: 0.5723785064168759 +---------- +Epoch: 194/300 +train loss: 0.5708345717320871 +---------- +Epoch: 195/300 +train loss: 0.5627649647901671 +---------- +Epoch: 196/300 +train loss: 0.5750793810045756 +---------- +Epoch: 197/300 +train loss: 0.5741033718312857 +---------- +Epoch: 198/300 +train loss: 0.5778550891315236 +---------- +Epoch: 199/300 +train loss: 0.5620668767591009 +---------- +Epoch: 200/300 +train loss: 0.5723251026850367 +---------- +Epoch: 201/300 +train loss: 0.5726388204762072 +---------- +Epoch: 202/300 +train loss: 0.5720572968016467 +---------- +Epoch: 203/300 +train loss: 0.5737994054891745 +---------- +Epoch: 204/300 +train loss: 0.5726441243669197 +---------- +Epoch: 205/300 +train loss: 0.5654018422582939 +---------- +Epoch: 206/300 +train loss: 0.5721300107775827 +---------- +Epoch: 207/300 +train loss: 0.5674502250764392 +---------- +Epoch: 208/300 +train loss: 0.5661794402097401 +---------- +Epoch: 209/300 +train loss: 0.565577471496151 +---------- +Epoch: 210/300 +train loss: 0.5717732342588643 +---------- +Epoch: 211/300 +train loss: 0.5689131697818591 +---------- +Epoch: 212/300 +train loss: 0.5645846638701648 +---------- +Epoch: 213/300 +train loss: 0.5738475428830728 +---------- +Epoch: 214/300 +train loss: 0.5720115142525534 +---------- +Epoch: 215/300 +train loss: 0.5752112238953357 +---------- +Epoch: 216/300 +train loss: 0.5772492190817192 +---------- +Epoch: 217/300 +train loss: 0.5704983932315012 +---------- +Epoch: 218/300 +train loss: 0.569904790205114 +---------- +Epoch: 219/300 +train loss: 0.5742690336224464 +---------- +Epoch: 220/300 +train loss: 0.568482704575955 +---------- +Epoch: 221/300 +train loss: 0.5715297753965891 +---------- +Epoch: 222/300 +train loss: 0.5710316764496428 +---------- +Epoch: 223/300 +train loss: 0.5715734553595445 +---------- +Epoch: 224/300 +train loss: 0.5672295156278109 +---------- +Epoch: 225/300 +train loss: 0.5646657074568072 +---------- +Epoch: 226/300 +train loss: 0.5673439821960756 +---------- +Epoch: 227/300 +train loss: 0.5700345693542492 +---------- +Epoch: 228/300 +train loss: 0.5602112738156098 +---------- +Epoch: 229/300 +train loss: 0.5691522084891611 +---------- +Epoch: 230/300 +train loss: 0.5622219814235581 +---------- +Epoch: 231/300 +train loss: 0.5705981853392103 +---------- +Epoch: 232/300 +train loss: 0.5717427863425145 +---------- +Epoch: 233/300 +train loss: 0.566420454358907 +---------- +Epoch: 234/300 +train loss: 0.5703431164886191 +---------- +Epoch: 235/300 +train loss: 0.5664396363515234 +---------- +Epoch: 236/300 +train loss: 0.5644527944987034 +---------- +Epoch: 237/300 +train loss: 0.5765276849269867 +---------- +Epoch: 238/300 +train loss: 0.5697608117717707 +---------- +Epoch: 239/300 +train loss: 0.5707514197464698 +---------- +Epoch: 240/300 +train loss: 0.568966758694073 +---------- +Epoch: 241/300 +train loss: 0.5714757817079408 +---------- +Epoch: 242/300 +train loss: 0.5690984512814796 +---------- +Epoch: 243/300 +train loss: 0.5704802971321732 +---------- +Epoch: 244/300 +train loss: 0.5740080759990326 +---------- +Epoch: 245/300 +train loss: 0.5745089057798356 +---------- +Epoch: 246/300 +train loss: 0.5653779470699122 +---------- +Epoch: 247/300 +train loss: 0.5691389676771665 +---------- +Epoch: 248/300 +train loss: 0.5720810018272223 +---------- +Epoch: 249/300 +train loss: 0.5658170342814443 +---------- +Epoch: 250/300 +train loss: 0.5725755191439814 +---------- +Epoch: 251/300 +train loss: 0.5666882629180471 +---------- +Epoch: 252/300 +train loss: 0.564656544119212 +---------- +Epoch: 253/300 +train loss: 0.5677354193693344 +---------- +Epoch: 254/300 +train loss: 0.5748839044349482 +---------- +Epoch: 255/300 +train loss: 0.5665894175646106 +---------- +Epoch: 256/300 +train loss: 0.567643519341023 +---------- +Epoch: 257/300 +train loss: 0.5634990612235231 +---------- +Epoch: 258/300 +train loss: 0.5685394195026657 +---------- +Epoch: 259/300 +train loss: 0.5634476017472175 +---------- +Epoch: 260/300 +train loss: 0.5658026995489103 +---------- +Epoch: 261/300 +train loss: 0.5762477362119007 +---------- +Epoch: 262/300 +train loss: 0.5678475147614908 +---------- +Epoch: 263/300 +train loss: 0.569275289773941 +---------- +Epoch: 264/300 +train loss: 0.5606244695444963 +---------- +Epoch: 265/300 +train loss: 0.5778651704360088 +---------- +Epoch: 266/300 +train loss: 0.5702718371761841 +---------- +Epoch: 267/300 +train loss: 0.5581895816067793 +---------- +Epoch: 268/300 +train loss: 0.5675852225845444 +---------- +Epoch: 269/300 +train loss: 0.5733042543886616 +---------- +Epoch: 270/300 +train loss: 0.5750072927851426 +---------- +Epoch: 271/300 +train loss: 0.56704161253876 +---------- +Epoch: 272/300 +train loss: 0.57172726606806 +---------- +Epoch: 273/300 +train loss: 0.566815867604855 +---------- +Epoch: 274/300 +train loss: 0.5693643953962592 +---------- +Epoch: 275/300 +train loss: 0.5793589622981777 +---------- +Epoch: 276/300 +train loss: 0.5724858647160486 +---------- +Epoch: 277/300 +train loss: 0.574933646264091 +---------- +Epoch: 278/300 +train loss: 0.5787208814739073 +---------- +Epoch: 279/300 +train loss: 0.572715374522903 +---------- +Epoch: 280/300 +train loss: 0.5646711404294052 +---------- +Epoch: 281/300 +train loss: 0.5654006999897145 +---------- +Epoch: 282/300 +train loss: 0.5695910326467579 +---------- +Epoch: 283/300 +train loss: 0.5692749171987775 +---------- +Epoch: 284/300 +train loss: 0.5623931064509755 +---------- +Epoch: 285/300 +train loss: 0.5706357027724063 +---------- +Epoch: 286/300 +train loss: 0.5685308650366662 +---------- +Epoch: 287/300 +train loss: 0.5641438151845253 +---------- +Epoch: 288/300 +train loss: 0.5641026778302326 +---------- +Epoch: 289/300 +train loss: 0.5752063679621315 +---------- +Epoch: 290/300 +train loss: 0.5673458081649922 +---------- +Epoch: 291/300 +train loss: 0.5645986811110848 +---------- +Epoch: 292/300 +train loss: 0.5719952690343001 +---------- +Epoch: 293/300 +train loss: 0.5668923838219776 +---------- +Epoch: 294/300 +train loss: 0.5691729476761892 +---------- +Epoch: 295/300 +train loss: 0.5649229059278411 +---------- +Epoch: 296/300 +train loss: 0.5668271249477339 +---------- +Epoch: 297/300 +train loss: 0.5688653608593779 +---------- +Epoch: 298/300 +train loss: 0.5739670262986293 +---------- +Epoch: 299/300 +train loss: 0.5699526408323932 +---------- +Epoch: 300/300 +train loss: 0.5748210990392018 +Traceback (most recent call last): + File "main.py", line 83, in + print('程序总运行时间:%s毫秒' % ((T2 - T1) * 1000)) +NameError: name 'T1' is not defined diff --git a/myenlarge.log b/myenlarge.log new file mode 100644 index 0000000..97e09d1 --- /dev/null +++ b/myenlarge.log @@ -0,0 +1,397 @@ +nohup: ignoring input +Setting up data... +Starting training... +---------- +Epoch: 1/300 +train loss: 3.307037867423965 +---------- +Epoch: 2/300 +/home/thsw/anaconda3/envs/yolov5_bridge/lib/python3.8/site-packages/torch/optim/lr_scheduler.py:154: UserWarning: The epoch parameter in `scheduler.step()` was not necessary and is being deprecated where possible. Please use `scheduler.step()` to step the scheduler. During the deprecation, if epoch is different from None, the closed form is used instead of the new chainable form, where available. Please open an issue if you are unable to replicate your use case: https://github.com/pytorch/pytorch/issues/new/choose. + warnings.warn(EPOCH_DEPRECATION_WARNING, UserWarning) +train loss: 1.8490978410331214 +---------- +Epoch: 3/300 +train loss: 1.561141774058342 +---------- +Epoch: 4/300 +train loss: 1.4109461198492748 +---------- +Epoch: 5/300 +train loss: 1.3152732482043707 +---------- +Epoch: 6/300 +train loss: 1.23120613178102 +---------- +Epoch: 7/300 +train loss: 1.1735509862987006 +---------- +Epoch: 8/300 +train loss: 1.1067496543613875 +---------- +Epoch: 9/300 +train loss: 1.0879325459643108 +---------- +Epoch: 10/300 +train loss: 1.0459921903363087 +---------- +Epoch: 11/300 +train loss: 1.0326051524863011 +---------- +Epoch: 12/300 +train loss: 0.9921930325103969 +---------- +Epoch: 13/300 +train loss: 0.9749882384771253 +---------- +Epoch: 14/300 +train loss: 0.9526009223446613 +---------- +Epoch: 15/300 +train loss: 0.924446231344851 +---------- +Epoch: 16/300 +train loss: 0.9120315565932088 +---------- +Epoch: 17/300 +train loss: 0.8949574039476674 +---------- +Epoch: 18/300 +train loss: 0.8795958457560074 +---------- +Epoch: 19/300 +train loss: 0.8690951808196742 +---------- +Epoch: 20/300 +train loss: 0.839984535625795 +---------- +Epoch: 21/300 +train loss: 0.8357012524473958 +---------- +Epoch: 22/300 +train loss: 0.8244846405052557 +---------- +Epoch: 23/300 +train loss: 0.8116382245973843 +---------- +Epoch: 24/300 +train loss: 0.784335666676847 +---------- +Epoch: 25/300 +train loss: 0.7887035886325487 +---------- +Epoch: 26/300 +train loss: 0.7719192650259995 +---------- +Epoch: 27/300 +train loss: 0.7664937497820796 +---------- +Epoch: 28/300 +train loss: 0.7657128625163218 +---------- +Epoch: 29/300 +train loss: 0.7466670109367952 +---------- +Epoch: 30/300 +train loss: 0.7491191251248848 +---------- +Epoch: 31/300 +train loss: 0.7392067185989241 +---------- +Epoch: 32/300 +train loss: 0.7254988480268455 +---------- +Epoch: 33/300 +train loss: 0.72247884095442 +---------- +Epoch: 34/300 +train loss: 0.7225755510352007 +---------- +Epoch: 35/300 +train loss: 0.7113728040783871 +---------- +Epoch: 36/300 +train loss: 0.6882840236876069 +---------- +Epoch: 37/300 +train loss: 0.6928801804599238 +---------- +Epoch: 38/300 +train loss: 0.6762253627544497 +---------- +Epoch: 39/300 +train loss: 0.676805709375114 +---------- +Epoch: 40/300 +train loss: 0.6736773376057787 +---------- +Epoch: 41/300 +train loss: 0.6719661420438348 +---------- +Epoch: 42/300 +train loss: 0.667674303599974 +---------- +Epoch: 43/300 +train loss: 0.6575799101009602 +---------- +Epoch: 44/300 +train loss: 0.6586109829566827 +---------- +Epoch: 45/300 +train loss: 0.6569638466689645 +---------- +Epoch: 46/300 +train loss: 0.646054647953772 +---------- +Epoch: 47/300 +train loss: 0.6500433959612032 +---------- +Epoch: 48/300 +train loss: 0.6366679424919733 +---------- +Epoch: 49/300 +train loss: 0.6255944731031976 +---------- +Epoch: 50/300 +train loss: 0.6329708500061093 +---------- +Epoch: 51/300 +train loss: 0.6252293430450486 +---------- +Epoch: 52/300 +train loss: 0.635402276112539 +---------- +Epoch: 53/300 +train loss: 0.6177184131087327 +---------- +Epoch: 54/300 +train loss: 0.6235615758270752 +---------- +Epoch: 55/300 +train loss: 0.6224451232247237 +---------- +Epoch: 56/300 +train loss: 0.610399562047749 +---------- +Epoch: 57/300 +train loss: 0.6147097092030979 +---------- +Epoch: 58/300 +train loss: 0.6103556625908468 +---------- +Epoch: 59/300 +train loss: 0.6093381568789482 +---------- +Epoch: 60/300 +train loss: 0.5974853209606031 +---------- +Epoch: 61/300 +train loss: 0.607551729715452 +---------- +Epoch: 62/300 +train loss: 0.6001740366038752 +---------- +Epoch: 63/300 +train loss: 0.5975715004634566 +---------- +Epoch: 64/300 +train loss: 0.6036988319601955 +---------- +Epoch: 65/300 +train loss: 0.6021600912620382 +---------- +Epoch: 66/300 +train loss: 0.5951395198339369 +---------- +Epoch: 67/300 +train loss: 0.5903787380311547 +---------- +Epoch: 68/300 +train loss: 0.5812304458785348 +---------- +Epoch: 69/300 +train loss: 0.5848958731242796 +---------- +Epoch: 70/300 +train loss: 0.5830151068909866 +---------- +Epoch: 71/300 +train loss: 0.5838195401720885 +---------- +Epoch: 72/300 +train loss: 0.5782773125825859 +---------- +Epoch: 73/300 +train loss: 0.5841681860932489 +---------- +Epoch: 74/300 +train loss: 0.5878641362779025 +---------- +Epoch: 75/300 +train loss: 0.5744512092049529 +---------- +Epoch: 76/300 +train loss: 0.5784077225480138 +---------- +Epoch: 77/300 +train loss: 0.5778905999188017 +---------- +Epoch: 78/300 +train loss: 0.5806078254813101 +---------- +Epoch: 79/300 +train loss: 0.5736329948938474 +---------- +Epoch: 80/300 +train loss: 0.577592335005359 +---------- +Epoch: 81/300 +train loss: 0.5712515053044005 +---------- +Epoch: 82/300 +train loss: 0.5629513234626956 +---------- +Epoch: 83/300 +train loss: 0.5674999619765979 +---------- +Epoch: 84/300 +train loss: 0.572166397168142 +---------- +Epoch: 85/300 +train loss: 0.5600198752632956 +---------- +Epoch: 86/300 +train loss: 0.5641529346566375 +---------- +Epoch: 87/300 +train loss: 0.5696737862578253 +---------- +Epoch: 88/300 +train loss: 0.5660816598229292 +---------- +Epoch: 89/300 +train loss: 0.5631480350545267 +---------- +Epoch: 90/300 +train loss: 0.557942715087315 +---------- +Epoch: 91/300 +train loss: 0.5627899840474129 +---------- +Epoch: 92/300 +train loss: 0.5633124596462017 +---------- +Epoch: 93/300 +train loss: 0.5645929554977068 +---------- +Epoch: 94/300 +train loss: 0.5542543557722394 +---------- +Epoch: 95/300 +train loss: 0.5531571798208283 +---------- +Epoch: 96/300 +train loss: 0.557213164048224 +---------- +Epoch: 97/300 +train loss: 0.5653773972355738 +---------- +Epoch: 98/300 +train loss: 0.557706034038125 +---------- +Epoch: 99/300 +train loss: 0.556364589348072 +---------- +Epoch: 100/300 +train loss: 0.5555244980425369 +---------- +Epoch: 101/300 +train loss: 0.5536440839854683 +---------- +Epoch: 102/300 +train loss: 0.5535611885531646 +---------- +Epoch: 103/300 +train loss: 0.5573019144556871 +---------- +Epoch: 104/300 +train loss: 0.5536222801339336 +---------- +Epoch: 105/300 +train loss: 0.5522710204851337 +---------- +Epoch: 106/300 +train loss: 0.5528217791238936 +---------- +Epoch: 107/300 +train loss: 0.5496333808433719 +---------- +Epoch: 108/300 +train loss: 0.5561074961612864 +---------- +Epoch: 109/300 +train loss: 0.5574712738758181 +---------- +Epoch: 110/300 +train loss: 0.5491735800737287 +---------- +Epoch: 111/300 +train loss: 0.5571781733050579 +---------- +Epoch: 112/300 +train loss: 0.555856435309823 +---------- +Epoch: 113/300 +train loss: 0.5511427012885489 +---------- +Epoch: 114/300 +train loss: 0.5534139981538784 +---------- +Epoch: 115/300 +train loss: 0.5492776229795886 +---------- +Epoch: 116/300 +train loss: 0.5522508076051387 +---------- +Epoch: 117/300 +train loss: 0.5524138775540561 +---------- +Epoch: 118/300 +train loss: 0.5566331935001583 +---------- +Epoch: 119/300 +train loss: 0.5521774955275582 +---------- +Epoch: 120/300 +train loss: 0.5556204090939789 +---------- +Epoch: 121/300 +train loss: 0.5481414351521469 +---------- +Epoch: 122/300 +train loss: 0.5481620049331246 +---------- +Epoch: 123/300 +train loss: 0.5498910303704623 +---------- +Epoch: 124/300 +train loss: 0.5474408364332304 +---------- +Epoch: 125/300 +train loss: 0.5461990730609836 +---------- +Epoch: 126/300 +train loss: 0.5499345149572302 +---------- +Epoch: 127/300 +train loss: 0.5495844648742094 +---------- +Epoch: 128/300 +train loss: 0.5491425968343164 +---------- +Epoch: 129/300 +train loss: 0.550200116525336 +---------- +Epoch: 130/300 +train loss: 0.5534766463608276 +---------- +Epoch: 131/300 diff --git a/nms.py b/nms.py new file mode 100644 index 0000000..14af917 --- /dev/null +++ b/nms.py @@ -0,0 +1,119 @@ +import numpy as np +import cv2 + +def calc_IoU(a, b): + # step1: + inter_x1 = np.maximum(np.min(a[:,0]), np.min(b[:,0])) + inter_x2 = np.minimum(np.max(a[:,0]), np.max(b[:,0])) + inter_y1 = np.maximum(np.min(a[:,1]), np.min(b[:,1])) + inter_y2 = np.minimum(np.max(a[:,1]), np.max(b[:,1])) + if inter_x1>=inter_x2 or inter_y1>=inter_y2: + return 0. + x1 = np.minimum(np.min(a[:,0]), np.min(b[:,0])) + x2 = np.maximum(np.max(a[:,0]), np.max(b[:,0])) + y1 = np.minimum(np.min(a[:,1]), np.min(b[:,1])) + y2 = np.maximum(np.max(a[:,1]), np.max(b[:,1])) + if x1>=x2 or y1>=y2 or (x2-x1)<2 or (y2-y1)<2: + return 0. + else: + mask_w = np.int(np.ceil(x2-x1)) + mask_h = np.int(np.ceil(y2-y1)) + mask_a = np.zeros(shape=(mask_h, mask_w), dtype=np.uint8) + mask_b = np.zeros(shape=(mask_h, mask_w), dtype=np.uint8) + a[:,0] -= x1 + a[:,1] -= y1 + b[:,0] -= x1 + b[:,1] -= y1 + mask_a = cv2.fillPoly(mask_a, pts=np.asarray([a], 'int32'), color=1) + mask_b = cv2.fillPoly(mask_b, pts=np.asarray([b], 'int32'), color=1) + inter = np.logical_and(mask_a, mask_b).sum() + union = np.logical_or(mask_a, mask_b).sum() + iou = float(inter)/(float(union)+1e-12) + # print(iou) + # cv2.imshow('img1', np.uint8(mask_a*255)) + # cv2.imshow('img2', np.uint8(mask_b*255)) + # k = cv2.waitKey(0) + # if k==ord('q'): + # cv2.destroyAllWindows() + # exit() + return iou + +def draw_image(pts, image): + cen_pts = np.mean(pts, axis=0) + tt = pts[0, :] + rr = pts[1, :] + bb = pts[2, :] + ll = pts[3, :] + cv2.line(image, (int(cen_pts[0]), int(cen_pts[1])), (int(tt[0]), int(tt[1])), (0, 0, 255), 2, 1) + cv2.line(image, (int(cen_pts[0]), int(cen_pts[1])), (int(rr[0]), int(rr[1])), (255, 0, 255), 2, 1) + cv2.line(image, (int(cen_pts[0]), int(cen_pts[1])), (int(bb[0]), int(bb[1])), (0, 255, 0), 2, 1) + cv2.line(image, (int(cen_pts[0]), int(cen_pts[1])), (int(ll[0]), int(ll[1])), (255, 0, 0), 2, 1) + return image + + +def NMS_numpy_exboxes(exboxes, conf, nms_thresh=0.5, image=None): + if len(exboxes)==0: + return None + sorted_index = np.argsort(conf) # Ascending order + keep_index = [] + while len(sorted_index)>0: + curr_index = sorted_index[-1] + keep_index.append(curr_index) + if len(sorted_index)==1: + break + sorted_index = sorted_index[:-1] + IoU = [] + for index in sorted_index: + iou = calc_IoU(exboxes[index,:,:].copy(), exboxes[curr_index,:,:].copy()) + IoU.append(iou) + IoU = np.asarray(IoU, np.float32) + sorted_index = sorted_index[IoU<=nms_thresh] + return keep_index + + + +def NMS_numpy_bbox(bboxes, nms_thresh=0.5): + """ + bboxes: num_insts x 5 [x1,y1,x2,y2,conf] + """ + if len(bboxes)==0: + return None + x1 = bboxes[:,0] + y1 = bboxes[:,1] + x2 = bboxes[:,2] + y2 = bboxes[:,3] + conf = bboxes[:,4] + area_all = (x2-x1)*(y2-y1) + sorted_index = np.argsort(conf) # Ascending order + keep_index = [] + + while len(sorted_index)>0: + # get the last biggest values + curr_index = sorted_index[-1] + keep_index.append(curr_index) + if len(sorted_index)==1: + break + # pop the value + sorted_index = sorted_index[:-1] + # get the remaining boxes + yy1 = np.take(y1, indices=sorted_index) + xx1 = np.take(x1, indices=sorted_index) + yy2 = np.take(y2, indices=sorted_index) + xx2 = np.take(x2, indices=sorted_index) + # get the intersection box + yy1 = np.maximum(yy1, y1[curr_index]) + xx1 = np.maximum(xx1, x1[curr_index]) + yy2 = np.minimum(yy2, y2[curr_index]) + xx2 = np.minimum(xx2, x2[curr_index]) + # calculate IoU + w = xx2-xx1 + h = yy2-yy1 + w = np.maximum(0., w) + h = np.maximum(0., h) + inter = w*h + rem_areas = np.take(area_all, indices=sorted_index) + union = (rem_areas-inter)+area_all[curr_index] + IoU = inter/union + sorted_index = sorted_index[IoU<=nms_thresh] + + return keep_index diff --git a/resize_image.py b/resize_image.py new file mode 100644 index 0000000..7d9be9f --- /dev/null +++ b/resize_image.py @@ -0,0 +1,42 @@ +#coding=utf-8 + +import cv2 +# import numpy as np +# from PIL import Image, ImageDraw, ImageFont +# +# # 当前目录读取一张图片(499Kb,1920*1080) +# img = cv.imread('hintersee01.jpg') +# +# # 压缩图片(226Kb) +# cv.imwrite('temp/compress1.jpg', img, [cv.IMWRITE_JPEG_QUALITY, 50]) +# +# # 调整长宽(长宽指定数值,非等比例缩放时图片会变形) +# img2 = cv.resize(img, (500,500), interpolation=cv.INTER_CUBIC) +# cv.imwrite('temp/resize2.jpg', img2) +# +# # 调整长宽(长宽各调整为原来的一半,即 0.5) +# img3 = cv.resize(img, (0,0), fx=0.5, fy=0.5, interpolation=cv.INTER_CUBIC) +# cv.imwrite('temp/resize3.jpg', img3) + + +## 遍历一个文件夹下的所有图像 +def bianli_pics(path1,path2): + import os + img_folder = path1 + img_list = [os.path.join(nm) for nm in os.listdir(img_folder) if nm[-3:] in ['jpg', 'png', 'gif']] + ## print(img_list) 将所有图像遍历并存入一个列表 + ## ['test_14.jpg', 'test_15.jpg', 'test_9.jpg', 'test_17.jpg', 'test_16.jpg'] + for i in img_list: + path = os.path.join(path1, i) + ## print(path) + ## ./input/test_14.jpg + ## ./input/test_15.jpg + image = cv2.imread(path) ## 逐个读取 + img2 = cv2.resize(image, (1920, 1080), interpolation=cv2.INTER_CUBIC) + # img2 = cv2.resize(image, (960, 540), interpolation=cv2.INTER_CUBIC) + cv2.imwrite(path2+i, img2) + print('第',i) +if __name__ == "__main__": + path1 = "./dataPath/images" + path2 = "./dataPath/images3/" + bianli_pics(path1,path2) diff --git a/split_txt.py b/split_txt.py new file mode 100644 index 0000000..addb1dc --- /dev/null +++ b/split_txt.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +import os +import random + +# obb data split +annfilepath=r'./dataPath/labelTxt/' +saveBasePath=r'./dataPath/' +train_percent=0.9 +total_file = os.listdir(annfilepath) +num=len(total_file) +list=range(num) +tr=int(num*train_percent) +train=random.sample(list,tr) +ftrain = open(os.path.join(saveBasePath,'train.txt'), 'w') +fval = open(os.path.join(saveBasePath,'val.txt'), 'w') +for i in list: + name=total_file[i].split('.')[0]+'\n' + if i in train: + ftrain.write(name) + else: + fval.write(name) +ftrain.close() +fval.close() +print("train size",tr) +print("valid size",num-tr) diff --git a/test.py b/test.py new file mode 100644 index 0000000..14d5cb2 --- /dev/null +++ b/test.py @@ -0,0 +1,225 @@ +import torch +import numpy as np +import cv2 +import time +import os +import matplotlib.pyplot as plt +import func_utils +import time + +def apply_mask(image, mask, alpha=0.5): + """Apply the given mask to the image. + """ + color = np.random.rand(3) + for c in range(3): + image[:, :, c] = np.where(mask == 1, + image[:, :, c] * + (1 - alpha) + alpha * color[c] * 255, + image[:, :, c]) + return image + +if not os.path.exists('output'): + os.mkdir('output') +saveDir = 'output' + +class TestModule(object): + def __init__(self, dataset, num_classes, model, decoder): + torch.manual_seed(317) + self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.dataset = dataset + self.num_classes = num_classes + self.model = model + self.decoder = decoder + + def load_model(self, model, resume): + checkpoint = torch.load(resume, map_location=lambda storage, loc: storage) + print('loaded weights from {}, epoch {}'.format(resume, checkpoint['epoch'])) + state_dict_ = checkpoint['model_state_dict'] + model.load_state_dict(state_dict_, strict=True) + return model + + def map_mask_to_image(self, mask, img, color=None): + if color is None: + color = np.random.rand(3) + mask = np.repeat(mask[:, :, np.newaxis], 3, axis=2) + mskd = img * mask + clmsk = np.ones(mask.shape) * mask + clmsk[:, :, 0] = clmsk[:, :, 0] * color[0] * 256 + clmsk[:, :, 1] = clmsk[:, :, 1] * color[1] * 256 + clmsk[:, :, 2] = clmsk[:, :, 2] * color[2] * 256 + img = img + 1. * clmsk - 1. * mskd + return np.uint8(img) + + def imshow_heatmap(self, pr_dec, images): + wh = pr_dec['wh'] + hm = pr_dec['hm'] + cls_theta = pr_dec['cls_theta'] + wh_w = wh[0, 0, :, :].data.cpu().numpy() + wh_h = wh[0, 1, :, :].data.cpu().numpy() + hm = hm[0, 0, :, :].data.cpu().numpy() + cls_theta = cls_theta[0, 0, :, :].data.cpu().numpy() + images = np.transpose((images.squeeze(0).data.cpu().numpy() + 0.5) * 255, (1, 2, 0)).astype(np.uint8) + wh_w = cv2.resize(wh_w, (images.shape[1], images.shape[0])) + wh_h = cv2.resize(wh_h, (images.shape[1], images.shape[0])) + hm = cv2.resize(hm, (images.shape[1], images.shape[0])) + fig = plt.figure(1) + ax1 = fig.add_subplot(2, 3, 1) + ax1.set_xlabel('width') + ax1.imshow(wh_w) + ax2 = fig.add_subplot(2, 3, 2) + ax2.set_xlabel('height') + ax2.imshow(wh_h) + ax3 = fig.add_subplot(2, 3, 3) + ax3.set_xlabel('center hm') + ax3.imshow(hm) + ax5 = fig.add_subplot(2, 3, 5) + ax5.set_xlabel('input image') + ax5.imshow(cls_theta) + ax6 = fig.add_subplot(2, 3, 6) + ax6.set_xlabel('input image') + ax6.imshow(images) + plt.savefig('heatmap.png') + + + def test(self, args, down_ratio): + + save_path = 'weights_'+args.dataset + self.model = self.load_model(self.model, os.path.join(save_path, args.resume)) + self.model = self.model.to(self.device) + self.model.eval() + + t1 = time.time() + dataset_module = self.dataset[args.dataset] + dsets = dataset_module(data_dir=args.data_dir, + phase='test', + input_h=args.input_h, + input_w=args.input_w, + down_ratio=down_ratio) + data_loader = torch.utils.data.DataLoader(dsets, + batch_size=1, + shuffle=False, + num_workers=1, + pin_memory=True) + t2 = time.time() + total_time = [] + for cnt, data_dict in enumerate(data_loader): + + image = data_dict['image'][0].to(self.device) #布置到cuda上 + img_id = data_dict['img_id'][0] + print('processing {}/{} image ...'.format(cnt, len(data_loader))) + # begin_time = time.time() + t4 = time.time() + with torch.no_grad(): + pr_decs = self.model(image) + + #self.imshow_heatmap(pr_decs[2], image) + + torch.cuda.synchronize(self.device) #异步变同步? + decoded_pts = [] + decoded_scores = [] + predictions = self.decoder.ctdet_decode(pr_decs) + pts0, scores0 = func_utils.decode_prediction(predictions, dsets, args, img_id, down_ratio) + decoded_pts.append(pts0) + decoded_scores.append(scores0) + t5 = time.time() + #nms + results = {cat:[] for cat in dsets.category} + # '''这里啊 + for cat in dsets.category: + if cat == 'background': + continue + pts_cat = [] + scores_cat = [] + for pts0, scores0 in zip(decoded_pts, decoded_scores): + pts_cat.extend(pts0[cat]) + scores_cat.extend(scores0[cat]) + pts_cat = np.asarray(pts_cat, np.float32) + scores_cat = np.asarray(scores_cat, np.float32) + if pts_cat.shape[0]: + nms_results = func_utils.non_maximum_suppression(pts_cat, scores_cat) + results[cat].extend(nms_results) + + # end_time = time.time() + # total_time.append(end_time-begin_time) + + #""" + ori_image = dsets.load_image(cnt) + height, width, _ = ori_image.shape + + # 这里啊''' + + # ori_image = cv2.resize(ori_image, (args.input_w, args.input_h)) + # ori_image = cv2.resize(ori_image, (args.input_w//args.down_ratio, args.input_h//args.down_ratio)) + #nms + for cat in dsets.category: + if cat == 'background': + continue + result = results[cat] + for pred in result: + score = pred[-1] + tl = np.asarray([pred[0], pred[1]], np.float32) + tr = np.asarray([pred[2], pred[3]], np.float32) + br = np.asarray([pred[4], pred[5]], np.float32) + bl = np.asarray([pred[6], pred[7]], np.float32) + + # tt = (np.asarray(tl, np.float32) + np.asarray(tr, np.float32)) / 2 + # rr = (np.asarray(tr, np.float32) + np.asarray(br, np.float32)) / 2 + # bb = (np.asarray(bl, np.float32) + np.asarray(br, np.float32)) / 2 + # ll = (np.asarray(tl, np.float32) + np.asarray(bl, np.float32)) / 2 + + box = np.asarray([tl, tr, br, bl], np.float32) + cen_pts = np.mean(box, axis=0) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(tt[0]), int(tt[1])), (0,0,255),1,1) #原来 + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(rr[0]), int(rr[1])), (255,0,255),1,1) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(bb[0]), int(bb[1])), (0,255,0),1,1) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(ll[0]), int(ll[1])), (255,0,0),1,1) + + cv2.circle(ori_image, (int(cen_pts[0]), int(cen_pts[1])), 20, (0, 0,255), -1) #绘制实心圆 + + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(tl[0]), int(tl[1])), (0,0,255),1,1) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(tr[0]), int(tr[1])), (255,0,255),1,1) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(br[0]), int(br[1])), (0,255,0),1,1) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(bl[0]), int(bl[1])), (255,0,0),1,1) + # ori_image = cv2.drawContours(ori_image, [np.int0(box)], -1, (255,0,255),1,1) + ori_image = cv2.drawContours(ori_image, [np.int0(box)], -1, (255,0,255),3,1) + # box = cv2.boxPoints(cv2.minAreaRect(box)) + # ori_image = cv2.drawContours(ori_image, [np.int0(box)], -1, (0,255,0),1,1) + # cv2.putText(ori_image, '{:.2f} {}'.format(score, cat), (int(box[1][0]), int(box[1][1])), + # cv2.FONT_HERSHEY_COMPLEX, 0.5, (0,255,255), 1,1) + cv2.putText(ori_image, '{:.2f} {}'.format(score, cat), (int(box[1][0]), int(box[1][1])), + cv2.FONT_HERSHEY_COMPLEX, 1, (78,110,240), 2,1) + t6 = time.time() + # print(f'one picture. ({(1E3 * (t5 - t4)):.1f}ms) Inference, ({(1E3 * (t6 - t5)):.1f}ms) NMS,') + + + if args.dataset == 'hrsc': + gt_anno = dsets.load_annotation(cnt) + for pts_4 in gt_anno['pts']: + bl = pts_4[0, :] + tl = pts_4[1, :] + tr = pts_4[2, :] + br = pts_4[3, :] + cen_pts = np.mean(pts_4, axis=0) + box = np.asarray([bl, tl, tr, br], np.float32) + box = np.int0(box) + cv2.drawContours(ori_image, [box], 0, (255, 255, 255), 1) + # imgName = os.path.basename(img_id) + '.png' + imgName = os.path.basename(img_id) + '.jpg' + saveFile = os.path.join(saveDir, imgName) + cv2.imwrite(saveFile, ori_image,[cv2.IMWRITE_JPEG_QUALITY, 10]) + # cv2.imwrite(saveFile, ori_image,[cv2.IMWRITE_PNG_COMPRESSION, 10]) + t7 = time.time() + print(f'one picture. ({(1E3 * (t5 - t4)):.1f}ms) Inference, ({(1E3 * (t6 - t5)):.1f}ms) NMS,({(1E3 * (t7 - t6)):.1f}ms) save image') + print(saveFile) + + # cv2.imshow('pr_image', ori_image) + # k = cv2.waitKey(0) & 0xFF + # if k == ord('q'): + # cv2.destroyAllWindows() + # exit() + #""" + t3 = time.time() + # total_time = total_time[1:] + # print('avg time is {}'.format(np.mean(total_time))) + # print('FPS is {}'.format(1./np.mean(total_time))) + print(f'Done. ({(1E3 * (t3 - t2)):.1f}ms) Inference, ({(1E3 * (t2 - t1)):.1f}ms) load data,') diff --git a/test20230320.py b/test20230320.py new file mode 100644 index 0000000..335bfe9 --- /dev/null +++ b/test20230320.py @@ -0,0 +1,220 @@ +import torch +import numpy as np +import cv2 +import time +import os +import matplotlib.pyplot as plt +import func_utils +import time + +def apply_mask(image, mask, alpha=0.5): + """Apply the given mask to the image. + """ + color = np.random.rand(3) + for c in range(3): + image[:, :, c] = np.where(mask == 1, + image[:, :, c] * + (1 - alpha) + alpha * color[c] * 255, + image[:, :, c]) + return image + +if not os.path.exists('output'): + os.mkdir('output') +saveDir = 'output' + +class TestModule(object): + def __init__(self, dataset, num_classes, model, decoder): + torch.manual_seed(317) + self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.dataset = dataset + self.num_classes = num_classes + self.model = model + self.decoder = decoder + + def load_model(self, model, resume): + checkpoint = torch.load(resume, map_location=lambda storage, loc: storage) + print('loaded weights from {}, epoch {}'.format(resume, checkpoint['epoch'])) + state_dict_ = checkpoint['model_state_dict'] + model.load_state_dict(state_dict_, strict=True) + return model + + def map_mask_to_image(self, mask, img, color=None): + if color is None: + color = np.random.rand(3) + mask = np.repeat(mask[:, :, np.newaxis], 3, axis=2) + mskd = img * mask + clmsk = np.ones(mask.shape) * mask + clmsk[:, :, 0] = clmsk[:, :, 0] * color[0] * 256 + clmsk[:, :, 1] = clmsk[:, :, 1] * color[1] * 256 + clmsk[:, :, 2] = clmsk[:, :, 2] * color[2] * 256 + img = img + 1. * clmsk - 1. * mskd + return np.uint8(img) + + def imshow_heatmap(self, pr_dec, images): + wh = pr_dec['wh'] + hm = pr_dec['hm'] + cls_theta = pr_dec['cls_theta'] + wh_w = wh[0, 0, :, :].data.cpu().numpy() + wh_h = wh[0, 1, :, :].data.cpu().numpy() + hm = hm[0, 0, :, :].data.cpu().numpy() + cls_theta = cls_theta[0, 0, :, :].data.cpu().numpy() + images = np.transpose((images.squeeze(0).data.cpu().numpy() + 0.5) * 255, (1, 2, 0)).astype(np.uint8) + wh_w = cv2.resize(wh_w, (images.shape[1], images.shape[0])) + wh_h = cv2.resize(wh_h, (images.shape[1], images.shape[0])) + hm = cv2.resize(hm, (images.shape[1], images.shape[0])) + fig = plt.figure(1) + ax1 = fig.add_subplot(2, 3, 1) + ax1.set_xlabel('width') + ax1.imshow(wh_w) + ax2 = fig.add_subplot(2, 3, 2) + ax2.set_xlabel('height') + ax2.imshow(wh_h) + ax3 = fig.add_subplot(2, 3, 3) + ax3.set_xlabel('center hm') + ax3.imshow(hm) + ax5 = fig.add_subplot(2, 3, 5) + ax5.set_xlabel('input image') + ax5.imshow(cls_theta) + ax6 = fig.add_subplot(2, 3, 6) + ax6.set_xlabel('input image') + ax6.imshow(images) + plt.savefig('heatmap.png') + + + def test(self, args, down_ratio): + + save_path = 'weights_'+args.dataset + self.model = self.load_model(self.model, os.path.join(save_path, args.resume)) + self.model = self.model.to(self.device) + self.model.eval() + + t1 = time.time() + dataset_module = self.dataset[args.dataset] + dsets = dataset_module(data_dir=args.data_dir, + phase='test', + input_h=args.input_h, + input_w=args.input_w, + down_ratio=down_ratio) + data_loader = torch.utils.data.DataLoader(dsets, + batch_size=1, + shuffle=False, + num_workers=1, + pin_memory=True) + t2 = time.time() + total_time = [] + for cnt, data_dict in enumerate(data_loader): + t4=time.time() + image = data_dict['image'][0].to(self.device) + img_id = data_dict['img_id'][0] + print('processing {}/{} image ...'.format(cnt, len(data_loader))) + begin_time = time.time() + with torch.no_grad(): + pr_decs = self.model(image) + + #self.imshow_heatmap(pr_decs[2], image) + + torch.cuda.synchronize(self.device) + decoded_pts = [] + decoded_scores = [] + predictions = self.decoder.ctdet_decode(pr_decs) + pts0, scores0 = func_utils.decode_prediction(predictions, dsets, args, img_id, down_ratio) + decoded_pts.append(pts0) + decoded_scores.append(scores0) + t5 = time.time() + #nms + results = {cat:[] for cat in dsets.category} + for cat in dsets.category: + if cat == 'background': + continue + pts_cat = [] + scores_cat = [] + for pts0, scores0 in zip(decoded_pts, decoded_scores): + pts_cat.extend(pts0[cat]) + scores_cat.extend(scores0[cat]) + pts_cat = np.asarray(pts_cat, np.float32) + scores_cat = np.asarray(scores_cat, np.float32) + if pts_cat.shape[0]: + nms_results = func_utils.non_maximum_suppression(pts_cat, scores_cat) + results[cat].extend(nms_results) + + end_time = time.time() + total_time.append(end_time-begin_time) + + #""" + ori_image = dsets.load_image(cnt) + height, width, _ = ori_image.shape + # ori_image = cv2.resize(ori_image, (args.input_w, args.input_h)) + # ori_image = cv2.resize(ori_image, (args.input_w//args.down_ratio, args.input_h//args.down_ratio)) + #nms + for cat in dsets.category: + if cat == 'background': + continue + result = results[cat] + for pred in result: + score = pred[-1] + tl = np.asarray([pred[0], pred[1]], np.float32) + tr = np.asarray([pred[2], pred[3]], np.float32) + br = np.asarray([pred[4], pred[5]], np.float32) + bl = np.asarray([pred[6], pred[7]], np.float32) + + tt = (np.asarray(tl, np.float32) + np.asarray(tr, np.float32)) / 2 + rr = (np.asarray(tr, np.float32) + np.asarray(br, np.float32)) / 2 + bb = (np.asarray(bl, np.float32) + np.asarray(br, np.float32)) / 2 + ll = (np.asarray(tl, np.float32) + np.asarray(bl, np.float32)) / 2 + + box = np.asarray([tl, tr, br, bl], np.float32) + cen_pts = np.mean(box, axis=0) + cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(tt[0]), int(tt[1])), (0,0,255),1,1) #原来 + cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(rr[0]), int(rr[1])), (255,0,255),1,1) + cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(bb[0]), int(bb[1])), (0,255,0),1,1) + cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(ll[0]), int(ll[1])), (255,0,0),1,1) + + # cv2.circle(ori_image, (320, 240), 5, (0, 0, 255), -1) + + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(tl[0]), int(tl[1])), (0,0,255),1,1) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(tr[0]), int(tr[1])), (255,0,255),1,1) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(br[0]), int(br[1])), (0,255,0),1,1) + # cv2.line(ori_image, (int(cen_pts[0]), int(cen_pts[1])), (int(bl[0]), int(bl[1])), (255,0,0),1,1) + # ori_image = cv2.drawContours(ori_image, [np.int0(box)], -1, (255,0,255),1,1) + ori_image = cv2.drawContours(ori_image, [np.int0(box)], -1, (255,0,255),3,1) + # box = cv2.boxPoints(cv2.minAreaRect(box)) + # ori_image = cv2.drawContours(ori_image, [np.int0(box)], -1, (0,255,0),1,1) + # cv2.putText(ori_image, '{:.2f} {}'.format(score, cat), (int(box[1][0]), int(box[1][1])), + # cv2.FONT_HERSHEY_COMPLEX, 0.5, (0,255,255), 1,1) + cv2.putText(ori_image, '{:.2f} {}'.format(score, cat), (int(box[1][0]), int(box[1][1])), + cv2.FONT_HERSHEY_COMPLEX, 2, (78,110,240), 3,1) + t6 = time.time() + # print(f'one picture. ({(1E3 * (t5 - t4)):.1f}ms) Inference, ({(1E3 * (t6 - t5)):.1f}ms) NMS,') + + + if args.dataset == 'hrsc': + gt_anno = dsets.load_annotation(cnt) + for pts_4 in gt_anno['pts']: + bl = pts_4[0, :] + tl = pts_4[1, :] + tr = pts_4[2, :] + br = pts_4[3, :] + cen_pts = np.mean(pts_4, axis=0) + box = np.asarray([bl, tl, tr, br], np.float32) + box = np.int0(box) + cv2.drawContours(ori_image, [box], 0, (255, 255, 255), 1) + # imgName = os.path.basename(img_id) + '.png' + imgName = os.path.basename(img_id) + '.jpg' + saveFile = os.path.join(saveDir, imgName) + cv2.imwrite(saveFile, ori_image,[cv2.IMWRITE_JPEG_QUALITY, 10]) + # cv2.imwrite(saveFile, ori_image,[cv2.IMWRITE_PNG_COMPRESSION, 10]) + t7 = time.time() + print(f'one picture. ({(1E3 * (t5 - t4)):.1f}ms) Inference, ({(1E3 * (t6 - t5)):.1f}ms) NMS,({(1E3 * (t7 - t6)):.1f}ms) save image') + print(saveFile) + + # cv2.imshow('pr_image', ori_image) + # k = cv2.waitKey(0) & 0xFF + # if k == ord('q'): + # cv2.destroyAllWindows() + # exit() + #""" + t3 = time.time() + # total_time = total_time[1:] + # print('avg time is {}'.format(np.mean(total_time))) + # print('FPS is {}'.format(1./np.mean(total_time))) + print(f'Done. ({(1E3 * (t3 - t2)):.1f}ms) Inference, ({(1E3 * (t2 - t1)):.1f}ms) load data,') diff --git a/train.py b/train.py new file mode 100644 index 0000000..df265a8 --- /dev/null +++ b/train.py @@ -0,0 +1,194 @@ +import torch +import torch.nn as nn +import os +import numpy as np +import loss +import cv2 +import func_utils + + +def collater(data): + out_data_dict = {} + for name in data[0]: + out_data_dict[name] = [] + for sample in data: + for name in sample: + out_data_dict[name].append(torch.from_numpy(sample[name])) + for name in out_data_dict: + out_data_dict[name] = torch.stack(out_data_dict[name], dim=0) + return out_data_dict + +class TrainModule(object): + def __init__(self, dataset, num_classes, model, decoder, down_ratio): + torch.manual_seed(317) + self.dataset = dataset + self.dataset_phase = {'dota': ['train'], + 'hrsc': ['train', 'test']} + self.num_classes = num_classes + self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.model = model + self.decoder = decoder + self.down_ratio = down_ratio + + def save_model(self, path, epoch, model, optimizer): + if isinstance(model, torch.nn.DataParallel): + state_dict = model.module.state_dict() + else: + state_dict = model.state_dict() + torch.save({ + 'epoch': epoch, + 'model_state_dict': state_dict, + 'optimizer_state_dict': optimizer.state_dict(), + # 'loss': loss + }, path) + + def load_model(self, model, optimizer, resume, strict=True): + checkpoint = torch.load(resume, map_location=lambda storage, loc: storage) + print('loaded weights from {}, epoch {}'.format(resume, checkpoint['epoch'])) + state_dict_ = checkpoint['model_state_dict'] + state_dict = {} + for k in state_dict_: + if k.startswith('module') and not k.startswith('module_list'): + state_dict[k[7:]] = state_dict_[k] + else: + state_dict[k] = state_dict_[k] + model_state_dict = model.state_dict() + if not strict: + for k in state_dict: + if k in model_state_dict: + if state_dict[k].shape != model_state_dict[k].shape: + print('Skip loading parameter {}, required shape{}, ' \ + 'loaded shape{}.'.format(k, model_state_dict[k].shape, state_dict[k].shape)) + state_dict[k] = model_state_dict[k] + else: + print('Drop parameter {}.'.format(k)) + for k in model_state_dict: + if not (k in state_dict): + print('No param {}.'.format(k)) + state_dict[k] = model_state_dict[k] + model.load_state_dict(state_dict, strict=False) + optimizer.load_state_dict(checkpoint['optimizer_state_dict']) + for state in optimizer.state.values(): + for k, v in state.items(): + if isinstance(v, torch.Tensor): + state[k] = v.cuda() + epoch = checkpoint['epoch'] + # loss = checkpoint['loss'] + return model, optimizer, epoch + + def train_network(self, args): + + self.optimizer = torch.optim.Adam(self.model.parameters(), args.init_lr) + self.scheduler = torch.optim.lr_scheduler.ExponentialLR(self.optimizer, gamma=0.96, last_epoch=-1) + save_path = 'weights_'+args.dataset + start_epoch = 1 + + # add resume part for continuing training when break previously, 10-16-2020 + if args.resume_train: + self.model, self.optimizer, start_epoch = self.load_model(self.model, + self.optimizer, + args.resume_train, + strict=True) + # end + + if not os.path.exists(save_path): + os.mkdir(save_path) + if args.ngpus>1: + if torch.cuda.device_count() > 1: + print("Let's use", torch.cuda.device_count(), "GPUs!") + # dim = 0 [30, xxx] -> [10, ...], [10, ...], [10, ...] on 3 GPUs + self.model = nn.DataParallel(self.model) + self.model.to(self.device) + + criterion = loss.LossAll() + print('Setting up data...') + + dataset_module = self.dataset[args.dataset] + + dsets = {x: dataset_module(data_dir=args.data_dir, + phase=x, + input_h=args.input_h, + input_w=args.input_w, + down_ratio=self.down_ratio) + for x in self.dataset_phase[args.dataset]} + + dsets_loader = {} + dsets_loader['train'] = torch.utils.data.DataLoader(dsets['train'], + batch_size=args.batch_size, + shuffle=True, + num_workers=args.num_workers, + pin_memory=True, + drop_last=True, + collate_fn=collater) + + print('Starting training...') + train_loss = [] + ap_list = [] + for epoch in range(start_epoch, args.num_epoch+1): + print('-'*10) + print('Epoch: {}/{} '.format(epoch, args.num_epoch)) + epoch_loss = self.run_epoch(phase='train', + data_loader=dsets_loader['train'], + criterion=criterion) + train_loss.append(epoch_loss) + self.scheduler.step(epoch) + + np.savetxt(os.path.join(save_path, 'train_loss.txt'), train_loss, fmt='%.6f') + + if epoch % 5 == 0 or epoch > 20: + self.save_model(os.path.join(save_path, 'model_{}.pth'.format(epoch)), + epoch, + self.model, + self.optimizer) + + if 'test' in self.dataset_phase[args.dataset] and epoch%5==0: + mAP = self.dec_eval(args, dsets['test']) + ap_list.append(mAP) + np.savetxt(os.path.join(save_path, 'ap_list.txt'), ap_list, fmt='%.6f') + + self.save_model(os.path.join(save_path, 'model_last.pth'), + epoch, + self.model, + self.optimizer) + + def run_epoch(self, phase, data_loader, criterion): + if phase == 'train': + self.model.train() + else: + self.model.eval() + running_loss = 0. + for data_dict in data_loader: + for name in data_dict: + data_dict[name] = data_dict[name].to(device=self.device, non_blocking=True) + if phase == 'train': + self.optimizer.zero_grad() + with torch.enable_grad(): + pr_decs = self.model(data_dict['input']) + loss = criterion(pr_decs, data_dict) + loss.backward() + self.optimizer.step() + else: + with torch.no_grad(): + pr_decs = self.model(data_dict['input']) + loss = criterion(pr_decs, data_dict) + + running_loss += loss.item() + epoch_loss = running_loss / len(data_loader) + print('{} loss: {}'.format(phase, epoch_loss)) + return epoch_loss + + + def dec_eval(self, args, dsets): + result_path = 'result_'+args.dataset + if not os.path.exists(result_path): + os.mkdir(result_path) + + self.model.eval() + func_utils.write_results(args, + self.model,dsets, + self.down_ratio, + self.device, + self.decoder, + result_path) + ap = dsets.dec_evaluation(result_path) + return ap \ No newline at end of file diff --git a/必看.log b/必看.log new file mode 100644 index 0000000..9cf6855 --- /dev/null +++ b/必看.log @@ -0,0 +1,17 @@ +用于训练倾斜框检测 + +1、\datasets\DOTA_devkit\dota-v1.5_evaluation_task3.py 为改后的求mAP文件。 yanzheng 文件夹里为mAP求值的格式 + +2、 dataPath下 images labelTxt 两个文件夹,再加上trainval.txt test.txt 由split_txt.py实现 + +3、change_jpg_2_png.py + +4、ctrbox_net.py中配置resnet网络18、34、50、101 + +5、dataset下dataset_dota.py 里图片png或jpg格式得调整下,只能一个。 + + +6、main用于训练、验证、检测 +./weights_dota 存放训练后的权重 + + \ No newline at end of file