RuntimeError: Форма маски [1682] с индексом 0 не соответствует форме индексированного тензора [1, 1682] с индексом 0 - PullRequest
0 голосов
/ 12 января 2019

Я разрабатываю автокодер в стеке, пытаясь настроить мою нейронную сеть по рейтингу фильма, если пользователь не оценил какой-либо фильм, который он не будет считать

Мой тренировочный набор работает отлично, но когда я запускаю тестовый набор, он показывает мне эту ошибку

RuntimeError: Форма маски [1682] с индексом 0 не соответствует форме индексированного тензора [1, 1682] с индексом 0 Я получил ошибку в конце тестового блока, который я там прокомментировал

КОД: -


# Auto Encoder


import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.nn as nn
import torch.nn.parallel
import torch.optim as optim
import torch.utils.data
from torch.autograd import Variable



# Importing dataset
movies= pd.read_csv('ml-1m/movies.dat',sep ='::', header= None,engine ='python', encoding= 'latin-1')
users= pd.read_csv('ml-1m/users.dat',sep ='::', header= None,engine ='python', encoding= 'latin-1')
ratings = pd.read_csv('ml-1m/ratings.dat',sep ='::', header= None,engine ='python', encoding= 'latin-1')

# preparing the training set and the dataset

training_set =pd.read_csv('ml-100k/u1.base',delimiter ='\t')
training_set =np.array(training_set, dtype= 'int')

test_set =pd.read_csv('ml-100k/u1.test',delimiter ='\t')
test_set =np.array(test_set, dtype= 'int')


# Getting the number of users and  movies
# we are taking the maximum no of values from training set and test set 

nb_users = int(max(max(training_set[:,0]), max(test_set[:,0])))
nb_movies = int(max(max(training_set[:,1]), max(test_set[:,1])))

# converting the data into an array within users in lines and movies in columns

def convert(data):
    new_data = []
    for id_users in range(1, nb_users +1):
        id_movies = data[:,1][data[:,0]==id_users]#movies id from data
        id_ratings = data[:,2][data[:,0]==id_users] #ratings
        ratings= np.zeros(nb_movies)
        ratings[id_movies-1] = id_ratings  # -1 for making it start from 1
        new_data.append(list(ratings))
    return new_data



training_set =convert(training_set)
test_set =convert(test_set)

# Converting the data into Torch tensor
training_set = torch.FloatTensor(training_set)
test_set = torch.FloatTensor(test_set)



# creating the architecture of the neural network
class SAE(nn.Module):

    def  __init__(self, ): # after comma it will consider parameters of module ie parent class
        super(SAE,self).__init__()#parent class inheritence
        self.fc1 = nn.Linear(nb_movies, 20)  #20 nodes in hidden layer
        self.fc2= nn.Linear(20,10)
        self.fc3 = nn.Linear(10,20)  #decoding 
        self.fc4= nn.Linear(20, nb_movies) #decoding
        self.activation= nn.Sigmoid()
            #self.myparameters= nn.ParameterList(self.fc1,self.fc2,self.fc3,self.fc4,self.activation)

    def forward(self, x): 
        x=self.activation(self.fc1(x))#encoding
        x=self.activation(self.fc2(x))#encoding
        x=self.activation(self.fc3(x)) #decoding
        x=self.fc4(x) #last layer machine understand automaically
        return x

sae= SAE()
criterion = nn.MSELoss()

optimizer= optim.RMSprop(sae.parameters(), lr= 0.01 , weight_decay =0.5)

# Training the SAE
nb_epoch = 200
for epoch in range(1, nb_epoch + 1):
    train_loss = 0
    s = 0.
    for id_user in range(nb_users):
        input = Variable(training_set[id_user]).unsqueeze(0)
        target = input.clone()
        if torch.sum(target.data > 0) > 0:
            output = sae(input)
            target.require_grad = False
            output[target == 0] = 0     
            loss = criterion(output, target)
            mean_corrector = nb_movies/float(torch.sum(target.data > 0) + 1e-10)
            loss.backward()
            train_loss += np.sqrt(loss.data.item()*mean_corrector)
            s += 1.
            optimizer.step()
    print('epoch: '+str(epoch)+' loss: '+str(train_loss/s))


# Testing the SAE
test_loss = 0
s = 0.
for id_user in range(nb_users):
    input = Variable(training_set[id_user]).unsqueeze(0)
    target = Variable(test_set[id_user])
    if torch.sum(target.data > 0) > 0:
        output = sae(input)
        target.require_grad = False
        output[target == 0] = 0      # I get error at this line
        loss = criterion(output, target)
        mean_corrector = nb_movies/float(torch.sum(target.data > 0) + 1e-10)
        test_loss += np.sqrt(loss.data.item()*mean_corrector)
        s += 1.
print('test loss: '+str(test_loss/s))

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Если вы посмотрите на тренировку своего SAE, целью является клон ввода, который имеет дополнительное измерение с помощью функции .unsqueeze (0).

Если вы посмотрите в тесте SAE, у цели нет добавленного измерения, поэтому измените ваш код следующим образом

Изменение
target = Variable (test_set [id_user])

Для
target = Variable (test_set [id_user]). Unsqueeze (0)

Чтобы у вашей цели было более одного тусклого цвета, требуемого тензорным.

0 голосов
/ 05 февраля 2019

Изменение

output[target == 0] = 0      # I get error at this line

К

output[(target == 0).unsqueeze(0)] = 0

Причина

torch.Tensor, возвращаемый target == 0, имеет форму [1682].

(target == 0).unsqueeze(0) преобразует его в [1, 1682]

...