i’m trying to run my neural network on catVSdog dataset with the following script:
from sklearn.metrics import accuracy_score, roc_auc_score
import numpy as pp
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import TensorDataset, random_split, DataLoader
import os, cv2
import tqdm
### process data ###
data = []
i = 0
for image in tqdm.tqdm(os.listdir('Cat')):
try:
image = cv2.resize(cv2.imread(f'Cat/{image}', 0), (60, 60)) / 255.
data.append((image, 1))
except:
i += 1
ii = 0
for image in tqdm.tqdm(os.listdir('Dog')):
try:
image = cv2.resize(cv2.imread(f'Dog/{image}', 0), (60, 60)) / 255.
data.append((image, 0))
except:
ii += 1
print(f'total errors in cat files: {i}')
print(f'total errors in dog files: {ii}')
pp.random.shuffle(data)
labels = torch.tensor([data[i][1] for i in range(len(data))]).type(torch.FloatTensor)
images = torch.tensor([data[i][0] for i in range(len(data))]).type(torch.FloatTensor).reshape(-1, 1, 60, 60)
# torch.save(labels, 'labels.pt')
# torch.save(images, 'images.pt')
### prepare data for training ###
# images = torch.load('images.pt')
# labels = torch.load('labels.pt')
trainSet, testSet = random_split(TensorDataset(images, labels), [19956, 4990])
trainLoader = DataLoader(trainSet, 20, True)
testLoader = DataLoader(testSet, 20, True)
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 10, 3, padding=1)
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(10, 20, 3, padding=1)
self.pool2 = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(90000, 120)
self.fc2 = nn.Linear(120, 100)
self.fc3 = nn.Linear(100, 1)
def forward(self, x):
x = self.pool1(F.relu(self.conv1(x)))
x = self.pool2(F.relu(self.conv2(x)))
x = x.view(-1, 90000)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return torch.sigmoid(x)
clf = Net()
optim = torch.optim.Adam(clf.parameters(), 0.01)
lossfn = nn.BCELoss()
def training_loop(epochs, optim, clf, lossf, train_loader):
for epoch in range(1, epochs + 1):
loss_train = 0.0
for imgs, labels in train_loader:
imgs, labels = torch.autograd.Variable(imgs), torch.autograd.Variable(labels)
output = clf(imgs)
loss = lossf(output, labels)
optim.zero_grad()
loss.backward()
optim.step()
loss_train += loss.item()
print(f'Epoch: {epoch}, Batch Loss: {loss_train}, Training Loss: {loss_train / len(train_loader)}')
# validataion loop
def val_loop(clf, train_loader, val_loader):
for name, loader in [('train', train_loader), ('val', val_loader)]:
scores = []
with torch.no_grad():
for img, labels in loader:
output = clf(img)
scores.append(roc_auc_score(labels, torch.round(output)))
print(f'{name} Accuracy : {pp.mean(scores)}')
print('start training')
training_loop(5, optim, clf, lossfn, trainLoader)
print('start val')
val_loop(clf, trainLoader, testLoader)
but when i run the script i get this problem:
C:\Users\BHAAK\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\modules\loss.py:529: UserWarning: Using a target size (torch.Size([20])) that is different to the input size (torch.Size([1, 1])) is deprecated. Please ensure they have the same size.
return F.binary_cross_entropy(input, target, weight=self.weight, reduction=self.reduction)
Traceback (most recent call last):
File "C:/Users/BHAAK/Desktop/ML_PATH/dirty-hands/dirty hands file 1/parser.py", line 111, in <module>
training_loop(5, optim, clf, lossfn, trainLoader)
File "C:/Users/BHAAK/Desktop/ML_PATH/dirty-hands/dirty hands file 1/parser.py", line 85, in training_loop
loss = lossf(output, labels)
File "C:\Users\BHAAK\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\modules\module.py", line 722, in _call_impl
result = self.forward(*input, **kwargs)
File "C:\Users\BHAAK\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\modules\loss.py", line 529, in forward
return F.binary_cross_entropy(input, target, weight=self.weight, reduction=self.reduction)
File "C:\Users\BHAAK\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\functional.py", line 2477, in binary_cross_entropy
"!= input nelement ({})".format(target.numel(), input.numel()))
ValueError: Target and input must have the same number of elements. target nelement (20) != input nelement (1)
it raise because of this line loss = lossf(output, labels)
in :
def training_loop(epochs, optim, clf, lossf, train_loader):
for epoch in range(1, epochs + 1):
loss_train = 0.0
for imgs, labels in train_loader:
imgs, labels = torch.autograd.Variable(imgs), torch.autograd.Variable(labels)
output = clf(imgs)
loss = lossf(output, labels)
....
when i print the shape of labels and output i get this
# labels
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 1., 0., 0., 0., 1., 1., 1., 0.,
1., 1.])
torch.Size([20])
# output
tensor([[0.0430]], grad_fn=<AddmmBackward>)
torch.Size([1, 1])
according to my knowledge, the output shape should be exactly like labels shape.
any one can help… thank you