title: High Loss Validation

body:
I use the following model to predict the competition: "intel-mobileodt-cervical-cancer-screening".
The labels are divided into 3 categories(1 ,2 ,3).

When I want to do a prediction workout I get the next output

Model:

resnet50 = pretrainedmodels.__dict__["resnet50"](num_classes=1000, pretrained='imagenet')
resnet50.last_linear=torch.nn.Linear(in_features=2048,out_features=3, bias=True)
#optim
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model=model.to(device)
loss_cross=torch.nn.CrossEntropyLoss().cuda()

optim Adam

DataLoader:

class Kaggle_Cancer(Dataset):
  def __init__(self, root_path, transform=None,preprocessing=None,resize=216):
    self.path = root_path
    self.transform=transform
    self.preprocessing=preprocessing
    self.resize=resize

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

  def __getitem__(self, idx):
    p=self.path[idx]
    image1=cv2.imread(p)
    label=p.split("/")[-2].split("_")[-1]
    image1=cv2.cvtColor(image1,cv2.COLOR_BGR2RGB)
    if self.transform:
      image1=self.transform(image=image1)['image']
    image1=transforms.ToPILImage()(image1)
    image1=transforms.ToTensor()(image1)
    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])
    image1=normalize(image1)
    return image1,int(label)

Train :

def train(epoch_number,model,optim,loss):
  model.train()
  all_loss=0
  correct=0
  tqdm_loader=tqdm(training_set)
  for  index,(img,target) in enumerate(tqdm_loader):
    img=img.float().cuda()
    target=target.long().cuda()

    optim.zero_grad()
    out=model(img)
    print(out," target ",target)
    loss1=loss(out,target)
    print(loss1)
    loss1.backward()
    optim.step()
    all_loss+=loss1.item()
    avg_loss=all_loss/(index+1)
    pred=out.argmax(dim=1,keepdim=True)
    correct+=pred.eq(target.view_as(pred)).sum().item()/len(target)

    avg_acc=correct/(index+1)
    tqdm_loader.set_description("Epoch {} train loss={:4}  acc={:4} ".format(epoch_number,round(avg_loss,4),round(avg_acc,4)))

  return avg_loss,avg_acc

output:

print(out," target ",target)

,
        [ 6.1667e-02, -3.9864e-01, -4.1212e-01],
        [-2.3100e-01, -3.7821e-01, -2.8159e-01],
        [-2.9442e-01, -5.0409e-01, -3.1046e-01],
        [ 1.4866e-01, -2.8496e-01, -1.7643e-01],
        [-2.4554e-01, -2.5063e-01, -6.7061e-01],
        [-7.1597e-02, -3.5376e-01, -5.7830e-01],
        [-2.1527e-01, -4.0284e-01, -4.5993e-01],
        [ 1.2050e-02, -5.5684e-01, -1.6044e-01],
        [-3.7750e-02, -5.3680e-01, -4.3820e-01],
        [-1.1966e-01, -2.5146e-01, -4.9405e-01],
        [-2.3308e-01, -6.3452e-01, -3.9821e-01],
        [-3.6530e-01, -1.5242e-01, -2.6457e-01],
        [-1.8864e-01, -6.0979e-01, -5.5342e-01],
        [-2.4755e-01, -4.7011e-01, -2.6204e-01],
        [-3.1907e-01, -4.2680e-01, -3.4576e-01],
        [-2.1872e-01, -5.3857e-01, -2.9729e-01],
        [-7.1475e-02, -4.0458e-01, -3.2042e-01],
        [-2.8925e-01, -4.3376e-02, -4.9899e-01],
        [-4.8227e-02, -1.8701e-01, -2.2106e-01],
        [ 1.7829e-02, -6.5816e-01, -4.0141e-01],
        [-2.7450e-01, -3.9498e-01, -2.3189e-01],
        [-1.8847e-01, -6.8187e-01, -2.0631e-01],
        [-3.5251e-01, -5.3258e-01, -6.3298e-01],
        [-6.5548e-02, -2.5093e-01, -5.4346e-01],
        [ 2.3848e-01, -3.6152e-01, -1.6380e-01],
        [-2.1488e-01, -6.4888e-01, -7.7022e-01],.....

target  tensor([2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 3, 2, 3, 2, 2, 2, 2, 3, 2, 1, 3, 3, 2, 2,
        3, 2, 3, 2, 3, 1, 3, 3, 1, 2, 3, 2, 1, 1, 3, 1, 1, 2, 3, 2, 2, 2, 2, 2,.....

print(loss1)

 1, 2, 3, 3, 1, 3, 1, 3, 3, 2, 3, 3, 2, 3, 2, 3], device='cuda:0'
tensor(1.0870, device='cuda:0', grad_fn=<NllLossBackward>

number epoch =10/20/30:

same result:

val loss=1.2  acc=0.4 train loss=0.6  acc=0.65

What i do wrong?


title: Debugging Reinforcement Learning Model (MsPacman)

body:
I'm new to RL and I'm attempting to train an RL agent to play MsPacman in PyTorch. I've adapted the code from this tutorial on the PyTorch page for my problem. The DQN has the following architecture:

DQN(
  (conv1): Conv2d(1, 32, kernel_size=(8, 8), stride=(4, 4), padding=(2, 2))
  (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (conv2): Conv2d(32, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
  (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (conv3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (bn3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (linear1): Linear(in_features=7040, out_features=512, bias=True)
  (linear2): Linear(in_features=512, out_features=9, bias=True)
)

I'm using the actor (policy) and critic (target) method with replay memory which has the following settings:

Replay Buffer: 100,000
Target Update: Every 10,000 steps
Bath Size: 128
Discount Rate: 0.999

For the exploration trade-off I'm using epsilon-greedy with the following curve:

where the x-axis is the step number (in million) and y the probability of selecting a random action.

The update of the policy network looks like this:

# next_state_values = Q-values precited by the target network
# GAMMA = discount rate (0.999)
# reward_batch = rewards for the states
expected_state_action_values = (next_state_values * GAMMA) + reward_batch

Loss calculation:

# state_action_values = actions taken by the policy agent
# expected_state_action_values - this is calculated above
loss = F.smooth_l1_loss(state_action_values, expected_state_action_values.unsqueeze(1))

Updating the policy (gradients are clamped):

optimiser.zero_grad()
loss.backward()
for param in policy_net.parameters():
    param.grad.data.clamp_(-1, 1)
optimiser.step()

While training the agent I plot the duration of each episode shown below (the orange line shows the average of the previous 100 episodes):

After 4,000 episodes the agent isn't really progressing and gets stuck in corners like below:

Any idea what could be the issue? Some tips and pointers would be extremely helpful.


title: Code run in Jupyter Lab uses very different GPU RAM than run as a script

body:
I am training a 3D siamese network in PyTorch. When I run the code from an iPython (v7.15.0) terminal the GPU RAM usage maxes out at 1739M:

When I copy the same code into a Jupyter notebook (in Jupyter Lab v2.1.5) the GPU RAM usage is 10209M:

Jupyter Lab was run from the terminal in the same Python virtual environment.
First, I don't understand why running the script in Jupyter Lab would increase GPU RAM usage by a factor of almost 6.
Second, and related, is there anyway to have Jupyter Lab run in a mode that uses somewhere in the range of 1739M for the GPU RAM?  I love the ability to have all the "documentation" around the code and output.
Python version 3.6.9.


title: Why EfficientNet same model return different predictions

body:
!pip install efficientnet_pytorch -q

import torch
import torch.nn as nn
import efficientnet_pytorch as efn

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
device

model = efn.EfficientNet.from_name('efficientnet-b0')
model = model.to(device)

img = torch.ones((2, 3, 680, 680))*0.5
img = img.to(device)
preds1 = model(img)
preds2 = model(img)
preds3 = model(img)

print(preds1[0][0])
print(preds2[0][0])
print(preds3[0][0])

del model, img, preds1, preds2, preds3

And preds1, preds2, and preds3 are different. I am confused about this point, model is same and input is same, why predictions are different?
tensor(0.2599, grad_fn=<SelectBackward>)
tensor(0.1364, grad_fn=<SelectBackward>)
tensor(0.1263, grad_fn=<SelectBackward>)


title: pytorch ValueError: Target and input must have the same number

body:
I try tutorial from this links and can't solve one problem.
part 1
part2
problem in part2
model.eval()
y_pred = model(test_input)
before_train = criterion(y_pred.squeeze(), test_output)

Output:
ValueError: Target and input must have the same number of elements. target nelement (60) != input nelement (20)

print(y_pred.squeeze())
  tensor([0.5050, 0.5063, 0.5000, 0.5040, 0.5050, 0.4984, 0.5041, 0.4939, 0.5016,
    0.5033, 0.4993, 0.5015, 0.5058, 0.5016, 0.5009, 0.4968, 0.5015, 0.5022,
    0.4953, 0.5050], grad_fn=<SqueezeBackward0>)

print(test_output)
    tensor([[0., 1., 0.],
    [0., 1., 0.],
    [0., 1., 0.],
    [1., 0., 0.],
    [0., 0., 1.],
    [1., 0., 0.],
    [0., 0., 1.],
    [1., 0., 0.],
    [0., 0., 1.],
    [0., 1., 0.],
    [1., 0., 0.],
    [0., 0., 1.],
    [0., 1., 0.],
    [1., 0., 0.],
    [0., 0., 1.],
    [1., 0., 0.],
    [0., 0., 1.],
    [0., 1., 0.],
    [0., 1., 0.],
    [0., 1., 0.]])

what i need change? All my code and data same as in tutorial Thanks!


title: PyTorch forward propagation returns different logits on same samples

body:
Consider the following LeNet model for MNIST
import torch
from torch import nn
import torch.nn.functional as F

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5, 1)
        self.conv2 = nn.Conv2d(20, 50, 5, 1)
        self.fc1 = nn.Linear(4*4*50, 500)
        self.fc2 = nn.Linear(500, 10)
        self.ceriation = nn.CrossEntropyLoss()
    def forward(self, x):
        x = self.conv1(x)
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(x)
        x = x.view(-1, 4*4*50)
        x = self.fc1(x)
        x = self.fc2(x)
        return x

Now, I use this model to do a single forward step on a batch of samples like
network=LeNet()
optimizer = torch.optim.SGD(self.network.parameters(), lr=0.001, momentum=0.9)
device = torch.device("cpu")
network.to(device)
network.train()
optimizer.zero_grad()
# X_batch= ... some batch of 50 samples pulled from a train_loader defined as
# torch.manual_seed(42)
# training_set = datasets.MNIST('./mnist_data', train=True, download=False,
#                               transform=transforms.Compose([
#                                   transforms.ToTensor(),
#                                   transforms.Normalize((0.1307,), (0.3081,))]))
# train_loader = torch.utils.data.DataLoader(training_set,
#                                            batch_size=50,
#                                            shuffle=False)
logits = network(X_batch)

Note that shuffle=False and download=False for the loader since the data set is already downloaded and I don't want to shuffle. My problem is that if I run this code twice I will get different values for logits and I don't understand why since everything else seems to be unchanged. For an extra check, I also extract X_batch to a numpy array and verify that the batch of samples is exactly the same as of previous execution. I do this check with numpy.array_equal() function.
I really can't figure out what I am missing here unless there are precision issues.


title: How to initialise the Weights for specific task and Backpropagation modification

body:
My model is used to predict values based on an minimising a loss function L. But, the loss function doesn’t have a single global minima value, but rather a large number of places where it achieves global minima.
So, the model is based like this:
Model Input is [nXn] tensor (let’s say: inp=[ [i_11, i_12, i_13, ..., i_1n],[i_21, i_22, ..., i_2n],...,[i_n1,i_n2, ..., i_nn] ]) and model output is [nX1] tensor (let’s say: out1=[o_1, o_2,..., o_n ])
Output tensor is out1 is passed in a function f to get out2 (let’s say: f(o_1, o_2, o_3,..., o_n)=[O_1, O_2, O_3, ..., O_n] )
These 2 values (i.e., out1 and out2) are minimised using MSELoss i.e., Loss = ||out1 - out2||
Now, there are a lot of values for [o_1, o_2, ..., o_n] for which the Loss goes to minimum.
But, I want the values of [o_1, o_2, ..., o_n] for which |o_1| + |o_2| + |o_3| + ... + |o_n| is maximum
Right now, the weights are initialised randomly:
self.weight = torch.nn.parameter.Parameter(torch.FloatTensor(in_features, out_features)) for some value of in_features and out_features

But by doing this, I am getting the values of [o_1, o_2, ..., o_n] for which |o_1| + |o_2| + |o_3| + ... + |o_n| is minimum.
I know this problem can be solved by without using deep-learning, but I am trying to get the results like this for some task computation.
Is there a way to change this to get the largest values predicted at the output of the neural net?
Or is there any other technique (backpropagation change) to change it to get the desired largest valued output?
Thanks in advance.
EDIT 1:
Based on the answer, out1=[o_1, o_2,..., o_n ] is tending to zero-valued tensor. In the initial epochs, out2=[O_1, O_2, O_3, ..., O_n] takes very large values, but subsequently comes down to lower values.
A snippet of code below will give the idea:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np

class Model(nn.Module):
    def __init__(self, inp_l, hid_l, out_l=1):
        super(Model, self).__init__()

        self.lay1 = nn.Linear(inp_l ,hid_l)
        self.lay2 = nn.Linear(hid_l ,out_l)
        self.dp = nn.Dropout(p=0.5)

    def forward(self, inp):

        self.out1= torch.tensor([]).float()

        for row in range(x.shape[0]):
            y = self.lay1(inp[row])
            y = F.relu(y)
            y = self.dp(y.float())
            y = self.lay2(y)
            y = F.relu(y)
            self.out1= torch.cat((self.out1, y))

        return self.out1.view(inp.shape[0],-1)

def function_f(inp, out1):
    '''
    Some functional computation is done to return out2.
    '''
    return out2

def train_model(epoch):
    model.train()
    t = time.time()
    optimizer.zero_grad()
    out1 = model(inp)

    out2 = function_f(inp, out1)

    loss1 = ((out1-out2)**2).mean()
    loss2 = -out1.abs().mean()
    loss_train = loss1 + loss2

    loss_train.backward(retain_graph=True)

    optimizer.step()

    if epoch%40==0:
        print('Epoch: {:04d}'.format(epoch+1),
                  'loss_train: {:.4f}'.format(loss_train.item()),
                  'time: {:.4f}s'.format(time.time() - t))

model= Model(inp_l=10, hid_l=5, out_l=1)
optimizer = optim.Adam(model.parameters(), lr=0.001)

inp = torch.randint(100, (10, 10))

for ep in range(100):
       train_model(ep)

But, out1 value goes to trivial solution i.e., zero-valued tensor which is the minimum valued solution. As mentioned before EDIT, I want to get the max-valued solution.
Thank you.


title: The gradient cannot be calculated automatically

body:
I am a beginner of Deep Learning and trying to making discriminator that judge cats/non-cats.

But When I run the code following, runtime error occured.
I know that "requires_grad" must be set to True in order to calculate the gradient automatically, but since X_train and Y_train are variables for reading, they are set to False.
I would be grateful if you could modify this code.
X_train = torch.tensor(train_set_x, dtype=dtype,requires_grad=False)
Y_train = torch.tensor(train_set_y, dtype=dtype,requires_grad=False)

def train_model(X_train, Y_train, X_test, Y_test, n_h, num_iterations=10000,learning_rate=0.5, print_cost=False):
    """
    Arguments:
    X_train -- training set represented by a numpy array of shape (num_px * num_px * 3, m_train)
    Y_train -- training labels represented by a numpy array (vector) of shape (1, m_train)
    X_test -- test set represented by a numpy array of shape (num_px * num_px * 3, m_test)
    Y_test -- test labels represented by a numpy array (vector) of shape (1, m_test)
    n_h -- size of the hidden layer
    num_iterations -- number of iterations in gradient descent loop
    learning_rate -- hyperparameter representing the learning rate used in the update rule of optimize()
    print_cost -- if True, print the cost every 200 iterations

    Returns:
    d -- dictionary containing information about the model.
    """
    n_x = X.size(1)
    n_y = Y.size(1)

    # Create model
    model = nn.Sequential(
          nn.Linear(n_x,n_h),
          nn.ReLU(),
          nn.Linear(n_h,n_y),
          nn.ReLU()
        )

    # Initialize parameters
    for name, param in model.named_parameters():
        if name.find('weight') != -1:
            torch.nn.init.orthogonal_(param)
        elif name.find('bias') != -1:
            torch.nn.init.constant_(param, 0)

    # Cost function
    cost_fn = nn.BCELoss()

    # Loop (gradient descent)
    for i in range(0, num_iterations):

        # Forward propagation: compute predicted labels by passing input data to the model.
        Y_predicted = model(X_train)
        A2 = (Y_predicted > 0.5).float()

        # Cost function. Inputs: predicted and true values. Outputs: "cost".
        cost = cost_fn(A2, Y_train)

        # Print the cost every 100 iterations
        if print_cost and i % 100 == 0:
            print("Cost after iteration %i: %f" % (i, cost.item()))

        # Zero the gradients before running the backward pass. See hint in problem description
        model.zero_grad()

        # Backpropagation. Compute gradient of the cost function with respect to all the
        # learnable parameters of the model. Use autograd to compute the backward pass.
        cost.backward()

        # Gradient descent parameter update.
        with torch.no_grad():
            for param in model.parameters():
                # Your code here !!
                param -= learning_rate * param.grad

    d = {"model": model,
         "learning_rate": learning_rate,
         "num_iterations": num_iterations}

    return d

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn


title: Getting indices of values in high dimension matrix

body:
I have  tensorA of size 10x4x9x2, the other tensorB is of size 10x5x2 that contains values from tensorA. Now, how can i find the index of each element in tensorB in tensorA.
Example:
First 2 elements of  TensorA:
         [[[[ 4.,  1.],
          [ 1.,  2.],
          [ 2.,  5.],
          [ 5.,  3.],
          [ 3., 11.],
          [11., 10.],
          [10., -1.],
          [-1., -1.],
          [-1., -1.]],

         [[12., 13.],
          [13.,  9.],
          [ 9.,  7.],
          [ 7.,  5.],
          [ 5.,  3.],
          [ 3.,  4.],
          [ 4.,  1.],
          [ 1.,  0.],
          [ 0., -1.]],
          ...... so on

Fist 2 elements of TensorB:
   [[[ 2.,  5.],
     [ 5.,  7.],
     [ 7.,  9.],
     [ 9., 10.],
     [10., 12.]],

     [[ 0.,  1.],
     [ 1.,  2.],
     [ 2.,  5.],
     [ 5., -1.],
     [-1., -1.]],

Now in tensorB the first element is [2,5] included in the first 5x2 matrix (dimension 0).
so the element should be matched against dimension 0 in  tensorA. And the output should be index
0,0,2 since it is the 3rd element.


title: How can I check the image sizes while CNN?

body:
I'm trying to classify cat and dog in CNN with PyTorch.
While I made few layers and processing images, I found that final processed feature map size doesn't match with calculated size.
So I tried to check feature map size step by step in CNN process with print shape but it doesn't work.
I heard tensorflow enables check tensor size in steps but how can I do that?
What I want is :
        def __init__(self):
        super(CNN, self).__init__()
        conv1 = nn.Conv2d(1, 16, 3, 1, 1)
        conv1_1 = nn.Conv2d(16, 16, 3, 1, 1)
        pool1 = nn.MaxPool2d(2)
        conv2 = nn.Conv2d(16, 32, 3, 1, 1)
        conv2_1 = nn.Conv2d(32, 32, 3, 1, 1)
        pool2 = nn.MaxPool2d(2)
        conv3 = nn.Conv2d(32, 64, 3, 1, 1)
        conv3_1 = nn.Conv2d(64, 64, 3, 1, 1)
        conv3_2 = nn.Conv2d(64, 64, 3, 1, 1)
        pool3 = nn.MaxPool2d(2)

        self.conv_module = nn.Sequential(
            conv1,
            nn.ReLU(),
            conv1_1,
            nn.ReLU(),
            pool1,
            # check first result size
            conv2,
            nn.ReLU(),
            conv2_1,
            nn.ReLU(),
            pool2,
            # check second result size
            conv3,
            nn.ReLU(),
            conv3_1,
            nn.ReLU(),
            conv3_2,
            nn.ReLU(),
            pool3,
            # check third result size
            pool4,
            # check fourth result size
            pool5
            # check fifth result size
        )

If there's any other way to check feature size at every step, please give some advice.
Thanks in advance.


title: What is the Pytorch sub for this tensor flow code?

body:
In converting this line of code to Pytorch from Tensor Flow, I am having trouble
datagen =  ImageDataGenerator(
  shear_range=0.2,
  zoom_range=0.2,
)
def read_img(filename, size, path):
    img = image.load_img(os.path.join(path, filename), target_size=size)
    #convert image to array
    img = img_to_array(img) / 255
    return img

and then
corona_df = final_train_data[final_train_data['Label_2_Virus_category'] == 'COVID-19']
with_corona_augmented = []

#create a function for augmentation
def augment(name):
    img = read_img(name, (255,255), train_img_dir)
    i = 0
    for batch in tqdm(datagen.flow(tf.expand_dims(img, 0), batch_size=32)):
        with_corona_augmented.append(tf.squeeze(batch).numpy())
        if i == 20:
            break
        i =i+1

#apply the function
corona_df['X_ray_image_name'].apply(augment)

I tried doing
transform = transforms.Compose([transforms.Resize(255*255)
                               ])
train_loader = torch.utils.data.DataLoader(os.path.join(train_dir,corona_df),transform = transform,batch_size =32)
def read_img(path):
    img  = train_loader()
    img = np.asarray(img,dtype='int32')
    img = img/255
    return img

I tried continuing but got soo confused by the errors.
I welcome any feedback. Tell me If i miss something
Even a small advice would work, thanks !


title: DQN algorithm in pytorch not converging

body:
I am new to deep reinforcement learning and have implemented the algorithm on my own but the value  is not converging could anyone take a look and tell me what is wrong with my algorithm and can i do to make it better
Here is the code:
import gym
import torch
import numpy as np
import torch
import random
from collections import deque
from itertools import count

class ReplayBuffer:
    def __init__(self):
        self.buffer=deque(maxlen=50000)
    def push(self,state,action,reward,next_state,done):
        if(len(self.buffer)<=1000):
            self.buffer.append((state,action,reward,next_state,done))
    def sample(self, batch_size: int, continuous: bool = True):
        if batch_size > len(self.buffer):
            batch_size = len(self.buffer)
        if continuous:
            rand = random.randint(0, len(self.buffer) - batch_size)
            return [self.buffer[i] for i in range(rand, rand + batch_size)]
        else:
            indexes = np.random.choice(np.arange(len(self.buffer)), size=batch_size, replace=False)
            return [self.buffer[i] for i in indexes]
class NNetwork(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.l1=torch.nn.Linear(4,128)
        self.l2=torch.nn.Linear(128,128)
        self.l3=torch.nn.Linear(128,2)

        self.optimizer=torch.optim.Adam(params=self.parameters(),lr=0.001)
        self.criterion=torch.nn.MSELoss()
    def forward(self,x):
        al1=torch.nn.ReLU()(self.l1(x))
        al2=torch.nn.ReLU()(self.l2(al1))
        al3=self.l3(al2)
        return al3
class Agent():
    def __init__(self):

        self.env=gym.make('CartPole-v0')
        self.mem=ReplayBuffer()
        self.q_local=NNetwork()
        self.q_target=NNetwork()
        self.q_target.load_state_dict(self.q_local.state_dict())
        self.epsilon=1.0
        self.e_decay=0.0995
        self.e_min=0.1
        self.update=4
        self.score=0
        self.gamma=0.99

    def predict(self,state):
        if (np.random.randn()<self.epsilon):
            return random.randint(0,1)
        else:
            index=self.q_local.forward(torch.Tensor(state).unsqueeze(0))
            return torch.argmax(index,dim=1).item()

    def step(self):
        state=self.env.reset()
        done=False
        i=0
        while not done:
            action=self.predict(state)
            n_state,reward,done,_=self.env.step(action)
            self.mem.push(state,action,reward,n_state,done)
            self.score+=reward
            self.learn()
            state=n_state
            i+=1
            if(i%10==0):
                if(self.epsilon>self.e_min):
                    self.epsilon=self.epsilon-self.e_decay
                else:
                    self.epsilon=self.e_min
                self.q_target.load_state_dict(self.q_local.state_dict())

        print(self.score)
        self.score=0
    def learn(self):
        if(len(self.mem.buffer)%32==0):
            return
        batch =self.mem.sample(32)
        state,action,reward,n_state,done= zip(*batch)
        state=torch.Tensor(state)
        action=torch.Tensor(action).unsqueeze(1)
        n_state=torch.Tensor(n_state)
        reward=torch.Tensor(reward).unsqueeze(1)
        done=torch.Tensor(done).unsqueeze(1)

        self.q_local.optimizer.zero_grad()

        q_N=self.q_local.forward(state).gather(1,action.long())
        q_t=self.q_target.forward(n_state)
        y=reward+(1-done)*self.gamma*torch.max(q_t,dim=1,keepdim=True)[0]

        loss=self.q_local.criterion(q_N,y)
        loss.backward()
        self.q_local.optimizer.step()
agent=Agent()
for t in count():
    print("EP ",t)
    agent.step()

Well  I am being ale to produce few scores but it is not converging


title: How to branch for TorchScript versions?

body:
I have a TorchScript and would like to branch based on the torch version:
import torch

def test_div():
    a = torch.tensor([10,20])
    b = torch.tensor([5,5])
    return torch.div(a, b) \
      if torch.__version__ < '1.6.0' else torch.floor_divide(a, b)

print(torch.__version__)
torch.jit.script(test_div)

However, the example doesn't work for older versions that don't have floor_divide:
1.2.0
RuntimeError:
object has no attribute floor_divide

How can I hide the floor_divide call from older version (__version__ < '1.6.0')?


title: Error while training logistic regression on FashionMNIST with Adam optimizer

body:
Dataset is FashionMNIST (784 input, 10 output). I'm trying to train logistic regression with Adam optimizer (coded it also):
weights = torch.randn(784, 10) / math.sqrt(784)
weights.requires_grad_()

bias = torch.zeros(10, requires_grad=True)

optimizer = Adam([weights, bias])
criterion = nn.CrossEntropyLoss()

The train function is:
def train_logistic_regression(weights, bias, batch, loss, optimizer):

    inputs, labels = batch

    inputs = inputs.view(inputs.shape[0], -1)

    optimizer.zero_grad()
    y_pred = torch.sigmoid(weights@inputs + bias) # there must be the problem
    loss = criterion(y_pred, labels)
    loss.backward()
    optimizer.step()

from IPython.display import clear_output

for epoch in range(1, 5):

    for batch in train_dataloader: # have to go with batches
      metrics = train_logistic_regression(weights, bias, batch, criterion, optimizer)

Every time I get the error:
RuntimeError                              Traceback (most recent call last)
<ipython-input-161-408b80d71db1> in <module>()
      5
      6     for batch in train_dataloader:
----> 7       metrics = train_logistic_regression(weights, bias, batch, criterion, optimizer)
      8
      9

<ipython-input-160-9c2f95ee56ee> in train_logistic_regression(weights, bias, batch, loss, optimizer)
      6
      7     optimizer.zero_grad()
----> 8     y_pred = torch.sigmoid(weights@inputs + bias)
      9     # y_pred = model(inputs)
     10     loss = criterion(y_pred, labels)

RuntimeError: size mismatch, m1: [784 x 10], m2: [128 x 784] at /pytorch/aten/src/TH/generic/THTensorMath.cpp:41

Would be very grateful if anyone could help me.


title: Remove circles and lines from an image to identify letters

body:
I am testing a way to identify the letters in a captcha only that in this type of captcha I am not able to remove these circles from the image. As you can see, they are different because they also have features that come out of the center. This causes the letters to be confused with the circles and dashes.
Example image captcha
I already tried to use OpenCv's Threshold to remove the "less dark" pixels to try to reduce these lines, but it ended up removing the letters a bit too.In this example it wasn’t so bad, but in some cases the letter is cut.
captcha with threshold
The code I used is below:
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
_, thresh1 = cv.threshold(img, 40, 255, cv.THRESH_BINARY)

Would anyone have a tip on how to solve this?
Thanks !


title: torch error of accessing weights of a neural network model built by multiple layer perceptrons

body:
I am trying to access weights of a neural network model built by torch on databricks.
the code :
 import torch
 import torch.nn as nn
 import numpy

 class Feedforward(nn.Module):

     def __init__(self, input_size, hidden_size):
         super(Feedforward, self).__init__()
         self.input_size = input_size
         self.hidden_size  = hidden_size
         self.fc1 = nn.Linear(self.input_size, self.hidden_size)
         self.relu = nn.ReLU()
         self.fc2 = nn.Linear(self.hidden_size, 1)
         self.sigmoid = nn.Sigmoid()

     def forward(self, x):
         hidden = self.fc1(x)
         relu = self.relu(hidden)
         output = self.fc2(relu)
         output = self.sigmoid(output)
         return output

from sklearn.datasets import make_blobs
def blob_label(y, label, loc): # assign labels
    target = numpy.copy(y)
    for l in loc:
        target[y == l] = label
    return target

x_train, y_train = make_blobs(n_samples=40, n_features=2, cluster_std=1.5, shuffle=True)
x_train = torch.FloatTensor(x_train)
y_train = torch.FloatTensor(blob_label(y_train, 0, [0]))
y_train = torch.FloatTensor(blob_label(y_train, 1, [1,2,3]))

x_test, y_test = make_blobs(n_samples=10, n_features=2, cluster_std=1.5, shuffle=True)
x_test = torch.FloatTensor(x_test)
y_test = torch.FloatTensor(blob_label(y_test, 0, [0]))
y_test = torch.FloatTensor(blob_label(y_test, 1, [1,2,3]))

model = Feedforward(2, 10)
criterion = torch.nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)

y_pred = model(x_test)
before_train = criterion(y_pred.squeeze(), y_test)
print('Test loss before training' , before_train.item())

model.train()
epoch = 20
for epoch in range(epoch):
    optimizer.zero_grad()
    # Forward pass
    y_pred = model(x_train)
    # Compute Loss
    loss = criterion(y_pred.squeeze(), y_train)

print('Epoch {}: train loss: {}'.format(epoch, loss.item()))
# Backward pass
loss.backward()
optimizer.step()

model.eval()
y_pred = model(x_test)
after_train = criterion(y_pred.squeeze(), y_test)
print('Test loss after Training' , after_train.item())

The code works well. But, when I tried to access the weights of the model, I got error:
 model.weight # ModuleAttributeError: 'Feedforward' object has no attribute 'weight'

But, if I tried
model.fc1.weight

it works well..
How to access the weights of a model built by multiple layer perceptron ?
This post Can't init the weights of my neural network PyTorch
does not work for me.
thanks


title: Save files names in numpy file (.npy)

body:
I  have a folder that has some pickles files, I would like to save the file names in a numpy file (file .np)
I am able to save file names in text file (file1.txt) as the following:
A23H.Pickel
H3DH.Pickle
H2T4.pickle
...

However, I am not able to save them in file.npy or convert that txt file to numpy file file2.npy. Could you please help me with this?


title: pytorch tensors cat on dim =0 not worked for me

body:
I have a problem with cat in pytorch. I want to concatenate tensors on dim=0, for exampe, I want something like this
>>> x = torch.randn(2, 3)
>>> x
tensor([[ 0.6580, -1.0969, -0.4614],
        [-0.1034, -0.5790,  0.1497]])
>>> torch.cat((x, x, x), 0)
tensor([[ 0.6580, -1.0969, -0.4614],
        [-0.1034, -0.5790,  0.1497],
        [ 0.6580, -1.0969, -0.4614],
        [-0.1034, -0.5790,  0.1497],
        [ 0.6580, -1.0969, -0.4614],
        [-0.1034, -0.5790,  0.1497]])

but, when I try to do it in my program I have
def create_batches_to_device(train_df, test_df, device,batch_size=2):
    train_tensor = torch.tensor([])
    for i in range (batch_size):
        rand_2_strs = train_df.sample(2)
        tmp_tensor = torch.tensor([rand_2_strs.get('Sigma').iloc[0],rand_2_strs.get('Sigma').iloc[1],
                               rand_2_strs.get('mu').iloc[0],rand_2_strs.get('mu').iloc[1],
                               rand_2_strs.get('th').iloc[0],rand_2_strs.get('th').iloc[1],
                               np.log(weighted_mse(np.array(rand_2_strs.get('Decay').iloc[0]),np.array(rand_2_strs.get('Decay').iloc[1]),t)[0])])
        print("it is tmp tensor")
        print(tmp_tensor)
        train_tensor = torch.cat((train_tensor,tmp_tensor),dim=0)
        print("this is after cat")
        print(train_tensor)
create_batches_to_device(train_data, test_data, device)

I have a result
it is tmp tensor
tensor([ 0.3244, -0.6401, -0.7959,  0.9019,  0.1468, -1.7093, -6.4419],
       dtype=torch.float64)
this is after cat
tensor([ 0.3244, -0.6401, -0.7959,  0.9019,  0.1468, -1.7093, -6.4419],
       dtype=torch.float64)
it is tmp tensor
tensor([ 1.2923, -0.3088, -0.1275,  0.6417, -1.3383,  1.4020, 28.9065],
       dtype=torch.float64)
this is after cat
tensor([ 0.3244, -0.6401, -0.7959,  0.9019,  0.1468, -1.7093, -6.4419,  1.2923,
        -0.3088, -0.1275,  0.6417, -1.3383,  1.4020, 28.9065],
       dtype=torch.float64)

and the result has no matter was dim=0 or dim=-1, the result is the same for both variance
This is example(look what dim=-1)
def create_batches_to_device(train_df, test_df, device,batch_size=2):
    train_tensor = torch.tensor([])
    for i in range (batch_size):
        rand_2_strs = train_df.sample(2)
        tmp_tensor = torch.tensor([rand_2_strs.get('Sigma').iloc[0],rand_2_strs.get('Sigma').iloc[1],
                               rand_2_strs.get('mu').iloc[0],rand_2_strs.get('mu').iloc[1],
                               rand_2_strs.get('th').iloc[0],rand_2_strs.get('th').iloc[1],
                               np.log(weighted_mse(np.array(rand_2_strs.get('Decay').iloc[0]),np.array(rand_2_strs.get('Decay').iloc[1]),t)[0])])
        print("it is tmp tensor")
        print(tmp_tensor)
        train_tensor = torch.cat((train_tensor,tmp_tensor),dim=-1)
        print("this is after cat")
        print(train_tensor)
create_batches_to_device(train_data, test_data, device)

and the result is the same
it is tmp tensor
tensor([  1.0183,   0.2162,   0.4987,  -0.0165,   0.2094,   0.9425, -14.4564],
       dtype=torch.float64)
this is after cat
tensor([  1.0183,   0.2162,   0.4987,  -0.0165,   0.2094,   0.9425, -14.4564],
       dtype=torch.float64)
it is tmp tensor
tensor([ 0.2389, -1.0108, -0.2350,  0.7105, -0.9200,  0.3282,  7.5456],
       dtype=torch.float64)
this is after cat
tensor([  1.0183,   0.2162,   0.4987,  -0.0165,   0.2094,   0.9425, -14.4564,
          0.2389,  -1.0108,  -0.2350,   0.7105,  -0.9200,   0.3282,   7.5456],
       dtype=torch.float64)


title: Translating Conv1D Layer from pytorch to tensorflow/keras

body:
I want to create an equal keras layer from this source:
Layer=torch.nn.Conv1d(in_features, out_features, 1)

My Input is shaped (Batch_size,Channel,Width)
This Layer is compiled to:
Conv1d(10, 256, kernel_size=(1,), stride=(1,))

By pytorch.
How can I express this Layer in tensorflow?
I have so far this:
layer1 = tf.keras.layers.Conv1D(in_features-out_features+1, kernel_size=1)

But I am not confident that this will is the right approach.


title: Is there way to change convolution method in Pytorch? (Or in other Frameworks?)

body:
We are currently developing an optimized convolution algorithm for ARM, in C++. We are using Ubuntu 18.04 for aarch64 on an ARM development board, Odroid N2+ to be exact.
To test the algorithm against other popular methods, (im2col+gemm, FFT, Winograd...) we download Pytorch, and compiled its C++ API, libtorch, natively in our development environment.
But unfortunately it seems there aren't a way to change the convolution algorithm from the given API.
Is there a way to change the convolution algorithm in Pytorch? (Or libtorch?) If not, are there any other frameworks or APIs that would provide optimized implementations of different convolution algorithms for our environment? (ARMv8, aarch64, C++)


title: How do I to average irregularly spaced x & y coordinate tensor into a grid with a specific cell size?

body:
I have an algorithm that generates a tensor of irregularly spaced x and y coordinates (ex: torch.size([3600, 2])), and I need to average the points into grid cells of a specific size (ex: 8 by 8). The resulting grid needs to be either an array or tensor.
It's not required, but I would also like to be able to determine if any of the resulting cells have less than a specified number of points in them.
For example I can graph the tensor using matplotlib's plt.scatter, and it looks like this:

In the above example, 100,000 points exist but the number of points can sometimes be in the tens of millions.
I've tried using histogram approaches, and most of them use a specific number of cells vs a specific cell size. Matplotlib can seemingly do it in a graph, but that doesn't help me get an array or tensor.
Edit:
This code might work, if it can be made to work properly.
def grid_torch(x_coords, y_coords, grid_size=(8,8), x_extent=(0., 1.), y_extent=(0., 1.)):
    x_coords = ((x_coords - x_extent[0]) / (x_extent[1] - x_extent[0])) * grid_size[0]
    y_coords = ((y_coords - y_extent[0]) / (y_extent[1] - y_extent[0])) * grid_size[1]

    x_list = []
    for x in range(grid_size[0]):
        x = torch.ones_like(x_coords) * x
        y_list = []
        for y in range(grid_size[1]):
            y = torch.ones_like(y_coords) * y
            in_bounds_x = torch.logical_and(x <= x_coords, x_coords <= x + 1)
            in_bounds_y = torch.logical_and(y <= y_coords, y_coords <= y + 1)
            in_bounds = torch.logical_and(in_bounds_x, in_bounds_y)

            in_bounds_indices = torch.where(in_bounds)
            print(in_bounds_indices)
            y_list.append(in_bounds_indices)
        x_list.append(torch.stack(y_list))
    return torch.stack(x_list)

out = grid_torch(xy_tensor[:,0], xy_tensor[:,1])

print(out.shape)

def create_grid(grid_layout, activ, grid_size=(8,8), min_density=8):
    cells = []
    for x in range(grid_size[0]):
        for y in range(grid_size[1]):
            indices = grid_layout[x, y]
            if len(indices) > min_density:
                average_activation = torch.mean(activ[indices])
                cells.append((average_activation, x, y))
                print(average_activation, x, y)
    return torch.stack(cells)

grid_test = create_grid(out, xy_tensor, grid_size=(8,8))


title: Does adding a forward hook to a layer of ensure that the gradient of the loss calculated using the layer's output will be calculated automatically?

body:
I have a model
class NewModel(nn.Module):
    def __init__(self,output_layer,*args):
        self.output_layer = output_layer
        super().__init__(*args)

        self.output_layer = output_layer
        self.selected_out = None
        #PRETRAINED MODEL
        self.pretrained = models.resnet18(pretrained=True)

        #TAKING OUTPUT FROM AN INTERMEDIATE LAYER

        #self._layers = []
        for l in list(self.pretrained._modules.keys()):
            #self._layers.append(l)
            if l == self.output_layer:
                handle = getattr(self.pretrained,l).register_forward_hook(self.hook)

    def hook(self,module, input,output):
        self.selected_out = output

    def forward(self, x):
        return x = self.pretrained(x)

I have two target outputs, one which is same as any label of an image and the second one is the same dimensions as the output obtained from self.output_layer, called target_feature
out = model(img)
layerout = model.selected_out

Now, if I want to calculate the loss of layerout with the target feature map, can it be done like the line written below?
loss = criterion(y_true, out) + feature_criterion(layerout, target_feature)

Or do I need to add backward_hooks?
In this Kaggle notebook
https://www.kaggle.com/sironghuang/understanding-pytorch-hooks
it is written that loss.backward() cannot be used when using backward_hooks.
Quoting the author
# backprop once to get the backward hook results
out.backward(torch.tensor([1,1],dtype=torch.float),retain_graph=True)
#! loss.backward(retain_graph=True)  # doesn't work with backward hooks,
#! since it's not a network layer but an aggregated result from the outputs of last layer vs target

Then how can be gradient be calculated based on the loss function?


title: Torch, how to use Multiple GPU for different dataset

body:
Assume that I have 4 different datasets and 4 GPU like below
4 dataset
dat0 = [np.array(...)], dat1 = [np.array(...)] , dat2 = [np.array(...)] , dat3 = [np.array(...)]

4 GPU
device = [torch.device(f'cuda:{i}') for i in range(torch.cuda.device_count())]

assume all the four data set have already converted into tensor and transfer to 4 different GPU.
Now, I have a function f from other module which can be used on GPU
How can I do the following at the same time,
compute 4 resulf of this
 ans0 = f(dat0) on device[0], ans1 = f(dat1) on device[1], ans2 = f(dat2) on device[2], ans3 = f(dat3) on device[3]

then move all the 4 ans back to cpu then calculate the sum
 ans = ans0 + ans1 + ans2 + ans3


title: Neural Network predicts same sequence of answers for every example in dataset

body:
thanks in advance for your help. My problem is the following: I have dataset of images and I'm trying to predict properties for images in this dataset. It is multi-label classification meaning that one image can have multiple properties. If I count all these properties across dataset and put their amount in descending order I will get the following sequence (I put here only first 10 values): [594,  41, 234,  58, 410,  47, 616, 231, 278, 477] where number means corresponding property. As loss function I'm using binary_cross_entropy_with_logits the thing is that after some small amount of time loss drops drastically so it seems that it is trained, but when I look on logits predicted by network using
torch.topk(property_logits[:10], k=10)

I'm getting the following:
torch.return_types.topk(
values=tensor([[-3.1373, -3.1558, -3.3370, -3.4383, -3.6139, -3.6574, -4.0421, -4.0930, 4.1260, -4.1534],
        [-2.8343, -2.9064, -3.0966, -3.1550, -3.3528, -3.3624, -3.7855, -3.8403,-3.8690, -3.9195],
        [-2.9859, -3.0170, -3.2494, -3.3170, -3.4875, -3.5206, -3.9383, -3.9951, -4.0376, -4.0742],
        [-2.8249, -2.8296, -2.9950, -3.0566, -3.2388, -3.2454, -3.7068, -3.7439, -3.7702, -3.8347],
        [-3.0599, -3.1202, -3.3430, -3.4330, -3.6226, -3.6342, -4.1087, -4.1403, -4.1948, -4.2462],
        [-2.9096, -2.9212, -3.0136, -3.0498, -3.2810, -3.3346, -3.6669, -3.7131,  -3.7174, -3.7790],
        [-2.8381, -2.9388, -3.2149, -3.2657, -3.4252, -3.4790, -3.9891, -4.0117, -4.0768, -4.1491],
        [-2.8207, -2.8712, -3.1752, -3.2148, -3.3849, -3.3923, -3.8807, -3.9231, -3.9844, -4.0404],
        [-2.4821, -2.7968, -2.9032, -3.2681, -3.3561, -3.6469, -3.6578, -3.7010,  -3.9183, -4.0160],
        [-2.5708, -2.8196, -3.0798, -3.3211, -3.5090, -3.7856, -3.8019, -3.8113, -4.0176, -4.1625]],
        device='cuda:0', grad_fn=<TopkBackward>),
indices=tensor([[594,  41, 234,  58, 410,  47, 616, 231, 278, 477],
        [594,  41, 234,  58, 410,  47, 616, 231, 278, 477],
        [594,  41, 234,  58, 410,  47, 616, 231, 278, 477],
        [594,  41, 234,  58, 410,  47, 616, 231, 278, 477],
        [594,  41, 234,  58,  47, 410, 616, 231, 278, 477],
        [ 41, 594, 234,  58, 410,  47, 616, 231, 278, 477],
        [594,  41, 234,  58,  47, 410, 616, 231, 278, 477],
        [594,  41, 234,  58,  47, 410, 616, 231, 278, 477],
        [234, 594,  58,  47,  41, 278, 410, 231, 477, 616],
        [234, 594,  58,  47,  41, 278, 410, 231, 477, 616]], device='cuda:0'))

So there is two problems with it: first one is obviusly that indices almost everywhere have the same order and second one is that values are negative everywhere. During training I guarantee that training samples which are given to the loss function are correct. But it can be the problem regarding sparsity of my data because there is more than 600 different properties and only 50% of dataset has at least one property and only 15% more than 2 of them. So I was expecting having a lot of predictions with "blank" (index 0) property, but I have literally none of them.
I don't really know how to debug this thing. I tried to instead on this more than 600 properties to have only 3 of them and i experienced the same story, there was just everywhere the same order and only negative values.


title: Cannot increase the accuracy of the neural network

body:
I have been learning CNN implementation in PyTorch recently, and I tried to write my own code with CNNs to process the CIFAR images. I got very low accuracy in the beginning, which, while going through the code and fixing the mistakes, I managed to pull up to 40% - 45%.
I am not able to increase it beyond that, and was wondering, if I could get some help, and comments with what could be done to increase it.
Here is the code which I used to create the data :
import torch
import matplotlib.pyplot as plt
import numpy as np
import pickle

REBUILD_DATA = False  #True

files = ["C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_1", "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_2",
         "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_3", "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_4",
         "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_5", "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\Test_batch"]

file_names = ["training_data_conv_batch_1.npy", "training_data_conv_batch_2.npy", "training_data_conv_batch_3.npy",
              "training_data_conv_batch_4.npy", "training_data_conv_batch_5.npy", "training_data_conv_test_batch.npy"]

LABELS = {0 : "AIRPLANE", 1 : "AUTOMOBILE", 2 : "BIRD", 3 : "CAT", 4 : "DEER", 5 : "DOG", 6 : "FROG", 7 : "HORSE",
          8 : "SHIP", 9 : "TRUCK"}

def create_training_data(file, ctr):
    training_data = []

    with open(file, 'rb') as fo:
        data = pickle.load(fo, encoding='bytes')

    r = int(data[b'data'][0].shape[0] / 3)

    if REBUILD_DATA:
        for n in range(len(data[b'labels'])):
          images = np.zeros((32, 32, 3))

          r_matrix = data[b'data'][n][:r]
          g_matrix = data[b'data'][n][r:2 * r]
          b_matrix = data[b'data'][n][2 * r:3 * r]

          counter = 0

          print(n, end=" ")

          for i in range(32):
              print("|", end = "")
              for j in range(32):
                  images[i][j] = [r_matrix[counter]/255, g_matrix[counter]/255, b_matrix[counter]/255]
                  counter += 1
          training_data.append([images, np.eye(10)[data[b'labels'][n]]])
          print()

        np.random.shuffle(training_data)
        np.save(file_names[ctr], training_data)

ctr = 0
if REBUILD_DATA:
    for file in files:
        print("BATCH ", ctr + 1)
        create_training_data(file, ctr)
        ctr += 1
        print()

    for i in file_names:
        training_data = np.load(i, allow_pickle=True)
        for n in range(5):
            plt.imshow(training_data[n][0])  # , cmap = "gray")
            print(LABELS[np.argmax(training_data[n][1])])
            plt.show()

Here is the code of the CNN :
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np

files = ["C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_1", "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_2",
         "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_3", "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_4",
         "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\data_batch_5", "C:\TORCH_CNN\CIFAR\cifar-10-batches-py\Test_batch"]

file_names = ["training_data_conv_batch_1.npy", "training_data_conv_batch_2.npy", "training_data_conv_batch_3.npy",
              "training_data_conv_batch_4.npy", "training_data_conv_batch_5.npy", "training_data_conv_test_batch.npy"]

LABELS = {0 : "AIRPLANE", 1 : "AUTOMOBILE", 2 : "BIRD", 3 : "CAT", 4 : "DEER", 5 : "DOG", 6 : "FROG", 7 : "HORSE",
          8 : "SHIP", 9 : "TRUCK"}

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

print()
print()

class CIDAR_CONV_NETS(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.conv3 = nn.Conv2d(64, 128, 3)
        self.conv4 = nn.Conv2d(128, 256, 3)
        self.conv5 = nn.Conv2d(256, 512, 3)

        self.toLinear = None
        if self.toLinear == None:
            x = self.convolution(torch.randn(32, 32, 3).view(-1, 3, 32, 32))
            self.toLinear = x[0].shape[0] * x[0].shape[1] * x[0].shape[2]

        self.fc1 = nn.Linear(self.toLinear, 512)
        self.fc2 = nn.Linear(512, 512)
        self.fc3 = nn.Linear(512, 512)
        self.fc4 = nn.Linear(512, 10)

    def convolution(self, x):
        x = F.relu(self.conv1(x))
        x = F.relu(self.conv2(x))
        x = F.relu(self.conv3(x))
        x = F.relu(self.conv4(x))
        conv = F.max_pool2d(F.relu(self.conv5(x)), (2, 2))
        return conv

    def forward(self, x):
        x = self.convolution(x).view(-1, self.toLinear)
        h1 = F.relu(self.fc1(x))
        h2 = F.relu(self.fc2(h1))
        h3 = F.relu(self.fc3(h2))
        h4 = self.fc4(h3)
        return h4

def train(net, x, y, batch_size):
    optimizer = optim.Adam(net.parameters(), lr = 0.0001)
    loss_function = nn.CrossEntropyLoss()
    EPOCHS = 50
    for epoch in range(EPOCHS):
        for batch in range(0, len(x), batch_size):
            batch_x = x[batch : batch + batch_size].view(-1, 3, 32, 32)
            batch_y = y[batch : batch + batch_size]   #.view(-1, 3, 32, 32) .uniform_(0, batch_size)
            net.zero_grad()
            output = net(batch_x)
            loss = loss_function(output, torch.max(batch_y, 1)[1])  #torch.max(batch_y, 1)[1]
            loss.backward()
            optimizer.step()
        print("epoch : ", epoch + 1, end = "   ||   ")
        print("loss : ", loss)

def test(net, x, y, batch_size_test):
    correct = 0
    total = 0
    #step_size = int(len(x) / batch_size_test)
    print()
    ctr = 0
    with torch.no_grad():
        for batch in range(0, len(x), batch_size_test):
            test_batch_x = x[batch: batch + batch_size_test].view(-1, 3, 32, 32)
            test_batch_y = y[batch: batch + batch_size_test]
            predicted_output = net(test_batch_x)
            print(ctr, end = " ")
            ctr += 1
            for i in range(len(test_batch_x)):
                if torch.argmax(predicted_output[i]) == torch.argmax(test_batch_y[i]):
                    correct += 1
                total += 1
                print(".", end = "")
            print(".")
    return correct/total

NETWORK = True

conv_net = CIDAR_CONV_NETS().to(device)
#print(conv_net)

if NETWORK:
    BATCH_SIZE = 100
    BATCH_SIZE_TEST = 1000
    BATCH_NO = 1
    for file in file_names:
        if file == "training_data_conv_test_batch.npy":
            training_data = np.load(file, allow_pickle=True)
            print("TRAINING COMPLETE.")
            print()
            print("TEST BATCH : ")
            X = torch.tensor([i[0] for i in training_data], dtype=torch.float32).cuda()
            Y = torch.tensor([i[1] for i in training_data], dtype=torch.int64).cuda()
            accuracy = test(conv_net, X, Y, BATCH_SIZE_TEST)
            print()
            print("Accuracy of the network : ", accuracy*100, end = "")
            print("%")
        else:
            training_data = np.load(file, allow_pickle=True)
            print("DATA BATCH : ", BATCH_NO)
            X = torch.tensor([i[0] for i in training_data], dtype=torch.float32).cuda()
            Y = torch.tensor([i[1] for i in training_data], dtype=torch.int64).cuda()
            train(conv_net, X, Y, BATCH_SIZE)
            print()
            print()
            BATCH_NO += 1

I would appreciate help!
Thank you!


title: tensorflow autodiff slower than pytorch's counterpart

body:
I am using tensorflow 2.0 and trying to evaluate gradients for backpropagating to a simple feedforward neural network. Here's how my model looks like:
def __init__(self, input_size, output_size):
        inputs = tf.keras.Input(shape=(input_size,))
        hidden_layer1 = tf.keras.layers.Dense(30, activation='relu')(inputs)
        outputs = tf.keras.layers.Dense(output_size)(hidden_layer1)
        self.model = tf.keras.Model(inputs=inputs, outputs=outputs)

        self.optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
        self.loss_function = tf.keras.losses.Huber()

The forward pass to this network is fine but when I use gradient tape to train the model, it is at least 10x slower than PyTorch.
Training function:
def learn_modified_x(self, inputs, targets, actions):
        with tf.GradientTape() as tape:
            predictions = self.model(inputs)
            predictions_for_action = gather_single_along_axis(predictions, actions)
            loss = self.loss_function(targets, predictions_for_action)

        grads = tape.gradient(loss, self.model.trainable_weights)
        self.optimizer.apply_gradients(zip(grads, self.model.trainable_weights))

I tried commenting lines to find what is actually causing the problem. I discovered that tape.gradient is a significant contributor to this situation.
Any idea?
PyTorch implementation
    def __init__(self, input_size, nb_action):
        super(Network, self).__init__()
        self.input_size = input_size
        self.nb_action = nb_action
        self.fc1 = nn.Linear(input_size, 30)
        self.fc2 = nn.Linear(30, nb_action)

    def forward(self, state):
        x = F.relu(self.fc1(state))
        q_values = self.fc2(x)
        return q_values

    def learn(self, batch_state, batch_next_state, batch_reward, batch_action):
        outputs = self.model(batch_state).gather(1, batch_action.unsqueeze(1)).squeeze(1)
        next_outputs = self.model(batch_next_state).detach().max(1)[0]
        target = self.gamma*next_outputs + batch_reward
        td_loss = F.smooth_l1_loss(outputs, target)
        self.optimizer.zero_grad()
        td_loss.backward(retain_variables = True)
        self.optimizer.step()


title: Error: optimizer got an empty parameter list. How can i modify my code?

body:
Here is code:
class MLP(nn.Module):
    def __ini__(self):
         super (MLP, self). __init__()
         self.model=nn.nn.Sequential(
            nn.Linear(784, 200),
            nn.LeakyReLU(inplace=True),
            nn.Linear(200, 200),
            nn.LeakyReLU(inplace=True),
            nn.Linear(200, 10),
            nn.LeakyReLU(inplace=True),
            )

    def forward(self,x):
                x=self.model(x)
                return
device= torch.device('cuda:0')
net = MLP().to(device)

when running these codes
optimizer = optim.SGD(net.parameters(),lr=learning_rate)

I get

ValueError: optimizer got an empty parameter list"

I am trying to imitate this notebook.


title: Pytorch variable size input for GRUCell

body:
I'm new in PyTorch and I'm trying to train something with variable size inputs. And I want to use nn.GRUCell not nn.GRU. I firstly post padded the inputs, such that it could be of the same length. I want to whether my Model class is correct or not. What I'm doing is, I'm storing the output after every time_step into output_sequence and then only keeping the output only for the trajectory_length point.
class Model(nn.Module):
    def __init__(self, cell, length, input_size, hidden_size, num_layers, output_size):
        super(Model,self).__init__()
        self.cell = cell
        self.length = length
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.num_layers  = num_layers
        self.output_size = output_size
        self.rnn = cell(self.input_size, self.hidden_size)
        self.linear1 = nn.Linear(self.hidden_size+1, self.hidden_size)
        self.linear2 = nn.Linear(self.hidden_size, self.output_size)

    def forward(self, state, batch_size, action_masks, trajectory_length):

        hidden_layer = torch.zeros(batch_size, self.hidden_size)
        state = torch.transpose(state, 0, 1).float()
        output_sequence = []
        for i in range(self.length):
            hidden_layer = self.rnn(state[i], hidden_layer)
            output_sequence.append(hidden_layer)

        output = torch.stack([output_sequence[l-1][i] for i, l in enumerate(trajectory_length)])

        output = self.linear2(output)

        for i in range(batch_size):
            output[i][~action_masks[i]] = float('-inf')

        return output


title: Object detection using optimised pytorch model

body:
I'm trying to use an quantized and optimised model frcnn-resnet50 which is in .pt zip format for object detection using ptorch. I tried torch.load and various methods and codes available in google but none worked. I have used the below mention code for quantisation and optimisation. How do i use the resulted model for object detection?
import torchvision
model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
import os
import torch

def print_model_size(mdl):
    torch.save(mdl.state_dict(), "tmp4.pt")
    print("%.2f MB" %(os.path.getsize("tmp4.pt")/1e6))
    #os.remove('tmp.pt')
print_model_size(model) # will print original model size
backend = "qnnpack"
model.qconfig = torch.quantization.get_default_qconfig(backend)
torch.backends.quantized.engine = backend
model_static_quantized = torch.quantization.prepare(model, inplace=False)
model_static_quantized = torch.quantization.convert(model_static_quantized, inplace=False)
print_model_size(model_static_quantized) ## will print quantized model size

script_model = torch.jit.script(model_static_quantized)
from torch.utils.mobile_optimizer import optimize_for_mobile
script_model_vulkan = optimize_for_mobile(script_model, backend='Vulkan')
torch.jit.save(script_model_vulkan, "faster-rcnn.pt")


title: gabor filter implementation for cifar10 data

body:
I implemented a code filtering cifar10 data using gabor function. I do not know why the images after being filtered and stacked are unclear. I am doubtful that I am not using the best values for gabor filter parameterts. Here is my code 'you can start reading from the comment 'calculating sigmas ....' before that is just routine stuff
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from torchvision import datasets, transforms
import tensorflow as tf
import tensorflow_io as tfio
import numpy as np
import math
from math import pi
from math import sqrt
import matplotlib.pyplot as plt
# Read config to figure out whether to use CUDA.
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# CUDA-related parameters. (Got this from pytorch's official tutorials.)
kwargs = {'num_workers': 1, 'pin_memory': True} if torch.cuda.is_available()else {}

# Load Cifar10 dataset using standard torchvision package.
data_transform = transforms.Compose([transforms.ToTensor(),
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

cifar_trainset = torch.utils.data.DataLoader(datasets.CIFAR10(root='./data',
 train=True, download=True,transform=data_transform),
 batch_size= 10, shuffle=True, **kwargs)

cifar_valset = torch.utils.data.DataLoader(datasets.CIFAR10(root='./data',
 train=True, download=True,transform=data_transform),
 batch_size= 10, shuffle=True, **kwargs)

cifar_testset = torch.utils.data.DataLoader( datasets.CIFAR10(root='./data',
 train=False, download=True, transform=data_transform),
    batch_size= 10, shuffle=False, **kwargs)

# to show the images before and after gabor filter
def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    npimg = plt.imshow(np.transpose(npimg, (1, 2, 0)))

#calculating sigmas using the formula from the paper 'Adding biological constraints
#to CNNs makes image classification more human-like and robust'
lambdaa = 5
b = [1,1.4,1.8]
gamma = [0.5,1]

sigma_x1 = (lambdaa/pi)*(sqrt(np.log(2)/2))*((2**b[0] + 1)/(2**b[0] - 1))
sigma_x2 = (lambdaa/pi)*(sqrt(np.log(2)/2))*((2**b[1] + 1)/(2**b[1] - 1))
sigma_x3 = (lambdaa/pi)*(sqrt(np.log(2)/2))*((2**b[2] + 1)/(2**b[2] - 1))
sigma_x4 = (lambdaa/pi)*(sqrt(np.log(2)/2))*((2**b[0] + 1)/(2**b[0] - 1))
sigma_x5 = (lambdaa/pi)*(sqrt(np.log(2)/2))*((2**b[1] + 1)/(2**b[1] - 1))
sigma_x6 = (lambdaa/pi)*(sqrt(np.log(2)/2))*((2**b[2] + 1)/(2**b[2] - 1))
sigma_y1 = sigma_x1/gamma[1]
sigma_y2 = sigma_x2/gamma[1]
sigma_y3 = sigma_x3/gamma[1]
sigma_y4 = sigma_x1/gamma[0]
sigma_y5 = sigma_x2/gamma[0]
sigma_y6 = sigma_x3/gamma[0]

thetas = np.array([0, pi/8, pi/4, pi*3/8, pi/2, pi*5/8, pi*3/4, pi*7/8])
offsets = np.array([0, pi/2, pi, pi*3/2])
sigmas = np.array([[sigma_x1, sigma_y1], [sigma_x2, sigma_y2], [sigma_x3, sigma_y3],
                   [sigma_x4, sigma_y4], [sigma_x5, sigma_y5], [sigma_x6, sigma_y6]])

for batch_idx, (x, t) in enumerate(cifar_trainset):
    current_batch_size = x.data.size()[0]
    x, t = x.to(device), t.to(device)

    #imshow(torchvision.utils.make_grid(x))
    for theta in thetas:
        for offset in offsets:
            for sigma in sigmas:
                x1 = tfio.experimental.filter.gabor(x, freq = 0.2,
                         sigma = sigma,theta = theta, nstds=31, offset = offset)

    x1 = tf.add(x1, 1)
    x1 = x1.numpy()       # converting tensorflow tensor to numpy
    x1 = np.array(x1)    # done to becaue dtype = complex64 had to be converted
    x1 = np.uint8(x1)
    x2 = torch.from_numpy(x1)  # converting numpy to pytorch tensor
    np.add(x1, 1, out=x1)

    imshow(torchvision.utils.make_grid(x2))

Does anyone tried specific values for gabor filter parameters with cifar10 data and it workd? or you think the problem is in the code itself?


title: How to index a tensor in a for loop?

body:
I am getting an error that says my tensor has to be a long, byte, or bool tensor. Debugging showed me that it is not getting an index [i], but the actual row [i] of the tensor x. I need that index to grab another row of another tensor y, tho.
Any ideas how to solve this?
number_batches_in = int(len(dataset_in)/batch_size)
number_batches_out = int(len(dataset_out)/batch_size)

x = torch.empty(size=(number_batches_in, 800))
y = torch.empty(size=(number_batches_out,1200), dtype=torch.float64)

for index, (x1, x2) in enumerate(dataloader_in):
    batch = torch.cat((x1, x2), 0)
    x[index] = batch

for index, (y1, y2, y3) in enumerate(dataloader_out):
    batch = torch.cat((y1, y2, y3), 0)
    y[index] = batch

model = Network(800,1200,3,800,200)
SAVE_PATH = "trained/model.dat"
epochs = 5
learning_rate = 0.001
optimizer = optim.Adam(model.parameters(),lr=learning_rate, eps=1e-08)
hist_error = []
hist_loss = []
beta = 0.5

for epoch in range(epochs):
    epoch_error = []
    epoch_loss = []
    for i in x:
        optimizer.zero_grad()
        pred = model.forward(i)
        y_true = y[i]
        loss = torch.mean(torch.sum((pred - y_true)) ** 2)
        loss.backward()
        optimizer.step()
        error = torch.mean(torch.sqrt((pred - y[i]) ** 2)).detach().numpy()
        epoch_error.append(error)
        epoch_loss.append(loss.data.detach().numpy())
    hist_error.append(np.mean(epoch_error))
    hist_loss.append(np.mean(epoch_loss))
    print("Epoch %d -- loss %f, RMS error %f " % (epoch+1, hist_loss[-1], hist_error[-1]))
torch.save(model.state_dict(), SAVE_PATH)
print("Model saved to %s" % SAVE_PATH)

Error message:
Traceback (most recent call last):
  File "/home/samim/miniconda3/envs/deep/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 3343, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-54864ad18480>", line 1, in <module>
    runfile('/home/samim/Documents/train.py', wdir='/home/samim/Documents/')
  File "/home/samim/.local/share/JetBrains/PyCharm2020.3/python/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/home/samim/.local/share/JetBrains/PyCharm2020.3/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/home/samim/Documents/train.py", line 61, in <module>
    y_true = y[i]
IndexError: tensors used as indices must be long, byte or bool tensors


title: How to increase the size of output images in GANs?

body:
My aim is to generate images using GAN. I have referred this and this code. This can generate images of size 64 x 64. I want to generate the images of size 128 * 128. I tried the following code but got the error.
## Initializing

# Root directory for dataset
dataroot = "/content/patterns"

# Number of workers for dataloader
workers = 2

# Batch size during training
batch_size = 128

# Spatial size of training images. All images will be resized to this
#   size using a transformer.
image_size = 128

# Number of channels in the training images. For color images this is 3
nc = 3

# Size of z latent vector (i.e. size of generator input)
nz = 100

# Size of feature maps in generator
ngf = 64

# Size of feature maps in discriminator
ndf = 64

# Number of training epochs
num_epochs = 100

# Learning rate for optimizers
lr = 0.0002

# Beta1 hyperparam for Adam optimizers
beta1 = 0.5

# Number of GPUs available. Use 0 for CPU mode.
ngpu = 1

## Generator
class Generator(nn.Module):
    def __init__(self, ngpu):
        super(Generator, self).__init__()
        self.ngpu = ngpu
        self.main = nn.Sequential(
            nn.ConvTranspose2d( nz, ngf * 16, 4, 1, 0, bias=False),
            nn.BatchNorm2d(ngf * 16),
            nn.ReLU(True),

            nn.ConvTranspose2d(ngf * 16, ngf * 4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 8),
            nn.ReLU(True),

            nn.ConvTranspose2d( ngf * 8, ngf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 4),
            nn.ReLU(True),

            nn.ConvTranspose2d( ngf * 4, ngf, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 2),
            nn.ReLU(True),

            nn.ConvTranspose2d( ngf * 2, ngf, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf),
            nn.ReLU(True),

            nn.ConvTranspose2d( ngf, nc, 4, 2, 1, bias=False),
            nn.Tanh()
            # state size. (nc) x 128 x 128
        )

    def forward(self, input):
        return self.main(input)

## Discriminator
class Discriminator(nn.Module):
    def __init__(self, ngpu):
        super(Discriminator, self).__init__()
        self.ngpu = ngpu
        self.main = nn.Sequential(

            nn.Conv2d(nc, ndf, 4, 2, 1, bias=False),
            nn.LeakyReLU(0.2, inplace=True),

            nn.Conv2d(nc, ndf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 2),
            nn.LeakyReLU(0.2, inplace=True),

            nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 4),
            nn.LeakyReLU(0.2, inplace=True),

            nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 8),
            nn.LeakyReLU(0.2, inplace=True),

            nn.Conv2d(ndf * 8, ndf * 16, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 16),
            nn.LeakyReLU(0.2, inplace=True),

            nn.Conv2d(ndf * 16, 1, 4, 1, 0, bias=False),
            nn.Sigmoid()
        )

    def forward(self, input):
        return self.main(input)

Please let me know what I am doing wrong. Is this not the way to generate 128 x 128 images? It would be great if anyone of you can make the required changes in the discriminator and generator. Also, let me know if my question requires more clarity.


title: PyTorch gather 3D source with 2D index

body:
Given a source tensor of shape [B,N,F] and an index tensor of shape [B,k], where index[i][j] is an index to a specific feature inside source[i][j] is there a way to extract an output tensor such that:
output[i][j] = source[i][j][index[i][j]]

torch.gather specifies that index.shape == source.shape, while here the shape of the source is one dimension bigger.
source = [
[[0.1,0.2],[0.2,0.3]],
[[0.4,0.5],[0.6,0.7]],
[[0.7,0.6],[0.8,0.9]]
]
index = [
[1,0],
[0,0],
[1,1]
]

desired_output = [
[0.2,0.2],
[0.4,0.6],
[0.6,0.9]
]


title: how to save a Pytorch model?

body: I am new to Deep learning and I want to know, how can I save the final model in Pytorch? I tried some things that were mentioned but I got confused with, how to save the model and how to load it back?


title: How to extend a binary transfer learning model with Pytorch to multiple image categories?

body:
I'm working with some code that classifies the infamous dog vs cat image classification using a ResNet-18 model and I'd like to extend it to be able to classify for greater than two image categories (like dog vs cat vs hamster vs ....). In particular I've got 5 categories. I'm new at transfer learning and I'm not sure what I have to change in my code to make this work.
import torch
import numpy as np
import torch.nn.functional as F
from torch.nn import Linear
from torch.utils.data import DataLoader, random_split
from torch.optim import Adam
from torchvision.transforms import Compose, Resize, ToTensor
from torchvision.datasets import ImageFolder
from torchvision.models import resnet18
from matplotlib import pyplot as plt
import random

transform = Compose([Resize((128,128)), ToTensor()])

ds = ImageFolder("*Image_Folder*", transform=transform)
ds_train, ds_val = random_split(ds, [3250, 1073])
dl_train = DataLoader(ds_train, batch_size= 32, shuffle=True)
dl_val = DataLoader(ds_val, batch_size= len(ds_val), shuffle= True)

model = resnet18(pretrained=True)
model.requires_grad_(False)
model.fc = Linear(model.fc.in_features, 5)
X_val, y_val = next(dl_val.__iter__())

opt = torch.optim.Adam(model.parameters(), lr=0.001)
def accuracy(yy, y):
  return torch.mean(1.0*(yy == y))
X_val.shape, y_val.shape
y_val = y_val.reshape(-1, 1).float()

for epoch in range(10):
  losses = []
  accs = []
  losses_val = []
  accs_val = []
  model.train()
  for X, y in dl_train:
    y = y.reshape(-1, 1).float()
    yy = torch.sigmoid(model(X))
    loss = F.binary_cross_entropy(yy, y)
    losses.append(loss.item())
    loss.backward()
    opt.step()
    opt.zero_grad()
    acc = accuracy(torch.round(yy), y)
    accs.append(acc.item())
  model.eval()
  with torch.no_grad():
    yy_val = torch.sigmoid(model(X_val))
    loss_val = F.binary_cross_entropy(yy_val, y_val)
    losses_val.append(loss_val.item())
    acc_val = accuracy(torch.round(yy_val), y_val)
    accs_val.append(acc_val.item())
  print(f"Epoch {epoch}: t-loss = {np.mean(losses):.4f}, t-acc = {np.mean(accs):.4f}, v-loss = {loss_val:.4f}, v-acc = {acc_val:.4f}")

I believe the code is fine up to the for loop, however it could be something I need to add or alter. Currently the line loss = F.binary_cross_entropy(yy, y) is what's giving me an error ValueError: Using a target size (torch.Size([32, 1])) that is different to the input size (torch.Size([32, 5])) is deprecated. Please ensure they have the same size.
This is the data I'm working from: https://www.kaggle.com/alxmamaev/flowers-recognition


title: Decode a json file properly, when get it as an input via message request

body:
I would like to read a request, sent via curl, as given below:
curl -X POST http://127.0.0.1:8080/eval/res -v path/request.json. With the json having the following format:
{
    "imgX": [{
        "key": "x",
        "url": "http://127.0.0.1:8080/imgs/x.png"
    }],

    "imgY": [{
        "key": "y",
        "url": "http://127.0.0.1:8080/imgs/y.png"
    }]
}

After service initialization, my code is:
 def preprocess(self, data):
    _json = {}
    for row in data:
        json_obj = row.get("data") or row.get("body")
        self.parameter_dict = dict(json_obj)
    image_url = ""
    json_obj = dict(json_obj)
    for img_inputs, msk_inputs in zip(json_obj['imgX'], json_obj['imgY']):
        key = img_inputs['key']

However, that gives:
KeyError: 'img'

I debug and find that when reading json file, each row is a bytearray:
{'body': bytearray(b'')}.

How can I decode to get the .json format back?


title: How to load/fetch the next data batches for the next epoch, during the current epoch?

body:
I know that since PyTorch 1.7.0 it is possible to prefetch some batches before an epoch begins. However, this does not make it possible to fetch batches while the operations within an epoch are being performed and before the next epoch begins. Based on this thread, it seems that it should be possible to use a Sampler to load batches during an epoch, and before the next epoch begins. However, I cannot wrap my head around how I can use a Sampler to achieve this.
Can anyone provide a code sample for a Sampler that allows fetching samples during an epoch?


title: Pytorch: Need help implementing a custom sliding window

body:
Lets say I have two matrices A and B, both are 10x10.
Now I want a sliding window, 3x3 to go through A and B and:

calculate the following result:

then take this result matrix, sum it up, and save it at location e inside of a new matrix.


title: How does the BERT model select the label ordering?

body: I'm training BertForSequenceClassification for a classification task. My dataset consists of 'contains adverse effect' (1) and 'does not contain adverse effect' (0). The dataset contains all of the 1s and then the 0s after (the data isn't shuffled). For training I've shuffled my data and get the logits. From what I've understood, the logits are the probability distributions before softmax. An example logit is [-4.673831, 4.7095485]. Does the first value correspond to the label 1 (contains AE) because it appears first in the dataset, or label 0. Any help would be appreciated thanks.


title: Can't do lazy loading with allennlp

body:
Currently I'm trying to implement lazy loading with allennlp, but can't.
My code is as the followings.
def biencoder_training():
    params = BiEncoderExperiemntParams()
    config = params.opts
    reader = SmallJaWikiReader(config=config)

    # Loading Datasets
    train, dev, test = reader.read('train'), reader.read('dev'), reader.read('test')
    vocab = build_vocab(train)
    vocab.extend_from_instances(dev)

    # TODO: avoid memory consumption and lazy loading
    train, dev, test = list(reader.read('train')), list(reader.read('dev')), list(reader.read('test'))

    train_loader, dev_loader, test_loader = build_data_loaders(config, train, dev, test)
    train_loader.index_with(vocab)
    dev_loader.index_with(vocab)

    embedder = emb_returner()
    mention_encoder, entity_encoder = Pooler_for_mention(word_embedder=embedder), \
                                      Pooler_for_cano_and_def(word_embedder=embedder)

    model = Biencoder(mention_encoder, entity_encoder, vocab)

    trainer = build_trainer(lr=config.lr,
                            num_epochs=config.num_epochs,
                            model=model,
                            train_loader=train_loader,
                            dev_loader=dev_loader)
    trainer.train()

    return model

When I commented-out  train, dev, test = list(reader.read('train')), list(reader.read('dev')), list(reader.read('test')), iterator doesn't work and training is conducted with 0 sample.
Building the vocabulary
100it [00:00, 442.15it/s]01, 133.57it/s]
building vocab: 100it [00:01, 95.84it/s]
100it [00:00, 413.40it/s]
100it [00:00, 138.38it/s]
You provided a validation dataset but patience was set to None, meaning that early stopping is disabled
0it [00:00, ?it/s]
0it [00:00, ?it/s]

I'd like to know if there is any solution for avoid this.
Thanks.

Supplement, added at fifth, May.
Currently I am trying to avoid putting all of each sample data on top of memory before training the model.
So I have implemented the _read method as a generator. My understanding is that by calling this method and wrapping it with SimpleDataLoader, I can actually pass the data to the model.
In the DatasetReader, the code for the _read method looks like this. It is my understanding that this is intended to be a generator that avoids memory consumption.
    @overrides
    def _read(self, train_dev_test_flag: str) -> Iterator[Instance]:
        '''
        :param train_dev_test_flag: 'train', 'dev', 'test'
        :return: list of instances
        '''
        if train_dev_test_flag == 'train':
            dataset = self._train_loader()
            random.shuffle(dataset)
        elif train_dev_test_flag == 'dev':
            dataset = self._dev_loader()
        elif train_dev_test_flag == 'test':
            dataset = self._test_loader()
        else:
            raise NotImplementedError(
                "{} is not a valid flag. Choose from train, dev and test".format(train_dev_test_flag))

        if self.config.debug:
            dataset = dataset[:self.config.debug_data_num]

        for data in tqdm(enumerate(dataset)):
            data = self._one_line_parser(data=data, train_dev_test_flag=train_dev_test_flag)
            yield self.text_to_instance(data)

Also, build_data_loaders actually looks like this.
def build_data_loaders(config,
    train_data: List[Instance],
    dev_data: List[Instance],
    test_data: List[Instance]) -> Tuple[DataLoader, DataLoader, DataLoader]:

    train_loader = SimpleDataLoader(train_data, config.batch_size_for_train, shuffle=False)
    dev_loader = SimpleDataLoader(dev_data, config.batch_size_for_eval, shuffle=False)
    test_loader = SimpleDataLoader(test_data, config.batch_size_for_eval, shuffle=False)

    return train_loader, dev_loader, test_loader

But, by somewhat reason I don't know, this code doesn't work.
def biencoder_training():
    params = BiEncoderExperiemntParams()
    config = params.opts
    reader = SmallJaWikiReader(config=config)

    # Loading Datasets
    train, dev, test = reader.read('train'), reader.read('dev'), reader.read('test')
    vocab = build_vocab(train)
    vocab.extend_from_instances(dev)

    train_loader, dev_loader, test_loader = build_data_loaders(config, train, dev, test)
    train_loader.index_with(vocab)
    dev_loader.index_with(vocab)

    embedder = emb_returner()
    mention_encoder, entity_encoder = Pooler_for_mention(word_embedder=embedder), \
                                      Pooler_for_cano_and_def(word_embedder=embedder)

    model = Biencoder(mention_encoder, entity_encoder, vocab)

    trainer = build_trainer(lr=config.lr,
                            num_epochs=config.num_epochs,
                            model=model,
                            train_loader=train_loader,
                            dev_loader=dev_loader)
    trainer.train()

    return model

In this code, the SimpleDataLoader will wrap the generator type as it is. I would like to do the lazy loading that allennlp did in the 0.9 version.
But this code iterates training over 0 instances, so currently I have added
train, dev, test = list(reader.read('train')), list(reader.read('dev')), list(reader.read('test'))
before
train_loader, dev_loader, test_loader = build_data_loaders(config, train, dev, test).
And it works. But this means that I can't train or evaluate the model until I have all the instances in memory. Rather, I want each batch to be called into memory only when it is time to train.


title: How the rewards are incorporated into the learning process?

body:
I have an environment in which I am trying to learn the system dynamics using baseline3  library. Since my example is quite big, I am using the following example to clarify the problem I have.
The problems

Where actually environment reword incorporate into the learning process?

Is there any upper and lower bound for the rewards?

My code:
from stable_baselines.common.policies import MlpPolicy
from stable_baselines.common.vec_env import DummyVecEnv
from stable_baselines import PPO2

env = gym.make('CartPole-v1')

model = PPO2(MlpPolicy, env, verbose=1)
model.learn(total_timesteps=10000)

obs = env.reset()
for i in range(1000):
    action, _states = model.predict(obs)
    obs, rewards, dones, info = env.step(action)
    env.render()

I could not find any information regarding this yet.


title: Ensuring that optimization does not find the trivial solution by setting weights to 0

body:
I am trying to train a neural network which takes as input (input_t0) and an initial hidden state (call it s_t0) and produces a new hidden state (s_t1) by transforming the input via a series of transformations (neural network layers). At the next time step, a transformed input (input_t1) and the hidden state from the previous time step (s_t1) is passed to the same model. This process keeps repeating for a couple of steps.
The goal of optimization is to ensure the distance between s_t0 and s_t1 is small through self-supervision, as s_t1 is supposed to be an transformed version of s_t0. In other words, I want s_t1 to only carry new information in the new input. My intuition tells me taking the norm of the weights and ensuring the norm does not go to zero (is this even possible?) would be one way to achieve this. However, I'm afraid won't be the best thing to do necessarily, as it might not encourage the model to update the state vector with new information.
Currently the way I train the model is by taking the absolute distance between s_t0 and s_t1 via loss = torch.abs(s_t1 - s_t0).mean(dim=1). Then I call loss.backward() and optimizer.step() which changes the weights. Note that the reason that I use abs() is that the hidden states are produced after applying ReLU, so the only hold positive values. So what is the best way to achieve this and ensure the weights don't go to 0?  Would I be able to somehow use mutual information for this?
However, I noticed that optimization quickly finds the trivial solution by setting weights to 0. This causes both s_t0 and s_t1 get smaller and smaller until their difference is 0, which satisfies the constraint but does not yield the behavior I expect. Is there a way to ensure weights do not go to zero during optimization?


title: Question about understanding of Pytorch .named_modules() loops

body:
I am referring to this implementation here:
https://github.com/hszhao/semseg/blob/master/model/pspnet.py
In line 49-58, the author writes:
for n, m in self.layer3.named_modules():
    if 'conv2' in n:
        m.dilation, m.padding, m.stride = (2, 2), (2, 2), (1, 1)
    elif 'downsample.0' in n:
        m.stride = (1, 1)

for n, m in self.layer4.named_modules():
    if 'conv2' in n:
        m.dilation, m.padding, m.stride = (4, 4), (4, 4), (1, 1)
    elif 'downsample.0' in n:
        m.stride = (1, 1)

What exactly is happening in these loops?
My understanding is, that the author is creatig a resnet model (his resnet.py here https://github.com/hszhao/semseg/blob/master/model/resnet.py ) and then is calling the different layers, which he implemented in his resnet class to forward them below.
layer3 and layer4 in resnet.py are made by calling the function def _make_layer(self, block, planes, blocks, stride=1): , so I assume that when .named_modules() is used in the loops, it is looping through the modules in this def _make_layer function, is it? If so, what happens in the elif part? There is no module, that is called downsample.0 ? (The only modules are nn.Conv2d and nn.BatchNorm2d )


title: How to load pretrained pytorch weight for

body:
I am following this blog https://pytorch.org/tutorials/advanced/super_resolution_with_onnxruntime.html  want to run pytorch model in onnx runtime . here in example it has given a pretrained weight a URL how to load a pretrained weight from local disk .
# Load pretrained model weights
model_url = 'https://s3.amazonaws.com/pytorch/test_data/export/superres_epoch100-44c6958e.pth'
path = "/content/best.pt"
batch_size = 1    # just a random number

# Initialize model with the pretrained weights
map_location = lambda storage, loc: storage
if torch.cuda.is_available():
    map_location = None
torch_model.load_state_dict(model_zoo.load_url(model_url, map_location=map_location))

# set the model to inference mode
torch_model.eval()

I want to load the weight which is defined as Path .


title: How to reshape a 32x512 into 128x128 keeping it as consistant 4 32x128 parts stacked?

body:
So I want to turn 32x512 into 128x128 keeping it as consistant 4 32x128 parts stacked like this:
.
How to do such a thing inside the PyTorch model?

So here is what I tried based on this answer:
import torch
x = torch.arange(32*512*3*2).reshape(2, 3, 32, 512)
print(x.shape)

x = list(x.split(4, dim=3))
print(f" xx {len(x)} {iii.shape for iii in x }")

x = torch.cat(x)
print(f" xs {x.shape}")

And this outputs:
torch.Size([2, 3, 32, 512])
 xx 128 <generator object <genexpr> at 0x7f358f1edad0>
 xs torch.Size([256, 3, 32, 4])

While I wanted  xs torch.Size([2, 3, 128, 128])


title: F.conv2d stuck on my CentOS

body:
I run my pytorch code well on mac and even on windows system but the same code seems stuck on CentOS6.3.

I debug with ipdb, and found the code was stuck at F.conv2d function:

> /home/work/anaconda2/envs/PyTorch/lib/python2.7/site-packages/torch/nn/modules/conv.py(301)forward()
    300    return F.conv2d(input, self.weight, self.bias, self.stride,
--> 301        self.padding, self.dilation, self.groups)
    302

ipdb> s

The running env was created with anaconda(python 2.7/3.6), pytorch version is 0.4.0.

I tried for a long time to resolve this problem and i tried. Do you have a suggestion? Thank you so much!


title: The same calculation in CUDA output differently in pytorch?

body:
I built a simple network using pytorch in GPU GTX 1080ti and initiate the network weight at the beginning and randomly initiate input tensors. And then I calculate the network output 10 times but each output has a little difference(in this phase, all weights and input are FIXED, I have printed them out for a check.). as shown following:

I wonder why will it happen? Is it because of the Floating point precision of the GPU? Thanks for any suggestion:)

SUMMARY

Finally, I figure out what happened, the code looks like:

import torch
import torch.nn as nn
import numpy as np
import torch.nn.functional as F
# import torch.utils.data.dataloader as dataloader

class Net(nn.Module):
  def __init__(self):
    super().__init__()
    params = [
      [3,16],
      [16,32],
      [32,32],
    ]
    self.model_list = nn.ModuleList()
    for each in params:
      self.model_list.append(
        nn.Conv2d(in_channels=each[0],
                  out_channels=each[1],
                  kernel_size=(3,3),
                  stride=(1,1))
      )
    self.pool = nn.MaxPool2d(stride=3, kernel_size=(3,3))
    # self.fcn = nn.Linear(in_features=3200, out_features=10).cuda()
  def forward(self, inputv):
    tmp = inputv
    for each in self.model_list:
      tmp = each(tmp)
    for each in range(2):
      tmp = self.pool(tmp)
    tmp = tmp.view(tmp.shape[0], -1)
    fcn = nn.Linear(in_features=tmp.shape[1], out_features=10).cuda()
    # build a new layer here will initiate the weight every time i call forward, which make everything mess.
    tmp = fcn(tmp)
    print(tmp.shape)
    return tmp.mean()

model = Net().cuda()
inputv = np.ones(shape=(32,3,100,100))
inputv = inputv.astype(np.float32)
inputv = torch.tensor(inputv).cuda()

model.eval()
for each in range(10):
  n = model(inputv)
  print(n)

The problem is that I build a new layer fcn in forward which will initiate the weight every time I call it. Once I build the layer in the init, every problem gone. However it's reasonable why I build some layer in forward. Sometimes some parameter needed to calculate dynamic instead of specifying manually such as the fcn input_dimension. Just like what I do in TensorFlow, it will manage a pipeline and I don't need to worry about some parameters after I change the network structure. What should I do if I want to build a network in tensorflow style? Thanks for any suggestion:)


title: CNN weights at input image location

body:
Given a CNN, say AlexNet:

How could one relate kernel locations at the 3rd conv block, i.e 13x13 filter size to the input image. I want to compare the filters at different locations.
I was thinking of just bilinearly upsampling the location, from 13x13 to 224x224,

nn.Upsample(size = (224,224), mode='bilinear')

however it's hard to justify local correspondence.


title: What does it mean if a deeper conv layer converges first?

body:
I am training a 3-layer convnet to classify images - a very standard problem, I know. I first tried 3 convolutional layers with ReLU, and got this:

weights from layer 1 with ReLU - looks like edge detection

weights from layer 3 with ReLU - looks like feature detection

The first layer (16 filters) is learning edges, as expected, and the third layer (64 filters) is learning features, as expected. Then, I just wanted to try a different non-linear term so I tried sELU instead.

Oddly, the third layer seems to be now learning features, and the first layer seems to not converge at all? What does it mean for a third layer to learn edges, does it mean I need more layers? I don't see why the first layer would fail to learn edges.

weights from layer 1 with SELU - looks unconverged?

weights from layer 3 with SELU - looks like edge detection?

I don't think the architecture is super important, but I have a 180x180 black-and-white image, and the filters are all 10 x 10 with stride 2 (16 filters for layer 1, 32 for layer 2, 64 for layer 3).


title: Strange behavior of Inception_v3

body:
I am trying to create a generative network based on the pre-trained Inception_v3.

1)  I fix all the weights in the model

2)  create a Variable whose size is (2, 3, 299, 299)

3)  create targets of size (2, 1000) that I want my final layer activations to become as close as possible to by optimizing the Variable.
(I do not set the batchsize of 1, because unlike VGG16, Inception_v3 doesn't take batchsize=1, but that's not the point).

The following code should work, but gives me the error: «RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation».

# minimalist code with Inception_v3 that throws the error:

import torch
from torch.autograd import Variable
import torch.optim as optim
import torch.nn as nn
import torchvision

torch.set_default_tensor_type('torch.FloatTensor')
Iv3 = torchvision.models.inception_v3(pretrained=True)
for i in Iv3.parameters():
    i.requires_grad = False

criterion = nn.CrossEntropyLoss()

x = Variable(torch.randn(2, 3, 299, 299), requires_grad=True)
target = torch.empty(2, dtype=torch.long).random_(1000)

output = Iv3(x)
loss = criterion(output[0], target)
loss.backward()

print(x.grad)

This is very strange, because if I do the same thing with VGG16, everything works fine:

# minimalist working code with VGG16:

import torch
from torch.autograd import Variable
import torch.optim as optim
import torch.nn as nn
import torchvision

# torch.cuda.empty_cache()
# vgg16 = torchvision.models.vgg16(pretrained=True).cuda()
# torch.set_default_tensor_type('torch.cuda.FloatTensor')

torch.set_default_tensor_type('torch.FloatTensor')
vgg16 = torchvision.models.vgg16(pretrained=True)
for i in vgg16.parameters():
    i.requires_grad = False

criterion = nn.CrossEntropyLoss()

x = Variable(torch.randn(2, 3, 229, 229), requires_grad=True)
target = torch.empty(2, dtype=torch.long).random_(1000)

output = vgg16(x)
loss = criterion(output, target)
loss.backward()

print(x.grad)

Please help.


title: Is there a standard way to optimize models to run well on different mobile devices?

body:
I’m working on a few side projects that involve deploying ML models to the edge. One of them is a photo-editing app that includes CNN’s for facial recognition, object detection, classification, and style transfer. The other is a NLP app that assists in the writing process by suggesting words and sentence completions..

Once I have a trained model that’s accurate, it ends up being really slow on one or more mobile devices that I'm testing on (usually the lower end Android). I’ve read that there are optimizations one can do to speed models up, but I don’t know how. Is there a standard, go-to tool for optimizing models for mobile/edge?


title: Is it possible to use Keras module in Pytorch script?

body:
I'm creating a network similar to lpcnet introduced by mozilla but in PyTorch. At the one point I need the module src/mdense.py in my script but it is written with keras. Is it possible to import keras module to torch framework? What could be the easiest way? I don't want to re-write the module with PyTorch.

There exists some converters but as I see, these are in early stages. Is there any I can depend on?


title: I want to apply (50000,32,32) mask to the dataloader (50000,32,32,3)

body:
I made the siliency mask shape with torch.Size([50000, 32, 32])

How should I apply this to the original dataset shape with (50000, 32, 32, 3)

I'm tryint to do the change the original dataloader's dataset

  original dataset(50000,32,32,3) x mask(50000,32,32)

but the becasue of the shape difference I have no idea how to apply


title: Where should I put the csv test file in PyTorch dataloader?

body:
Let say  I have test.csv

   filename
1  a.jpg

2  b.jpb

then I have test image folder
/test

test_dataset = torchvision.datasets.ImageFolder(root= path + 'test/',transform=trans)

this will bring all the test files

If I want to make a submission file after done training, how should I link test folder's name and submission.csv file name?

%%time
from torch.autograd import Variable
results = []
with torch.no_grad():
    model.eval()
    print('start')
    for num, data in enumerate(test_loader):
        #print(num)
        imgs, label = data
        imgs,labels = imgs.to(device), label.to(device)
        test = Variable(imgs)
        output = model(test)
        ps = torch.exp(output)
        top_p, top_class = ps.topk(1, dim = 1)
        #print(top_class)
        results += top_class.cpu().numpy().tolist()

predictions = np.array(results).flatten()

  array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
  0,
         1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
         0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
         1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
         0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
         1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

How should I know which result is from which file?


title: How to tackle the class imbalance problem during training in PyTorch

body:
Can someone please tell me if I have a different number of images per class during training on how to tackle the class imbalance problem in PyTorch?

How to solve this “class imbalance problem” of a classification model in PyTorch?


title: Need help understanding this Python list syntax

body:
I'm having trouble understanding what this syntax means in Python:

out = out[lengths - 1, range(len(lengths))]

Why is there a range inside a list? How does that work? For context, I'm training a machine learning model in PyTorch. lengths is a list of the lengths of the input.


title: Retrieving documents based on matrix multiplication

body:
I have a model that represents a collection of documents in multidimensional vector space. So, for example, for 100k documents, my model represents them in the form of 300 dimensional vectors. So, finally, I get a matrix of size [100K, 300]. For retrieving those documents according to relevance to the given query,  I do matrix multiplication. For example, I represent a given query as a [300, 1]. Then I get the cosine similarity scores using matrix multiplication as follows :
[100K, 300]*[300, 1] = [100K, 1].
Now how can I retrieve top 1000 documents from this collection with highest cosine similarity. The trivial way would be to sort based on cosine similarity and grab the first 1000 docs. Is there any way to retrieve the documents this way using some function in pytorch?

I mean, how can I get the indices of highest 1000 values from a 1D torch tensor?p


title: Neural Network for Matrix Eigenvalues

body:
I am interested in training a network that can take a square (symmetric, for the sake of real eigenvalues) 2x2 matrix as an input and output the corresponding eigenvalues.

So far I have attempted this using pytorch. I create a training set by randomly generating matrices and then using scipy.linalg to solve for the eignevalues:

A = np.random.randint(10, size=(2, 2))
A = (A + A.T)/2 #Make the matrices symmetric
results = la.eig(A)

Training a CNN with pytorch on a single input matrix, it can achieve a high training set accuracy and approximate the eigenvalues well.

However when using a training set with two or more input matrices, the cost function decreases some, but the resulting eigenvalues have a low training set accuracy.

I've tried changing the network depth/size, as well as just using a regular ANN instead of a CNN, but I am unable to achieve a low training set error when the training set contains more than one matrix.

Is there some fundamental reason why a NN is not able to be applied to this kind of problem? Or is it just a problem of my incorrect implementation?