Почему я не могу изучить функцию XOR с этой сетью и ограничениями? - PullRequest
0 голосов
/ 06 марта 2019

Допустим, у меня есть следующие ограничения и сеть:

  1. Архитектура исправлена ​​( см. Это изображение ) (обратите внимание, что смещений нет)
  2. Функция активации для скрытого слоя: ReLU
  3. Нет функции активации для выходного слоя (нужно просто вернуть сумму входных данных, которые он получает).

Я пытался реализоватьэто в pytorch с различными схемами инициализации и различными наборами данных, но я не смог (код внизу).

Мои вопросы:

  1. Что-то не так с моей тренировкой NN?процесс?
  2. Это выполнимая проблема?Если да, то как?
  3. Если это выполнимо, можем ли мы все еще достичь этого, ограничивая веса в наборе {-1, 0, 1}

Код:

import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as data_utils
import numpy as np

class Network(nn.Module):

     def __init__(self):

        super(Network, self).__init__()
        self.fc1 = nn.Linear(2,2,bias=False)
        self.fc2 = nn.Linear(2,1, bias=False)
        self.rl = nn.ReLU()

      def forward(self, x):
        x = self.fc1(x)
        x = self.rl(x)
        x = self.fc2(x)
        return x 

#create an XOR data set to train    
rng = np.random.RandomState(0)
X = rng.randn(200, 2)
y = np.logical_xor(X[:, 0] > 0, X[:, 1] > 0).astype('int32')

# test data set
X_test = np.array([[0,0],[0,1], [1,0], [1,1]])

train = data_utils.TensorDataset(torch.from_numpy(X).float(), \
                         torch.from_numpy(y).float())
train_loader = data_utils.DataLoader(train, batch_size=50, shuffle=True)

test = torch.from_numpy(X_test).float()

# training the network
num_epoch = 10000

net = Network()
net.fc1.weight.data.clamp_(min=-1, max=1)
net.fc2.weight.data.clamp_(min=-1, max=1)

# define loss and optimizer
criterion = nn.MSELoss()
optimizer = optim.Adam(net.parameters())

for epoch in range(num_epoch):
  running_loss = 0 # loss per epoch
  for (X, y)in train_loader:
    # make the grads zero
    optimizer.zero_grad()
    # forward propagate
    out = net(X)
    # calculate loss and update
    loss = criterion(out, y)
    loss.backward()
    optimizer.step()
    running_loss += loss.data
  if epoch%500== 0:      
      print("Epoch: {0} Loss: {1}".format(epoch, running_loss))

Потеря не улучшается.Он застревает в каком-то значении после нескольких эпох (я не уверен, как сделать это воспроизводимым, поскольку я получаю разные значения каждый раз)

net(test) возвращает набор предсказаний, которые совсем близкона выход XOR.

...