Skip to content

Commit

Permalink
Merge pull request #19 from boostcampaitech3/feature/soft-voting
Browse files Browse the repository at this point in the history
Feature/soft voting
  • Loading branch information
JoonHyun814 authored May 4, 2022
2 parents e56942f + aabed64 commit 51c831a
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 80 deletions.
132 changes: 132 additions & 0 deletions mmsegmentation/soft_voting.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"import glob\n",
"import os\n",
"import pandas as pd\n",
"from tqdm import tqdm"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"624it [00:52, 11.78it/s]\n"
]
}
],
"source": [
"data_root = 'out'\n",
"path_list = ['test','psa_80k']\n",
"\n",
"pt_lists = []\n",
"for p in path_list:\n",
" pt_list = sorted(glob.glob(f'{data_root}/{p}/*.pt'))\n",
" pt_lists.append(pt_list)\n",
"\n",
"os.makedirs(f'{data_root}/essamble', exist_ok=True)\n",
"\n",
"for p in tqdm(zip(*pt_lists),total=len(pt_list)):\n",
" logits = list(map(lambda x: torch.load(x),p))\n",
" logit_sum = sum(logits)\n",
" result = torch.argmax(logit_sum,dim=1)\n",
" file_name = p[0].split('/')[-1].replace('.pt','.txt')\n",
" with open(f'{data_root}/essamble/{file_name}', 'w') as f:\n",
" for r in result[0]:\n",
" r_list = r.tolist()\n",
" f.write(' '.join(map(str,r_list)) + '\\n')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
" 3%|▎ | 17/624 [00:00<00:03, 162.46it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"making submission ...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 624/624 [00:04<00:00, 146.46it/s]\n"
]
}
],
"source": [
"print('\\nmaking submission ...')\n",
"dic = {\"image_id\":[],\"PredictionString\":[]}\n",
"for path in tqdm(sorted(glob.glob(f'{data_root}/essamble/*.txt'))):\n",
" image_id = path.replace(f'{data_root}/essamble/','').replace('_03_','_03/').replace('vt_','vt/').replace('.txt','.jpg')\n",
" with open(path, 'r') as f:\n",
" value_list = f.readlines()\n",
" new_value_list = []\n",
" for i in range(0,len(value_list),2):\n",
" value = value_list[i].split(' ')\n",
" value = ' '.join(value[0::2])\n",
" new_value_list.append(value)\n",
"\n",
" dic[\"image_id\"].append(image_id)\n",
" dic[\"PredictionString\"].append(' '.join(new_value_list))\n",
"\n",
"df = pd.DataFrame(dic)\n",
"df.to_csv(f'{data_root}/essamble/_submission.csv',index=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"interpreter": {
"hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe"
},
"kernelspec": {
"display_name": "Python 3.8.5 ('base')",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
189 changes: 109 additions & 80 deletions mmsegmentation/tools/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import shutil
import time
import warnings
from matplotlib.pyplot import axis

import mmcv
import torch
import torchvision
from mmcv.cnn.utils import revert_sync_batchnorm
from mmcv.parallel import MMDataParallel, MMDistributedDataParallel
from mmcv.runner import (get_dist_info, init_dist, load_checkpoint,
Expand Down Expand Up @@ -237,87 +239,114 @@ def main():
print('"PALETTE" not found in meta, use dataset.PALETTE instead')
model.PALETTE = dataset.PALETTE

# clean gpu memory when starting a new evaluation.
torch.cuda.empty_cache()
eval_kwargs = {} if args.eval_options is None else args.eval_options

# Deprecated
efficient_test = eval_kwargs.get('efficient_test', False)
if efficient_test:
warnings.warn(
'``efficient_test=True`` does not have effect in tools/test.py, '
'the evaluation and format results are CPU memory efficient by '
'default')

eval_on_format_results = (
args.eval is not None and 'cityscapes' in args.eval)
if eval_on_format_results:
assert len(args.eval) == 1, 'eval on format results is not ' \
'applicable for metrics other than ' \
'cityscapes'
if args.format_only or eval_on_format_results:
if 'imgfile_prefix' in eval_kwargs:
tmpdir = eval_kwargs['imgfile_prefix']
else:
tmpdir = '.format_cityscapes'
eval_kwargs.setdefault('imgfile_prefix', tmpdir)
mmcv.mkdir_or_exist(tmpdir)
else:
tmpdir = None

if not distributed:
warnings.warn(
'SyncBN is only supported with DDP. To be compatible with DP, '
'we convert SyncBN to BN. Please use dist_train.sh which can '
'avoid this error.')
if not torch.cuda.is_available():
assert digit_version(mmcv.__version__) >= digit_version('1.4.4'), \
'Please use MMCV >= 1.4.4 for CPU training!'
model = revert_sync_batchnorm(model)
model = MMDataParallel(model, device_ids=cfg.gpu_ids)
results = single_gpu_test(
model,
data_loader,
args.show,
args.show_dir,
False,
args.opacity,
pre_eval=args.eval is not None and not eval_on_format_results,
format_only=args.format_only or eval_on_format_results,
format_args=eval_kwargs)
else:
model = MMDistributedDataParallel(
model.cuda(),
device_ids=[torch.cuda.current_device()],
broadcast_buffers=False)
results = multi_gpu_test(
model,
data_loader,
args.tmpdir,
args.gpu_collect,
False,
pre_eval=args.eval is not None and not eval_on_format_results,
format_only=args.format_only or eval_on_format_results,
format_args=eval_kwargs)
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

rank, _ = get_dist_info()
if rank == 0:
if args.out:
warnings.warn(
'The behavior of ``args.out`` has been changed since MMSeg '
'v0.16, the pickled outputs could be seg map as type of '
'np.array, pre-eval results or file paths for '
'``dataset.format_results()``.')
print(f'\nwriting results to {args.out}')
mmcv.dump(results, args.out)
if args.eval:
eval_kwargs.update(metric=args.eval)
metric = dataset.evaluate(results, **eval_kwargs)
metric_dict = dict(config=args.config, metric=metric)
mmcv.dump(metric_dict, json_file, indent=4)
if tmpdir is not None and eval_on_format_results:
# remove tmp dir when cityscapes evaluation
shutil.rmtree(tmpdir)
model.eval()
model.to(device)
# Get logit
os.makedirs(args.show_dir,exist_ok=True)
for i in tqdm(range(len(dataset))):
sample = dataset[i]
img = sample['img'][0].data.unsqueeze(0).to(device)
img = torchvision.transforms.Resize((512,512))(img)
logit = model.whole_inference(img=img, img_meta=sample['img_metas'][0].data, rescale=False)
logit = torch.nn.Softmax(dim=None)(logit)
result = torch.argmax(logit,dim=1)

file_name = sample['img_metas'][0].data['filename'].split('/')[-1]
# file_name_ann = file_name.replace('.jpg','_ann.jpg')
file_name_pt = file_name.replace('.jpg','.pt')
file_name_txt = file_name.replace('.jpg','.txt')

# logit 저장
torch.save(logit,f'{args.show_dir}/{file_name_pt}')
# result 저장
with open(f'{args.show_dir}/{file_name_txt}','w') as f:
for r in result[0]:
f.write(' '.join(map(str,r.tolist())) + '\n')


# # clean gpu memory when starting a new evaluation.
# torch.cuda.empty_cache()
# eval_kwargs = {} if args.eval_options is None else args.eval_options

# # Deprecated
# efficient_test = eval_kwargs.get('efficient_test', False)
# if efficient_test:
# warnings.warn(
# '``efficient_test=True`` does not have effect in tools/test.py, '
# 'the evaluation and format results are CPU memory efficient by '
# 'default')

# eval_on_format_results = (
# args.eval is not None and 'cityscapes' in args.eval)
# if eval_on_format_results:
# assert len(args.eval) == 1, 'eval on format results is not ' \
# 'applicable for metrics other than ' \
# 'cityscapes'
# if args.format_only or eval_on_format_results:
# if 'imgfile_prefix' in eval_kwargs:
# tmpdir = eval_kwargs['imgfile_prefix']
# else:
# tmpdir = '.format_cityscapes'
# eval_kwargs.setdefault('imgfile_prefix', tmpdir)
# mmcv.mkdir_or_exist(tmpdir)
# else:
# tmpdir = None

# if not distributed:
# warnings.warn(
# 'SyncBN is only supported with DDP. To be compatible with DP, '
# 'we convert SyncBN to BN. Please use dist_train.sh which can '
# 'avoid this error.')
# if not torch.cuda.is_available():
# assert digit_version(mmcv.__version__) >= digit_version('1.4.4'), \
# 'Please use MMCV >= 1.4.4 for CPU training!'
# model = revert_sync_batchnorm(model)
# model = MMDataParallel(model, device_ids=cfg.gpu_ids)
# results = single_gpu_test(
# model,
# data_loader,
# args.show,
# args.show_dir,
# False,
# args.opacity,
# pre_eval=args.eval is not None and not eval_on_format_results,
# format_only=args.format_only or eval_on_format_results,
# format_args=eval_kwargs)
# else:
# model = MMDistributedDataParallel(
# model.cuda(),
# device_ids=[torch.cuda.current_device()],
# broadcast_buffers=False)
# results = multi_gpu_test(
# model,
# data_loader,
# args.tmpdir,
# args.gpu_collect,
# False,
# pre_eval=args.eval is not None and not eval_on_format_results,
# format_only=args.format_only or eval_on_format_results,
# format_args=eval_kwargs)

# rank, _ = get_dist_info()
# if rank == 0:
# if args.out:
# warnings.warn(
# 'The behavior of ``args.out`` has been changed since MMSeg '
# 'v0.16, the pickled outputs could be seg map as type of '
# 'np.array, pre-eval results or file paths for '
# '``dataset.format_results()``.')
# print(f'\nwriting results to {args.out}')
# mmcv.dump(results, args.out)
# if args.eval:
# eval_kwargs.update(metric=args.eval)
# metric = dataset.evaluate(results, **eval_kwargs)
# metric_dict = dict(config=args.config, metric=metric)
# mmcv.dump(metric_dict, json_file, indent=4)
# if tmpdir is not None and eval_on_format_results:
# # remove tmp dir when cityscapes evaluation
# shutil.rmtree(tmpdir)

print('\nmaking submission ...')
dic = {"image_id":[],"PredictionString":[]}
Expand Down

0 comments on commit 51c831a

Please sign in to comment.