Skip to content

Commit

Permalink
Merge pull request #8 from jizongFox/autoencoder
Browse files Browse the repository at this point in the history
Autoencoder
  • Loading branch information
Jizong's Fox committed May 31, 2019
2 parents 228b410 + 67fb3a1 commit 40bd900
Show file tree
Hide file tree
Showing 25 changed files with 413 additions and 770 deletions.
7 changes: 2 additions & 5 deletions deepclustering/arch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .segmentation import *
from ..utils.general import _register

__all__ = ['weights_init', 'get_arch', 'ARCH_CALLABLES']
__all__ = ['weights_init', 'get_arch', 'ARCH_CALLABLES', 'PlaceholderNet']
"""
Package
"""
Expand Down Expand Up @@ -51,10 +51,7 @@ def weights_init(m):
def get_arch(arch: str, kwargs) -> nn.Module:
""" Get the architecture. Return a torch.nn.Module """
arch_callable = ARCH_CALLABLES.get(arch.lower())
try:
kwargs.pop('arch')
except KeyError:
pass
kwargs.pop('arch', None)
assert arch_callable, "Architecture {} is not found!".format(arch)
net = arch_callable(**kwargs)
# try:
Expand Down
2 changes: 0 additions & 2 deletions deepclustering/arch/classification/IIC/net6c_two_head.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ def __init__(self, num_channel: int = 3, input_size: int = 64, output_k_A: int =
num_sub_heads=num_sub_heads, semisup=semisup,
batchnorm_track=self.batchnorm_track)

print("semisup: %s" % semisup)

self.head_B = ClusterNet6cTwoHeadHead(input_size=input_size, output_k=output_k_B,
num_sub_heads=num_sub_heads, semisup=semisup,
batchnorm_track=self.batchnorm_track)
Expand Down
12 changes: 12 additions & 0 deletions deepclustering/arch/classification/dummy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
from torch import nn


class PlaceholderNet(nn.Module):

def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(128, 256, 3)
self.avg_pool = nn.AdaptiveAvgPool2d((1, 1))

def forward(self, input):
return input
# return self.avg_pool(self.conv1(input))


class Dummy(nn.Module):
"""
This is a dummy network for debug
Expand Down
113 changes: 93 additions & 20 deletions deepclustering/dataset/classification/mnist_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,101 @@ def _creat_concatDataset(self, image_transform: Callable, target_transform: Call
return serial_dataset


# default transform

default_mnist_img_transform = {
"tf1": transforms.Compose([
augment.CenterCrop(size=(26, 26)),
augment.Resize(size=(28, 28), interpolation=PIL.Image.BILINEAR),
augment.Img2Tensor(include_rgb=False, include_grey=True),
transforms.Normalize((0.5,), (0.5,))
]),
"tf1":
transforms.Compose([
augment.RandomChoice(transforms=
[augment.RandomCrop(size=(20, 20), padding=None),
augment.CenterCrop(size=(20, 20))
]),
augment.Resize(size=24, interpolation=PIL.Image.BILINEAR),
transforms.ToTensor()
]),
"tf2":
transforms.Compose([
augment.RandomCrop(size=(26, 26), padding=2),
augment.Resize(size=(28, 28), interpolation=PIL.Image.BILINEAR),
# transforms.RandomHorizontalFlip(p=0.5),
transforms.ColorJitter(brightness=[0.6, 1.4], contrast=[0.6, 1.4], saturation=[0.6, 1.4],
hue=[-0.125, 0.125]),
augment.Img2Tensor(include_rgb=False, include_grey=True),
transforms.Normalize((0.5,), (0.5,))
augment.RandomApply(transforms=[transforms.RandomRotation(
degrees=(-25.0, 25.0),
resample=False,
expand=False
)], p=0.5),
augment.RandomChoice(transforms=[
augment.RandomCrop(size=(16, 16), padding=None),
augment.RandomCrop(size=(20, 20), padding=None),
augment.RandomCrop(size=(24, 24), padding=None),
]),
augment.Resize(size=24, interpolation=PIL.Image.BILINEAR),
transforms.ToTensor()
]),
"tf3":
transforms.Compose([
augment.CenterCrop(size=(20, 20)),
augment.Resize(size=24, interpolation=PIL.Image.BILINEAR),
transforms.ToTensor()
]),
"tf3": transforms.Compose([
augment.CenterCrop(size=(26, 26)),
augment.Resize(size=(28, 28), interpolation=PIL.Image.BILINEAR),
augment.Img2Tensor(include_rgb=False, include_grey=True),
transforms.Normalize((0.5,), (0.5,))
])

}

""" Taken from the IIC paper
tf1
Compose(
RandomChoice(
RandomCrop(size=(20, 20), padding=None)
CenterCrop(size=(20, 20))
)
Resize(size=24, interpolation=PIL.Image.BILINEAR)
ToTensor()
)
tf2
Compose(
RandomApply(
p=0.5
RandomRotation(degrees=(-25.0, 25.0), resample=False, expand=False)
)
RandomChoice(
RandomCrop(size=(16, 16), padding=None)
RandomCrop(size=(20, 20), padding=None)
RandomCrop(size=(24, 24), padding=None)
)
Resize(size=(24, 24), interpolation=PIL.Image.BILINEAR)
ColorJitter(
brightness=[0.6, 1.4],
contrast=[0.6, 1.4],
saturation=[0.6, 1.4],
hue=[-0.125, 0.125]
)
ToTensor()
)
tf3:
Compose(
CenterCrop(size=(20, 20))
Resize(size=24, interpolation=PIL.Image.BILINEAR)
ToTensor()
)
"""

# default transform
# default_mnist_img_transform = {
# "tf1": transforms.Compose([
# augment.CenterCrop(size=(26, 26)),
# augment.Resize(size=(28, 28), interpolation=PIL.Image.BILINEAR),
# augment.Img2Tensor(include_rgb=False, include_grey=True),
# transforms.Normalize((0.5,), (0.5,))
# ]),
# "tf2":
# transforms.Compose([
# augment.RandomCrop(size=(26, 26), padding=2),
# augment.Resize(size=(28, 28), interpolation=PIL.Image.BILINEAR),
# # transforms.RandomHorizontalFlip(p=0.5),
# transforms.ColorJitter(brightness=[0.6, 1.4], contrast=[0.6, 1.4], saturation=[0.6, 1.4],
# hue=[-0.125, 0.125]),
# augment.Img2Tensor(include_rgb=False, include_grey=True),
# transforms.Normalize((0.5,), (0.5,))
# ]),
# "tf3": transforms.Compose([
# augment.CenterCrop(size=(26, 26)),
# augment.Resize(size=(28, 28), interpolation=PIL.Image.BILINEAR),
# augment.Img2Tensor(include_rgb=False, include_grey=True),
# transforms.Normalize((0.5,), (0.5,))
# ])
# }
23 changes: 23 additions & 0 deletions deepclustering/dataset/segmentation/toydataset_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from typing import Callable

from .toydataset import Cls_ShapesDataset
from ..classification.clustering_helper import ClusterDatasetInterface


class ToyExampleInterFace(ClusterDatasetInterface):
ALLOWED_SPLIT = ['1']

def __init__(self, batch_size: int = 1, shuffle: bool = False,
num_workers: int = 1, pin_memory: bool = True, drop_last=False) -> None:
super().__init__(Cls_ShapesDataset, ['1'], batch_size, shuffle, num_workers, pin_memory, drop_last)

def _creat_concatDataset(self, image_transform: Callable, target_transform: Callable, dataset_dict: dict = {}):
train_set = Cls_ShapesDataset(
count=5000,
height=100,
width=100,
max_object_scale=0.75,
transform=image_transform,
target_transform=target_transform,
**dataset_dict)
return train_set
8 changes: 6 additions & 2 deletions deepclustering/manager.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
from pathlib import Path
from pprint import pprint
from typing import Dict, Any
Expand All @@ -8,9 +9,12 @@
class ConfigManger:
DEFAULT_CONFIG = ""

def __init__(self, DEFAULT_CONFIG_PATH: str, verbose=True) -> None:
def __init__(self, DEFAULT_CONFIG_PATH: str = None, verbose=True) -> None:
self.parsed_args: Dict[str, Any] = yaml_parser(verbose=verbose)
if DEFAULT_CONFIG_PATH is None:
warnings.warn('No default yaml is provided, only used for parser input arguments.', UserWarning)
return
self.SET_DEFAULT_CONFIG_PATH(DEFAULT_CONFIG_PATH)
self.parsed_args: Dict[str, Any] = yaml_parser(True)
self.default_config = yaml_load(self.parsed_args.get('Config', self.DEFAULT_CONFIG), verbose=verbose)
self.merged_config = dict_merge(self.default_config, self.parsed_args, re=True)
self._check_integrality(self.merged_config)
Expand Down
54 changes: 41 additions & 13 deletions deepclustering/model/general.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
from abc import ABC
from typing import *

Expand All @@ -9,14 +10,19 @@
from torch.optim import lr_scheduler

from deepclustering import ModelMode
from deepclustering.arch import get_arch
from deepclustering.arch import get_arch, PlaceholderNet
# from torch import optim
from .. import optim


class Model(ABC):

def __init__(self, arch_dict: Dict[str, Any], optim_dict: Dict[str, Any], scheduler_dict: Dict[str, Any]) -> None:
def __init__(
self,
arch_dict: Dict[str, Any] = None,
optim_dict: Dict[str, Any] = None,
scheduler_dict: Dict[str, Any] = None
) -> None:
super().__init__()
self.arch_dict = arch_dict
self.optim_dict = optim_dict
Expand All @@ -25,19 +31,41 @@ def __init__(self, arch_dict: Dict[str, Any], optim_dict: Dict[str, Any], schedu
self.to(device=torch.device('cpu'))

def _setup(self) -> Tuple[nn.Module, optim.SGD, torch.optim.lr_scheduler.LambdaLR]:
self.arch_name = self.arch_dict['name']
self.arch_params = {k: v for k, v in self.arch_dict.items() if k != 'name'}
self.optim_name = self.optim_dict['name']
self.optim_params = {k: v for k, v in self.optim_dict.items() if k != 'name'}
self.scheduler_name = self.scheduler_dict['name']
self.scheduler_params = {k: v for k, v in self.scheduler_dict.items() if k != 'name'}
torchnet = get_arch(self.arch_name, self.arch_params)
if self.arch_dict is not None:
self.arch_name = self.arch_dict['name']
self.arch_params = {k: v for k, v in self.arch_dict.items() if k != 'name'}
torchnet = get_arch(self.arch_name, self.arch_params)
else:
warnings.warn(f'torchnet is a placeholder, override it later.', RuntimeWarning)
self.arch_name = None
self.arch_params = None
torchnet = PlaceholderNet()
# this put the tensor to cuda directly, including the forward image implicitly.
# torchnet = nn.DataParallel(torchnet)
optimizer: optim.SGD = getattr(optim, self.optim_name) \
(torchnet.parameters(), **self.optim_params)
scheduler: lr_scheduler.LambdaLR = getattr(lr_scheduler, self.scheduler_name) \
(optimizer, **self.scheduler_params)
if self.optim_dict is not None:
self.optim_name = self.optim_dict['name']
self.optim_params = {k: v for k, v in self.optim_dict.items() if k != 'name'}
optimizer: optim.SGD = getattr(optim, self.optim_name) \
(torchnet.parameters(), **self.optim_params)
else:
warnings.warn(f'optimizer is a placeholder, override it later.', RuntimeWarning)
self.optim_name = None
self.optim_params = None
optimizer: optim.SGD = getattr(optim, 'SGD')(torchnet.parameters(), lr=0.01)

if self.scheduler_dict is not None:
self.scheduler_name = self.scheduler_dict['name']
self.scheduler_params = {k: v for k, v in self.scheduler_dict.items() if
k != 'name'}
scheduler: lr_scheduler.LambdaLR = getattr(lr_scheduler, self.scheduler_name) \
(optimizer, **self.scheduler_params) if self.scheduler_name is not None else None
else:
warnings.warn(f'scheduler is a placeholder, override it later.', RuntimeWarning)
self.scheduler_name = None
self.scheduler_params = None
scheduler: lr_scheduler.LambdaLR = getattr(lr_scheduler, 'StepLR') \
(optimizer, 10, 0.1)

return torchnet, optimizer, scheduler

def predict(self, img: Tensor, logit=True) -> Tensor:
Expand Down
1 change: 1 addition & 0 deletions deepclustering/trainer/IICMultiheadTrainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This is the trainer for IIC multiple-header Clustering
"""
from collections import OrderedDict
from math import isnan
from typing import List

import torch
Expand Down
7 changes: 4 additions & 3 deletions deepclustering/trainer/Trainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def to(self, device):
self.model.to(device=device)

@abstractmethod
def _train_loop(self, train_loader=None, epoch=0, mode=ModelMode.TRAIN, *args, **kwargs):
def _train_loop(self, train_loader=None, epoch: int = 0, mode=ModelMode.TRAIN, *args, **kwargs):
# warning control
_warnings(args, kwargs)

Expand All @@ -113,7 +113,7 @@ def _trainer_specific_loss(self, *args, **kwargs):
_warnings(args, kwargs)

@abstractmethod
def _eval_loop(self, val_loader: DataLoader, epoch: int, mode=ModelMode.EVAL, *args, **kwargs) -> float:
def _eval_loop(self, val_loader: DataLoader = None, epoch: int = 0, mode=ModelMode.EVAL, *args, **kwargs) -> float:
# warning control
_warnings(args, kwargs)

Expand Down Expand Up @@ -147,7 +147,8 @@ def load_checkpoint(self, state_dict):

def clean_up(self):
import shutil

import time
time.sleep(60) # to prevent that the call_draw function is not ended.
Path(self.ARCHIVE_PATH).mkdir(exist_ok=True, parents=True)
sub_dir = self.save_dir.relative_to(Path(self.RUN_PATH))
save_dir = Path(self.ARCHIVE_PATH) / str(sub_dir)
Expand Down
20 changes: 12 additions & 8 deletions deepclustering/writer/draw_csv.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
import argparse
import os
import subprocess
Expand Down Expand Up @@ -32,14 +33,17 @@ def __init__(
self.csv_name = csv_name

def call_draw(self):
_csv_path = os.path.join(str(self.save_dir), self.csv_name)
_columns_to_draw = " ".join(self.columns_to_draw)
_save_dir = str(self.save_dir)
cmd = f"python {PROJECT_PATH}/deepclustering/writer/draw_csv.py " \
f"--csv_path={_csv_path} " \
f"--save_dir={_save_dir} " \
f"--columns_to_draw {_columns_to_draw} &"
subprocess.call(cmd, shell=True)
try:
_csv_path = os.path.join(str(self.save_dir), self.csv_name)
_columns_to_draw = " ".join(self.columns_to_draw)
_save_dir = str(self.save_dir)
cmd = f"python {PROJECT_PATH}/deepclustering/writer/draw_csv.py " \
f"--csv_path={_csv_path} " \
f"--save_dir={_save_dir} " \
f"--columns_to_draw {_columns_to_draw} &"
subprocess.call(cmd, shell=True)
except TypeError:
warnings.warn(f'Given columns to draw: {self.columns_to_draw}.', UserWarning)

def draw(self, dataframe, together=False):
if together:
Expand Down
29 changes: 0 additions & 29 deletions playground/GN_BN/analyse_model.py

This file was deleted.

Loading

0 comments on commit 40bd900

Please sign in to comment.