I am using PyTorch in my program(Binary Classification).
The output from my model and actual labels are
JavaScript
x
9
1
model outputs are: (tensor([[0.4512],
2
[0.2273],
3
[0.4710],
4
[0.2965]], grad_fn=<SigmoidBackward0>), torch.float32),
5
actuall labels are (tensor([[0],
6
[1],
7
[0],
8
[1]], dtype=torch.int8), torch.int8)
9
When I calculate the Binary Cross Entropy, it gives me the error
JavaScript
1
2
1
RuntimeError: Found dtype Char but expected Float
2
I have no idea how it is finding the Char dtype.
Even If calculate it manually, it gives me this error.
JavaScript
1
4
1
import torch
2
cri = torch.nn.BCELoss()
3
cri(torch.tensor([[0.4470],[0.5032],[0.3494],[0.5057]], dtype=torch.float), torch.tensor([[0],[1],[0],[0]], dtype=torch.int8))
4
My DataLoader is
JavaScript
1
30
30
1
# CREATING DATA LOADER
2
3
class MyDataset(torch.utils.data.Dataset):
4
def __init__(self, dataframe, subset='train'):
5
self.subset = subset
6
7
self.dataframe = dataframe
8
self.transforms = transforms.Compose([
9
transforms.RandomResizedCrop(224),
10
transforms.RandomHorizontalFlip(),
11
transforms.Grayscale(),
12
transforms.ToTensor(),
13
transforms.Normalize((0.5), (0.5))
14
])
15
16
17
def __len__(self):
18
return len(self.dataframe)
19
20
def __getitem__(self, index):
21
row = self.dataframe.iloc[index]
22
img = Image.open(os.path.join('/kaggle/input/mura-v11',row['path']))
23
24
if self.subset=='train':
25
# print(torch.tensor(0, dtype=torch.int8) if row['labels'] == 'negative' else torch.tensor(1, dtype=torch.int8))
26
return (self.transforms(img), torch.tensor(0, dtype=torch.int8) if row['labels'] == 'negative' else torch.tensor(1, dtype=torch.int8))
27
else:
28
tensor_img = torchvision.transforms.functional.to_tensor(img)
29
return (tensor_img, torch.tensor(0, dtype=torch.int8) if row['labels'] == 'negative' else torch.tensor(1, dtype=torch.int8))
30
my training loop is
JavaScript
1
67
67
1
def train_model(model, criterion, optimizer, scheduler, num_epochs=25):
2
since = time.time()
3
4
best_model_wts = copy.deepcopy(model.state_dict())
5
best_acc = 0.0
6
7
for epoch in range(num_epochs):
8
print(f'Epoch {epoch}/{num_epochs - 1}')
9
print('-' * 10)
10
11
# Each epoch has a training and validation phase
12
for phase in ['train', 'val']:
13
if phase == 'train':
14
model.train() # Set model to training mode
15
else:
16
model.eval() # Set model to evaluate mode
17
18
running_loss = 0.0
19
running_corrects = 0
20
21
# Iterate over data.
22
for inputs, labels in dataloaders[phase]:
23
inputs = inputs.to(device)
24
labels = labels.to(device)
25
26
# zero the parameter gradients
27
optimizer.zero_grad()
28
29
# forward
30
# track history if only in train
31
with torch.set_grad_enabled(phase == 'train'):
32
outputs = model(inputs)
33
_, preds = torch.max(outputs, 1)
34
print(f"model outputs are: {outputs, outputs.dtype}, nmodel labels are {labels.view(labels.shape[0],1), labels.dtype}")
35
loss = criterion(outputs, labels.view(labels.shape[0], 1))
36
37
# backward + optimize only if in training phase
38
if phase == 'train':
39
loss.backward()
40
optimizer.step()
41
42
# statistics
43
running_loss += loss.item() * inputs.size(0)
44
running_corrects += torch.sum(preds == labels.data)
45
if phase == 'train':
46
scheduler.step()
47
48
epoch_loss = running_loss / dataset_sizes[phase]
49
epoch_acc = running_corrects.double() / dataset_sizes[phase]
50
51
print(f'{phase} Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}')
52
53
# deep copy the model
54
if phase == 'val' and epoch_acc > best_acc:
55
best_acc = epoch_acc
56
best_model_wts = copy.deepcopy(model.state_dict())
57
58
print()
59
60
time_elapsed = time.time() - since
61
print(f'Training complete in {time_elapsed // 60:.0f}m {time_elapsed % 60:.0f}s')
62
print(f'Best val Acc: {best_acc:4f}')
63
64
# load best model weights
65
model.load_state_dict(best_model_wts)
66
return model
67
And my Model is
JavaScript
1
46
46
1
class MuraModel(torch.nn.Module):
2
def __init__(self):
3
"""
4
In the constructor we instantiate four parameters and assign them as
5
member parameters.
6
"""
7
super().__init__()
8
self.inp = torch.nn.Conv2d(1, 3, 3) # Change the num of channels to 3
9
self.backbone = models.resnet18(pretrained=True)
10
num_ftrs = self.backbone.fc.in_features
11
self.backbone.fc = nn.Linear(num_ftrs, 1)
12
self.act = nn.Sigmoid()
13
14
def forward(self, x):
15
"""
16
In the forward function we accept a Tensor of input data and we must return
17
a Tensor of output data. We can use Modules defined in the constructor as
18
well as arbitrary operators on Tensors.
19
"""
20
three_channel = self.inp(x)
21
back_out = self.backbone(three_channel)
22
return self.act(back_out)
23
24
25
26
# inp = nn.Conv2d(1, 3, 3)
27
# model_ft = models.resnet18(pretrained=True)(inp)
28
# num_ftrs = model_ft.fc.in_features
29
# model_ft.fc = nn.Linear(num_ftrs, 2)
30
31
# model_ft = model_ft.to(device)
32
33
34
35
36
criterion = nn.BCELoss()
37
model = MuraModel()
38
39
optimizer_ft = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
40
41
# Decay LR by a factor of 0.1 every 7 epochs
42
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
43
44
model = train_model(model, criterion, optimizer_ft, exp_lr_scheduler,
45
num_epochs=25)
46
How to overcome it.
EDIT
Trace back on train_model function:
JavaScript
1
37
37
1
---------------------------------------------------------------------------
2
RuntimeError Traceback (most recent call last)
3
/tmp/ipykernel_17/2718774237.py in <module>
4
1 model = train_model(model, criterion, optimizer_ft, exp_lr_scheduler,
5
----> 2 num_epochs=25)
6
7
/tmp/ipykernel_17/2670448577.py in train_model(model, criterion, optimizer, scheduler, num_epochs)
8
33 _, preds = torch.max(outputs, 1)
9
34 print(f"model outputs are: {outputs, outputs.dtype}, nmodel labels are {labels.view(labels.shape[0],1), labels.dtype}")
10
---> 35 loss = criterion(outputs, labels.view(labels.shape[0], 1))
11
36
12
37 # backward + optimize only if in training phase
13
14
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
15
1108 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
16
1109 or _global_forward_hooks or _global_forward_pre_hooks):
17
-> 1110 return forward_call(*input, **kwargs)
18
1111 # Do not call functions when jit is used
19
1112 full_backward_hooks, non_full_backward_hooks = [], []
20
21
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/loss.py in forward(self, input, target)
22
610
23
611 def forward(self, input: Tensor, target: Tensor) -> Tensor:
24
--> 612 return F.binary_cross_entropy(input, target, weight=self.weight, reduction=self.reduction)
25
613
26
614
27
28
/opt/conda/lib/python3.7/site-packages/torch/nn/functional.py in binary_cross_entropy(input, target, weight, size_average, reduce, reduction)
29
3063 weight = weight.expand(new_size)
30
3064
31
-> 3065 return torch._C._nn.binary_cross_entropy(input, target, weight, reduction_enum)
32
3066
33
3067
34
RuntimeError: Found dtype Char but expected Float
35
36
37
Trace back on calculating loss individually
JavaScript
1
30
30
1
---------------------------------------------------------------------------
2
RuntimeError Traceback (most recent call last)
3
/tmp/ipykernel_17/4156819471.py in <module>
4
1 import torch
5
2 cri = torch.nn.BCELoss()
6
----> 3 cri(torch.tensor([[0.4470],[0.5032],[0.3494],[0.5057]], dtype=torch.float), torch.tensor([[0],[1],[0],[0]], dtype=torch.int8))
7
8
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
9
1108 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
10
1109 or _global_forward_hooks or _global_forward_pre_hooks):
11
-> 1110 return forward_call(*input, **kwargs)
12
1111 # Do not call functions when jit is used
13
1112 full_backward_hooks, non_full_backward_hooks = [], []
14
15
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/loss.py in forward(self, input, target)
16
610
17
611 def forward(self, input: Tensor, target: Tensor) -> Tensor:
18
--> 612 return F.binary_cross_entropy(input, target, weight=self.weight, reduction=self.reduction)
19
613
20
614
21
22
/opt/conda/lib/python3.7/site-packages/torch/nn/functional.py in binary_cross_entropy(input, target, weight, size_average, reduce, reduction)
23
3063 weight = weight.expand(new_size)
24
3064
25
-> 3065 return torch._C._nn.binary_cross_entropy(input, target, weight, reduction_enum)
26
3066
27
3067
28
29
RuntimeError: Found dtype Char but expected Float
30
Advertisement
Answer
BCELoss()
expects float labels. Yours are int8 (aka char). Converting them to float in the last line of__getitem__()
should fix the issue.