Ошибка PyTorch Размер тензора a (128) должен соответствовать размеру тензора b (9) при не синглетонном измерении 0 - PullRequest
0 голосов
/ 11 апреля 2019

Я использую модель HAR CNN с использованием PyTorch 1.01 в Anaconda с графическим процессором Делая итерацию, она дает мне ошибку Размер тензора a (128) должен соответствовать размеру тензора b (9) при не синглетонном измерении 0. Я полагаю, что это модель данных при перечислении train_model, выдающем ошибку. Кто-нибудь сталкивался с подобными проблемами в PyTorch? Нужна небольшая поддержка, как новичок в PyTorch.

Я перепробовал все трюки с датамоделами, найденные в Google.

'' '

    def train(model, optimizer, train_loader, test_loader):
    n_batch = len(train_loader.dataset) // BATCH_SIZE    
    criterion = nn.CrossEntropyLoss()

     for e in range(N_EPOCH):
       model.train()
       correct, total_loss = 0, 0
        total = 0
         for index, (sample, target) in enumerate(train_loader):
        sample, target = sample.to(DEVICE).float(), target.to(DEVICE).long()            
        sample = sample.view(-1, 9, 1, 128)
        output = model(sample)
        loss = criterion(output, target)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
        _, predicted = torch.max(output.data, 1)
        total += target.size(0)
        correct += (predicted == target).sum()

        if index % 20 == 0:
            tqdm.tqdm.write('Epoch: [{}/{}], Batch: [{}/{}], loss:{:.4f}'.format(e + 1, N_EPOCH, index + 1, n_batch,
                                                                                 loss.item()))
    acc_train = float(correct) * 100.0 / (BATCH_SIZE * n_batch)
    tqdm.tqdm.write(
        'Epoch: [{}/{}], loss: {:.4f}, train acc: {:.2f}%'.format(e + 1, N_EPOCH, total_loss * 1.0 / n_batch,
                                                                  acc_train))

    # Testing
    model.train(False)
    with torch.no_grad():
        correct, total = 0, 0
        for sample, target in test_loader:
            sample, target = sample.to(DEVICE).float(), target.to(DEVICE).long()
            sample = sample.view(-1, 9, 1, 128)
            output = model(sample)
            _, predicted = torch.max(output.data, 1)
            total += target.size(0)
            correct += (predicted == target).sum()
    acc_test = float(correct) * 100 / total
    tqdm.tqdm.write('Epoch: [{}/{}], test acc: {:.2f}%'.format(e + 1, N_EPOCH, float(correct) * 100 / total))
    result.append([acc_train, acc_test])
    result_np = np.array(result, dtype=float)
    np.savetxt('result.csv', result_np, fmt='%.2f', delimiter=',')   

 Error ----------------------------
 (7352, 1152)
 (7352, 128, 9)
 (2947, 1152)
  (2947, 128, 9)
   ----------------------------------------------------------------- 
    ----------
 RuntimeError                              Traceback (most recent 
call last)
 <ipython-input-1-64c1adae4ee0> in <module>
 86     model = net.Network().to(DEVICE)
 87     optimizer = optim.SGD(params=model.parameters(), 
 lr=LEARNING_RATE, momentum=0.9)
---> 88     train(model, optimizer, train_loader, test_loader)
 89     result = np.array(result, dtype=float)
 90     np.savetxt('result.csv', result, fmt='%.2f', delimiter=',')

 <ipython-input-1-64c1adae4ee0> in train(model, optimizer, 
 train_loader, test_loader)
 29         correct, total_loss = 0, 0
 30         total = 0
 ---> 31         for index, (sample, target) in 
 enumerate(train_loader):
 32             sample, target = sample.to(DEVICE).float(), 
 target.to(DEVICE).long()
 33             print('Sample',sample)

 ~/anaconda3/envs/rnn_lstm_har_pytorch/lib/python3.6/site- 
 packages/torch/utils/data/dataloader.py in __next__(self)
613         if self.num_workers == 0:  # same-process loading
614             indices = next(self.sample_iter)  # may raise 
StopIteration
--> 615             batch = self.collate_fn([self.dataset[i] for i 
in indices])
616             if self.pin_memory:
617                 batch = pin_memory_batch(batch)

  ~/anaconda3/envs/rnn_lstm_har_pytorch/lib/python3.6/site- 
 packages/torch/utils/data/dataloader.py in <listcomp>(.0)
  613         if self.num_workers == 0:  # same-process loading
  614             indices = next(self.sample_iter)  # may raise 
 StopIteration
 --> 615             batch = self.collate_fn([self.dataset[i] for i 
 in 
  indices])
  616             if self.pin_memory:
  617                 batch = pin_memory_batch(batch)

 ~/anaconda3/envs/rnn_lstm_har_pytorch/data_preprocess.py in 
 __getitem__(self, index)
  97     def __getitem__(self, index):
  98         sample, target = self.samples[index], 
  self.labels[index]
  ---> 99         return self.T(sample), target
  100 
  101     def __len__(self):

 ~/anaconda3/envs/rnn_lstm_har_pytorch/lib/python3.6/site- 
   packages/torchvision/transforms/transforms.py in __call__(self, 
   img)
   58     def __call__(self, img):
   59         for t in self.transforms:
   ---> 60             img = t(img)
   61         return img
   62 

   ~/anaconda3/envs/rnn_lstm_har_pytorch/lib/python3.6/site- 
   packages/torchvision/transforms/transforms.py in __call__(self, 
  tensor)
   161             Tensor: Normalized Tensor image.
   162         """
  --> 163         return F.normalize(tensor, self.mean, self.std, 
  self.inplace)
   164 
   165     def __repr__(self):

  ~/anaconda3/envs/rnn_lstm_har_pytorch/lib/python3.6/site- 
  packages/torchvision/transforms/functional.py in normalize(tensor, 
  mean, std, inplace)
  206     mean = torch.tensor(mean, dtype=torch.float32)
  207     std = torch.tensor(std, dtype=torch.float32)
 --> 208     tensor.sub_(mean[:, None, None]).div_(std[:, None, 
  None])
  209     return tensor
  210 

RuntimeError: The size of tensor a (128) must match the size of 
tensor b (9) at non-singleton dimension 0

   # This is for parsing the X data, you can ignore it if you do not 
   need preprocessing
   def format_data_x(datafile):
    x_data = None
    for item in datafile:
    item_data = np.loadtxt(item, dtype=np.float)
    if x_data is None:
        x_data = np.zeros((len(item_data), 1))
    x_data = np.hstack((x_data, item_data))
    x_data = x_data[:, 1:]
    print(x_data.shape)
    X = None
    for i in range(len(x_data)):
    row = np.asarray(x_data[i, :])
    row = row.reshape(9, 128).T
    if X is None:
        X = np.zeros((len(x_data), 128, 9))
    X[i] = row
    print(X.shape)
    return X


    # This is for parsing the Y data, you can ignore it if you do not 
    need preprocessing
    def format_data_y(datafile):
    data = np.loadtxt(datafile, dtype=np.int) - 1
    YY = np.eye(6)[data]
    return YY


    # Load data function, if there exists parsed data file, then use 
    it
    # If not, parse the original dataset from scratch
   def load_data():
   import os

    # This for processing the dataset from scratch
    # After downloading the dataset, program put it in the DATA_PATH 
   folder

    #str_folder = 'data/' + 'UCI HAR Dataset/'
    DATA_PATH = 'data/'
    DATASET_PATH = DATA_PATH + 'UCI HAR Dataset/'
    TRAIN = 'train/'
    TEST = 'test/'

    INPUT_SIGNAL_TYPES = [
        "body_acc_x_",
        "body_acc_y_",
        "body_acc_z_",
        "body_gyro_x_",
        "body_gyro_y_",
        "body_gyro_z_",
        "total_acc_x_",
        "total_acc_y_",
        "total_acc_z_"
    ]

    str_train_files = [DATASET_PATH + TRAIN + 'Inertial Signals/' + 
    item + 'train.txt' for item in
                       INPUT_SIGNAL_TYPES]
    str_test_files = [DATASET_PATH + TEST + 'Inertial Signals/' + item 
    + 'test.txt' for item in INPUT_SIGNAL_TYPES]
    str_train_y = DATASET_PATH + TRAIN + 'y_train.txt'
    str_test_y = DATASET_PATH + TEST + 'y_test.txt'

    X_train = format_data_x(str_train_files)
    X_test = format_data_x(str_test_files)
    Y_train = format_data_y(str_train_y)
    Y_test = format_data_y(str_test_y)

   return X_train, onehot_to_label(Y_train), X_test, 
   onehot_to_label(Y_test)


  def onehot_to_label(y_onehot):
  a = np.argwhere(y_onehot == 1)
  return a[:, -1]

    class data_loader(Dataset):
    def __init__(self, samples, labels, t):
    self.samples = samples
    self.labels = labels
    self.T = t

    def __getitem__(self, index):
    sample, target = self.samples[index], self.labels[index]
    return self.T(sample), target

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


   def load(batch_size=64):
   x_train, y_train, x_test, y_test = load_data()
   x_train, x_test = x_train.reshape((-1, 9, 1, 128)), 
   x_test.reshape((-1, 9, 1, 128))
   transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=(0,0,0,0,0,0,0,0,0), std= 
    (1,1,1,1,1,1,1,1,1))
    ])
  train_set = data_loader(x_train, y_train, transform)
  test_set = data_loader(x_test, y_test, transform)    
  train_loader = DataLoader(train_set, batch_size=batch_size, 
  shuffle=True, drop_last=True)
  test_loader = DataLoader(test_set, batch_size=batch_size, 
  shuffle=False)
  return train_loader, test_loader

'' '

1 Ответ

0 голосов
/ 12 апреля 2019

Размер mean в преобразовании normalize должен иметь тот же размер, что и количество каналов в sample. Например, если образец N x 9 x 5 x 7 mean будет размером 9. В этом случае ваш образец имеет 128 каналов, но среднее значение имеет размер 9.

Похоже, вы пытаетесь изменить форму образца, используя sample.view(-1, 9, 1, 128), но это происходит после ошибки при загрузке данных.

Вам необходимо изменить тензор до преобразования normalize. Например,

def reshape_tensor(x):
    return x.reshape(9, 1, 128)

train_dataset = datasets.ImageFolder(
    traindir,
    transforms.Compose([
        ...,
        reshape_tensor,
        normalize,
    ]))
...