title: Deep Reinforcement Learning - CartPole Problem

body:
I tried to implement the most simple Deep Q Learning algorithm. I think, I've implemented it right and know that Deep Q Learning struggles with divergences but the reward is declining very fast and the loss is diverging. I would be grateful if someone could help me pointing out the right hyperparameters or if I implemented the algorithm wrong. I've tried a lot of hyperparameter combinations and also changing the complexity of the QNet.
import torch
import torch.optim as optim
import torch.nn as nn
import torch.nn.functional as F
import collections
import numpy as np
import matplotlib.pyplot as plt
import gym
from torch.nn.modules.linear import Linear
from torch.nn.modules.loss import MSELoss

class ReplayBuffer:
  def __init__(self, max_replay_size, batch_size):
    self.max_replay_size = max_replay_size
    self.batch_size      = batch_size
    self.buffer          = collections.deque()

def push(self, *transition):
    if len(self.buffer) == self.max_replay_size:
        self.buffer.popleft()
    self.buffer.append(transition)

def sample_batch(self):
    indices = np.random.choice(len(self.buffer), self.batch_size, replace = False)
    batch   = [self.buffer[index] for index in indices]

    state, action, reward, next_state, done = zip(*batch)

    state      = np.array(state)
    action     = np.array(action)
    reward     = np.array(reward)
    next_state = np.array(next_state)
    done       = np.array(done)

    return state, action, reward, next_state, done

def __len__(self):
    return len(self.buffer)

class QNet(nn.Module):
  def __init__(self, state_dim, action_dim):
    super(QNet, self).__init__()

    self.linear1 = Linear(in_features = state_dim, out_features = 64)
    self.linear2 = Linear(in_features = 64, out_features = action_dim)

  def forward(self, x):
    x = self.linear1(x)
    x = F.relu(x)
    x = self.linear2(x)
    return x

def train(replay_buffer, model, target_model, discount_factor, mse, optimizer):
  state, action, reward, next_state, _ = replay_buffer.sample_batch()
  state, next_state = torch.tensor(state, dtype = torch.float), torch.tensor(next_state,
  dtype = torch.float)

  # Compute Q Value and Target Q Value
  q_values = model(state).gather(1, torch.tensor(action, dtype = torch.int64).unsqueeze(-1))

  with torch.no_grad():
    max_next_q_values = target_model(next_state).detach().max(1)[0]
    q_target_value = torch.tensor(reward, dtype = torch.float) + discount_factor *
                     max_next_q_values

  optimizer.zero_grad()
  loss = mse(q_values, q_target_value.unsqueeze(1))
  loss.backward()
  optimizer.step()

  return loss.item()

def main():
  # Define Hyperparameters and Parameters
  EPISODES        = 10000
  MAX_REPLAY_SIZE = 10000
  BATCH_SIZE      = 32
  EPSILON         = 1.0
  MIN_EPSILON     = 0.05
  DISCOUNT_FACTOR = 0.95
  DECAY_RATE      = 0.99
  LEARNING_RATE   = 1e-3
  SYNCHRONISATION = 33
  EVALUATION      = 32

  # Initialize Environment, Model, Target-Model, Optimizer, Loss Function and Replay Buffer
  env = gym.make("CartPole-v0")

  model        = QNet(state_dim = env.observation_space.shape[0], action_dim =
                 env.action_space.n)
  target_model = QNet(state_dim = env.observation_space.shape[0], action_dim =
                 env.action_space.n)
  target_model.load_state_dict(model.state_dict())

  optimizer = optim.Adam(model.parameters(), lr = LEARNING_RATE)
  mse       = MSELoss()

  replay_buffer = ReplayBuffer(max_replay_size = MAX_REPLAY_SIZE, batch_size = BATCH_SIZE)

  while len(replay_buffer) != MAX_REPLAY_SIZE:
    state = env.reset()
    done  = False
    while done != True:
        action = env.action_space.sample()

        next_state, reward, done, _ = env.step(action)

        replay_buffer.push(state, action, reward, next_state, done)

        state = next_state

  # Begin with the Main Loop where the QNet is trained
  count_until_synchronisation = 0
  count_until_evaluation      = 0
  history = {'Episode': [], 'Reward': [], 'Loss': []}
  for episode in range(EPISODES):
    total_reward = 0.0
    total_loss   = 0.0
    state        = env.reset()
    iterations   = 0
    done         = False
    while done != True:
        count_until_synchronisation += 1
        count_until_evaluation      += 1

        # Take an action
        if np.random.rand(1) < EPSILON:
            action = env.action_space.sample()
        else:
            with torch.no_grad():
                output = model(torch.tensor(state, dtype = torch.float)).numpy()
            action = np.argmax(output)

        # Observe new state and reward + store into replay_buffer
        next_state, reward, done, _ = env.step(action)
        total_reward += reward

        replay_buffer.push(state, action, reward, next_state, done)

        state = next_state

        if count_until_synchronisation % SYNCHRONISATION == 0:
            target_model.load_state_dict(model.state_dict())

        if count_until_evaluation % EVALUATION == 0:
            loss = train(replay_buffer = replay_buffer, model = model, target_model =
                         target_model, discount_factor = DISCOUNT_FACTOR,
                         mse = mse, optimizer = optimizer)
            total_loss += loss

        iterations += 1

    print (f"Episode {episode} is concluded in {iterations} iterations with a total reward
           of {total_reward}")

    if EPSILON > MIN_EPSILON:
        EPSILON *= DECAY_RATE

    history['Episode'].append(episode)
    history['Reward'].append(total_reward)
    history['Loss'].append(total_loss)

# Plot the Loss + Reward per Episode
fig, ax = plt.subplots(figsize = (10, 6))
ax.plot(history['Episode'], history['Reward'], label = "Reward")
ax.set_xlabel('Episodes', fontsize = 15)
ax.set_ylabel('Total Reward per Episode', fontsize = 15)
plt.legend(prop = {'size': 15})
plt.show()

fig, ax = plt.subplots(figsize = (10, 6))
ax.plot(history['Episode'], history['Loss'], label = "Loss")
ax.set_xlabel('Episodes', fontsize = 15)
ax.set_ylabel('Total Loss per Episode', fontsize = 15)
plt.legend(prop = {'size': 15})
plt.show()

if __name__ == "__main__":
  main()


title: RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation. Can't understand why?

body:
Use case, I am training model 1 (using train1) with a specific loss function that involves tensor A. I am accumulating the loss and then want to perform an update. Next I am training a second model 2 (train2) in which I want to calculate the gradients wrt A using the loss calculated in train2. Thus I am adding loss 1 to loss2.
#reproduce error
from transformers import BertModel, BertForMaskedLM, BertConfig, EncoderDecoderModel
import torch
import torch.nn.functional as F
model1 = EncoderDecoderModel.from_encoder_decoder_pretrained('bert-base-uncased', 'bert-base-uncased') # initialize Bert2Bert from pre-trained checkpoints
model2 = EncoderDecoderModel.from_encoder_decoder_pretrained('bert-base-uncased', 'bert-base-uncased') # initialize Bert2Bert from pre-trained checkpoints

optimizer1 = torch.optim.Adam(model1.parameters(), lr=0.001)
A=torch.rand(1, requires_grad=True)
optimizer3 = torch.optim.SGD([A], lr=0.1)

en_input=torch.tensor([[1,2], [3,4]])
en_masks=torch.tensor([[0,0], [0,0]])
de_output=torch.tensor([[3,1], [4,2]])
de_masks=torch.tensor([[0,0], [0,0]])
lm_labels=torch.tensor([[5,7], [6,8]])

torch.autograd.set_detect_anomaly(True)

def train1():
  acc=torch.zeros(1)
  for i in range(2):
    optimizer1.zero_grad()
    out = model1(input_ids=en_input, attention_mask=en_masks, decoder_input_ids=de_output,
                        decoder_attention_mask=de_masks, labels=lm_labels.clone())

    prediction_scores = out[1]
    predictions = F.log_softmax(prediction_scores, dim=2)
    p=((predictions.sum() - de_output.sum())*A).sum()
    p=torch.unsqueeze(p, dim=0)
    acc = torch.cat((p,acc)) # accumulating the loss

  loss=acc.sum()
  A.retain_grad()
  loss.backward(retain_graph=True)
  optimizer1.step()
  return loss

def train2(loss1):
  for i in range (2):
     optimizer3.zero_grad()
     output = model2(input_ids=en_input, attention_mask=en_masks,
                               decoder_input_ids=de_output,
                      decoder_attention_mask=de_masks, labels=lm_labels.clone())

     prediction_scores_ = output[1]
     predictions_= F.log_softmax(prediction_scores_, dim=2)
     loss2=((predictions_.sum() - de_output.sum())).sum()+loss1 # want to calculate gradients wrt A
     A.retain_grad()
     loss2.backward(inputs=[A], retain_graph=True)
     optimizer3.step() #update A based on calculated gradients

loss1=train1()
train2(loss1)

If this is the right method, I am not understanding whats wrong in my code? If its not right, I would appreciate if someone pointed me in the right direction
Error trace
/usr/local/lib/python3.7/dist-packages/torch/autograd/__init__.py:147: UserWarning: Error detected in MulBackward0. Traceback of forward call that caused the error:
  File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py", line 16, in <module>
    app.launch_new_instance()
  File "/usr/local/lib/python3.7/dist-packages/traitlets/config/application.py", line 845, in launch_instance
    app.start()
  File "/usr/local/lib/python3.7/dist-packages/ipykernel/kernelapp.py", line 499, in start
    self.io_loop.start()
  File "/usr/local/lib/python3.7/dist-packages/tornado/platform/asyncio.py", line 132, in start
    self.asyncio_loop.run_forever()
  File "/usr/lib/python3.7/asyncio/base_events.py", line 541, in run_forever
    self._run_once()
  File "/usr/lib/python3.7/asyncio/base_events.py", line 1786, in _run_once
    handle._run()
  File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/local/lib/python3.7/dist-packages/tornado/platform/asyncio.py", line 122, in _handle_events
    handler_func(fileobj, events)
  File "/usr/local/lib/python3.7/dist-packages/tornado/stack_context.py", line 300, in null_wrapper
    return fn(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/zmq/eventloop/zmqstream.py", line 451, in _handle_events
    self._handle_recv()
  File "/usr/local/lib/python3.7/dist-packages/zmq/eventloop/zmqstream.py", line 480, in _handle_recv
    self._run_callback(callback, msg)
  File "/usr/local/lib/python3.7/dist-packages/zmq/eventloop/zmqstream.py", line 434, in _run_callback
    callback(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/tornado/stack_context.py", line 300, in null_wrapper
    return fn(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/ipykernel/kernelbase.py", line 283, in dispatcher
    return self.dispatch_shell(stream, msg)
  File "/usr/local/lib/python3.7/dist-packages/ipykernel/kernelbase.py", line 233, in dispatch_shell
    handler(stream, idents, msg)
  File "/usr/local/lib/python3.7/dist-packages/ipykernel/kernelbase.py", line 399, in execute_request
    user_expressions, allow_stdin)
  File "/usr/local/lib/python3.7/dist-packages/ipykernel/ipkernel.py", line 208, in do_execute
    res = shell.run_cell(code, store_history=store_history, silent=silent)
  File "/usr/local/lib/python3.7/dist-packages/ipykernel/zmqshell.py", line 537, in run_cell
    return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py", line 2718, in run_cell
    interactivity=interactivity, compiler=compiler, result=result)
  File "/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py", line 2822, in run_ast_nodes
    if self.run_code(code, result):
  File "/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py", line 2882, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-66-c603f915c713>", line 78, in <module>
    loss1=train1()
  File "<ipython-input-66-c603f915c713>", line 25, in train1
    p=((predictions.sum() - de_output.sum())*A).sum()
 (Triggered internally at  /pytorch/torch/csrc/autograd/python_anomaly_mode.cpp:104.)
  allow_unreachable=True, accumulate_grad=True)  # allow_unreachable flag
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-66-c603f915c713> in <module>()
     77 for i in range(2):
     78   loss1=train1()
---> 79   train2(loss1)

2 frames
<ipython-input-66-c603f915c713> in train2(loss1)
     69     print(A.grad)
     70     #loss2.grad(inputs=A,outputs=A, only_inputs=True)
---> 71     loss2.backward(inputs=[A],retain_graph=True) #calculates gradients # retain_graph=True #list(dec.parameters())
     72     print(A.grad)
     73     # torch.nn.utils.clip_grad_norm_(model1.parameters(), 1.0)

/usr/local/lib/python3.7/dist-packages/torch/tensor.py in backward(self, gradient, retain_graph, create_graph, inputs)
    243                 create_graph=create_graph,
    244                 inputs=inputs)
--> 245         torch.autograd.backward(self, gradient, retain_graph, create_graph, inputs=inputs)
    246
    247     def register_hook(self, hook):

/usr/local/lib/python3.7/dist-packages/torch/autograd/__init__.py in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables, inputs)
    145     Variable._execution_engine.run_backward(
    146         tensors, grad_tensors_, retain_graph, create_graph, inputs,
--> 147         allow_unreachable=True, accumulate_grad=True)  # allow_unreachable flag
    148
    149

RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [1]] is at version 1; expected version 0 instead. Hint: the backtrace further above shows the operation that failed to compute its gradient. The variable in question was changed in there or anywhere later. Good luck!


Description
I am using PTAN library with an A3C model and I am trying to work with wandb sweep but I've encountered some weird problems, and I am not sure if it's a bug regarding sweep (because if I am going to use just a simple model without any threads involving is going to work properly) or I am doing something wrong.
How to reproduce
training function:
def train(conf):
    batch = []
    step_idx = 0
    epoch = conf['epochs']
    try:
        with commune.RewardTracker(writer, stop_reward=conf['reward_bound']) as tracker:
            with ptan.common.utils.TBMeanTracker(writer, batch_size=100) as tb_tracker:
                while True:
                    if step_idx == epoch:
                        break
                    train_entry = train_queue.get()
                    if isinstance(train_entry, TotalReward):
                        if tracker.reward(train_entry.reward, step_idx):
                            break
                        continue
                    if isinstance(train_entry, TotalProfit):
                        tracker.profits(train_entry.total_profit, train_entry.curr_profit, step_idx)
                        continue
                    step_idx += 1
                    if step_idx % 100 == 0:
                        torch.save(net.state_dict(), os.path.join(SAVING_FOLDER, PROJECT_NAME))

                    batch.append(train_entry)
                    if len(batch) < conf['batch_size']:
                        continue

                    states_v, actions_t, vals_ref_v = commune.unpack_batch(batch, net,
                                                                           last_val_gamma=conf['gamma'] ** conf['reward_steps'],
                                                                           device=device)
                    batch.clear()

                    optimizer.zero_grad()
                    logits_v, value_v = net(states_v)

                    loss_value_v = F.mse_loss(value_v.squeeze(-1), vals_ref_v)

                    log_prob_v = F.log_softmax(logits_v, dim=1)
                    adv_v = vals_ref_v - value_v.detach()
                    log_prob_actions_v = adv_v * log_prob_v[range(conf['batch_size']), actions_t]
                    loss_policy_v = -log_prob_actions_v.mean()

                    prob_v = F.softmax(logits_v, dim=1)
                    entropy_loss_v = conf['entropy_beta'] * (prob_v * log_prob_v).sum(dim=1).mean()

                    loss_v = entropy_loss_v + loss_value_v + loss_policy_v
                    loss_v.backward()
                    nn_utils.clip_grad_norm_(net.parameters(), conf['clip_grad'])
                    optimizer.step()

                    tb_tracker.track("advantage", adv_v, step_idx)
                    tb_tracker.track("values", value_v, step_idx)
                    tb_tracker.track("batch_rewards", vals_ref_v, step_idx)
                    tb_tracker.track("loss_entropy", entropy_loss_v, step_idx)
                    tb_tracker.track("loss_policy", loss_policy_v, step_idx)
                    tb_tracker.track("loss_value", loss_value_v, step_idx)
                    tb_tracker.track("loss_total", loss_v, step_idx)
    finally:
        for p in data_proc_list:
            p.terminate()
            p.join()

main function:
if __name__ == "__main__":
    mp.set_start_method('fork')
    device = torch.device("cuda:0" if use_cuda else "cpu")

    with open(r'sweep_config.yaml') as file:
        sweep_config = yaml.load(file, Loader=yaml.FullLoader)

    logs_dir_name = "a3c_stock"
    wandb.tensorboard.patch(root_logdir=logs_dir_name)

    sweep_id = wandb.sweep(sweep_config, project="sweep_project", entity="vildnex")
    wandb.init(config=config_default)

    config = wandb.config

    writer = SummaryWriter(comment=logs_dir_name)

    env = make_env(config)
    net = commune.AtariA2C(env.observation_space.shape, env.action_space.n).to(device)
    net.share_memory()

    if not os.path.isdir(SAVING_FOLDER):
        os.mkdir(SAVING_FOLDER)

    if os.path.isfile(os.path.join(SAVING_FOLDER, PROJECT_NAME)):
        net.load_state_dict(torch.load(os.path.join(SAVING_FOLDER, PROJECT_NAME), map_location=device))

    optimizer = optim.RMSprop(net.parameters(), lr=config.learning_rate, eps=1e-3)

    train_queue = mp.Queue(maxsize=config.processes_count)
    data_proc_list = []
    dict_conf = dict(config)
    for _ in range(config.processes_count):
        data_proc = mp.Process(target=data_func, args=(net, device, train_queue, dict_conf))
        data_proc.start()
        data_proc_list.append(data_proc)

    wandb.agent(sweep_id, lambda: train(dict_conf))

Error message:
Exception in thread Thread-6:
Traceback (most recent call last):
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/agents/pyagent.py", line 303, in _run_job
    self._function()
  File "<PATH>/RL_TraningBot/EXPERIMENTS/A3C_TEST.py", line 191, in <lambda>
    wandb.agent(sweep_id, lambda: train(dict_conf))
  File "<PATH>/RL_TraningBot/EXPERIMENTS/A3C_TEST.py", line 105, in train
    tracker.profits(train_entry.total_profit, train_entry.curr_profit, step_idx)
  File "<PATH>/RL_TraningBot/EXPERIMENTS/commune.py", line 118, in profits
    self.writer.add_scalar("total_profit", total_profit, frame)
  File "<PATH>/venv/lib/python3.9/site-packages/torch/utils/tensorboard/writer.py", line 344, in add_scalar
    self._get_file_writer().add_summary(
  File "<PATH>/venv/lib/python3.9/site-packages/torch/utils/tensorboard/writer.py", line 250, in _get_file_writer
    self.file_writer = FileWriter(self.log_dir, self.max_queue,
  File "<PATH>/venv/lib/python3.9/site-packages/torch/utils/tensorboard/writer.py", line 60, in __init__
    self.event_writer = EventFileWriter(
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/integration/tensorboard/monkeypatch.py", line 157, in __init__
    _notify_tensorboard_logdir(logdir, save=save, root_logdir=root_logdir_arg)
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/integration/tensorboard/monkeypatch.py", line 167, in _notify_tensorboard_logdir
    wandb.run._tensorboard_callback(logdir, save=save, root_logdir=root_logdir)
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/sdk/wandb_run.py", line 804, in _tensorboard_callback
    self._backend.interface.publish_tbdata(logdir, save, root_logdir)
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/sdk/interface/interface.py", line 202, in publish_tbdata
    self._publish(rec)
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/sdk/interface/interface.py", line 518, in _publish
    raise Exception("The wandb backend process has shutdown")
Exception: The wandb backend process has shutdown

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/agents/pyagent.py", line 308, in _run_job
    wandb.finish(exit_code=1)
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/sdk/wandb_run.py", line 2374, in finish
    wandb.run.finish(exit_code=exit_code)
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/sdk/wandb_run.py", line 1144, in finish
    if self._wl and len(self._wl._global_run_stack) > 0:
  File "<PATH>/venv/lib/python3.9/site-packages/wandb/sdk/wandb_setup.py", line 234, in __getattr__
    return getattr(self._instance, name)
AttributeError: 'NoneType' object has no attribute '_global_run_stack'

Environment

OS: Manjaro 5.21.5
Environment: PyCharm Local
Python Version: 3.9


title: Can I assign the coordinate that convolutional filter works on?

body:
I do not want the conv kernel to slide every pixel in the image, I only need to to do conv operation on the pixels I assigned. For example, on a 224 x 224 image, normally the conv operation will slide all 224 x 224 = 50176 pixels. However, if I only want it to do conv on (15,67), (34, 90), (143,201)...., how can I do it?
BTW, I want these operations all run on GPU.
Thanks a lot!


title: Increasing number of artificial images generated with DCGAN

body:
I am actually working with DCGAN (Py-Torch implementation), and the output is always a 64-sized grid of artificial images per epoch. I would like to increase such number, but do not know (I do not know which parameter to change, but I tried to check the code without success).
Does anyone have some idea of how to do that?

The entire Py-Torch implementation of DCGAN can be found in the following link:
https://pytorch.org/tutorials/beginner/dcgan_faces_tutorial.html


title: Hosting a Pytorch Environment on Azure with Jupyter Notebooks usng Active Directory Authentication

body:
I am looking for a way for non-technical employees within my company to access a Jupyter Notebook hosted on a python environment (with pytorch) hosted on Azure, with active directory authentication. I do not want to use the Azure Machine Learning tools. The goal is to setup an Azure VM with the Jupyter Notebook script along with the necessary dataset/files that the script needs to access existing in the VM's resources. A simple use case would be a user clicks a link directing them to Active Directory authentication, then once logged in, takes them directly to the Jupyter notebook containing a single script that the user can execute, but not edit. The VM also needs to have dependencies such as Pytorch and Scikit-learn. Does anybody know a possible solution to this?

I would use notebooks.azure.com, however there is no current functionality for privately sharing notebooks.


title: 3D Conv on non-overlapping blocks of a 3D tensor then remapping them (pytorch)

body:
Hi I have a 3D tensor of size (128,128,128) as input to my model. When it enters the model it has the shape (8, 4, 128, 128, 128) which is (Batch, Channels, H, W, D).

I would like to separate the channels and perform a convolution on blocks of (32,32,32) for this (128,128,128) input. Then I wish to take the conv weights and multiply it with the input values to the conv and remap them to a (128,128,128) block.

My current inefficient solution (using many for loops, converting between numpy<->tensor, and scikit-image) is below however it takes too long and requires too much memory. What's the best way to do this on tensors?

from skimage.util.shape import view_as_blocks

class LFBlock(nn.Module):
    def __init__(self, input_shape=(128,128,128), kernel_size=(1,1,1), blk_div=4):
        super(LFBlock,self).__init__()

        # Divides the (128,128,128)//4 -> (32,32,32)
        self.block_shape = (input_shape[0]//blk_div, input_shape[1]//blk_div, input_shape[2]//blk_div)

        self.num_blocks = (input_shape[0]//self.block_shape[0])*(input_shape[0]//self.block_shape[0])*\
        (input_shape[0]//self.block_shape[0])

        conv_list = []
        for n in range(self.num_blocks):
            conv_list.append(nn.Conv3d(1,1, kernel_size=kernel_size, stride=1, padding=0, bias=True))

        self.conv1x1s = nn.ModuleList(conv_list)

    def forward(self, lf_in):
        # Batch
        for i in range(lf_in.shape[0]):
            # Modality
            for ch in range(lf_in.shape[1]):
                x_lf = lf_in[i,ch,:]
                lf_blocks = view_as_blocks(x_lf.cpu().numpy(), block_shape=self.block_shape)

                # Do Conv3d on each block
                for x in range(len(lf_blocks)):
                    for y in range(len(lf_blocks)):
                        for z in range(len(lf_blocks)):

                            conv_idx = x*len(lf_blocks) + y*len(lf_blocks) + z

                            # Convolve the block, then multiply with the weight of the block.
                            tensor_img = torch.from_numpy(lf_blocks[x,y,z])[None, None,:]
                            conv = self.conv1x1s[conv_idx](tensor_img.cuda())

                            # w * x.
                            # view_as_blocks returns a view so modifications are done in-place

                            lf_blocks[x,y,z] = tensor_img.cpu()*self.conv1x1s[conv_idx].weight.data.cpu()

        # Linearly sum the modalities together
        # out = w0*x0 + w1*x1 + w2*x2 + w3*x3
        out = (lf_in[:,0]+lf_in[:,1]+lf_in[:,2]+lf_in[:,3])[:,None]

        return out

Any help is appreciated. Thank you!


title: How to compose several matrices into a big matrix diagonally in Pytorch

body:
I have several matrices, let's say [M1,M2,M3,M4]. Each matrix has a different shape. How do I compose these matrices into one big matrix diagonally like:
[[M1, 0, 0, 0]
 [0, M2, 0, 0]
 [0, 0, M2, 0]
 [0, 0, 0, M2]]

Example:
M1 = [[1,2],[2,1]]
M2 = [[1,2]]
M3 = [[3]]
M4 = [[3,4,5],[4,5,6]]

To compose this big matrix:
[[1, 2, 0, 0, 0, 0, 0]
 [2, 1, 0, 0, 0, 0, 0]
 [0, 0, 1, 2, 0, 0, 0]
 [0, 0, 0, 0, 3, 4, 5]
 [0, 0, 0, 0, 4, 5, 6]]


title: Picking 1 action out of multiple continous actions

body:
Im trying to implement an environment where you have multiple dials which can be turned from 0-100. Only 1 dial can be turned at each step. So far i did it with a discrete actionspace giving 100 action for each dial, so the agent would pick a dial and a position.
I would like to convert it to continous actionspace. To do so i took a look at the implementation of a2c for BipedalWalker-v2. The problem i am facing now is that these implementations return an action for each actuator. In my case the agent is only allowed to choose 1 actuator and turn it from 0-100. What would be the optimal approach to do so?


title: pytorch net creation does not generate weights if done in a list

body:
I'm creating a net in pytorch by writing a class called MyNet with init() and forward() method.
If I create a layer in init() like:

self.fc = nn.Linear(5, 10)

everything works fine and

net = MyNet()
paramL = list(net.parameters())

gives me a list with some weights inside.
However, if I create layers in the following way

self.layerL = [nn.Linear(5,10)]

something seems to go wrong, since list(net.parameters()) now gives an empty list :-(

Any idea what I'm doing wrong ??

Many thanks


title: torch tensor changes to numpy array in for/while loop?

body:
print('\nCollecting experience')
for ep in range(400):
  state = env.reset()
  #print(state.shape)
  #state = np.array(state)
  state = state.transpose((2, 0, 1))
  #state = torch.from_numpy(state)
  state = Variable(torch.from_numpy(state))
  state = state.unsqueeze(0)
  print("AA", state.shape)
  episode_reward = 0
  step = 0

  for i in range(50):
    # env.render()
    print("BB",state.shape)
    action = agent.get_action(state)

i have tried and it works without the loop, it doesn't work with while loop either

what is printed:

Collecting experience
AA torch.Size([1, 1, 84, 84])
BB torch.Size([1, 1, 84, 84])
BB (84, 84, 1)

what is causing the second BB print?


title: run conv2d against a list

body:
I tested conv2d with following code:

import torch
import torch.nn as nn

x=torch.randint(500,(256,))
conv=nn.Conv2d(1,6,5,padding=1)
y=x.view(1,1,16,16)
z=conv(y)
print (z.shape)

and I got error:

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/conv.py in conv2d_forward(self, input, weight)
    340                             _pair(0), self.dilation, self.groups)
    341         return F.conv2d(input, weight, self.bias, self.stride,
--> 342                         self.padding, self.dilation, self.groups)
    343
    344     def forward(self, input):

RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'weight' in call to _thnn_conv2d_forward

How to fix it?


title: no reference to Module.parameters() after using more than once

body:
I have a class that inherits from torch.nn.Module,

now when I do this code:

d = net.parameters()
print(len(list(d)))
print(len(list(d)))
print(len(list(d)))

the output is:

10
0
0

So I have reference to the net.parameters() only once, whys that?

Then it apparently disappear..
I got this error while trying to make my own Optimizer, so I pass this net.parameters() as a parameter to my new class, and apparently I couldn't use it because of that odd situation.


title: Pytorch, backprop and composite models

body:
Just a quick check for a question I have.

I want to build a model that generates its output based on two models F and G like so.

y = G(F(x))

where x is of course the input, and y the output.

However, first I want to update the weights of the F(x) and then later update the weights of both F and G based on the value of y.

I understand that pytorch offers a way to specify your own backprop method.. but since my "method" seems to build out of basic components, could it be that I can do this with a standard solution?

My thoughts would be that I need separate optimizer/loss for the F and G objects. But in addition to that, also some update functionality for the composite model G(F()). Can anyone confirm this as well?


title: Find specific element index from Tensor(Matrix)

body:
I am a student just beginning to study deep learning.

   x_norm = (x**2).sum(1).view(-1, 1)
   if y is not None:
       y_norm = (y**2).sum(1).view(1, -1)
   else:
       y = x
       y_norm = x_norm.view(1, -1)
   ## NOTICE ##
   dist = torch.exp(-1*(x_norm + y_norm - 2.0 * torch.mm(x, torch.transpose(y, 0, 1))))
   return dist

dist = pairwise_distances(atom_s[:3,-3:])
zero_mat=torch.zeros_like(dist,dtype=torch.float)
dist= torch.where(dist>exp(-8),dist,zero_mat)

Above is my coding to make pairwise distance map. And change some element that satiesfy a condition to 0.

Question is that "how can I get indexes of elements that satiesfy specific condition ( e.g larger than >0.5)?? without using slow 'for' loop.


title: Pytorch-Optimzer doesn't update parameters

body:
I made my custom model, AlexNetQIL (Alexnet with QIL layer)
'QIL' means quantization intervals learning
I trained my model and loss value didn't decrease at all and I found out parameters in my model were not updated at all because of QIL layer I added
I attached my codes AlexNetQil and qil
please someone let me know what's the problem in my codes

AlexNetQIL

import torch
import torch.nn as nn
from qil import *

class AlexNetQIL(nn.Module):

    #def __init__(self, num_classes=1000): for imagenet
    def __init__(self, num_classes=10): # for cifar-10
        super(AlexNetQIL, self).__init__()

        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=2, padding=1)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu2 = nn.ReLU(inplace=True)
        self.maxpool1 = nn.MaxPool2d(kernel_size=2)

        self.qil2 = Qil()
        self.conv2 = nn.Conv2d(64, 192, kernel_size=3, padding=1)
        self.bn2 = nn.BatchNorm2d(192)
        self.relu2 = nn.ReLU(inplace=True)
        self.maxpool2 = nn.MaxPool2d(kernel_size=2)

        self.qil3 = Qil()
        self.conv3 = nn.Conv2d(192, 384, kernel_size=3, padding=1)
        self.bn3 = nn.BatchNorm2d(384)
        self.relu3 = nn.ReLU(inplace=True)

        self.qil4 = Qil()
        self.conv4 = nn.Conv2d(384, 256, kernel_size=3, padding=1)
        self.bn4 = nn.BatchNorm2d(256)
        self.relu4 = nn.ReLU(inplace=True)

        self.qil5 = Qil()
        self.conv5 = nn.Conv2d(256, 256, kernel_size=3, padding=1)
        self.bn5 = nn.BatchNorm2d(256)
        self.relu5 = nn.ReLU(inplace=True)
        self.maxpool5 = nn.MaxPool2d(kernel_size=2)

        self.classifier = nn.Sequential(
            nn.Linear(256 * 2 * 2, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )
    def forward(self,x,inference = False):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu2(x)
        x = self.maxpool1(x)

        x,self.conv2.weight = self.qil2(x,self.conv2.weight,inference ) # if I remove this line, No problem
        x = self.conv2(x)
        x = self.bn2(x)
        x = self.relu2(x)
        x = self.maxpool2(x)

        x,self.conv3.weight = self.qil3(x,self.conv3.weight,inference ) # if I remove this line, No problem
        x = self.conv3(x)
        x = self.bn3(x)
        x = self.relu3(x)

        x,self.conv4.weight = self.qil4(x,self.conv4.weight,inference ) # if I remove this line, No problem
        x = self.conv4(x)
        x = self.bn4(x)
        x = self.relu4(x)

        x,self.conv5.weight = self.qil5(x,self.conv5.weight,inference ) # if I remove this line, No problem
        x = self.conv5(x)
        x = self.bn5(x)
        x = self.relu5(x)
        x = self.maxpool5(x)
        x = x.view(x.size(0),256 * 2 * 2)
        x = self.classifier(x)
        return x

QIL

forward

quantize weights and input activation with 2 steps
transformer(params) -> discretizer(params)

import torch
import torch.nn as nn
import numpy as np
import copy

#Qil (Quantize intervals learning)
class Qil(nn.Module):

    discretization_level = 32
    def __init__(self):
        super(Qil,self).__init__()
        self.cw = nn.Parameter(torch.rand(1)) # I have to train this interval parameter
        self.dw = nn.Parameter(torch.rand(1)) # I have to train this interval parameter
        self.cx = nn.Parameter(torch.rand(1)) # I have to train this interval parameter
        self.dx = nn.Parameter(torch.rand(1)) # I have to train this interval parameter
        self.gamma = nn.Parameter(torch.tensor(1.0))  # I have to train this transformer parameter

        self.a = Qil.discretization_level
    def forward(self,x,weights,Inference = False):
        if not Inference:
            weights = self.transfomer_weights(weights)
            weights = self.discretizer(weights)
        x = self.transfomer_activation(x)
        x = self.discretizer(x)
        return torch.nn.Parameter(x), torch.nn.Parameter(weights)

    def transfomer_weights(self,weights):
        device = weights.device
        aw,bw = (0.5 / self.dw) , (-0.5*self.cw / self.dw + 0.5)

        weights = torch.where( abs(weights) < self.cw - self.dw,
                                torch.tensor(0.).to(device),weights)
        weights = torch.where( abs(weights) > self.cw + self.dw,
                                weights.sign(), weights)
        weights = torch.where( (abs(weights) >= self.cw - self.dw) & (abs(weights) <= self.cw + self.dw),
                                (aw*abs(weights) + bw)**self.gamma * weights.sign() , weights)
        return weights

    def transfomer_activation(self,x):
        device = x.device
        ax,bx = (0.5 / self.dx) , (-0.5*self.cx / self.dx + 0.5)

        x = torch.where(x < self.cx - self.dx,
                        torch.tensor(0.).to(device),x)
        x = torch.where(x > self.cx + self.dx,
                        torch.tensor(1.0).to(device),x)
        x = torch.where( (abs(x) >= self.cx - self.dx) & (abs(x) <= self.cx + self.dx),
                            ax*abs(x) + bx, x)
        return x

    def discretizer(self,tensor):
        q_D = pow(2, Qil.discretization_level)
        tensor = torch.round(tensor * q_D) / q_D
        return tensor


title: How do I do a convolution in pytorch where the kernel is different for each minibatch?

body:
Let me express the title with an example:

Let A be a tensor of shape [16, 15, 128, 128] (which means [batchsize, channels, height, width])

Let B be a tensor of shape [16,  3, 128, 128] (which means [batchsize, channels, height, width])

I want to output a tensor of shape [16, 5, 128, 128] (which means [batchsize, channels, height, width])

Where the i_th channel of the 5 channels of the output is computed by
multiplying elementwise B with the i_th slice of 3 channels of A and them performing a sum along the channel dimension.

How would you do that operation in pytorch?

Thanks!

PD: It's very difficult to express what I want from the operation, if I wasn't clear, please ask me and I'll try to reexplain it


Here is the error I got

*** RuntimeError: size mismatch, m1: [288 x 9], m2: [2592 x 256] at /tmp/pip-req-build-4baxydiv/aten/src/TH/generic/THTensorMath.cpp:197

Here my model :

class DQN(nn.Module):
    def __init__(self, num_actions, lr):
        super(DQN, self).__init__()

        self.conv1 = nn.Conv2d(
            in_channels=4, out_channels=16, kernel_size=8, stride=4)
        self.conv2 = nn.Conv2d(
            in_channels=16, out_channels=32, kernel_size=4, stride=2)

        # You have to respect the formula ((W-K+2P/S)+1)
        self.fc = nn.Linear(in_features=32*9*9, out_features=256)
        self.out = nn.Linear(in_features=256, out_features=num_actions)

    def forward(self, state):
        import ipdb; ipdb.set_trace()
        # (1) Hidden Conv. Layer
        self.layer1 = F.relu(self.conv1(state))

        # (2) Hidden Conv. Layer
        self.layer2 = F.relu(self.conv2(self.layer1))

        # (3) Hidden Linear Layer
        self.layer3 = self.fc(self.layer2)

        # (4) Output
        actions = self.out(self.layer3)

        return actions

The error is triggered at line self.layer3 = self.fc(self.layer2). state is a pytorch tensor of shape (1, 4, 84, 84).

The full traceback is

Traceback (most recent call last):
  File "/home/infinity/Projects/Exercice_Project/AI_Exercices/Atari_2600_Breakout.py", line 228, in <module>
    action = agent.choose_action(state, policy_network)
  File "/home/infinity/Projects/Exercice_Project/AI_Exercices/Atari_2600_Breakout.py", line 166, in choose_action
    return policy_net(state).argmax(dim=1).to(self.device)
  File "/home/infinity/anaconda3/lib/python3.7/site-packages/torch/nn/modules/module.py", line 541, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/infinity/Projects/Exercice_Project/AI_Exercices/Atari_2600_Breakout.py", line 101, in forward
    self.layer3 = self.fc(self.layer2)
  File "/home/infinity/anaconda3/lib/python3.7/site-packages/torch/nn/modules/module.py", line 541, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/infinity/anaconda3/lib/python3.7/site-packages/torch/nn/modules/linear.py", line 87, in forward
    return F.linear(input, self.weight, self.bias)
  File "/home/infinity/anaconda3/lib/python3.7/site-packages/torch/nn/functional.py", line 1372, in linear
    output = input.matmul(weight.t())
RuntimeError: size mismatch, m1: [288 x 9], m2: [2592 x 256] at /tmp/pip-req-build-4baxydiv/aten/src/TH/generic/THTensorMath.cpp:197


title: What is the best practice for wrtting custom module in pytorch?

body:
class TfidfEmbeds(BaseEmbeds):
    # Input just placeholder
    def __init__(self, _=None):
        super().__init__()
        self.tfidf = TfidfVectorizer().fit([" ".join(i) for i in train_data])
        # Need these to map features
        self.tfidf_word_list = self.tfidf.get_feature_names()
        self.word_to_ix = {word: i for i, word in enumerate(self.tfidf_word_list)}
        self.cache = {}

    def forward(self, X):
        # Cache
        key = tuple(X)
        if key in self.cache:
            return cache[key]
        # Get text
        words = [word_list[i] for i in X.cpu().numpy()]
        idx = [self.word_to_ix[word] if word in self.word_to_ix else 0 for word in words]
        mask = [False if word in self.word_to_ix else True for word in words]
        outputs = self.tfidf.transform([" ".join(words)])[:, idx].toarray().reshape(-1, 1)
        outputs[mask] = 0
        self.cache[key] = outputs
        return torch.from_numpy(outputs).to(device).float()

    def get_output_dim(self):
        return 1

I have the above python code for encoding tfidf feature for a list of documents. I wrapped the code inside Module but apparently torch is not really appropriate as I am not using nn components. And one cannot save state_dict of such class. I want to know what is the proper way of creating such Modules in pytorch to allow better integration saving with .state_dict()?

Thanks


title: Does conv_transpose2d do a convolution or a cross-correlation operator?

body:
The documentation for the nn mentions it does a cross-correlation, however, my results indicate it does a convolution operator.

import torch
import torch.nn.functional as F
im = torch.Tensor([[0,1],[2,3]]).unsqueeze(0).unsqueeze(0)

kernel = torch.Tensor([[0,1,2],[3,4,5], [6,7,8]]).unsqueeze(0).unsqueeze(0)
op = F.conv_transpose2d(im, kernel, stride=2)
print(op)

It outputs :

tensor([[[[ 0.,  0.,  0.,  1.,  2.],
          [ 0.,  0.,  3.,  4.,  5.],
          [ 0.,  2., 10., 10., 14.],
          [ 6.,  8., 19., 12., 15.],
          [12., 14., 34., 21., 24.]]]])

which would be the result if there was a convolution, I had expected the correlation result to be:

tensor([[[[ 0.,  0.,  8.,  7.,  6.],
          [ 0.,  0.,  5.,  4.,  3.],
          [16., 14., 38., 22., 18.],
          [10.,  8., 21., 12.,  9.],
          [ 4.,  2.,  6.,  3.,  0.]]]])

Did I misunderstand something?


title: RuntimeError: shape '[10, 326400]' is invalid for input of size 326400

body:
Forming CNN with hidden layers
I have defined my
class Network(nn.Module):
def init(self):
super().init()
self.conv1 = nn.Conv2d(in_channels=1, out_channels=8, kernel_size=5) # Convolution layer 1
self.conv2 = nn.Conv2d(in_channels=8, out_channels=12, kernel_size=5) # Convolution layer 2
    self.fc1 = nn.Linear(in_features=12 * 100 * 272, out_features=120) # Linear layer 1 [Linear layer also called Fully Connected Layers]
    self.fc2 = nn.Linear(in_features=120, out_features=60) # Linear layer 2
    self.out = nn.Linear(in_features=60, out_features=3) # Linear layer 3 (output layer)

def forward(self, t):
    # input layer
    t=t
    # (2) hidden conv layer
    t = self.conv1(t)
    t = F.relu(t)
    t = F.max_pool2d(t, kernel_size=2, stride=2)

    # (3) hidden conv layer
    t = self.conv2(t)
    t = F.relu(t)
    t = F.max_pool2d(t, kernel_size=2, stride=2)

    # (4) hidden linear layer
    t = t.reshape(t.size(0), 12 * 100 * 272)
    t = self.fc1(t)
    t = F.relu(t)

    # (5) hidden linear layer
    t = self.fc2(t)
    t = F.relu(t)

    # (6) output layer
    t = self.out(t)
    #t = F.softmax(t, dim=1)

    return t

network = Network()
train_loader = torch.utils.data.DataLoader(train, batch_size=10)
optimizer = optim.Adam(network.parameters(), lr=0.01)
for epoch in range(8):
total_loss = 0
total_correct = 0

for batch in train_loader: # Get Batch
    images, labels = batch

    preds = network(images) # Pass Batch
    loss = F.cross_entropy(preds, labels) # Calculate Loss

    optimizer.zero_grad()
    loss.backward() # Calculate Gradients
    optimizer.step() # Update Weights

    total_loss += loss.item()
    total_correct += get_num_correct(preds, labels)

print("epoch", epoch, "total_correct:", total_correct, "loss:", total_loss)


title: Implementing Squeeze and Excitation block with pretrained resnet

body:
I am trying to implement SE block with any pretrained resnet architecture.
self.encoder = torchvision.models.resnet34(pretrained=pretrained)

self.conv1 = nn.Sequential(
    self.encoder.conv1,
    self.encoder.bn1,
    self.encoder.relu
    SeBlock(64,2),
    nn.MaxPool2d(2, 2) )

self.conv2 = nn.Sequential(
    self.encoder.layer1,
    SeBlock(64,2),
    )

self.conv3 = nn.Sequential(
    self.encoder.layer2,
    SeBlock(128,2),
    )

self.conv4 = nn.Sequential(
    self.encoder.layer3,
    SeBlock(256,2),
    )

self.conv5 = nn.Sequential(
    self.encoder.layer4,
    SeBlock(512,2),
    )

Above is my code but It is not working out. Looking into githubs they build resnet from scratch and induce SE block and then load model.state_dict() weights for the layers of resnet and train the remaining model.
I just need to know what is the correct procedure to use SE block with pretrained resnet.?
Thanks.!!


title: Problem using conv2d - wrong tensor input shape

body:
I need to forward a tensor [1, 3, 128, 128] representing a 128x128 rgb image into a
nn.Conv2d(128,128,1)

but I get the error
RuntimeError: Given groups=1, weight of size [128, 128, 1, 1], expected input[1, 3, 128, 128] to have 128 channels, but got 3 channels instead

PS: the image tensor is shaped as a 4d because the previous step is a nn.UpsamplingBilinear2d(size=None, scale_factor=2) which needs a 4d tensor as input


title: Seperating premise and hypothesis in MNLI

body:
I'm trying to implement Siamese like transformer architecture. Similar work has been done in SentenceBERT paper. I'm facing an issue. To seperate hypothesis and premise, I modify this line from _glue_convert_examples_to_features. Instead I do
batch_encoding_a = tokenizer(
        [example.text_a for example in examples],
        max_length=max_length,
        padding="max_length",
        truncation=True,
    )

Do the same thing for examples.text_b. Then I modify the GlueDataset by modifying this line mainly, since this will return two items now (segregated "hypothesis" and premise").
Then __getitem__ is modified accordingly to return self.features_a[i], self.features_b[i].
That's the gist of how I'm obtaining segregated "hypothesis" and "premise". These are then passed to two BERTs (or one BERT if its weights are kept frozen).
This is how I've defined the collate_fn
def siamese_data_collator(batch):
    features_a, features_b = [], []
    for item in batch:
        for k, v in item.items():
            if k == "a":
                features_a.append(v)
            else:
                features_b.append(v)
    return {
        "a": default_data_collator(features_a),
        "b": default_data_collator(features_b),
    }

Then the dataloader is created in the usual way. So when we iterate like this:
for inputs in dataloader:
    # we get inputs['a'] and inputs['b'] which is passed to the model

I had to modify _training_step and evaluate accordingly in the Trainer class.
Now the problem is, the model doesn't learn at all. I tried with using my model and modified Trainer with standard GlueDataset, and it works. This leads to the conclusion that something is off with the data. The model should learn something (even if is not being fed concatenated "hypothesis" and "premise".
The model basically has one BERT and one linear layer. The logits come from linear layer which is then used to compute loss function (typical siamese like architecture).
Can you suggest if there's an issue in how the Dataset is being created here, or propose something of your own to segregate "hypothesis" and "premise" so that they can be fed separately to BERT.


title: PyTorch: How to distribute training work according to performance of each GPU?

body:
I've run into this problem of trying to train a neural network with two GPUs. One is Nvidia 1070 and the other one is Nvidia 2070. Obviously, 2070 is faster than 1070 and so if I just throw the same amount of training samples in each of them, 1070 would become the bottleneck which slows down the training process.
What I'm trying to do is to have these two GPUs do different amount of work. For example, if my batch size is 100, I'd like to have my 2070 card to deal with 80% of them and my 1070 card to deal with 20% of them. Is this possible with existing APIs that PyTorch provides? PyTorch's DataParallel and DistributedDataParallel don't seem to support this.


title: How to apply multiprocessing with cuda?

body: I want to apply multiprocessing on some simple cuda-related problem as above(Jupyter Notebook). It ought to print out the tensor if everything goes well. However, nothing happens(even without any errors…) after running out all cells. And the ‘traditional’ method-----set_start_method(‘spawn’) didn’t help… I’m pretty eager to figure out the real problem.


title: How to add a (fake) callable parameter to my PyTorch model?

body:
I know that the code below would add torch.tensor([0.], requires_grad=True, dtype=torch.float64) as a parameter to myPyTorchModel:
myPyTorchModel = torch.nn.Parameter(torch.tensor([0.],
                                    requires_grad=True, dtype=torch.float64))

However, torch.tensor([0.], requires_grad=True, dtype=torch.float64) is not a callable parameter.
Is there any way that I can manually add a (fake) callable parameter to myPyTorchModel?
Thank you,


title: Feed Intermediate Hidden States from RNN to Fully Connected

body:
I am attempting to create a model that can predict a probability distribution based on a set of features. There may be multiple updates to the feature set which may correct the distribution. I was able to create a basic Neural Network with just a simple feature input and the distribution output without much problem but the addition of the update system made me opt to attach an RNN above the working model.
Without too much detail, I want to make the RNN output a hidden state per update step (per set of features). In other words, a set of features can be N length. The RNN takes (L, N) and output (L, M) where L is the sequence length and M is the hidden layer size. Then the following Neural Net takes (L, M) and creates L amounts of distributions. I need the intermediate results because I want to compute a loss between each of the distributions with the actual distribution. This way, the model will get progressively more accurate as I increase the L from 1 to maybe 15.
The following is what I have in the model class. As you can see, it's extremely inefficient as I break up the rnn output then feed it back into the neural net. The two issues are inefficient list manipulations and a latter problem of an even more over-complicated loss function calculation. I would have to copy L target distributions, and finally calculate the backpropagation. Is there a better method to do all of them?
def __init__(self):
    super(NN, self).__init__()
    self.out_length = int(max_num/step+2)

    self.rnn = nn.RNN(13, 64)

    self.network = nn.Sequential(nn.Linear(64, 64),
                                 nn.ELU(),
                                 nn.Linear(64, 64),
                                 nn.ELU(),
                                 nn.Linear(64, 64),
                                 nn.ELU(),
                                 nn.Linear(64, self.out_length),
                                 nn.ELU(),
                                 nn.Softmax()
                                )
    print(self)

def forward(self, features):
    rnn_output, hiddens = self.rnn(features.float(), None)
    rnn_output, lengths = pad_packed_sequence(rnn_output, batch_first=True)
    print(rnn_output.shape)
    print(lengths)
    output = [self.network(rnn_output[i,:,:]) for i in range(len(lengths))]
    return output


title: Does python return the reference or the copy of an element when accessing the elements of a generator/iterator in a for loop?

body:
I am a little confused by this behavior of python. Suppose I write
x = [1,2]
for i in x:
    i += 1
print(x)

The output would be
[1,2]

So it seems that when the code is run, i iterates over the copies of the elements in x because i += 1 does not modify the values in x.
However, when I was reading the pytorch official documents, I saw this piece of code:
for iterations...
    ...
    for param in model.parameters():
        param.grad = None
    loss.backward()

which is a proper substitute for zero_grad(). But for this to work, param must be references, not copies.
Exactly what happened in these two loops?


title: Tensorboard dimension error when visualize graph

body:
i am trying to get the add_graph()-function working in my project.
I run a bit modified code of this repo (iUnet)
The iUnet model is the same like this, just for 2D
I got the code of the pytorch-docus running fine
If you need more Information, just tell me what
Python 3.7.7,
torch                     1.5.1,
tensorboard               2.3.0,
y_forGraph = torch.randn(1, 4, 512, 512)
print("this is the shape of y_forGraph",y_forGraph.shape)
writer.add_graph(iunet, y_forGraph)

Thanks for the Help
this is the shape of y_forGraph torch.Size([1, 4, 512, 512])
Given groups=1, weight of size [4, 4, 3, 3], expected input[1, 0, 512, 512] to have 4 channels, but got 0 channels instead
Error occurs, No graph saved
Traceback (most recent call last):
  File "lud_train_loop_n.py", line 589, in <module>
    writer.add_graph(iunet, (y_forGraph,))
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/utils/tensorboard/writer.py", line 707, in add_graph
    self._get_file_writer().add_graph(graph(model, input_to_model, verbose))
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/utils/tensorboard/_pytorch_graph.py", line 291, in graph
    raise e
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/utils/tensorboard/_pytorch_graph.py", line 285, in graph
    trace = torch.jit.trace(model, args)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/jit/__init__.py", line 875, in trace
    check_tolerance, _force_outplace, _module_class)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/jit/__init__.py", line 1027, in trace_module
    module._c._create_method_from_trace(method_name, func, example_inputs, var_lookup_fn, _force_outplace)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/module.py", line 548, in __call__
    result = self._slow_forward(*input, **kwargs)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/module.py", line 534, in _slow_forward
    result = self.forward(*input, **kwargs)
  File "/home/lud/Dokumente/BA/UNET/iunets/networks.py", line 188, in forward
    x = self.module_L[i][j](x)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/module.py", line 548, in __call__
    result = self._slow_forward(*input, **kwargs)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/module.py", line 534, in _slow_forward
    result = self.forward(*input, **kwargs)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/memcnn/models/revop.py", line 201, in forward
    *(xin + tuple([p for p in self._fn.parameters() if p.requires_grad])))
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/memcnn/models/revop.py", line 40, in forward
    outputs = ctx.fn(*x)
  File "/home/lud/Dokumente/BA/UNET/iunets/layers.py", line 550, in forward
    y2 = x1 + self.F.forward(x2)
  File "/home/lud/Dokumente/BA/UNET/iunets/layers.py", line 637, in forward
    return self.F(x)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/module.py", line 548, in __call__
    result = self._slow_forward(*input, **kwargs)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/module.py", line 534, in _slow_forward
    result = self.forward(*input, **kwargs)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/container.py", line 100, in forward
    input = module(input)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/module.py", line 548, in __call__
    result = self._slow_forward(*input, **kwargs)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/module.py", line 534, in _slow_forward
    result = self.forward(*input, **kwargs)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/conv.py", line 353, in forward
    return self._conv_forward(input, self.weight)
  File "/home/lud/anaconda3/envs/unet_torch_env/lib/python3.7/site-packages/torch/nn/modules/conv.py", line 350, in _conv_forward
    self.padding, self.dilation, self.groups)
RuntimeError: Given groups=1, weight of size [4, 4, 3, 3], expected input[1, 0, 512, 512] to have 4 channels, but got 0 channels instead


title: How to get the file name of image that I put into Dataloader in Pytorch or read the image from 0 to 100?

body:
I use PyTorch to load images like this:
inf_data = InfDataloader(img_folder=args.imgs_folder, target_size=args.img_size)
inf_dataloader = DataLoader(inf_data, batch_size=1, shuffle=False, num_workers=2)

And then:
with torch.no_grad():
    for batch_idx, (img_np, img_tor) in enumerate(inf_dataloader, start=1):
        img_tor = img_tor.to(device)
        pred_masks, _ = model(img_tor)

But my input folder is like

Windows read files like: 000,001,002.....100,101,102,....110,111....
As the system doesn't read my file from 0 to 10, it will misorder the output files' order.
For example, the input is 0.png. The output is 183.png.
One way is that I hope to read the image from 0.png or I want to get the file name in Dataloader.
I also have a question here.
How to get the file name of image that I put into Dataloader in Pytorch


title: How to change variable from one TPU device for all TPU devices?

body:
Can I change variable within one TPU device so that it could be changed for other TPU devices ?
I tried the following approach:
!pip install cloud-tpu-client==0.10 https://storage.googleapis.com/tpu-pytorch/wheels/torch_xla-1.6-cp36-cp36m-linux_x86_64.whl
import torch
import torch_xla.core.xla_model as xm
a=torch.tensor([2], device=torch.device("cpu"))
def tr(rank, flags):
  device = xm.xla_device()
  global a
  if xm.is_master_ordinal():
    a=torch.tensor([3], device=torch.device("cpu"))
  xm.rendezvous('download_only_once')
  b = a.to(device)
  print(b)

import torch_xla.distributed.xla_multiprocessing as xmp
flags={}
xmp.spawn(tr, args=(flags,), nprocs=8, start_method='fork')

It doesn't work: the variable is not changing for other devices.


title: How to view all possible distributions that can be used in PyTorch kl_divergence function?

body: I would like to know what are all of the possible combinations of distributions I can plug into PyTorch's kl_divergence function out of the box. How can I view all of the possibilities?


title: Building Input Data pipeline for KITTI odometry dataset using Tensorflow 2.0

body:
Building an input data pipeline using PyTorch is pretty straight forward using Dataset class from torch.utils.
However, tensorflow made it simple for structured datasets. But, coming to the pipeline for KITTI odometry involves totally different approach involving stacking images and converting [R|T] matrix into 6DOF Euler’s labels
The reason for shifting to TensorFlow is to take advantage of Built-in history of models and Hparameters Tuning (simpler using Hparams).
Thank you very much in advance and It would be helpful for me if someone could drop some repositories or posts related to this in this thread.


title: Kymatio Scattering Transform 1D Error 'The input must be contiguous.'

body:
I am starting to work with the Kymatio library, in order to use the Scattering transform as an extractor of 1D signal characteristics. The final idea is to classify 1D signals.
I followed the example available at the link
https://www.kymat.io/gallery_1d/plot_classif_torch.html#sphx-glr-gallery-1d-plot-classif-torch-py
Based on this example, I imported three .mat files that contain the compiled data from the COOLL dataset (https://coolldataset.github.io/). Two variables were imported:
x2 contains the values of the appliance currents. x2 is a matrix with 840 lines and 4 * 8192 columns.
y2 contains the Label list. It has 840 positions, one for each appliance.
I'm trying to calculate the coefficients of the Scattering1D transform for each of the signals that x2 contains. For this, I am doing the following:
T=32768;
J=8;
Q=12;
if use_cuda:
    scattering.cuda()

    x2 = x2.cuda()
    y2 = y2.cuda()

Sx_all = scattering.forward(x2)

When I do this, the following error appears:
RuntimeError                              Traceback (most recent call last)
<ipython-input-62-26c538d90a70> in <module>()
      1 #Sx_all = scattering(x2)
----> 2 Sx_all = scattering.forward(x2)

1 frames
/usr/local/lib/python3.6/dist-packages/kymatio/backend/torch_backend.py in input_checks(x)
      9
     10     if not x.is_contiguous():
---> 11         raise RuntimeError('The input must be contiguous.')
     12
     13 def _is_complex(x):

RuntimeError: The input must be contiguous.

This error does not appear when I run the original program, from the example available at https://www.kymat.io/gallery_1d/plot_classif_torch.html#sphx-glr-gallery-1d-plot-classif-torch-py.
What exactly does the error message 'The input must be contiguous' mean, and how do you suggest I fix the problem? I tried to read the library documentation but I still haven't solved the problem.


title: Training Object Detection model on just 10 images

body:
I am trying to train an object detection model using Mask-RCNN with Resnet50 as backbone. I am using the pre-trained models from PyTorch's Torchvision library. I have only 10 images that I can use to train. Of the same 10 images, I am using 3 images for validation. For the evaluation, I am using the evaluation method used in COCO dataset which is also provided as .py scripts in the TorchVision's github repository.
To have enough samples for training, I am oversampling the same 10 images by a factor of 100 i.e. I end up with 1000 images that I can use to train my model. Similarly, I end up having 300 images that I can use for validation.
Now, the problem is that I am getting 0% mAP after train and 0% recall. I have two questions:
Q1. Why would it return 0% mAP?
If it has something to do with the fact that I am oversampling to a large extent, then my next question is
Q2.  Shouldn't the oversampling just cause the model to Overfit and instead provide a higher training as well as validation accuracy for my case (since I have picked the validation data from the training data itself?


title: Using torch.nn.DataParallel with torch.distributions.Laplace throws TypeError: 'Laplace' object is not iterable

body:
I am trying to train my model on multiple GPUs but I have some trouble with torch.distributions.Laplace that I call in the forward pass.
I have uploaded a minimal working example that runs fine without torch.nn.DataParallel but fails when using it.
Is there any way to make this code run on multiple GPUs?


title: When should a tensors gradients be detached?

body: I understand how detaching gradients from tensors work. However, I do not know when to do this. When looking at a research paper, how do you know which variables to let gradients flow through? An example from an RL paper (say DDPG) might be helpful.


title: Why my last class has wrong classification in testing?

body:
I have trained the model with five-classes data. When tested, the last class has all mis-classifications with some other classes.
That last class test image folder is removed from the test set. Then in the four-classes test data, the new last test class images have mis-classifications again, but that class has correct classification when tested with five-classes dateset.
What is wrong?
My training algo is as follow.
I have found one link. The discussion is because of shuffling in training.
My training and validation sets have five folders each with correct images. All folders have same number of images.
import os
import torch
import numpy as np
import torchvision
#import envoy
from os import path
from shutil import copyfile
source = '/home/itc/Data/Cheers_Store/Classifications/'

#Get classes
classes = os.listdir(source+'data/train')
print(classes)

import torchvision.transforms as tt
from torchvision.datasets import ImageFolder
from PIL import Image
inputH = 300
inputW = 300
#Data transform (normalization & data augmentation)
stats = ((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))

train_tfms = tt.Compose([tt.Resize((inputH, inputW), interpolation=2),
                         tt.RandomHorizontalFlip(),
                         tt.ToTensor(),
                         tt.Normalize(*stats)])
valid_tfms = tt.Compose([tt.Resize((inputH, inputW), interpolation=2),
                         tt.ToTensor(),
                         tt.Normalize(*stats)])
test_tfms = tt.Compose([tt.Resize((inputH, inputW), interpolation=2),
                        tt.ToTensor(),
                        tt.Normalize(*stats)])

#Create dataset
#Train dataset has two. One is with
#augmentation and another one is without
#augmentation
train_ds = ImageFolder(source+'data/train', train_tfms)
valid_ds = ImageFolder(source+'data/valid', valid_tfms)
test_ds = ImageFolder(source+'data/test', test_tfms)

from torch.utils.data.dataloader import DataLoader
batch_size = 8

#Training data loader
train_dl = DataLoader(train_ds, batch_size, shuffle = True, num_workers = 8, pin_memory=True)
#Validation data loader
valid_dl = DataLoader(valid_ds, batch_size, shuffle = True, num_workers = 8, pin_memory=True)
#Test data loader
test_dl = DataLoader(test_ds, 1, shuffle = False, num_workers = 1, pin_memory=True)

import torch.nn as nn
import torch.nn.functional as F

#Wideresnet22
def conv_2d(ni, nf, stride=1, ks=3):
  return nn.Conv2d(in_channels=ni, out_channels=nf,
                   kernel_size=ks, stride=stride,
                   padding=ks//2, bias=False)

def bn_relu_conv(ni, nf):
  return nn.Sequential(nn.BatchNorm2d(ni),
                       nn.ReLU(inplace=True),
                       conv_2d(ni, nf))

class ResidualBlock(nn.Module):
  def __init__(self, ni, nf, stride=1):
    super().__init__()
    self.bn = nn.BatchNorm2d(ni)
    self.conv1 = conv_2d(ni, nf, stride)
    self.conv2 = bn_relu_conv(nf, nf)
    self.shortcut = lambda x: x
    if ni != nf:
      self.shortcut = conv_2d(ni, nf, stride, 1)

  def forward(self, x):
    x = F.relu(self.bn(x), inplace=True)
    r = self.shortcut(x)
    x = self.conv1(x)
    x = self.conv2(x) * 0.2
    return x.add_(r)

def make_group(N, ni, nf, stride):
  start = ResidualBlock(ni, nf, stride)
  rest = [ResidualBlock(nf, nf) for j in range(1, N)]
  return [start] + rest

class Flatten(nn.Module):
  def __init__(self): super().__init__()
  def forward(self, x): return x.view(x.size(0), -1)

class WideResNet(nn.Module):
  def __init__(self, n_groups, N, n_classes, k=1, n_start=16):
    super().__init__()
    #increase channels to n_start using conv layer
    layers = [conv_2d(3, n_start)]
    n_channels = [n_start]

    #Add groups of basic blocks (increase channels & downsample)
    for i in range(n_groups):
      n_channels.append(n_start*(2**i)*k)
      stride = 2 if i>0 else 1
      layers += make_group(N, n_channels[i], n_channels[i+1], stride)

    #Pool, flatten, & add linear layer for classification
    layers += [nn.BatchNorm2d(n_channels[3]),
               nn.ReLU(inplace=True),
               nn.AdaptiveAvgPool2d(1),
               Flatten(),
               nn.Linear(n_channels[3], n_classes)]

    self.features = nn.Sequential(*layers)

  def forward(self, x):
    return self.features(x)

#we have 3 groups, 3 residual blocks in each group, scaling factor of 6 from 16 layers to 384 layers
def wrn_22():
  return WideResNet(n_groups=3, N=3, n_classes=5, k=6)

from torchsummary import summary
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = wrn_22().to(device)
summary(model, (3, 300, 300))
print(device)

from fastai.basic_data import DataBunch
from fastai.train import Learner
from fastai.metrics import accuracy

#DataBunch takes data and internall create data loader
data = DataBunch.create(train_ds, valid_ds, bs=batch_size, path='./data')
#Learner uses Adam as default for learning
learner = Learner(data, model, loss_func=F.cross_entropy, metrics=[accuracy])
#Gradient is clipped
learner.clip = 0.1

#learner finds its learning rate
learner.lr_find()

learner.recorder.plot()

"""**Training the model**"""

#Weight decay helps to lower down weight. Learn in https://towardsdatascience.com/
learner.fit_one_cycle(15, 5e-4, wd=1e-4)

learner.recorder.plot_lr()

learner.recorder.plot_losses()
learner.recorder.plot_metrics()

"""**Save the trained model**"""

torch.save(model.state_dict(), 'data/models/best.pth')

modeltest = wrn_22().to(device)
modeltest.load_state_dict(torch.load('data/models/best.pth'))

def predict_image(img):
  #Convert to a batch of 1
  #xb = img.unsqueeze(0)
  #Get prediction from model
  yb = modeltest(img.to(device))
  #Pick index with highest probability
  _, preds = torch.max(yb, dim=1)
  #Retrieve the class label
  return classes[preds.cpu()[0].item()]

count=1
correct=0
wrong=0
for image, label in test_dl:
  out = predict_image(image)
  print('label: ' + classes[label.item()] + ' prediction: ' + out)
  if(classes[label.item()] == out):
    correct=correct+1
  else:
    wrong=wrong+1
  count=count+1

print('total: ' + str(count)+' correct detection: ' + str(correct) + ' wrong detection ' + str(wrong))
print('accuracy: '+str(correct/count))

What is wrong with my training?


title: Weird behavior using pytorch's nn.Embedding multiple times

body:
I want my model to take the input sequence as input 3 times. Once uni-gram, once bi-gram and once tri-gram. Each of the three will pass through it's own lstm and then it will be concatinated.
But I get an error when Im using the embedding layers:
in the model's init() :
vocab_size_n1 = pow(26, 1) + 2  # A + "<space>" + "<pad-0>"
self.embed_n1 = nn.Embedding(vocab_size_n1, self.embedding_size)

vocab_size_n2 = pow(26, 2) + 3  # A^2 + "<space>" + "<pad-0>"
self.embed_n2 = nn.Embedding(vocab_size_n2, self.embedding_size)

vocab_size_n3 = pow(26, 3) + 3 # A^3 + "<space>" + "<pad-0>"
self.embed_n3 = nn.Embedding(vocab_size_n3, self.embedding_size)

in forward:
x_n1 = self.embed_n1(x_n1.type(torch.LongTensor).to(device=device))
x_n2 = self.embed_n2(x_n2.type(torch.LongTensor).to(device=device))
x_n3 = self.embed_n3(x_n3.type(torch.LongTensor).to(device=device))

So the first n1 embedding is working fine. But in the second and third is giving me a cuda assertion error which, in this case, means that there are more unique characters in the input than vocab_size. I checked that multiple times and everything is correct. When I delete any two of the three embeddings it is working. Turns out, when I rearange the embeddings like this:
x_n3 = self.embed_n3(x_n3.type(torch.LongTensor).to(device=device))
x_n2 = self.embed_n2(x_n2.type(torch.LongTensor).to(device=device))
x_n1 = self.embed_n1(x_n1.type(torch.LongTensor).to(device=device))

is works. This shows me that when the first embedding is used, the next two will not use the embedding I initialized for them but also the first. Therefore, when starting with n1, the vocab size of n1 is smaller than all unique characters in bi- and tri-gram and I get the assertion error (index out of bounds basically). But when Im starting with the embedding with the biggest vocab size (n3 tri-gram) it will also work for the smaller two. I guess it wastes to much memory when the embedding uses a vocab size which is bigger than the actual amount unique characters. What causes that and how can I fix it? Thank you


title: How to create a neural network that takes in an image and ouputs another image?

body:
I'm trying to create a neural network that has an image of the L (from Lab) format and output the ab dimensions. I am able to pass the L dimension without an issue, but I'm having trouble figuring out how to output the ab dimensions. The output should be for shape 1x2xHxW, where H and W are the height and width of the input image. Here is my network so far:
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        # Get the resnet18 model from torchvision.model library
        self.model = models.resnet18(pretrained=True)

        self.model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)

        # Replace fully connected layer of our model to a 2048 feature vector output
        self.model.classifier = nn.Sequential()

        # Add custom classifier layers
        self.fc1 = nn.Linear(1000, 1024)
        self.Dropout1 = nn.Dropout()
        self.PRelU1 = nn.PReLU()

        self.fc2 = nn.Linear(1024, 512)
        self.Dropout2 = nn.Dropout()
        self.PRelU2 = nn.PReLU()

        self.fc3 = nn.Linear(512, 256)
        self.Dropout3 = nn.Dropout()
        self.PRelU3 = nn.PReLU()

        self.fc4 = nn.Linear(256, 313)
        # self.PRelU3 = nn.PReLU()

        self.softmax = nn.Softmax(dim=1)
        self.model_out = nn.Conv2d(313, 2, kernel_size=1, padding=0, dilation=1, stride=1, bias=False)
        self.upsample4 = nn.Upsample(scale_factor=4, mode='bilinear')

    def forward(self, x):
        # x is our input data
        x = self.model(x)
        x = self.Dropout1(self.PRelU1(self.fc1(x)))
        x = self.Dropout2(self.PRelU2(self.fc2(x)))
        x = self.Dropout3(self.PRelU3(self.fc3(x)))
        x = self.softmax(self.fc4(x))

        return x


title: Dataloader of different sequence of images in a single folder

body:
I'm doing frame generation.  For each images in Dataset/train/    folder (e.g 1.png ) I generated a sequence of 100 images and save all of  them into a single Dataset/frames/train/ as (1_1.png...1_100.png), here is an example of my folder structure:
Dataset:
      train:
           1.png
           2.png
           3.png
           .
           .
           N.png
     frames:
           train:
               1_1.png
               1_2.png
               .
               .
               N_100.png

               2_1.png
               2_2.png
               .
               .
               N_100.png

I have created my custom dataloader where I stack the frames generated as channels to form a sequence, but my problem I don't want to frames from image 2 to overlap with frames from 1 when create a sequence, How can I ensure the different frames don't overlap?
Here is my custom dataloader:

class LevelSetDataset(Dataset):
    """
    Dataset object for CNN models
    Temporal is defined implicitly
    as the number of channels
    example:
        - X dimension
            [H, W, C=number_of_timestap(t)]
        - Y dimension
            [W, W, C =(t+1)]
    """
    def __init__(self, input_image_path:str,
                target_image_path:str,
                threshold:float=0.5,
                num_input_steps:int=3,
                num_future_steps:int=1,
                image_dimension:int=32,
                data_transformations=None,
                istraining_mode:bool=True
                ):

        self.input_image_path    = input_image_path
        self.target_image_path   = target_image_path
        self.threshold           = threshold
        self.num_input_steps     = num_input_steps
        self.num_future_steps    = num_future_steps
        self.image_dimension     = image_dimension
        self.data_transformations= data_transformations
        self.istraining_mode     = istraining_mode

        # get a list of input filenames as sort them (e.g. 1.png, 2.png,..,N.png)
        input_image_fp = sorted(glob(os.path.join(self.input_image_path , "*")),
                                    key=lambda x: int(os.path.basename(x).split('.')[0])
                                                     )

        # repeat the input image untill it matches the number of segmentation
        # step of the target image
        self.input_image_fp = [i for i in input_image_fp for _ in range(100)]

        # get a list of the target filenames and sort them by the first id and second
        # id after the underscore (e.g.  1_1.png, 1_2,..,N_M.png)
        self.target_image_fp= sorted(glob(os.path.join(self.target_image_path , "*")),
                                    key=lambda x: (int(os.path.basename(x).split('_')[0]),
                                                   int(os.path.basename(x).split('_')[1].split('.')[0]))
                                    )

        # check if in training mode
        # to apply transformations
        if (self.data_transformations is None) and (self.istraining_mode):
            self.data_transformations= torchvision.transforms.Compose([
                                            torchvision.transforms.Resize(size=(self.image_dimension,self.image_dimension),
                                                                                interpolation=Image.BILINEAR),
                                            torchvision.transforms.RandomHorizontalFlip(p=0.5),
                                            torchvision.transforms.RandomVerticalFlip(p=0.5),
                                            torchvision.transforms.ToTensor()
                                                                      ])

        if (self.data_transformations is None) and (not self.istraining_mode):
            self.data_transformations== torchvision.transforms.Compose([
                                            torchvision.transforms.Resize(size=(self.image_dimension,self.image_dimension),
                                                                                interpolation=Image.BILINEAR),
                                            torchvision.transforms.ToTensor()
                                                                      ])

        self.transforms = self.data_transformations

    def _create_binary_mask(self, x):
        x[x>=self.threshold] = 1
        x[x <self.threshold] = 0
        return x

    def _stat_norm(self, x):
        norm =torchvision.transforms.Compose([torchvision.transforms.Resize(
            size=(self.image_dimension,self.image_dimension),
                      interpolation=Image.BILINEAR),
                    torchvision.transforms.ToTensor()])
        return norm(x)

    def __len__(self):
        return len(self.target_image_fp) - (self.num_input_steps+self.num_future_steps)

    def __getitem__(self, index):
        X          = torch.zeros((self.image_dimension, self.image_dimension, self.num_input_steps+1))
        for step_idx, step in enumerate(np.arange(index, self.num_input_steps, 1)):
            target_image = Image.open(self.target_image_fp[step+self.num_input_steps+self.num_future_steps-1])
            target_image = self.transforms(target_image)
            target_image = self._create_binary_mask(target_image)
            X[:, :, step_idx] = target_image # (t+1)

        input_img  = Image.open(self.input_image_fp[index]).convert('L')
        #         input_img  = self.transforms(input_img)
        input_img  = self.transforms(input_img)
        X[:, :, 0] = input_img
        target_image = Image.open(self.target_image_fp[index+self.num_input_steps+self.num_future_steps-1])
        target_image = self.transforms(target_image)
        target_image = self._create_binary_mask(target_image)
        image_name   = self.target_image_fp[index+self.num_input_steps+self.num_future_steps-1].split('/')[-1]

        Y = target_image
        return X, Y, image_name


title: What is the algorithm of pytorch tensor sort

body:
Is there anybody who knows sorting algorithm of pytorch?
I want to implement sorting function as same as torch.sort() but I can't find related source.
and this code doesn't seem to be used for sorting.


title: How to Fine Tune BERT for "Custom" Named Entities Recognition task?

body:
I have a BERT model for Classification which I am using for classification task. The Model Structure is as follows:
class BERT_Subject_Classifier(nn.Module):

    def __init__(self,out_classes,hidden1=128,hidden2=32,dropout_val=0.2):
      super(BERT_Subject_Classifier, self).__init__(

      self.hidden1 = hidden1
      self.hidden2 = hidden2
      self.dropout_val = dropout_val
      self.bert = AutoModel.from_pretrained('bert-base-uncased')
      self.out_classes = out_classes

      self.dropout = nn.Dropout(self.dropout_val)
      self.relu =  nn.ReLU()
      self.fc1 = nn.Linear(768,self.hidden1)
      self.fc2 = nn.Linear(self.hidden1,self.hidden2)
      self.fc3 = nn.Linear(self.hidden2,self.out_classes)

    def forward(self, sent_id, mask):
      _, cls_hs = self.bert(sent_id, attention_mask=mask)
      x = self.fc1(cls_hs)
      x = self.relu(x)
      x = self.dropout(x)
      x = self.fc2(x)
      x = self.dropout(x)
      x = self.fc3(x)
      return x

How can I make a NER or Named Recognition Model using BERT on my custom datasets? I have just 40 documents in .docx format and the corresponding labels in a csv file?  My training CSV file looks like:

How do I tackle the problem? Should I make the model work as a classifier with but then it'll try to classify instead of finding the entities names. What should be the model structure and Training data shape for the task?


title: pytorch MultivariateNormal backward error with respect to covariance

body:
Here is a simple piece of code to learn covariance of 2D gaussian.
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.optim import Adam

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.cov = nn.Parameter(torch.tensor([0.],requires_grad = True))
        self.cur_cov = torch.cat((torch.tensor([1.0]), self.cov,self.cov,torch.tensor([1.0])),axis=0).reshape(2,2)
        self.dist = torch.distributions.multivariate_normal.MultivariateNormal(\
                torch.tensor([0.,0.]),self.cur_cov)

    def forward(self,x):
        return self.dist.log_prob(x)

model = Net()
op = Adam(model.parameters(),lr=0.1)

data = torch.tensor([1,2,3,5]).reshape(-1,2)
for i in range(10):
    op.zero_grad()
    log_p = model(data)
    loss = -torch.sum(log_p)
    loss.backward()
    op.step()

The code raise error
RuntimeError: Trying to backward through the graph a second time, but the saved intermediate results have already been freed. Specify retain_graph=True when calling backward the first time.

However, as I added the flag
for i in range(10):
    op.zero_grad()
    log_p = model(data)
    loss = -torch.sum(log_p)
    loss.backward(retain_graph=True)
    op.step()
    print(loss.item())

The loss did not change.The loss and model.cov did not change.


title: Very low gradient values in Graph Neural Network

body:
I am using Pytorch-Geometric library to implement a Graph Neural Network for a regression problem. The model is defined as:
import torch
from torch.nn.parameter import Parameter
import torch.optim as optim
import torch.nn.functional as F
import torch.nn as nn
from torch_geometric.nn import GCNConv

class Model(nn.Module):
    def __init__(self, nin=1, nhid1=128, nout=128, hid_l=64, out_l=1):
        super(Model, self).__init__()

        self.gc1 = GCNConv(in_channels= nin, out_channels= nhid1)
        self.gc2 = GCNConv(in_channels= nhid1, out_channels= nout)
        self.lay1 = nn.Linear(nout ,hid_l)
        self.l0 = nn.Linear(hid_l,hid_l)
        self.l1 = nn.Linear(hid_l,hid_l)
        self.lay2 = nn.Linear(hid_l ,out_l)
        self.active = nn.LeakyReLU(0.1)

        with torch.no_grad():
            self.gc1.weight = Parameter(nn.init.uniform_(torch.empty(nin,nhid1),a=0.0,b=1.0))
            self.gc1.bias = Parameter(nn.init.uniform_(torch.empty(nhid1),a=0.0,b=1.0))
            self.gc2.weight = Parameter(nn.init.uniform_(torch.empty(nhid1,nout),a=0.0,b=1.0))
            self.gc2.bias = Parameter(nn.init.uniform_(torch.empty(nout),a=0.0,b=1.0))
            self.lay1.weight = Parameter(nn.init.uniform_(torch.empty(hid_l, nout ),a=0.0,b=1.0))
            self.l0.weight = Parameter(nn.init.uniform_(torch.empty(hid_l, hid_l),a=0.0,b=1.0))
            self.l1.weight = Parameter(nn.init.uniform_(torch.empty(hid_l, hid_l),a=0.0,b=1.0))
            self.lay2.weight = Parameter(nn.init.uniform_(torch.empty(out_l,hid_l),a=0.0,b=1.0))

    def forward(self, features, edge_list):
        x = self.active(self.gc1(features, edge_list))
        x = self.active(self.gc2(x, edge_list))
        x = self.active(self.lay1(x))
        x = self.active(self.l0(x))
        x = self.active(self.l1(x))
        x = self.active(self.lay2(x))

        return x

where features is the feature matrix of dimension [n X 1] and edge_listis the edge index used in Pytorch-Geometric. The gradient seems to have a very sharp descent even when training for just 40 epochs with batch gradient descent.  I am training on scale-free graphs with around 1K nodes and ~3K edges. What can I do to get a better gradient values?


title: Keras DataGenerator slower by design than Pytorch DataLoader?

body:
DataGenerator's getitem() returns a batch. This means that if you don't make getitem() parallel under the hood then it won't be. This is one possible reason, why when I increase the number of workers (I tried with -> 0,1,4,8,16 workers), my train time does not get affected much.
Contrast this with Pytorch's DataLoader which takes in a Dataset object. In Dataset getitem() returns a single item by index, and because of this handles multiprocessing under the hood.
Does DataGenerator have a similar abstraction for faster data loading?


title: Subsetting a two dimensional tensor with a one dimensional tensor

body:
I want to extract from each row of a two-dimensional tensor the column that is stored in another one dimensional tensor.
import torch
test_tensor = tensor([1,-2,3], [-2,7,4]).float()
select_tensor = tensor([1,2])

So in this particular example I would like to get the element in position 1 for the first row (so -2) and the element in position 2 for the second row (so 4).
I tried:
test_tensor[:, select_tensor]

But this selects the elements at position 1 and 2 for each row. I suspect it might be something very simple that I am missing.


title: Tensorboard with pytorch in a MESS

body:
I'm working with PyTorch and visualize the training scalars such as loss in tensorboard. I have 3 models' event file lying in directory as follows:
├─data
│  └─tb
│      ├─baseline-cnn-cnn
│      │  └─large
│      │      └─20210121-04
│      │              events.out.tfevents.1611202426.node153.55453.0
│      │
│      ├─fim
│      │  └─large
│      │      └─20210120-04
│      │              events.out.tfevents.1611117755.node153.382325.0
│      │
│      └─npa
│          └─large
│              └─20210120-10
│                      events.out.tfevents.1611137925.node153.417110.0

I run tensorboard by
tensorboard logdir=data/tb

HOWEVER, the browser shows figure of npa only although I've checked the toggle all button. Moreover, after I remove event file of npa, figure of fim magically appear!
Somebody know why?? I'm really confused. I'm pretty sure all of the event files are okay.


title: How to use a custom flip function using get_transform in fastai v1?

body:
I would like to use a custom flip. For my use case, mirror flips don't have sense:
def _dihedral_affine(k:partial(random.choice, [0, 3, 5, 6])):
    "Randomly flip `x` image based on `k`."
    x = -1 if k&1 else 1
    y = -1 if k&2 else 1
    if k&4: return [[0, x, 0.],
                    [y, 0, 0],
                    [0, 0, 1.]]
    return [[x, 0, 0.],
            [0, y, 0],
            [0, 0, 1.]]

dihedral_affine = TfmAffine(_dihedral_affine)
additional_aug = [dihedral_affine()]
tfms = get_transforms(do_flip=False, xtra_tfms=additional_aug)
data = ImageDataBunch.from_df("../pathData", df_ground, valid_pct=0.2, label_col=1, size=224, ds_tfms=tfms, bs=64)
learn = cnn_learner(data, models.resnet34, metrics=[accuracy])
learn.lr_find()

I have this error (I'm using fastai 1.0.60, torch 1.3.1+cpu torchvision 0.4.2+cpu, python 3.6.12.):
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
---------------------------------------------------------------------------
Empty                                     Traceback (most recent call last)
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\torch\utils\data\dataloader.py in _try_get_data(self, timeout)
    723         try:
--> 724             data = self._data_queue.get(timeout=timeout)
    725             return (True, data)
~\Anaconda3\envs\env_fastai_v1\lib\multiprocessing\queues.py in get(self, block, timeout)
    104                     if not self._poll(timeout):
--> 105                         raise Empty
    106                 elif not self._poll():
Empty:
During handling of the above exception, another exception occurred:
RuntimeError                              Traceback (most recent call last)
<ipython-input-26-d81c6bd29d71> in <module>
----> 1 learn.lr_find()
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\fastai\train.py in lr_find(learn, start_lr, end_lr, num_it, stop_div, wd)
     39     cb = LRFinder(learn, start_lr, end_lr, num_it, stop_div)
     40     epochs = int(np.ceil(num_it/len(learn.data.train_dl)))
---> 41     learn.fit(epochs, start_lr, callbacks=[cb], wd=wd)
     42
     43 def to_fp16(learn:Learner, loss_scale:float=None, max_noskip:int=1000, dynamic:bool=True, clip:float=None,
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\fastai\basic_train.py in fit(self, epochs, lr, wd, callbacks)
    198         else: self.opt.lr,self.opt.wd = lr,wd
    199         callbacks = [cb(self) for cb in self.callback_fns + listify(defaults.extra_callback_fns)] + listify(callbacks)
--> 200         fit(epochs, self, metrics=self.metrics, callbacks=self.callbacks+callbacks)
    201
    202     def create_opt(self, lr:Floats, wd:Floats=0.)->None:
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\fastai\basic_train.py in fit(epochs, learn, callbacks, metrics)
     97             cb_handler.set_dl(learn.data.train_dl)
     98             cb_handler.on_epoch_begin()
---> 99             for xb,yb in progress_bar(learn.data.train_dl, parent=pbar):
    100                 xb, yb = cb_handler.on_batch_begin(xb, yb)
    101                 loss = loss_batch(learn.model, xb, yb, learn.loss_func, learn.opt, cb_handler)
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\fastprogress\fastprogress.py in __iter__(self)
     45         except Exception as e:
     46             self.on_interrupt()
---> 47             raise e
     48
     49     def update(self, val):
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\fastprogress\fastprogress.py in __iter__(self)
     39         if self.total != 0: self.update(0)
     40         try:
---> 41             for i,o in enumerate(self.gen):
     42                 if i >= self.total: break
     43                 yield o
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\fastai\basic_data.py in __iter__(self)
     73     def __iter__(self):
     74         "Process and returns items from `DataLoader`."
---> 75         for b in self.dl: yield self.proc_batch(b)
     76
     77     @classmethod
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\torch\utils\data\dataloader.py in __next__(self)
    802
    803             assert not self._shutdown and self._tasks_outstanding > 0
--> 804             idx, data = self._get_data()
    805             self._tasks_outstanding -= 1
    806
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\torch\utils\data\dataloader.py in _get_data(self)
    769         else:
    770             while True:
--> 771                 success, data = self._try_get_data()
    772                 if success:
    773                     return data
~\Anaconda3\envs\env_fastai_v1\lib\site-packages\torch\utils\data\dataloader.py in _try_get_data(self, timeout)
    735             if len(failed_workers) > 0:
    736                 pids_str = ', '.join(str(w.pid) for w in failed_workers)
--> 737                 raise RuntimeError('DataLoader worker (pid(s) {}) exited unexpectedly'.format(pids_str))
    738             if isinstance(e, queue.Empty):
    739                 return (False, None)
RuntimeError: DataLoader worker (pid(s) 19652, 19132, 27668, 1436, 5696, 5340, 3828, 26140) exited unexpectedly

I've seen this answer but it doesn't help me How to get add aditional transform to get_transform in fastai?
How to get it work?


title: Pyorch: Applying a batch of filters (kernels) on one single picture using conv2d

body:
I have a batch of filters, i.e., w, whose size is torch.Size([64, 3, 7, 7]) as follows:

Also, I have a picture p from Imagenet as follows:

How can I apply the filters to the picture and get a grid of 64x64 where each cell contains the same picture on which a different filter has been applied? I would like to make the grid using torchvision.utils.make_grid but do not know how?
My try
y = F.conv2d(p, w)

The size of y is torch.Size([1, 64, 250, 250]) which does not make sense to me.


title: TypeError running yolact's train.py

body:
I'm trying to execute the yolact code :
https://github.com/dbolya/yolact
but I have this error when I run train.py:

runfile('C:/Users/Sylvain ARD/Dropbox/Documents Sylvain/travail avec Boubacar/yolact/yolact-master/yolact-master/train.py', wdir='C:/Users/Sylvain ARD/Dropbox/Documents Sylvain/travail avec Boubacar/yolact/yolact-master/yolact-master')
Scaling parameters by 0.12 to account for a batch size of 1.
Per-GPU batch size is less than the recommended limit for batch norm. Disabling batch norm.
loading annotations into memory...
Done (t=0.03s)
creating index...
index created!
loading annotations into memory...
Done (t=0.00s)
creating index...
index created!
Initializing weights...
Begin training!

Traceback (most recent call last):

  File "C:\Users\Sylvain ARD\Dropbox\Documents Sylvain\travail avec Boubacar\yolact\yolact-master\yolact-master\train.py", line 505, in <module>
    train()

  File "C:\Users\Sylvain ARD\Dropbox\Documents Sylvain\travail avec Boubacar\yolact\yolact-master\yolact-master\train.py", line 271, in train
    for datum in data_loader:

  File "C:\Users\Sylvain ARD\.conda\envs\yolact\lib\site-packages\torch\utils\data\dataloader.py", line 819, in __next__
    return self._process_data(data)

  File "C:\Users\Sylvain ARD\.conda\envs\yolact\lib\site-packages\torch\utils\data\dataloader.py", line 846, in _process_data
    data.reraise()

  File "C:\Users\Sylvain ARD\.conda\envs\yolact\lib\site-packages\torch\_utils.py", line 369, in reraise
    raise self.exc_type(msg)

TypeError: __init__() missing 4 required positional arguments: 'casting', 'from_', 'to', and 'i'

please help me
thank you
best regards