我的代码是这样的,我做的一切发现错误,但它不工作
import cv2 import torch import torch.nn as nn import torchvision.transforms as transforms import torchvision import torchvision.datasets as datasets from torch.autograd import Variable import matplotlib.pyplot as plt from PIL import Image import numpy as np
#Transformation for image
transform_ori = transforms.Compose([transforms.RandomResizedCrop(64), #create 64x64 image
transforms.RandomHorizontalFlip(), #flipping the image horizontally
transforms.ToTensor(), #convert the image to a Tensor
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])]) #normalize the image
#Load our dataset
train_dataset = datasets.ImageFolder(root = '/content//Data',
transform = transform_ori)
test_dataset = datasets.ImageFolder(root = '/content/Data',
transform = transform_ori)
#Make the dataset iterable
batch_size = 100
train_load = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size,
shuffle = True)
batch_size = 100
train_load = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size,
shuffle = True) #Shuffle to create a mixed batches of 100 of cat & dog images
test_load = torch.utils.data.DataLoader(dataset = test_dataset,
batch_size = batch_size,
shuffle = False)
#Show a batch of images
def imshow(img):
img = img / 2 + 0.5 # unnormalize
npimg = img.numpy()
plt.figure(figsize=(20,20))
plt.imshow(np.transpose(npimg, (1, 2, 0)))
# get some random training images
dataiter = iter(train_load)
images, labels = dataiter.next()
# show images
imshow(torchvision.utils.make_grid(images))
print("There are {} images in train set".format(len(train_dataset)))
print("There are {} images in train loader".format(len(train_load)))
print("There are {} images in test set".format(len(test_dataset)))
print("There are {} images in test loader".format(len(test_load)))
class CNN(nn.Module):
def __init__(self):
super(CNN,self).__init__()
self.cnn1 = nn.Conv2d(in_channels=3, out_channels=8, kernel_size=3,stride=1, padding=1)
self.batchnorm1 = nn.BatchNorm2d(8) #Batch normalization
self.relu = nn.ReLU() #RELU Activation
self.maxpool1 = nn.MaxPool2d(kernel_size=2) #Maxpooling reduces the size by kernel size. 64/2 = 32
self.cnn2 = nn.Conv2d(in_channels=8, out_channels=32, kernel_size=5, stride=1, padding=2)
self.batchnorm2 = nn.BatchNorm2d(32)
self.maxpool2 = nn.MaxPool2d(kernel_size=2) #Size now is 32/2 = 16
#Flatten the feature maps. You have 32 feature mapsfrom cnn2. Each of the feature is of size 16x16 --> 32*16*16 = 8192
self.fc1 = nn.Linear(in_features=8192, out_features=4000) #Flattened image is fed into linear NN and reduced to half size
self.droput = nn.Dropout(p=0.5) #Dropout used to reduce overfitting
self.fc2 = nn.Linear(in_features=4000, out_features=2000)
self.droput = nn.Dropout(p=0.5)
self.fc3 = nn.Linear(in_features=2000, out_features=500)
self.droput = nn.Dropout(p=0.5)
self.fc4 = nn.Linear(in_features=500, out_features=50)
self.droput = nn.Dropout(p=0.5)
self.fc5 = nn.Linear(in_features=50, out_features=2) #Since there were so many features, I decided to use 45 layers to get output layers. You can increase the kernels in Maxpooling to reduce image further and reduce number of hidden linear layers.
def forward(self,x):
out = self.cnn1(x)
out = self.batchnorm1(out)
out = self.relu(out)
out = self.maxpool1(out)
out = self.cnn2(out)
out = self.batchnorm2(out)
out = self.relu(out)
out = self.maxpool2(out)
#Flattening is done here with .view() -> (batch_size, 32*16*16) = (100, 8192)
out = out.view(-1,8192) #-1 will automatically update the batchsize as 100; 8192 flattens 32,16,16
#Then we forward through our fully connected layer
out = self.fc1(out)
out = self.relu(out)
out = self.droput(out)
out = self.fc2(out)
out = self.relu(out)
out = self.droput(out)
out = self.fc3(out)
out = self.relu(out)
out = self.droput(out)
out = self.fc4(out)
out = self.relu(out)
out = self.droput(out)
out = self.fc5(out)
return out
model = CNN()
CUDA = torch.cuda.is_available()
if CUDA:
model = model.cuda()
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)
import time
num_epochs = 50
#Define the lists to store the results of loss and accuracy
train_loss = []
test_loss = []
train_accuracy = []
test_accuracy = []
#Training
for epoch in range(num_epochs):
#Reset these below variables to 0 at the begining of every epoch
start = time.time()
correct = 0
iterations = 0
iter_loss = 0.0
model.train() # Put the network into training mode
for i, (inputs, labels) in enumerate(train_load):
# Convert torch tensor to Variable
Inputs = Variable(inputs)
Labels = Variable(labels)
# If we have GPU, shift the data to GPU
CUDA = torch.cuda.is_available()
if CUDA:
print("Cuda is Available!")
Inputs = Inputs.cuda()
Labels = Labels.cuda()
optimizer.zero_grad()
outputs = model(inputs)
loss = loss_fn(outputs, labels)
iter_loss += loss.data[0] # Accumulate the loss
loss.backward() # Backpropagation
optimizer.step() # Update the weights
# Record the correct predictions for training data
_, predicted = torch.max(outputs, 1)
correct += (predicted == labels).sum()
iterations += 1
# Record the training loss
train_loss.append(iter_loss/iterations)
# Record the training accuracy
train_accuracy.append((100 * correct / len(train_dataset)))
#Testing
loss = 0.0
correct = 0
iterations = 0
model.eval() # Put the network into evaluation mode
for i, (inputs, labels) in enumerate(test_load):
# Convert torch tensor to Variable
inputs = Variable(inputs)
labels = Variable(labels)
CUDA = torch.cuda.is_available()
if CUDA:
inputs = inputs.cuda()
labels = labels.cuda()
outputs = model(inputs)
loss = loss_fn(outputs, labels) # Calculate the loss
loss += loss.data[0]
# Record the correct predictions for training data
_, predicted = torch.max(outputs, 1)
correct += (predicted == labels).sum()
iterations += 1
# Record the Testing loss
test_loss.append(loss/iterations)
# Record the Testing accuracy
test_accuracy.append((100 * correct / len(test_dataset)))
stop = time.time()
print ('Epoch {}/{}, Training Loss: {:.3f}, Training Accuracy: {:.3f}, Testing Loss: {:.3f}, Testing Acc: {:.3f}, Time: {}s'
.format(epoch+1, num_epochs, train_loss[-1], train_accuracy[-1], test_loss[-1], test_accuracy[-1], stop-start))
# Loss
f = plt.figure(figsize=(10, 10))
plt.plot(train_loss, label='Training Loss')
plt.plot(test_loss, label='Testing Loss')
plt.legend()
plt.show()
# Accuracy
f = plt.figure(figsize=(10, 10))
plt.plot(train_accuracy, label='Training Accuracy')
plt.plot(test_accuracy, label='Testing Accuracy')
plt.legend()
plt.show()
#Run this if you want to save the model
torch.save(model.state_dict(),'Cats-Dogs.pth')
#Run this if you want to load the model
model.load_state_dict(torch.load('Cats-Dogs.pth'))
def predict(img_name,model):
image = cv2.imread(img_name) #Read the image
img = Image.fromarray(image) #Convert the image to an array
img = transforms_photo(img) #Apply the transformations
img = img.view(1,3,64,64) #Add batch size
img = Variable(img)
#Wrap the tensor to a variable
model.eval()
if torch.cuda.is_available():
model = model.cuda()
img = img.cuda()
output = model(img)
print(output)
print(output.data)
_, predicted = torch.max(output,1)
if predicted.item()==0:
p = 'Cat'
else:
p = 'Dog'
cv2.imshow('Original',image)
return p
pred = predict('dataset/single_prediction/cat_or_dog_1.jpg', model)
print("The Predicted Label is {}".format(pred))
#Load the DenseNet
model_conv = torchvision.models.densenet201(pretrained=True)
#Freeze all layers in the network
for param in model_conv.parameters():
param.requires_grad = False
#Get the number of inputs of the last layer (or number of neurons in the layer preceeding the last layer)
num_ftrs = model_conv.classifier.in_features
#Reconstruct the last layer (output layer) to have only two classes
model_conv.classifier = nn.Linear(num_ftrs, 2)
#Initiate the model on GPU
if torch.cuda.is_available():
model_conv = model_conv.cuda()
#Loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model_conv.parameters(), lr=0.001, momentum=0.9) #Try Adam optimizer for better accuracy: optim.Adam(model_conv.parameters(), lr=0.001)
#Decay LR by a factor of 0.1 every 7 epochs
exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)
train_loss = []
test_loss = []
train_accuracy = []
test_accuracy = []
#Training
import time
num_epochs = 20
for epoch in range (num_epochs):
start = time.time()
exp_lr_scheduler.step()
#Reset the correct to 0 after passing through all the dataset
correct = 0
for images,labels in dataloaders['training_set']:
images = Variable(images)
labels = Variable(labels)
if torch.cuda.is_available():
images = images.cuda()
labels = labels.cuda()
optimizer.zero_grad()
outputs = model_conv(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
_, predicted = torch.max(outputs, 1)
correct += (predicted == labels).sum()
train_acc = 100 * correct / dataset_sizes['training_set']
stop = time.time()
print ('Epoch [{}/{}], Loss: {:.4f}, Train Accuracy: {}%, Time: {:.2f}s'
.format(epoch+1, num_epochs, loss.item(), train_acc, stop-start))
#Testing
model_conv.eval()
with torch.no_grad():
correct = 0
total = 0
start = time.time()
for (images, labels) in dataloaders['test_set']:
images = Variable(images)
labels = Variable(labels)
if torch.cuda.is_available():
images = images.cuda()
labels = labels.cuda()
outputs = model_conv(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
stop = time.time()
print('Test Accuracy: {:.3f} %, Time: {:.2f}s'.format(100 * correct / total,stop-start))
#Import your trial images and check against the model
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
#Predict your own image
def predict(img_name,model):
image = cv2.imread(img_name) #Read the image
#ret, thresholded = cv2.threshold(image,127,255,cv2.THRESH_BINARY) #Threshold the image
img = Image.fromarray(image) #Convert the image to an array
img = transforms_photo(img) #Apply the transformations
img = img.view(1,3,224,224) #Add batch size
img = Variable(img)
#Wrap the tensor to a variable
model.eval()
if torch.cuda.is_available():
model = model.cuda()
img = img.cuda()
output = model(img)
print(output)
print(output.data)
_, predicted = torch.max(output,1)
if predicted.item()==0:
p = 'Cat'
else:
p = 'Dog'
cv2.imshow('Original',image)
return p
This question already has answers here:
PyTorch NotImplementedError in forward (2 answers)
Your post has been associated with a similar question. If this question doesn’t resolve your question, ask a new one.
Closed 3 days ago.
(Private feedback for you)
here is my code :
import cv2
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
import torchvision.datasets as datasets
from torch.autograd import Variable
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
#Transformation for image
transform_ori = transforms.Compose([transforms.RandomResizedCrop(64), #create 64x64 image
transforms.RandomHorizontalFlip(), #flipping the image horizontally
transforms.ToTensor(), #convert the image to a Tensor
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])]) #normalize the image
#Load our dataset
train_dataset = datasets.ImageFolder(root = '/content//Data',
transform = transform_ori)
test_dataset = datasets.ImageFolder(root = '/content/Data',
transform = transform_ori)
#Make the dataset iterable
batch_size = 100
train_load = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size,
shuffle = True)
batch_size = 100
train_load = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size,
shuffle = True) #Shuffle to create a mixed batches of 100 of cat & dog images
test_load = torch.utils.data.DataLoader(dataset = test_dataset,
batch_size = batch_size,
shuffle = False)
#Show a batch of images
def imshow(img):
img = img / 2 + 0.5 # unnormalize
npimg = img.numpy()
plt.figure(figsize=(20,20))
plt.imshow(np.transpose(npimg, (1, 2, 0)))
# get some random training images
dataiter = iter(train_load)
images, labels = dataiter.next()
# show images
imshow(torchvision.utils.make_grid(images))
print("There are {} images in train set".format(len(train_dataset)))
print("There are {} images in train loader".format(len(train_load)))
print("There are {} images in test set".format(len(test_dataset)))
print("There are {} images in test loader".format(len(test_load)))
class CNN(nn.Module):
def __init__(self):
super(CNN,self).__init__()
self.cnn1 = nn.Conv2d(in_channels=3, out_channels=8, kernel_size=3,stride=1, padding=1)
self.batchnorm1 = nn.BatchNorm2d(8) #Batch normalization
self.relu = nn.ReLU() #RELU Activation
self.maxpool1 = nn.MaxPool2d(kernel_size=2) #Maxpooling reduces the size by kernel size. 64/2 = 32
self.cnn2 = nn.Conv2d(in_channels=8, out_channels=32, kernel_size=5, stride=1, padding=2)
self.batchnorm2 = nn.BatchNorm2d(32)
self.maxpool2 = nn.MaxPool2d(kernel_size=2) #Size now is 32/2 = 16
#Flatten the feature maps. You have 32 feature mapsfrom cnn2. Each of the feature is of size 16x16 --> 32*16*16 = 8192
self.fc1 = nn.Linear(in_features=8192, out_features=4000) #Flattened image is fed into linear NN and reduced to half size
self.droput = nn.Dropout(p=0.5) #Dropout used to reduce overfitting
self.fc2 = nn.Linear(in_features=4000, out_features=2000)
self.droput = nn.Dropout(p=0.5)
self.fc3 = nn.Linear(in_features=2000, out_features=500)
self.droput = nn.Dropout(p=0.5)
self.fc4 = nn.Linear(in_features=500, out_features=50)
self.droput = nn.Dropout(p=0.5)
self.fc5 = nn.Linear(in_features=50, out_features=2) #Since there were so many features, I decided to use 45 layers to get output layers. You can increase the kernels in Maxpooling to reduce image further and reduce number of hidden linear layers.
def forward(self,x):
out = self.cnn1(x)
out = self.batchnorm1(out)
out = self.relu(out)
out = self.maxpool1(out)
out = self.cnn2(out)
out = self.batchnorm2(out)
out = self.relu(out)
out = self.maxpool2(out)
#Flattening is done here with .view() -> (batch_size, 32*16*16) = (100, 8192)
out = out.view(-1,8192) #-1 will automatically update the batchsize as 100; 8192 flattens 32,16,16
#Then we forward through our fully connected layer
out = self.fc1(out)
out = self.relu(out)
out = self.droput(out)
out = self.fc2(out)
out = self.relu(out)
out = self.droput(out)
out = self.fc3(out)
out = self.relu(out)
out = self.droput(out)
out = self.fc4(out)
out = self.relu(out)
out = self.droput(out)
out = self.fc5(out)
return out
model = CNN()
CUDA = torch.cuda.is_available()
if CUDA:
model = model.cuda()
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)
import time
num_epochs = 50
#Define the lists to store the results of loss and accuracy
train_loss = []
test_loss = []
train_accuracy = []
test_accuracy = []
#Training
for epoch in range(num_epochs):
#Reset these below variables to 0 at the begining of every epoch
start = time.time()
correct = 0
iterations = 0
iter_loss = 0.0
model.train() # Put the network into training mode
for i, (inputs, labels) in enumerate(train_load):
# Convert torch tensor to Variable
Inputs = Variable(inputs)
Labels = Variable(labels)
# If we have GPU, shift the data to GPU
CUDA = torch.cuda.is_available()
if CUDA:
print("Cuda is Available!")
Inputs = Inputs.cuda()
Labels = Labels.cuda()
optimizer.zero_grad()
outputs = model(inputs)
loss = loss_fn(outputs, labels)
iter_loss += loss.data[0] # Accumulate the loss
loss.backward() # Backpropagation
optimizer.step() # Update the weights
# Record the correct predictions for training data
_, predicted = torch.max(outputs, 1)
correct += (predicted == labels).sum()
iterations += 1
# Record the training loss
train_loss.append(iter_loss/iterations)
# Record the training accuracy
train_accuracy.append((100 * correct / len(train_dataset)))
#Testing
loss = 0.0
correct = 0
iterations = 0
model.eval() # Put the network into evaluation mode
for i, (inputs, labels) in enumerate(test_load):
# Convert torch tensor to Variable
inputs = Variable(inputs)
labels = Variable(labels)
CUDA = torch.cuda.is_available()
if CUDA:
inputs = inputs.cuda()
labels = labels.cuda()
outputs = model(inputs)
loss = loss_fn(outputs, labels) # Calculate the loss
loss += loss.data[0]
# Record the correct predictions for training data
_, predicted = torch.max(outputs, 1)
correct += (predicted == labels).sum()
iterations += 1
# Record the Testing loss
test_loss.append(loss/iterations)
# Record the Testing accuracy
test_accuracy.append((100 * correct / len(test_dataset)))
stop = time.time()
print ('Epoch {}/{}, Training Loss: {:.3f}, Training Accuracy: {:.3f}, Testing Loss: {:.3f}, Testing Acc: {:.3f}, Time: {}s'
.format(epoch+1, num_epochs, train_loss[-1], train_accuracy[-1], test_loss[-1], test_accuracy[-1], stop-start))
# Loss
f = plt.figure(figsize=(10, 10))
plt.plot(train_loss, label='Training Loss')
plt.plot(test_loss, label='Testing Loss')
plt.legend()
plt.show()
# Accuracy
f = plt.figure(figsize=(10, 10))
plt.plot(train_accuracy, label='Training Accuracy')
plt.plot(test_accuracy, label='Testing Accuracy')
plt.legend()
plt.show()
#Run this if you want to save the model
torch.save(model.state_dict(),'Cats-Dogs.pth')
#Run this if you want to load the model
model.load_state_dict(torch.load('Cats-Dogs.pth'))
def predict(img_name,model):
image = cv2.imread(img_name) #Read the image
img = Image.fromarray(image) #Convert the image to an array
img = transforms_photo(img) #Apply the transformations
img = img.view(1,3,64,64) #Add batch size
img = Variable(img)
#Wrap the tensor to a variable
model.eval()
if torch.cuda.is_available():
model = model.cuda()
img = img.cuda()
output = model(img)
print(output)
print(output.data)
_, predicted = torch.max(output,1)
if predicted.item()==0:
p = 'Cat'
else:
p = 'Dog'
cv2.imshow('Original',image)
return p
pred = predict('dataset/single_prediction/cat_or_dog_1.jpg', model)
print("The Predicted Label is {}".format(pred))
#Load the DenseNet
model_conv = torchvision.models.densenet201(pretrained=True)
#Freeze all layers in the network
for param in model_conv.parameters():
param.requires_grad = False
#Get the number of inputs of the last layer (or number of neurons in the layer preceeding the last layer)
num_ftrs = model_conv.classifier.in_features
#Reconstruct the last layer (output layer) to have only two classes
model_conv.classifier = nn.Linear(num_ftrs, 2)
#Initiate the model on GPU
if torch.cuda.is_available():
model_conv = model_conv.cuda()
#Loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model_conv.parameters(), lr=0.001, momentum=0.9) #Try Adam optimizer for better accuracy: optim.Adam(model_conv.parameters(), lr=0.001)
#Decay LR by a factor of 0.1 every 7 epochs
exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)
train_loss = []
test_loss = []
train_accuracy = []
test_accuracy = []
#Training
import time
num_epochs = 20
for epoch in range (num_epochs):
start = time.time()
exp_lr_scheduler.step()
#Reset the correct to 0 after passing through all the dataset
correct = 0
for images,labels in dataloaders['training_set']:
images = Variable(images)
labels = Variable(labels)
if torch.cuda.is_available():
images = images.cuda()
labels = labels.cuda()
optimizer.zero_grad()
outputs = model_conv(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
_, predicted = torch.max(outputs, 1)
correct += (predicted == labels).sum()
train_acc = 100 * correct / dataset_sizes['training_set']
stop = time.time()
print ('Epoch [{}/{}], Loss: {:.4f}, Train Accuracy: {}%, Time: {:.2f}s'
.format(epoch+1, num_epochs, loss.item(), train_acc, stop-start))
#Testing
model_conv.eval()
with torch.no_grad():
correct = 0
total = 0
start = time.time()
for (images, labels) in dataloaders['test_set']:
images = Variable(images)
labels = Variable(labels)
if torch.cuda.is_available():
images = images.cuda()
labels = labels.cuda()
outputs = model_conv(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
stop = time.time()
print('Test Accuracy: {:.3f} %, Time: {:.2f}s'.format(100 * correct / total,stop-start))
#Import your trial images and check against the model
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
#Predict your own image
def predict(img_name,model):
image = cv2.imread(img_name) #Read the image
#ret, thresholded = cv2.threshold(image,127,255,cv2.THRESH_BINARY) #Threshold the image
img = Image.fromarray(image) #Convert the image to an array
img = transforms_photo(img) #Apply the transformations
img = img.view(1,3,224,224) #Add batch size
img = Variable(img)
#Wrap the tensor to a variable
model.eval()
if torch.cuda.is_available():
model = model.cuda()
img = img.cuda()
output = model(img)
print(output)
print(output.data)
_, predicted = torch.max(output,1)
if predicted.item()==0:
p = 'Cat'
else:
p = 'Dog'
cv2.imshow('Original',image)
return p
我得到了这个:
我测试了我的代码的一部分,但似乎一切正常,有人可以帮助?
/usr/local/lib/python3.6/dist-packages/torch/nn/functional.py in nll_loss(input, target, weight, size_average, ignore_index, reduce, reduction)
2262 .format(input.size(0), target.size(0)))
2263 if dim == 2:
-> 2264 ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
2265 elif dim == 4:
2266 ret = torch._C._nn.nll_loss2d(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
IndexError: Target 3 is out of bounds.
我在搜索网页时什么也没找到。而且我在堆栈中也什么也没找到,我读了它的文档,什么也没找到
2条答案
按热度按时间s2j5cfk01#
你正在使用分类损失(交叉熵)。然而,虽然模型只预测两个可能的类中的一个(
fc5
的输出维度是2),但看起来数据似乎有更多的类。确保网络的输出维度与数据中的类数相匹配。
顺便说一句,your
forward
method is not indented properly。goqiplq22#
我也有类似的问题。我没有0索引我的类。所以是1,2,3而不是0,1,2