I'm trying to randomly sample a mini-batch from Flux.dataloader rather than iterate through... I already created train_dataloader object, and all I need is random sampling from this object. Can you help me do this? I tried to look up the source code of dataloader in https://github.com/FluxML/Flux.jl/blob/master/src/data/dataloader.jl but I couldn't figure it out. The code below is what I'm trying to do:
train_loader = DataLoader((X, L), batchsize=batch_size, shuffle=true)
(x, l) = train_loader[rand(1:length(train_loader))]
I solved in ad hoc method...
I just created an array that holds batches, and randomly selected batches from that array.
batch_collection = []
for (x, l) in train_loader
push!(batch_collection, (x,l))
end
random_batch = rand(batch_collection, 1)[1]
Related
I am trying to implement some policy gradient training, similar to this. However, I would like to manipulate the rewards(like discounted future sum and other differentiable operations) before doing the backward propagation.
Consider the manipulate function defined to calculate the reward to go:
def manipulate(reward_pool):
n = len(reward_pool)
R = np.zeros_like(reward_pool)
for i in reversed(range(n)):
R[i] = reward_pool[i] + (R[i+1] if i+1 < n else 0)
return T.as_tensor(R)
I tried to store the rewards in a list:
#pseudocode
reward_pool = [0 for i in range(batch_size)]
for k in batch_size:
act = net(state)
state, reward = env.step(act)
reward_pool[k] = reward
R = manipulate(reward_pool)
R.backward()
optimizer.step()
It seems like inplace operation breaks the gradient computation, the code gives me an error: one of the variables needed for gradient computation has been modified by an inplace operation.
I also tried to initialize an empty tensor first, and store it in the tensor, but inplace operation is still the issue - a view of a leaf Variable that requires grad is being used in an in-place operation.
I am kind of new to PyTorch. Does anyone know what the right way recording rewards is in this case?
The issue is due to assignment to existing object.
Simply initialize the empty pool(list) for each iteration and append to the pool when new reward is calculated, i.e.
reward_pool = []
for k in batch_size:
act = net(state)
state, reward = env.step(act)
reward_pool.append(reward)
R = manipulate(reward_pool)
R.backward()
optimizer.step()
I have a pretrained model which was saved by
torch.save(net, 'lenet5_mnist_model')
And now I am loading it back and trying to calculate fisher information matrix like this:
precision_matrices = {}
batch_size = 32
my_model = torch.load('lenet5_mnist_model')
my_model.eval() # I tried to comment this off, but still no luck
for n, p in deepcopy({n: p for n, p in my_model.named_parameters()}).items()
p = torch.tensor(p, requires_grad = True)
p.data.zero_()
precision_matrices[n] = variable(p.data)
for idx in range(int(images.shape[0]/batch_size)):
x = images[idx*batch_size : (idx+1)*batch_size]
my_model.zero_grad()
x = Variable(x.cuda(), requires_grad = True)
output = my_model(x).view(1,-1)
label = output.max(1)[1].view(-1)
loss = F.nll_loss(F.log_softmax(output, dim=1), label)
loss = Variable(loss, requires_grad = True)
loss.backward()
for n, p in my_model.named_parameters():
precision_matrices[n].data += p.grad.data**2
Finally, the above code will crash at the last line, because p.grad is NoneType. So the error is:
AttributeError: 'NoneType' object has no attribute 'data'.
Could someone provide some guidance on what caused the NoneType grad for the parameters? How should I fix this?
Your loss does not backpropagate the gradients through the model, because you are creating a new loss tensor with the value of the actual loss, which is a leaf of the computational graph, meaning that there is no history to backpropagate through.
loss.backward() needs to be called on the output of loss = F.nll_loss(F.log_softmax(output, dim=1), label).
I'm assuming that you thought you need to create a tensor with requires_grad=True, to be able to calculate the gradients. That is not the case. Tensors created with requires_grad=True are the leaves of the computational graph (they start the graph) and every operation performed on any tensor that is part of the graph is tracked such that the gradients can flow through the intermediate results to the leaves. Only tensors that need to be optimised (i.e. learnable parameters) should set requires_grad=True manually (the model's parameters do that automatically), everything else regarding the gradients is inferred. Neither x nor the loss are learnable parameters.
This confusion presumably arose due to the use of Variable. It was deprecated in PyTorch 0.4.0, which was released over 2 years ago, and all of its functionality has been merged into the tensors. Please do not use Variable.
x = images[idx*batch_size : (idx+1)*batch_size]
my_model.zero_grad()
x = x.cuda()
output = my_model(x).view(1,-1)
label = output.max(1)[1].view(-1)
loss = F.nll_loss(F.log_softmax(output, dim=1), label)
loss.backward()
I'm searching to create a personnal dataloader with a specific format to use Pytorch library, someone have an idea how can I do it ? I have follow Pytorch Tutorial but I don't find my answer!
I need a DataLoader that yields the tuples of the following format:
(Bx3xHxW FloatTensor x, BxHxW LongTensor y, BxN LongTensor y_cls) where
x - batch of input images,
y - batch of groung truth seg maps,
y_cls - batch of 1D tensors of dimensionality N: N total number of classes,
y_cls[i, T] = 1 if class T is present in image i, 0 otherwise
I hope that someone can unlock the problem .. :) Thanks !
You simply need to have a database derived from torch.utils.data.Dataset, where __getitem__(index) returns a tuple (x, y, y_cls) of the types you want, pytorch will take care of everything else.
from torch.utils import data
class MyTupleDataset(data.Dataset):
def __init__(self):
super(MyTupleDataset, self).__init__()
# init your dataset here...
def __getitem__(index):
x = torch.Tensor(3, H, W) # batch dim is handled by the data loader
y = torch.Tensor(H, W).to(torch.long)
y_cls = torch.Tensor(N).to(torch.long)
return x, y, y_cls
That's it. Provide pytorch's torch.utils.data.DataLoader with MyTupleDataset and you are done.
When I run this code:
x = tf.placeholder(tf.int32, shape=(None, 3))
with tf.Session() as sess:
feed_dict = dict()
feed_dict[x] = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
input = sess.run([x], feed_dict=feed_dict)
I get this error:
Placeholder_2:0 is both fed and fetched.
I'm not sure what I'm doing wrong here. Why does this not work?
Are you sure this code covers what you are trying to achieve?
You ask to read out whatever you pass through. This is not a valid call in tensorflow. If you want to pass through values and do nothing with it (what for?) you should have an identity operation.
x = tf.placeholder(tf.int32, shape=(None, 3))
y = tf.identity(x)
with tf.Session() as sess:
feed_dict = dict()
feed_dict[x] = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
input = sess.run([y], feed_dict=feed_dict)
The problem is "feeding" actually kind of overwrites whatever your op generates, thus you cannot fetch it at this moment (since there is nothing being really produced by this particular op anymore). If you add this identity op, you correctly feed (override x) do nothing with the result (identity) and fetch it (what identity produces, which is whatever you feeded as an output of x)
I found out what I was doing wrong.
x is a placeholder -- it holds information and evaluating x does not do anything. I forgot that vital piece of information and proceeded to attempt to run the Tensor x inside sess.run()
Code similar to this would work if, say, there was another Tensor y that depended on x and I ran that like sess.run([y], feed_dict=feed_dict)
I am having trouble understanding how to perform LOOCV in SPSS.
I need to evaluate a simple linear regression
$Y=aX+b$.
Thanks.
For linear regression it is pretty easy, and SPSS allows you to save the statistics right within the REGRESSION command. See here for another example.
REGRESSION
/NOORIGIN
/DEPENDENT Y
/METHOD=ENTER X
/SAVE PRED (PredAll) DFIT (CVFit).
Then the leave one out prediction can be calculated as COMPUTE LeaveOneOut = PredAll - CVFit. But for non-linear models that SPSS does not provide convenient SAVE values for one can build the repeated dataset with the missing values, then use SPLIT FILE, and then obtain the leave one out statistics for whatever statistical procedure you want. If your id variable is simply the row number for the dataset, you simply need two loops of the maximum case number, and then match the needed info into the new file.
Here is an example of this procedure.
*Making some fake data to work with.
INPUT PROGRAM.
LOOP Id = 1 TO 10.
END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
DATASET NAME Sim.
COMPUTE X = RV.NORMAL(10,5).
COMPUTE Y = 3 + 0.2*(X) + RV.NORMAL(0,0.2).
FORMATS Id (F2.0) X Y (F4.2).
EXECUTE.
*Original regression model with the leave one.
*out fits.
REGRESSION
/NOORIGIN
/DEPENDENT Y
/METHOD=ENTER X
/SAVE PRED (PredAll) DFIT (CVFit).
*Manual way to create stacked dataset
*can use with other non-linear models.
INPUT PROGRAM.
COMPUTE #Cases = 10.
LOOP #Id = 1 TO #Cases.
LOOP #Iter = 1 TO #Cases.
COMPUTE L1O = #Iter.
COMPUTE Id = #Id.
END CASE.
END LOOP.
END LOOP.
END FILE.
END INPUT PROGRAM.
DATASET NAME LeaveOneOut.
*Merging in original data.
MATCH FILES FILE = *
/TABLE = 'Sim'
/BY Id.
*Set missing to
IF L1O = Id Y = $SYSMIS.
SORT CASES BY L1O.
SPLIT FILE BY L1O.
*You can replace regression with whatever procedure you are.
*interested in.
REGRESSION
/NOORIGIN
/DEPENDENT Y
/METHOD=ENTER X
/SAVE PRED (CVFit2).
SPLIT FILE OFF.
*This shows the original leave one out stats.
*And new stats are the same besides some floating.
*point differences.
COMPUTE Test = (CVFit2 - (PredAll-CVFit)).
TEMPORARY.
SELECT IF (L1O = Id).
FREQ VAR Test.
EXECUTE.