pytorch: получение одинакового результата в каждой эпохе - PullRequest
1 голос
/ 07 января 2020

Я пытаюсь обучить сеть rbf ... Я использовал базу данных MNIST. И рамки Pytorch ... Результаты одинаковы в каждой эпохе ...

Результаты ....:

Epoch: 1  
Accuracy: 0.785     Loss: 2.435     Recall: 0.386   Precision: 0.258


Epoch: 2  
Accuracy: 0.785     Loss: 2.435     Recall: 0.386   Precision: 0.258


Epoch: 3  
Accuracy: 0.785     Loss: 2.435     Recall: 0.386   Precision: 0.258


Epoch: 4  
Accuracy: 0.785     Loss: 2.435     Recall: 0.386   Precision: 0.258

Мой код ... Я думаю, что проблема заключается в где-то в линейном слое. Модель не имеет улучшений после тренировочной эпохи, возможно, это линейный слой. Кажется, что вес без изменений ...! Но я не знаю почему ...?

class RBF(nn.Module):
    def __init__(self, in_layers, centers, sigmas):
        super(RBF, self).__init__()
        self.in_layers = in_layers
        self.centers = nn.Parameter(centers)
        self.sigmas = nn.Parameter(torch.Tensor(self.centers.size(0)))
        torch.nn.init.constant_(self.sigmas, sigmas)

    def forward(self, x):
        x = x.view(-1, self.in_layers)
        size = [self.centers.size(0), x.size(0)]
        sigma = self.sigmas.view(-1).to(device)**2

        dists = torch.empty(size).to(device)

        for i,c in enumerate(self.centers):
            c = c.reshape(-1,c.size(0))
            temp = (x-c).pow(2).sum(-1).pow(0.5)
            dists[i] = temp

        dists = dists.permute(1,0)
        phi = torch.exp(-1*(dists/(2*sigma))) #gaussian
        return phi

class Net(nn.Module):
    def __init__(self, in_layers, centers, sigmas):
        super(Net, self).__init__()
        self.rbf_layers = nn.ModuleList()
        self.linear_layers = nn.ModuleList()
        for i in range(len(in_layers) - 1):
            self.rbf_layers.append(RBF(in_layers[i], centers, sigmas))
            self.linear_layers.append(nn.Linear(centers.size(0), in_layers[i+1], bias = True))

    def forward(self, x):
        out = x
        for i in range(len(self.rbf_layers)):
            out = self.rbf_layers[i](out)
            out = F.sigmoid( self.linear_layers[i](out.float()) )
        return out


def training(engine, batch, device, model, criterion, optimizer):
    inputs, labels = batch[0].to(device), batch[1].to(device)
    optimizer.zero_grad()
    outputs = model(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()
    return outputs, labels

Конечно, код непрерывный, но я думаю, что этого достаточно для решения проблемы (если вы хотите что-то еще «я здесь») .... У вас есть какие-нибудь идеи ???

и обучающая часть кода ....

def training(engine, batch, device, model, criterion, optimizer):
    inputs, labels = batch[0].to(device), batch[1].to(device)
    optimizer.zero_grad()
    outputs = model(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()
    return outputs, labels

def nn_run1(batch, classes, dim, learning_rate, epochs, clusters):
    # ---Load Model's Parameters---
    train_loader, test_loader = data_loading(batch, shuffle=False)
    kmeans_input = train_loader.dataset.train_data
    kmeans_input = torch.reshape(kmeans_input.double(), (kmeans_input.size(0), -1))
    _, centers = Kmeans(kmeans_input, clusters)
    centers = centers.to(device)
    sigma = Sigmas(centers)
    layers = in_layers(dim, len(classes), layers = 1)

    # ---Model Setup---
    model = Net(layers, centers, sigma)
    model.cuda()
    criterion = nn.CrossEntropyLoss()
    print(model.parameters)
    optimizer = torch.optim.SGD(model.parameters(), learning_rate)
...