Я создал пользовательские функции потерь следующим образом:
def my_loss(outputs, labels):
"""
Args:
outputs - output of network ([batch size, 3])
labels - desired labels ([batch size, 3])
"""
loss = torch.zeros(1, dtype=torch.float, requires_grad=True)
loss = loss.to(device)
#----------------------------------------------
# implementation needed here
#----------------------------------------------
batch_size = outputs.size()[0] # batch_size
outputs = F.log_softmax(outputs, dim=1) # compute the log of softmax values
outputs = outputs[range(batch_size), labels] # pick the values corresponding to the labels
loss = -torch.sum(outputs)/num_examples
# Observe: If you need to iterate and add certain values to loss defined above
# you cannot write: loss +=... because this will raise the error:
# "Leaf variable was used in an inplace operation"
# Instead, to avoid this error write: loss = loss + ...
return loss
Но когда я запускаю фактическое обучение NN, я получаю следующую ошибку, я искал в Интернете, но ничего не смог найти solid, которые могут мне помочь:
IndexError Traceback (most recent call last)
<ipython-input-31-5992a9440f01> in <module>
18 train_losses,
19 validation_losses,
---> 20 epochs=2)
<ipython-input-30-2fa819e6c600> in train_model(model, optimizer, train_loader, validation_loader, train_losses, validation_losses, epochs)
29 # Forward pass
30 outputs = model(inputs.float())
---> 31 loss = my_loss(outputs, labels)
32
33 # Backward and optimize
<ipython-input-25-1e2caf3c6a5e> in my_loss(outputs, labels)
18 batch_size = outputs.size()[0] # batch_size
19 outputs = F.log_softmax(outputs, dim=1) # compute the log of softmax values
---> 20 outputs = outputs[range(batch_size), labels] # pick the values corresponding to the labels
21 loss = -torch.sum(outputs)/num_examples
22
IndexError: tensors used as indices must be long, byte or bool tensors
Вот вспомогательные функции, которые используют функцию my_loss:
def validate_model(model, loader):
"""
This function parses a given loader and returns the avergae (per image) loss
(as defined by "my_loss") of the entire dataset associated with the given loader.
Args:
model - neural network to examine
loader - where input data comes from (train, validation, or test)
returns:
average loss per image in variable named "avg_loss"
"""
model.eval() # eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)
# (dropout is set to zero)
#----------------------------------------------
# implementation needed here
#----------------------------------------------
labels = next(iter(loader['labels']))
avg_loss = my_loss(model,labels)
model.train() #back to default
return avg_loss
def train_model(model,
optimizer,
train_loader,
validation_loader,
train_losses,
validation_losses,
epochs=1):
"""
Trains a neural network.
Args:
model - model to be trained
optimizer - optimizer used for training
train_loader - loader from which data for training comes
validation_loader - loader from which data for validation comes (maybe at the end, you use test_loader)
train_losses - adding train loss value to this list for future analysis
validation_losses - adding validation loss value to this list for future analysis
epochs - number of runs over the entire data set
"""
#----------------------------------------------
# implementation needed here
#----------------------------------------------
for epoch in range(epochs):
for i, data in enumerate(loader, 0):
inputs = (data['image']).to(device)
labels = (data['labels']).to(device)
# Forward pass
outputs = model(inputs.float())
loss = my_loss(outputs, labels)
# Backward and optimize
optimizer.zero_grad()
loss.backward()
optimizer.step()
return
Процесс, вызывающий ошибку:
# Using two lists (train_losses, validation_losses) containing history of losses
# (i.e., loss for each training epoch) for train and validation sets.
# If these are not defined, we define them. Otherwise, the function train_model
# updates these two lists (by adding loss values when it is called for further training)
# in order to be able to visualize train and validation losses
if not 'train_losses' in vars():
train_losses = []
if not 'validation_losses' in vars():
validation_losses = []
train_model(model,
optimizer,
train_loader,
validation_loader,
train_losses,
validation_losses,
epochs=2)