Skip to content

Commit 37db810

Browse files
committed
fixup legacy codebase
1 parent 0fae683 commit 37db810

File tree

13 files changed

+178
-261
lines changed

13 files changed

+178
-261
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ logs*/
1111
*.pyc
1212
*.log
1313
*.avi
14+
15+
data/

README.md

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,84 +13,59 @@
1313
}
1414
```
1515

16-
**The code is under evaluation and update TBD. Deprecated information below.**
1716
Thanks [@shuuchen](https://github.com/shuuchen) for an all-in-one project, you may also refer to https://github.com/shuuchen/lsun-room-dsc!
1817

1918
## Prerequisite
2019

2120
- Python 3.6+
21+
- PyTorch 1.0+
2222
- [OneGAN](https://github.com/leVirve/OneGAN) == `0.3.2`, clone and checkout to that tag.
2323

2424
```bash
2525
git clone https://github.com/leVirve/OneGA
2626
git checkout 0.3.2
2727
```
2828

29+
- `pip install -e requirements.txt`
30+
2931
## Dataset
3032

31-
- Download dataset from http://lsun.cs.princeton.edu/2015.html#layout and put them in the following folders.
32-
- Unfortunately, the website hosted LSUN Layout challenge is down, you can only find them from the [web archive](https://web.archive.org/web/20190118150204/http://lsun.cs.princeton.edu/2016/), e.g. [layout.zip](https://web.archive.org/web/20170221111502/http://lsun.cs.princeton.edu/challenge/2015/roomlayout/data/layout.zip), [training.mat](https://web.archive.org/web/20180923231343/http://lsun.cs.princeton.edu/challenge/2015/roomlayout/data/training.mat), [validation.mat](https://web.archive.org/web/20180923231343/http://lsun.cs.princeton.edu/challenge/2015/roomlayout/data/validation.mat), [testing.mat](https://web.archive.org/web/20180923231343/http://lsun.cs.princeton.edu/challenge/2015/roomlayout/data/testing.mat).
33-
- However, the `image.zip` is too large and still unavailable to download from the web archive, fortunately, you can find them in https://github.com/liamw96/pytorch.room.layout#data. [@liamw96](https://github.com/liamw96) provides dataset image in the `lsun.zip` on Google drive!
33+
- Download dataset from http://lsun.cs.princeton.edu/2015.html#layout.
34+
- Unfortunately, the website hosted LSUN Layout challenge is down.
35+
- Find them from the [web archive](https://web.archive.org/web/20190118150204/http://lsun.cs.princeton.edu/2016/)
36+
- [layout.zip](https://web.archive.org/web/20170221111502/http://lsun.cs.princeton.edu/challenge/2015/roomlayout/data/layout.zip)
37+
- [training.mat](https://web.archive.org/web/20180923231343/http://lsun.cs.princeton.edu/challenge/2015/roomlayout/data/training.mat), [validation.mat](https://web.archive.org/web/20180923231343/http://lsun.cs.princeton.edu/challenge/2015/roomlayout/data/validation.mat) and [testing.mat](https://web.archive.org/web/20180923231343/http://lsun.cs.princeton.edu/challenge/2015/roomlayout/data/testing.mat).
38+
- However, the `image.zip` is too large and still unavailable to download from the web archive.
39+
- Fortunately, you can find them in https://github.com/liamw96/pytorch.room.layout#data. [@liamw96](https://github.com/liamw96) provides dataset image in the `lsun.zip` on Google drive!
3440

3541
## Usage
3642

3743
- Dataset
3844

39-
- Edit the root of path at `config.yml` Line#8 `folder`.
40-
- Put `LSUN Room Layout Dataset` into folder `${folder}` relative to this project.
45+
- Put `LSUN Room Layout Dataset` into folder `./data/lsun_room`.
4146
- `images/`: RGB color image `*.jpg` of indoor room scene
4247
- `layout_seg/`: layout ground truth `*.mat` of indoor room scene
43-
- `layout_seg_images/`: generated layout ground truth `*.png` of indoor room scene
4448
- Prepare layout images for trianing/validation.
49+
- `layout_seg_images/`: generated layout ground truth `*.png` of indoor room scene
4550

4651
```bash
47-
python script/re_label.py
52+
python -m script.re_label
4853
```
4954

5055
- Training
5156

52-
- The trained model will be saved to folder `./exp/checkpoints/`
53-
- You can modify `config.yml` to play with hyperparameters for training.
57+
- The trained model will be saved to folder `./ckpts`
5458

5559
Example
5660

5761
```bash
5862
python main.py --phase train --arch resnet --edge_factor 0.2 --l2_factor 0.2 --name baseline
5963
```
6064

61-
Detials
62-
63-
```bash
64-
python main.py
65-
66-
Usage: main.py [OPTIONS]
67-
68-
Options:
69-
--name TEXT
70-
--dataset [lsun_room | others]
71-
--dataset_root TEXT
72-
--log_dir TEXT
73-
--image_size <INTEGER INTEGER>
74-
--epochs INTEGER
75-
--batch_size INTEGER
76-
--workers INTEGER
77-
--l1_weight FLOAT
78-
--resume PATH
79-
```
80-
8165
- Demo
8266

8367
```bash
84-
python demo.py
85-
86-
Usage: demo.py [OPTIONS]
87-
88-
Options:
89-
--device INTEGER
90-
--video TEXT
91-
--weight TEXT
92-
--input_size <INTEGER INTEGER>.
93-
68+
python demo.py --weight {checkpoint_path} --video {test_video}
9469
```
9570

9671
- Toolkit

config.yml

Lines changed: 0 additions & 8 deletions
This file was deleted.

datasets/lsunroom.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import torchvision.transforms as T
99
from PIL import Image
1010

11-
from lsun_room.label import Layout
12-
from lsun_room.loader import LsunRoomDataset as _BaseDataset
13-
from lsun_room.loader import get_meta
11+
from lib.lsun_room_api.lsun_room.label import Layout
12+
from lib.lsun_room_api.lsun_room.loader import LsunRoomDataset as _BaseDataset
13+
from lib.lsun_room_api.lsun_room.loader import get_meta
1414

1515

1616
class LsunRoomDataset(_BaseDataset):
@@ -31,7 +31,7 @@ def __init__(self, phase, args, **kwarges):
3131
def collect_meta(self, root, phase):
3232
''' metadata fold1: original dataset '''
3333
meta = [
34-
{'image_path': root / self.image_folder / f'{e["name"]}.jpg',
34+
{'image_path': root / self.image_folder / f'{e["name"]}.png',
3535
'layout_path': root / self.layout_folder / f'{e["name"]}.png',
3636
'name': e['name'] + '.png', 'type': e['type']}
3737
for e in get_meta(dataset_root=root, phase=phase)

demo.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55
import torchvision.transforms as T
66
from PIL import Image
77

8-
from trainer.賣扣老師 import build_resnet101_FCN
8+
from trainer import core
99

1010
torch.backends.cudnn.benchmark = True
1111

1212

1313
class Predictor:
1414

15-
def __init__(self, input_size, weight=None):
16-
self.model = self.build_model(weight)
15+
def __init__(self, input_size, weight_path):
16+
self.model = core.LayoutSeg.load_from_checkpoint(weight_path)
17+
self.model.freeze()
1718
self.colorizer = onegan.extension.Colorizer(
1819
colors=[
1920
[249, 69, 93], [255, 229, 170], [144, 206, 181],
@@ -24,22 +25,14 @@ def __init__(self, input_size, weight=None):
2425
T.Normalize(mean=[.5, .5, .5], std=[.5, .5, .5])
2526
])
2627

27-
def build_model(self, weight_path, joint_class=False):
28-
model = build_resnet101_FCN(pretrained=False, nb_classes=37, stage_2=True, joint_class=joint_class)
29-
weight = onegan.utils.export_checkpoint_weight(weight_path)
30-
model.load_state_dict(weight)
31-
model.eval()
32-
return model.cuda()
33-
3428
@onegan.utils.timeit
3529
def process(self, raw):
3630

3731
def _batched_process(batched_img):
38-
score, _ = self.model(onegan.utils.to_var(batched_img))
39-
_, output = torch.max(score, 1)
32+
_, outputs = self.model(batched_img)
4033

4134
image = (batched_img / 2 + .5)
42-
layout = self.colorizer.apply(output.data.cpu())
35+
layout = self.colorizer.apply(outputs.data.cpu())
4336
return image * .6 + layout * .4
4437

4538
img = Image.fromarray(raw)
@@ -55,8 +48,7 @@ def _batched_process(batched_img):
5548
@click.option('--weight', type=click.Path(exists=True))
5649
@click.option('--input_size', default=(320, 320), type=(int, int))
5750
def main(device, video, weight, input_size):
58-
59-
demo = Predictor(input_size, weight=weight)
51+
demo = Predictor(input_size, weight_path=weight)
6052

6153
reader = video if video else device
6254
cap = cv2.VideoCapture(reader)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__VERSION__ = '0.1.0'
1+
__VERSION__ = '0.1.1'

lib/lsun_room_api/lsun_room/item.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import scipy.io as sio
55

66
import cv2
7-
from lsun_room.label import mapping_func
7+
from .label import mapping_func
88

99

1010
def load_mat(path):
@@ -47,16 +47,15 @@ def layout(self):
4747

4848
def remap_layout(self, verbose=False):
4949
mapping = mapping_func(self.type)(self)
50-
5150
old_layout = load_mat(self.layout_mat_path)
5251
layout = np.zeros_like(old_layout)
5352
for new_label, point in mapping:
5453
old_label = old_layout[point[1], point[0]]
55-
layout[old_layout == old_label] = new_label
54+
layout[old_layout == old_label] = new_label.value
5655
return layout
5756

5857
def save_layout(self, visualization=False):
59-
save_image(self.layout_path, self.layout)
58+
save_image(self.layout_path, self.remap_layout())
6059

6160
def __str__(self):
6261
return '<DataItem: %s>' % self.name

lib/lsun_room_api/lsun_room/loader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from onegan.io.loader import load_image, BaseDataset
66
from onegan.io.transform import SegmentationPair
77

8-
from lsun_room.edge import gen_edge_map, gen_corner_map
8+
from .edge import gen_edge_map, gen_corner_map
99

1010

1111
def get_meta(dataset_root, phase):

main.py

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
import argparse
12
import importlib
2-
import logging
3+
from pprint import pprint
34

4-
import torch
55
import onegan
6+
import pytorch_lightning as pl
67

78
from trainer import core
8-
from trainer.model import ResPlanarSeg
99

1010

1111
def create_dataset(args):
@@ -24,19 +24,6 @@ def create_dataset(args):
2424
for phase in ['train', 'val'])
2525

2626

27-
def create_model(args):
28-
return {
29-
'resnet': lambda: ResPlanarSeg(num_classes=args.num_class, pretrained=True, base='resnet101')
30-
}[args.arch]()
31-
32-
33-
def create_optim(args, model, optim='sgd'):
34-
return {
35-
'adam': lambda: torch.optim.Adam(model.parameters(), lr=args.lr, betas=(0.5, 0.999)),
36-
'sgd': lambda: torch.optim.SGD(model.parameters(), lr=args.lr / 10, momentum=0.9)
37-
}[optim]()
38-
39-
4027
def hyperparams_search(args):
4128
search_hyperparams = {
4229
'arch': ['vgg', 'mike'],
@@ -54,33 +41,35 @@ def hyperparams_search(args):
5441

5542

5643
def main(args):
57-
log = logging.getLogger('room')
58-
log.info(''.join([f'\n-- {k}: {v}' for k, v in args.items()]))
44+
pprint(args)
5945

6046
train_loader, val_loader = create_dataset(args)
61-
model = create_model(args)
62-
6347
if args.phase == 'train':
64-
training_estimator = core.training_estimator(
65-
torch.nn.DataParallel(model.cuda()),
66-
create_optim(args, model, optim=args.optim), args)
67-
training_estimator(train_loader, val_loader, epochs=args.epoch)
68-
69-
if args.phase in ['eval', 'eval_search']:
70-
core_fn = core.evaluation_estimator if args.phase == 'eval' else core.weights_estimator
71-
evaluate_estimator = core_fn(torch.nn.DataParallel(model.cuda()), args)
72-
evaluate_estimator(val_loader)
48+
model = core.LayoutSeg(args.num_class, args.lr, args)
49+
trainer = pl.Trainer(
50+
gpus=1,
51+
limit_train_batches=.1,
52+
limit_val_batches=.1,
53+
max_epochs=args.epoch,
54+
weights_save_path=f'ckpts/{args.name}',
55+
logger=pl.loggers.TensorBoardLogger('ckpts/tb_logs', name=args.name)
56+
)
57+
trainer.fit(model, train_loader, val_loader)
7358

7459

7560
if __name__ == '__main__':
76-
parser = onegan.option.Parser(description='Indoor room corner detection', config='./config.yml')
61+
parser = argparse.ArgumentParser(description='Indoor room corner detection')
7762
parser.add_argument('--name', help='experiment name')
78-
parser.add_argument('--folder', help='where\'s the dataset')
63+
parser.add_argument('--folder', default='data/lsun_room', help='where is the dataset')
7964
parser.add_argument('--dataset', default='lsunroom', choices=['lsunroom', 'hedau', 'sunrgbd'])
8065
parser.add_argument('--phase', default='eval', choices=['train', 'eval', 'eval_search'])
66+
parser.add_argument('--worker', default=4, type=int)
67+
parser.add_argument('--epoch', default=30, type=int)
68+
parser.add_argument('--batch_size', default=8, type=int)
69+
parser.add_argument('--lr', default=0.0001, type=float)
8170

8271
# data
83-
parser.add_argument('--image_size', type=int)
72+
parser.add_argument('--image_size', default=320, type=int)
8473
parser.add_argument('--use_edge', action='store_true')
8574
parser.add_argument('--use_corner', action='store_true')
8675
parser.add_argument('--datafold', type=int, default=1)
@@ -98,11 +87,8 @@ def main(args):
9887
parser.add_argument('--l1_factor', type=float, default=0.0)
9988
parser.add_argument('--l2_factor', type=float, default=0.0)
10089
parser.add_argument('--edge_factor', type=float, default=0.0)
90+
parser.add_argument('--type_factor', type=float, default=0.0)
10191
parser.add_argument('--focal_gamma', type=float, default=0)
102-
args = parser.parse()
92+
args = parser.parse_args()
10393

104-
logging.basicConfig(level=logging.INFO,
105-
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
106-
datefmt='%m-%d %H:%M',
107-
handlers=[logging.StreamHandler(), ])
10894
main(args)

requirements.txt

500 Bytes
Binary file not shown.

script/re_label.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,21 @@
44

55
import click
66

7-
from datasets.lsun_room.item import DataItems
7+
from lib.lsun_room_api.lsun_room.item import DataItems
88

99

1010
def worker(item):
11-
item.remap_layout()
1211
item.save_layout()
1312

1413

1514
@click.command()
16-
@click.option('--dataset_root', default='../data/lsun_room/')
15+
@click.option('--dataset_root', default='data/lsun_room/')
1716
def main(dataset_root):
1817

1918
for phase in ['train', 'val']:
2019
print('==> re-label for data in %s phase' % phase)
2120
s = time.time()
22-
dataset = DataItems(root_dir=dataset_root, phase=phase)
21+
dataset = DataItems(root=dataset_root, phase=phase)
2322
with Pool(cpu_count()) as pool:
2423
pool.map(worker, dataset.items)
2524
print('==> Done in %.4f sec.' % (time.time() - s))

0 commit comments

Comments
 (0)