PyTorch为什么前向函数会多次运行,我可以改变输入形状吗?

问题描述 投票:0回答:1
import torch 
import torch.nn as nn
import torchvision.datasets as dsets
from skimage import transform
import torchvision.transforms as transforms
from torch.autograd import Variable
import pandas as pd;
import numpy as np;
from torch.utils.data import Dataset, DataLoader
import statistics

import random
import math

class FashionMNISTDataset(Dataset):
  '''Fashion MNIST Dataset'''
  def __init__(self, csv_file, transform=None):
    """
    Args:
        csv_file (string): Path to the csv file
        transform (callable): Optional transform to apply to sample
    """

    data = pd.read_csv(csv_file)
    self.X = np.array(data.iloc[:, 1:]).reshape(-1, 1, 28, 28)
    self.Y = np.array(data.iloc[:, 0])

    del data
    self.transform = transform

  def __len__(self):
    return len(self.X)

  def __getitem__(self, idx):
    item = self.X[idx]
    label = self.Y[idx]

    if self.transform:
        item = self.transform(item)

    return (item, label)

class CNN(nn.Module):
  def __init__(self):
    super(CNN, self).__init__()
    self.layer1 = nn.Sequential(
      nn.Linear(616,300),
      nn.ReLU())
    self.layer2 = nn.Sequential(
      nn.Linear(300,100),
      nn.ReLU())
    self.fc = nn.Linear(100, 10)

  def forward(self, x):
    print("x shape",x.shape)
    out = self.layer1(x)
    out = self.layer2(out)
    out = self.fc(out)
    return out

def run():

  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  num_epochs = 15
  batch_size = 100
  learning_rate = 0.0001

  train_dataset = FashionMNISTDataset(csv_file='fashion-mnist_train.csv')
  test_dataset = FashionMNISTDataset(csv_file='fashion-mnist_test.csv')

  train_loader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)
  test_loader = torch.utils.data.DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=True)

  #instance of the Conv Net
  cnn = CNN()
  cnn.to(device)

  #loss function and optimizer
  criterion = nn.CrossEntropyLoss()
  optimizer = torch.optim.Adam(cnn.parameters(), lr=learning_rate)


  losses = []
  for epoch in range(num_epochs):
    l = 0
    for i, (images, labels) in enumerate(train_loader):

      images = Variable(images.float())
      labels = Variable(labels)
      #print(images[0])
      images = images.to(device)
      labels = labels.to(device)
      print("img shape=",images.shape, "label shape=",labels.shape)
      images = images.resize_((100,616))

      print("img shape=",images.shape, "label shape=",labels.shape)
      # Forward + Backward + Optimize
      optimizer.zero_grad()
      outputs = cnn(images)

      loss = criterion(outputs, labels)
      #print(loss)
      loss.backward()
      optimizer.step()
      #print(loss.item())
      losses.append(loss.item())
      l = loss.item()

      cnn.eval()
      with torch.no_grad():
        val_loss = []
        for images, labels in test_loader:
          images = Variable(images.float()).to(device)
          labels = labels.to(device)
          outputs = cnn.forward(images)
          batch_loss = criterion(outputs, labels)
          val_loss.append(batch_loss.item())
        avgloss = statistics.mean(val_loss)
        if avgloss < min(losses):
          torch.save(cnn.state_dict(), 'model')
        cnn.train()
      if (i+1) % 100 == 0:
        print ('Epoch : %d/%d, Iter : %d/%d,  Loss: %.4f' 
              %(epoch+1, num_epochs, i+1, len(train_dataset)//batch_size, loss.item()))
    print(l)


  final_model = CNN()
  final_model.load_state_dict(torch.load('model'))
  final_model.eval()
  correct = 0
  total = 0
  for images, labels in test_loader:
      images = Variable(images.float()).to(device)
      outputs = final_model(images).to(device)
      labels.to(device)
      _, predicted = torch.max(outputs.data, 1)
      total += labels.size(0)
      correct += (predicted == labels).sum()
  print('Test Accuracy of the model on the 10000 test images: %.4f %%' % (100 * correct / total))



if __name__ == '__main__':
  run()

为了测试目的,我附上了所有代码。但这是我得到的错误

img shape = torch.Size([100,1,28,28])label shape = torch.Size([100])img shape = torch.Size([100,616])label shape = torch.Size([100 ])x shape torch.Size([100,616])x shape torch.Size([100,1,28,28])Traceback(最近一次调用最后一次):文件“test.py”,第145行,在运行中()文件“test.py”,第115行,在运行输出= cnn.forward(images)文件“test.py”,第56行,在forward out = self.layer1(x)文件“/ usr / share / anaconda3 /envs/DL/lib/python3.6/site-packages/torch/nn/modules/module.py“,第489行,在调用结果= self.forward(* input,** kwargs)文件”/ usr / share /anaconda3/envs/DL/lib/python3.6/site-packages/torch/nn/modules/container.py“,第92行,正向输入=模块(输入)文件”/ usr / share / anaconda3 / envs / DL / lib / python3.6 / site-packages / torch / nn / modules / module.py“,第489行,调用结果= self.forward(* input,** kwargs)文件”/ usr / share / anaconda3 / envs / DL / lib / python3.6 / site-packages / torch / nn / modules / linear.py“,第67行,正向返回F.linear(输入,self.weight,self.bias)文件”/ usr /share/anaconda3/envs/DL/lib/python3.6/site-packages/torch/nn/functional.py“,第1354行,在线性输出中= input.matmul(weight.t())RuntimeError:size mismatch, m1:[2800 x 28],m2:[616 x 300] atopt/conda/conda-bld/pytorch_1549630534704/work/aten/src/THC/generic/THCTensorMathBlas.cu:266

这里的问题是我希望所有616像素作为输入馈入神经网络,但我不知道该怎么做。我尝试重塑输入以解决问题,但它运行了model.forward两次,一次是正确的形状,然后是错误的形状。

python python-3.x pytorch mnist
1个回答
2
投票

你在forward两次打电话给run

  1. 一次为训练数据
  2. 一次用于验证数据

但是,您似乎没有将以下转换应用于验证数据:

images = images.resize_((100,616))

也许考虑在forward函数中进行调整大小。

© www.soinside.com 2019 - 2024. All rights reserved.