Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A major (performance) update on the submodule: srl-zoo #26

Closed
wants to merge 82 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
6ecfdbc
fix issue: image rotated by 90 degrees
ncble May 20, 2019
e37db43
default image processing should be 'tf' mode
ncble May 21, 2019
d11611f
fix preprocessing mode; add gan.py (not finished)
ncble May 21, 2019
9489bd2
add img_shape to input; add gan.py (not finished yet)
ncble May 22, 2019
aa24811
fix issue (image rotated); img_shape
ncble May 23, 2019
15323ed
30% training speed-up (for 'tf' preprocessing mode) by modifying few …
ncble May 24, 2019
9f7e992
update all CNN-based models for any image shape (input)
ncble May 24, 2019
7d5fc1e
fix plt slow down issue
ncble May 26, 2019
30f2850
new features in plotting/representation_plot.py: plotImage (support m…
ncble May 27, 2019
ac9f59c
improve data_loader.py git add .!
ncble May 27, 2019
0027c26
add monitor mode ('pbar' or 'loss')
ncble May 27, 2019
d35b908
update data_loader.py for test mode
ncble May 28, 2019
11762a6
fix plotRepre; replace DISPLAY_PLOT by fidir as args (savefig or not)
ncble May 29, 2019
096a15a
fix plot delay problem
ncble May 29, 2019
1a0dba7
fix train.py --log-folder bug
ncble May 29, 2019
ef30fac
huge update: re-modulize the srl-zoo (module/model part)
ncble May 29, 2019
676be83
tempo commit pb to be fixed: import error
ncble May 29, 2019
70745e0
remove getStates (ambiguous) from AutoEncoder model
ncble May 29, 2019
783ca2f
fix absolute/relative import issue
ncble May 30, 2019
95316d4
update VAE to new format
ncble May 30, 2019
00a177e
update srl module (forward/inverse loss)
ncble May 30, 2019
b645c83
fix image shape error
ncble May 31, 2019
cf8cfdc
add BaseTrainer
ncble May 31, 2019
78d7a39
First release of ASRL
ncble May 31, 2019
803cfda
First release of ASRL
ncble May 31, 2019
a601b42
first exp with gan
ncble Jun 1, 2019
057f03f
temporary update
ncble Jun 2, 2019
6b8b764
add CUDA VISIBLE DEVICES control
ncble Jun 4, 2019
35d38b9
fix plotRepresentation bug
ncble Jun 4, 2019
3915458
clean models
ncble Jun 4, 2019
893f0a3
first result with adv_srl
ncble Jun 5, 2019
f3989e7
remove N_CHANNELS and getNChannels from preprocessing/preprocess.py
ncble Jun 5, 2019
9314a85
default CUDA visible devices to 0
ncble Jun 5, 2019
7c8b9aa
fix reward loss
ncble Jun 5, 2019
b967b2a
merge adv_srl to master
ncble Jun 5, 2019
c08b44f
merge adv_srl2 to master
ncble Jun 5, 2019
8c61f2e
merge adv_srl2 to master
ncble Jun 5, 2019
33fb207
add BasicTrainer for inverse/forward models
ncble Jun 6, 2019
b06325c
clean files
ncble Jun 6, 2019
4d1fe1e
maintain consistency
ncble Jun 7, 2019
a467eb2
enable gan in enjoy_latent.py
ncble Jun 11, 2019
6717bf4
fix GTC error
ncble Jun 18, 2019
0852846
remove split module, integrate it into SRLModules
ncble Jun 19, 2019
eb36b52
autopep8
ncble Jun 20, 2019
004fa65
division by zero pb (in inverse model init)
ncble Jun 20, 2019
b84bd06
change Reward/Inverse models
ncble Jun 20, 2019
a641ce0
clean comments
ncble Jun 21, 2019
d530bb1
new reward model
ncble Jun 21, 2019
061561f
self-supervised srl split
ncble Jun 25, 2019
f704752
update coeff
ncble Jun 26, 2019
4c0b9da
fix autoencoder activation
ncble Jun 28, 2019
9337042
fix bug (autoencoder without activation): add activation tanh
ncble Jun 29, 2019
db583e8
Merge branch 'master' of https://github.com/ncble/srl-zoo
ncble Jun 29, 2019
764dd57
fix bug: add tanh activation to vae, autoencoder
ncble Jun 29, 2019
b4d20b9
fix bug (add activation tanh) in autoencoder and vae
ncble Jun 29, 2019
7484656
inverse label of rewardModel (-1,0,1) to (2,1,0) ignore 2
ncble Jun 30, 2019
8cc599c
pass loss_weights to args
ncble Jul 1, 2019
779ec54
fix issue #24 (VAE couldn't reconstruct image)
ncble Jul 2, 2019
07600ac
(hack) enable partially no-split with inverse/forward
ncble Jul 2, 2019
66ab7f2
quick fix
ncble Jul 2, 2019
2599f3d
integrate gan to losses; add reward2 for split
ncble Jul 4, 2019
682262e
tempo commit
ncble Jul 5, 2019
9c7b696
update reward2 compatibility
ncble Jul 5, 2019
e55fb28
refactor gan
ncble Jul 5, 2019
0067dfe
re-modular gan
ncble Jul 8, 2019
2a8d517
(partial) resnet gan
ncble Jul 8, 2019
8380c05
update gan.py
ncble Jul 9, 2019
32e4a84
merge debug2_tempo
ncble Jul 11, 2019
d3c6710
quick fix (pytorch dataloader leaking FDs); move spcls_loss out of re…
ncble Jul 13, 2019
61ffdd1
quick fix: num_classes for spcls_loss
ncble Jul 14, 2019
d0f91a3
fix spcls num_classes
ncble Jul 15, 2019
a3a53f2
gtc with labyrinth to be fixed
ncble Jul 17, 2019
b0c831e
add argument monitorGTC
ncble Jul 17, 2019
a041b34
clean ./preprocessing.data_loader.py
ncble Jul 18, 2019
0a4d2fd
quick fix for spcls num_classes (we should use new class design)
ncble Jul 19, 2019
7af3fd5
fix int64 can't save in json
ncble Jul 22, 2019
8140ecc
add supervised learning ('supervised') to losses
ncble Jul 22, 2019
20afc87
fix l2 loss in 'supervised' setting
ncble Jul 23, 2019
341671f
clean code
ncble Jul 23, 2019
0b62a6a
minor change to learner.py
ncble Jul 26, 2019
28188eb
use png instead of jpg/jpeg extension for saving images
ncble Aug 4, 2019
cc209a2
clean description
ncble Aug 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Custom
data/
figures/
.idea/
*.npy
*.npz
Expand All @@ -10,7 +11,7 @@ dev/
.ropeproject/
.pytest_cache/
_build/

figures/
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
24 changes: 16 additions & 8 deletions evaluation/enjoy_latent.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def getImage(srl_model, state, device):
net_out = srl_model.decode(state)
img = detachToNumpy(net_out)[0].T

img = deNormalize(img, mode="image_net")
img = deNormalize(img, mode="tf")
return img[:, :, ::-1]


Expand All @@ -61,14 +61,18 @@ def main():
parser = argparse.ArgumentParser(description="latent space enjoy")
parser.add_argument('--log-dir', default='', type=str, help='directory to load model')
parser.add_argument('--no-cuda', default=False, action="store_true")

parser.add_argument('--gpu-num', type=int, default=0, help='CUDA visible device (use CPU if -1, default: 0)')
parser.add_argument('--img-shape', type=str, default="(3,128,128)", help='image shape (default "(3,128,128)"')
args = parser.parse_args()
use_cuda = not args.no_cuda
device = th.device("cuda" if th.cuda.is_available() and use_cuda else "cpu")

srl_model, exp_config = SRL4robotics.loadSavedModel(args.log_dir, VALID_MODELS, cuda=use_cuda)
# use_cuda = not args.no_cuda
# device = th.device("cuda" if th.cuda.is_available() and use_cuda else "cpu")
if args.img_shape is None:
img_shape = None #(3,224,224)
else:
img_shape = tuple(map(int, args.img_shape[1:-1].split(",")))
srl_model, exp_config = SRL4robotics.loadSavedModel(args.log_dir, VALID_MODELS, cuda=args.gpu_num, img_shape=img_shape)
# Retrieve the pytorch model
srl_model = srl_model.model
srl_model = srl_model.module
losses = exp_config['losses']
state_dim = exp_config['state-dim']

Expand All @@ -83,7 +87,11 @@ def main():

if len(loss_dims) == 0:
print(losses)
loss_dims = {losses[0]: state_dim}
## HACK: GAN is currently a model_type not a losses (TODO)
if len(losses) == 0:
loss_dims = {'gan': state_dim}
else:
loss_dims = {losses[0]: state_dim}

# Load all the states and images
data = json.load(open(args.log_dir + 'image_to_state.json'))
Expand Down
9 changes: 7 additions & 2 deletions evaluation/predict_reward.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
parser = argparse.ArgumentParser(description='Predict Reward from Ground Truth')
parser.add_argument('--epochs', type=int, default=10,
help='number of epochs to train (default: 10)')
parser.add_argument('--img-shape', type=tuple, default=None, help='image shape (default (3,224,224))')
parser.add_argument('--seed', type=int, default=1, help='random seed (default: 1)')
parser.add_argument('-bs', '--batch-size', type=int, default=32, help='batch_size (default: 256)')
parser.add_argument('--training-set-size', type=int, default=-1,
Expand Down Expand Up @@ -80,8 +81,12 @@
mean_val = np.mean(states, axis=0, keepdims=True)

datasets = {'train': TensorDataset(X_train), 'val': TensorDataset(X_val)}
train_loader = DataLoader(datasets['train'], batch_size=args.batch_size, shuffle=True)
val_loader = DataLoader(datasets['val'], batch_size=args.batch_size, shuffle=False)
if args.img_shape is None:
img_shape = None #(3,224,224)
else:
img_shape = tuple(map(int, args.img_shape[1:-1].split(",")))
train_loader = DataLoader(datasets['train'], img_shape=img_shape, batch_size=args.batch_size, shuffle=True)
val_loader = DataLoader(datasets['val'], img_shape=img_shape, batch_size=args.batch_size, shuffle=False)
dataloaders = {'train': train_loader, 'val': val_loader}

start_time = time.time()
Expand Down
82 changes: 68 additions & 14 deletions losses/losses.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
import torch as th
import torch.nn as nn
import torch.nn.functional as F
try:
# absolute import
from models.priors import ReverseLayerF
except:
# relative import
from ..models.priors import ReverseLayerF

from models.priors import ReverseLayerF
from .utils import correlationMatrix

try:
Expand Down Expand Up @@ -36,7 +41,7 @@ def addToLosses(self, name, weight, loss_value):
"""
:param name: (str)
:param weight: (float)
:param loss_value: (FloatTensor)
:param loss_value: (torch.FloatTensor)
:return:
"""
self.names.append(name)
Expand All @@ -60,7 +65,7 @@ def resetLosses(self):


def roboticPriorsLoss(states, next_states, minibatch_idx,
dissimilar_pairs, same_actions_pairs, weight, loss_manager):
dissimilar_pairs, same_actions_pairs, weight, loss_manager):
"""
Computing the 4 Robotic priors: Temporal coherence, Causality, Proportionality, Repeatability
:param states: (th.Tensor)
Expand All @@ -77,17 +82,17 @@ def roboticPriorsLoss(states, next_states, minibatch_idx,

state_diff = next_states - states
state_diff_norm = state_diff.norm(2, dim=1)
similarity = lambda x, y: th.exp(-(x - y).norm(2, dim=1) ** 2)
def similarity(x, y): return th.exp(-(x - y).norm(2, dim=1) ** 2)
temp_coherence_loss = (state_diff_norm ** 2).mean()
causality_loss = similarity(states[dissimilar_pairs[:, 0]],
states[dissimilar_pairs[:, 1]]).mean()
proportionality_loss = ((state_diff_norm[same_actions_pairs[:, 0]] -
state_diff_norm[same_actions_pairs[:, 1]]) ** 2).mean()

repeatability_loss = (
similarity(states[same_actions_pairs[:, 0]], states[same_actions_pairs[:, 1]]) *
(state_diff[same_actions_pairs[:, 0]] - state_diff[same_actions_pairs[:, 1]]).norm(2,
dim=1) ** 2).mean()
similarity(states[same_actions_pairs[:, 0]], states[same_actions_pairs[:, 1]]) *
(state_diff[same_actions_pairs[:, 0]] - state_diff[same_actions_pairs[:, 1]]).norm(2,
dim=1) ** 2).mean()
weights = [1, 1, 1, 1]
names = ['temp_coherence_loss', 'causality_loss', 'proportionality_loss', 'repeatability_loss']
losses = [temp_coherence_loss, causality_loss, proportionality_loss, repeatability_loss]
Expand Down Expand Up @@ -155,20 +160,41 @@ def l2Loss(params, weight, loss_manager):
return weight * l2_loss


def rewardModelLoss(rewards_pred, rewards_st, weight, loss_manager):
def rewardModelLoss(rewards_pred, rewards_st, weight, loss_manager, label_weights, ignore_index=-1):
"""
Categorical Reward prediction Loss (Cross-entropy)
:param rewards_pred: predicted reward - categorical (th.Tensor)
:param rewards_st: (th.Tensor)
:param weight: coefficient to weight the loss
:param loss_manager: loss criterion needed to log the loss value (LossManager)
:param label_weights (torch tensor) specifies the loss weight for each label. (need to be a torch tensor)
:param ignore_index (int, optional) Specifies a target value that is ignored and does not
contribute to the input gradient.
:return:
"""
loss_fn = nn.CrossEntropyLoss()
loss_fn = nn.CrossEntropyLoss(weight=label_weights, ignore_index=ignore_index)
reward_loss = loss_fn(rewards_pred, target=rewards_st)
loss_manager.addToLosses('reward_loss', weight, reward_loss)
return weight * reward_loss


def spclsLoss(cls_pred, cls_gt, weight, loss_manager):
"""
Categorical Reward prediction Loss (Cross-entropy)
:param rewards_pred: predicted reward - categorical (th.Tensor)
:param rewards_st: (th.Tensor)
:param weight: coefficient to weight the loss
:param loss_manager: loss criterion needed to log the loss value (LossManager)
:param label_weights (torch tensor) specifies the loss weight for each label. (need to be a torch tensor)
:param ignore_index (int, optional) Specifies a target value that is ignored and does not
contribute to the input gradient.
:return:
"""
loss_fn = nn.CrossEntropyLoss()
cls_loss = loss_fn(cls_pred, target=cls_gt)
loss_manager.addToLosses('spcls_loss', weight, cls_loss)
return weight * cls_loss

def reconstructionLoss(input_image, target_image):
"""
Reconstruction Loss for Autoencoders
Expand Down Expand Up @@ -215,7 +241,7 @@ def generationLoss(decoded, next_decoded, obs, next_obs, weight, loss_manager):


def perceptualSimilarityLoss(encoded_real, encoded_prediction, next_encoded_real, next_encoded_prediction,
weight, loss_manager):
weight, loss_manager):
"""
Perceptual similarity Loss for VAE as in
# "DARLA: Improving Zero-Shot Transfer in Reinforcement Learning", Higgins et al.
Expand Down Expand Up @@ -272,14 +298,14 @@ def mutualInformationLoss(states, rewards_st, weight, loss_manager):
I = 0
eps = 1e-10
p_x = float(1 / np.sqrt(2 * np.pi)) * \
th.exp(-th.pow(th.norm((X - th.mean(X, dim=0)) / (th.std(X, dim=0) + eps), 2, dim=1), 2) / 2) + eps
th.exp(-th.pow(th.norm((X - th.mean(X, dim=0)) / (th.std(X, dim=0) + eps), 2, dim=1), 2) / 2) + eps
p_y = float(1 / np.sqrt(2 * np.pi)) * \
th.exp(-th.pow(th.norm((Y - th.mean(Y, dim=0)) / (th.std(Y, dim=0) + eps), 2, dim=1), 2) / 2) + eps
th.exp(-th.pow(th.norm((Y - th.mean(Y, dim=0)) / (th.std(Y, dim=0) + eps), 2, dim=1), 2) / 2) + eps
for x in range(X.shape[0]):
for y in range(Y.shape[0]):
p_xy = float(1 / np.sqrt(2 * np.pi)) * \
th.exp(-th.pow(th.norm((th.cat([X[x], Y[y]]) - th.mean(th.cat([X, Y], dim=1), dim=0)) /
(th.std(th.cat([X, Y], dim=1), dim=0) + eps), 2), 2) / 2) + eps
th.exp(-th.pow(th.norm((th.cat([X[x], Y[y]]) - th.mean(th.cat([X, Y], dim=1), dim=0)) /
(th.std(th.cat([X, Y], dim=1), dim=0) + eps), 2), 2) / 2) + eps
I += p_xy * th.log(p_xy / (p_x[x] * p_y[y]))

mutual_info_loss = th.exp(-I)
Expand Down Expand Up @@ -374,3 +400,31 @@ def tripletLoss(states, p_states, n_states, weight, loss_manager, alpha=0.2):
tcn_triplet_loss = tcn_triplet_loss.mean()
loss_manager.addToLosses('triplet_loss', weight, tcn_triplet_loss)
return weight * tcn_triplet_loss


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add docstrings for the loss methods in the following lines.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, please reformat the file (to conform with PEP8 style).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I used vscode autopep8.

def ganNonSaturateLoss(img_rating, label, weight, loss_manager, name="non_saturate_loss"):
binary_crossentropy = th.nn.BCELoss()(img_rating, label)
loss_manager.addToLosses(name, weight, binary_crossentropy)
return weight * binary_crossentropy


def ganBCEaccuracy(output, label=1):
"""
label (int): 0 or 1
"""
pred = output > 0.5
pred = pred.type(th.float)
if label:
acc = pred.sum() / pred.numel()
else:
acc = 1. - pred.sum() / pred.numel()
return acc


def AEboundLoss(state_pred, weight, loss_manager, name='bonud_state_loss', max_val=50):
# state_pred of shape (batch_size, state_dim)
A = state_pred ** 2
norm_inf, _ = th.max(A, 1)
bound_loss = th.mean(th.relu(norm_inf-max_val))
loss_manager.addToLosses(name, weight, bound_loss)
return weight * bound_loss
12 changes: 10 additions & 2 deletions losses/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
from pipeline import NO_PAIRS_ERROR
from utils import printRed
try:
# absolute import
from pipeline import NO_PAIRS_ERROR
from utils import printRed
except:
# relative import
from ..pipeline import NO_PAIRS_ERROR
from ..utils import printRed


import torch as th
import numpy as np


def overSampling(batch_size, m_list, pairs, function_on_pairs, actions, rewards):
"""
Look for minibatches missing pairs of observations with the similar/dissimilar rewards (see params)
Expand Down
8 changes: 4 additions & 4 deletions models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .models import CustomCNN
from .modules import SRLModules, SRLModulesSplit
from .priors import SRLConvolutionalNetwork, SRLDenseNetwork, SRLCustomCNN, Discriminator
from .supervised import ConvolutionalNetwork, DenseNetwork, CustomCNN
from .base_models import CustomCNN, UNet
from .modules import SRLModules
from .supervised import ConvolutionalNetwork, DenseNetwork
from .autoencoders import LinearAutoEncoder, DenseAutoEncoder, CNNAutoEncoder
from .vae import DenseVAE, CNNVAE

Loading