From e3a1d6c662757febff4736131a4f1f74a5659e36 Mon Sep 17 00:00:00 2001 From: DTheLegend Date: Thu, 9 Feb 2023 23:51:20 +0000 Subject: [PATCH] Training works --- cli/fcos/__main__.py | 4 ++ cli/poetry.lock | 38 ++++++++++++++++++- core/fcos/core/mAP/functions.py | 27 +++++++------- core/pyproject.toml | 2 +- train/fcos/train/train.py | 66 ++++++++++++++++++--------------- train/poetry.lock | 35 ++++++++++++++++- train/pyproject.toml | 3 +- 7 files changed, 127 insertions(+), 48 deletions(-) diff --git a/cli/fcos/__main__.py b/cli/fcos/__main__.py index f324eb8..e33169a 100644 --- a/cli/fcos/__main__.py +++ b/cli/fcos/__main__.py @@ -23,6 +23,8 @@ train_parser.add_argument('--optimizer_name', type=str, default="Adam", required=False) train_parser.add_argument('--save_file', type=pathlib.Path, required=False) +predict_parser = sub_parsers.add_parser("predict") + args = parser.parse_args() if args.command == "train": @@ -32,3 +34,5 @@ train(**vars(args)) except ImportError: print("Train Module not included.") +elif args.command == "predict": + pass diff --git a/cli/poetry.lock b/cli/poetry.lock index 6e12402..38cc2f0 100644 --- a/cli/poetry.lock +++ b/cli/poetry.lock @@ -110,9 +110,21 @@ files = [ {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"}, ] +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +category = "main" +optional = true +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + [[package]] name = "fcos-core" -version = "0.1.4" +version = "0.1.7" description = "" category = "main" optional = false @@ -131,7 +143,7 @@ url = "../core" [[package]] name = "fcos-train" -version = "0.1.6" +version = "0.1.7" description = "" category = "main" optional = true @@ -141,6 +153,7 @@ develop = false [package.dependencies] fcos-core = {path = "../core"} +tqdm = "^4.64.1" [package.source] type = "directory" @@ -379,6 +392,27 @@ scipy = ["scipy"] [package.source] type = "url" url = "https://download.pytorch.org/whl/cu117/torchvision-0.14.1%2Bcu117-cp310-cp310-win_amd64.whl" +[[package]] +name = "tqdm" +version = "4.64.1" +description = "Fast, Extensible Progress Meter" +category = "main" +optional = true +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +files = [ + {file = "tqdm-4.64.1-py2.py3-none-any.whl", hash = "sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1"}, + {file = "tqdm-4.64.1.tar.gz", hash = "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "typing-extensions" version = "4.4.0" diff --git a/core/fcos/core/mAP/functions.py b/core/fcos/core/mAP/functions.py index c1cc470..fc43820 100644 --- a/core/fcos/core/mAP/functions.py +++ b/core/fcos/core/mAP/functions.py @@ -124,7 +124,7 @@ def calculate_mAP_gt(box, gt_box,threshold=0.5): iou = compute_iou(gt_box[1:5], box[2:6]) if iou >= threshold: TP = True - return (box[:2], TP) + return (*box[:2], TP) def return_mAP(model, dataset, classes): model.cuda() @@ -136,26 +136,27 @@ def return_mAP(model, dataset, classes): # traverse dataset for image, tags in dataset: # get an image - cuda_image = image.cuda() + cuda_image = image.unsqueeze(0).cuda() # predict row = cuda_image.shape[2] col = cuda_image.shape[3] confs, locs, centers = model(cuda_image) - boxes = fcos_to_boxes(confs, locs, centers, row, col) + boxes = fcos_to_boxes(classes, confs, locs, centers, row, col) for gt_box in tags: - gt_count_all[gt_box[0]] += 1 + box_class = classes[int(gt_box[0].item())] + gt_count_all[box_class] += 1 for box in boxes: if(box[0] == gt_box[0]): - mAP_all[box[0]].append(calculate_mAP_gt(box, gt_box)) + mAP_all[box_class].append(calculate_mAP_gt(box, gt_box)) mAP = 0 - # p = 0 - # r = 0 - for c in mAP_all: + mp = 0 + mr = 0 + for c in classes: p, r, ap = compute_mAP(mAP_all[c], gt_count_all[c]) mAP += ap * gt_count_all[c] - # p += p * gt_count_all[c] - # r += r * gt_count_all[c] + mp += p * gt_count_all[c] + mr += r * gt_count_all[c] mAP /= sum(gt_count_all.values()) - # p /= sum(gt_count_all.values()) - # r /= sum(gt_count_all.values()) - return mAP + mp /= sum(gt_count_all.values()) + mr /= sum(gt_count_all.values()) + return mAP, mp, mr diff --git a/core/pyproject.toml b/core/pyproject.toml index 7e9f280..0a84bc8 100644 --- a/core/pyproject.toml +++ b/core/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "fcos-core" -version = "0.1.4" +version = "0.1.7" description = "" authors = ["DTheLegend "] readme = "README.md" diff --git a/train/fcos/train/train.py b/train/fcos/train/train.py index d3ddba5..93f4ab2 100644 --- a/train/fcos/train/train.py +++ b/train/fcos/train/train.py @@ -6,6 +6,8 @@ import os from fcos.core.mAP import return_mAP import torch +from tqdm import tqdm +from math import ceil # torch.manual_seed(1) #reproducible def train(weights, classfile, train_dataset, val_dataset, batch_size = 1, epoch = 1000, lr = 0.0001, ft_lr = 0.000001, start=0, weight_decay = 0.005, optimizer_name="Adam", save_file=False): @@ -22,17 +24,17 @@ def train(weights, classfile, train_dataset, val_dataset, batch_size = 1, epoch # apply hyper-parameters weight_p, bias_p, FT_weight_p, FT_bias_p, feat_weight_p, feat_bias_p = [], [], [], [], [], [] - for name, p in model.named_parameters(): + for name, mp in model.named_parameters(): if 'FT' in name: if 'bias' in name: - FT_bias_p += [p] + FT_bias_p += [mp] else: - FT_weight_p += [p] + FT_weight_p += [mp] else: if 'bias' in name: - bias_p += [p] + bias_p += [mp] else: - weight_p += [p] + weight_p += [mp] # initialize optimizer and loss function if optimizer_name == 'SGD': @@ -60,7 +62,7 @@ def train(weights, classfile, train_dataset, val_dataset, batch_size = 1, epoch dataset=train_dataset, # torch TensorDataset format batch_size=batch_size, # mini batch size shuffle=True, # shuffle the dataset - num_workers=2, # reading dataset by multi threads + num_workers=4, # reading dataset by multi threads collate_fn=FolderDataSetLoader.collate_fn ) # initialize maximum mAP @@ -68,27 +70,31 @@ def train(weights, classfile, train_dataset, val_dataset, batch_size = 1, epoch # training if not os.path.exists("module"): os.makedirs("module") - - for c_epoch in range(start, epoch): - # release a mini-batch data - for step, (images, tags) in enumerate(loader): - # read images and labels - device_image = images.to(train_device) - # obtain feature maps output by the model - confs, locs, centers = model(device_image) # .to(train_device) - # training - loss = loss_func(confs, locs, centers, tags, train_device) - optimizer.zero_grad() - loss.backward() - optimizer.step() - print('Epoch', c_epoch, 'Step:', step, '|train loss:%.4f' % loss) - - # evaluate the performance of current model - mAP = return_mAP(model, val_dataset, classes) - print('Epoch:', c_epoch, '|mAP: %.4f' % mAP) - # save if better - if mAP >= max_mAP: - if save_file: - torch.save(model.state_dict(), save_file) - max_mAP = mAP - + with tqdm(total=100, position=2, desc="Accuracy") as tqdm_accuracy, tqdm(total=100, position=3, desc="Recall") as tqdm_recall, tqdm(total=100, position=4, desc="Mean Average Precision") as tqdm_mAP: + for c_epoch in tqdm(range(start, epoch), position=0, desc="Epoch", leave=True): + # release a mini-batch data + with tqdm(enumerate(loader), total=ceil(len(train_dataset) / batch_size), unit_scale=batch_size, position=1, desc="Step", leave=True) as tdqm_enumerated_loader: + for step, (images, tags) in tdqm_enumerated_loader: + # read images and labels + device_image = images.to(train_device) + # obtain feature maps output by the model + confs, locs, centers = model(device_image) # .to(train_device) + # training + loss = loss_func(confs, locs, centers, tags, train_device) + optimizer.zero_grad() + loss.backward() + optimizer.step() + tqdm.write('Step: %d | train loss: %.4f' % (step, loss)) + tdqm_enumerated_loader.set_postfix(loss = '%.4f' % loss) + + # evaluate the performance of current model + mAP, mp, mr = return_mAP(model, val_dataset, classes) + tqdm_accuracy.update(mp * 100) + tqdm_recall.update(mr * 100) + tqdm_mAP.update(mAP * 100) + tqdm.write('Epoch: %d |mAP: %.4f' % (c_epoch, mAP)) + # save if better + if mAP >= max_mAP: + if save_file: + torch.save(model.state_dict(), save_file) + max_mAP = mAP diff --git a/train/poetry.lock b/train/poetry.lock index a3da865..c9af0e8 100644 --- a/train/poetry.lock +++ b/train/poetry.lock @@ -110,6 +110,18 @@ files = [ {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"}, ] +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + [[package]] name = "fcos-core" version = "0.1.4" @@ -480,6 +492,27 @@ typing-extensions = "*" [package.extras] scipy = ["scipy"] +[[package]] +name = "tqdm" +version = "4.64.1" +description = "Fast, Extensible Progress Meter" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +files = [ + {file = "tqdm-4.64.1-py2.py3-none-any.whl", hash = "sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1"}, + {file = "tqdm-4.64.1.tar.gz", hash = "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "typing-extensions" version = "4.4.0" @@ -527,4 +560,4 @@ test = ["pytest (>=3.0.0)"] [metadata] lock-version = "2.0" python-versions = "3.10.6" -content-hash = "1942ed2a62b94a03959b488c6a2ab46a520ac20da82ee767d67020c652e08a5d" +content-hash = "bf7a37253558dbe7a5f13d18d43b71a397ba80b9348578480c9e792543f2716d" diff --git a/train/pyproject.toml b/train/pyproject.toml index 4151e50..03a3044 100644 --- a/train/pyproject.toml +++ b/train/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "fcos-train" -version = "0.1.6" +version = "0.1.7" description = "" authors = ["DTheLegend "] readme = "README.md" @@ -9,6 +9,7 @@ packages = [{include = "fcos"}] [tool.poetry.dependencies] python = "3.10.6" fcos-core= {path = "../core"} +tqdm = "^4.64.1" [build-system]