问题描述
我正在研究带有数字的经典示例。我想创建第一个预测数字图像标签{0,1,2,3,4,5,6,7,8,9}的神经网络。因此train.txt
的第一列具有标签,其他所有列均为每个标签的特征。我定义了一个类来导入数据:
class DigitDataset(Dataset):
"""Digit dataset."""
def __init__(self,file_path,transform=None):
"""
Args:
csv_file (string): Path to the csv file with annotations.
root_dir (string): Directory with all the images.
transform (callable,optional): Optional transform to be applied
on a sample.
"""
self.data = pd.read_csv(file_path,header = None,sep =" ")
self.transform = transform
def __len__(self):
return len(self.data)
def __getitem__(self,idx):
if torch.is_tensor(idx):
idx = idx.tolist()
labels = self.data.iloc[idx,0]
images = self.data.iloc[idx,1:-1].values.astype(np.uint8).reshape((1,16,16))
if self.transform is not None:
sample = self.transform(sample)
return images,labels
然后,我运行以下命令将数据集分为若干批,以定义模型和损失:
train_dataset = DigitDataset("train.txt")
train_loader = DataLoader(train_dataset,batch_size=64,shuffle=True,num_workers=4)
# Model creation with neural net Sequential model
model=nn.Sequential(nn.Linear(256,128),# 1 layer:- 256 input 128 o/p
nn.ReLU(),# Defining Regular linear unit as activation
nn.Linear(128,64),# 2 Layer:- 128 Input and 64 O/p
nn.Tanh(),# Defining Regular linear unit as activation
nn.Linear(64,10),# 3 Layer:- 64 Input and 10 O/P as (0-9)
nn.Logsoftmax(dim=1) # Defining the log softmax to find the probablities
for the last output unit
)
# defining the negative log-likelihood loss for calculating loss
criterion = nn.NLLLoss()
images,labels = next(iter(train_loader))
images = images.view(images.shape[0],-1)
logps = model(images) #log probabilities
loss = criterion(logps,labels) #calculate the NLL-loss
我接受了错误:
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-2-7f4160c1f086> in <module>
47 images = images.view(images.shape[0],-1)
48
---> 49 logps = model(images) #log probabilities
50 loss = criterion(logps,labels) #calculate the NLL-loss
~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self,*input,**kwargs)
725 result = self._slow_forward(*input,**kwargs)
726 else:
--> 727 result = self.forward(*input,**kwargs)
728 for hook in itertools.chain(
729 _global_forward_hooks.values(),~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/container.py in forward(self,input)
115 def forward(self,input):
116 for module in self:
--> 117 input = module(input)
118 return input
119
~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self,~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/linear.py in forward(self,input)
91
92 def forward(self,input: Tensor) -> Tensor:
---> 93 return F.linear(input,self.weight,self.bias)
94
95 def extra_repr(self) -> str:
~/anaconda3/lib/python3.8/site-packages/torch/nn/functional.py in linear(input,weight,bias)
1688 if input.dim() == 2 and bias is not None:
1689 # fused op is marginally faster
-> 1690 ret = torch.addmm(bias,input,weight.t())
1691 else:
1692 output = input.matmul(weight.t())
RuntimeError: expected scalar type Float but found Byte
你知道出什么事了吗?感谢您的耐心配合和帮助!
解决方法
import torch
import torchvision
import matplotlib.pyplot as plt
from time import time
from torchvision import datasets,transforms
from torch import nn,optim
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,)),])
trainset = datasets.MNIST('data/train',download=True,train=True,transform=transform)
valset = datasets.MNIST('data/test',train=False,transform=transform)
trainloader = torch.utils.data.DataLoader(trainset,batch_size=64,shuffle=True)
valloader = torch.utils.data.DataLoader(valset,shuffle=True)
input_size = 784
hidden_sizes = [128,128,64]
output_size = 10
model = nn.Sequential(nn.Linear(input_size,hidden_sizes[0]),nn.ReLU(),nn.Linear(hidden_sizes[0],hidden_sizes[1]),nn.Linear(hidden_sizes[1],hidden_sizes[2]),nn.Linear(hidden_sizes[2],output_size),nn.LogSoftmax(dim=1))
# print(model)
criterion = nn.NLLLoss()
images,labels = next(iter(trainloader))
images = images.view(images.shape[0],-1)
logps = model(images) #log probabilities
loss = criterion(logps,labels) #calculate the NLL loss
optimizer = optim.SGD(model.parameters(),lr=0.003,momentum=0.9)
time0 = time()
epochs = 15
for e in range(epochs):
running_loss = 0
for images,labels in trainloader:
# Flatten MNIST images into a 784 long vector
images = images.view(images.shape[0],-1)
# Training pass
optimizer.zero_grad()
output = model(images)
loss = criterion(output,labels)
#This is where the model learns by backpropagating
loss.backward()
#And optimizes its weights here
optimizer.step()
running_loss += loss.item()
else:
print("Epoch {} - Training loss: {}".format(e,running_loss/len(trainloader)))
print("\nTraining Time (in minutes) =",(time()-time0)/60)
images,labels = next(iter(valloader))
img = images[0].view(1,784)
with torch.no_grad():
logps = model(img)
ps = torch.exp(logps)
probab = list(ps.numpy()[0])
print("Predicted Digit =",probab.index(max(probab)))
# view_classify(img.view(1,28,28),ps)
correct_count,all_count = 0,0
for images,labels in valloader:
for i in range(len(labels)):
img = images[i].view(1,784)
with torch.no_grad():
logps = model(img)
ps = torch.exp(logps)
probab = list(ps.numpy()[0])
pred_label = probab.index(max(probab))
true_label = labels.numpy()[i]
if(true_label == pred_label):
correct_count += 1
all_count += 1
print("Number Of Images Tested =",all_count)
print("\nModel Accuracy =",(correct_count/all_count))
torch.save(model,'./my_mnist_model.pt') ```
,
此行是导致您出错的原因:
images = self.data.iloc[idx,1:-1].values.astype(np.uint8).reshape((1,16,16))
images
是uint8
(byte
),而神经网络需要输入作为浮点来计算梯度(您不能使用整数计算反向传播的梯度,因为整数不是连续且不可微)。
您可以使用torchvision.transforms.functional.to_tensor
将图像转换为float
和[0,1]
,如下所示:
import torchvision
images = torchvision.transforms.functional.to_tensor(
self.data.iloc[idx,16))
)
或简单地除以255
即可将值存入[0,1]
。