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 0000000..5b3a911 Binary files /dev/null and b/__pycache__/decoder.cpython-38.pyc differ diff --git a/__pycache__/eval.cpython-38.pyc b/__pycache__/eval.cpython-38.pyc new file mode 100644 index 0000000..cda74a7 Binary files /dev/null and b/__pycache__/eval.cpython-38.pyc differ diff --git a/__pycache__/func_utils.cpython-38.pyc b/__pycache__/func_utils.cpython-38.pyc new file mode 100644 index 0000000..3022615 Binary files /dev/null and b/__pycache__/func_utils.cpython-38.pyc differ diff --git a/__pycache__/loss.cpython-38.pyc b/__pycache__/loss.cpython-38.pyc new file mode 100644 index 0000000..61f978a Binary files /dev/null and b/__pycache__/loss.cpython-38.pyc differ diff --git a/__pycache__/test.cpython-38.pyc b/__pycache__/test.cpython-38.pyc new file mode 100644 index 0000000..2e1b9b1 Binary files /dev/null and b/__pycache__/test.cpython-38.pyc differ diff --git a/__pycache__/train.cpython-38.pyc b/__pycache__/train.cpython-38.pyc new file mode 100644 index 0000000..7e3f60d Binary files /dev/null and b/__pycache__/train.cpython-38.pyc differ diff --git a/__pycache__/train.cpython-39.pyc b/__pycache__/train.cpython-39.pyc new file mode 100644 index 0000000..2098cfe Binary files /dev/null and b/__pycache__/train.cpython-39.pyc differ 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 0000000..efc7abb Binary files /dev/null and b/models/__pycache__/ctrbox_net.cpython-38.pyc differ diff --git a/models/__pycache__/model_parts.cpython-38.pyc b/models/__pycache__/model_parts.cpython-38.pyc new file mode 100644 index 0000000..757434c Binary files /dev/null and b/models/__pycache__/model_parts.cpython-38.pyc differ diff --git a/models/__pycache__/resnet.cpython-38.pyc b/models/__pycache__/resnet.cpython-38.pyc new file mode 100644 index 0000000..676bc0a Binary files /dev/null and b/models/__pycache__/resnet.cpython-38.pyc differ 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