首页 > 解决方案 > 用于位运算的神经网络 AND

问题描述

这可能不是问这个问题的最佳地点,但我真的很挣扎。我想创建一个“平凡”的神经网络,它有 2 个输入、3 个隐藏神经元和 1 个输出。这个想法是我们给它输入两个布尔值,然后它输出 AND 结果。

我想以一种有点“传统”的方式来做(我对 pytorch 还是很陌生)。我正在使用学习率为 0.001 的 Adam 优化器和 nll_loss 函数(尽管我需要更改它,因为我只需要 1 个输出,这需要输出的数量与类的数量相匹配 - 在这种情况下为 1和 0)

我知道这应该是一个非常微不足道的问题,但我真的很挣扎,在谷歌上找不到任何有用的东西。

标签: neural-networkpytorch

解决方案


.csv使用您的训练数据制作一个文件。

x1  x2  label
TRUE    FALSE   FALSE
TRUE    TRUE    TRUE
FALSE   FALSE   FALSE
FALSE   TRUE    FALSE

创建一个数据集类。

class boolData(Dataset):
    def __init__(self, csv_path):
        self.label = pd.read_csv(csv_path)

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

    def __getitem__(self, idx):
        sample = torch.tensor(self.label.iloc[idx,0:2]).int()
        label = torch.tensor(self.label.iloc[idx,2]).int()
        return sample, label

tensor_dataset = boolData(csv_path='sample_bool_stack.csv')

boolDL = DataLoader(tensor_dataset, batch_size=4, shuffle=True)

batch, labels = next(iter(boolDL))

batch, labels
(tensor([[1, 0],
         [1, 1],
         [0, 1],
         [0, 0]], dtype=torch.int32), tensor([0, 1, 0, 0], dtype=torch.int32))

初始化嵌入。

def _emb_init(x):
    x = x.weight.data
    sc = 2/(x.size(1)+1)
    x.uniform_(-sc,sc)

该模型将True,转换False为整数并将总和作为输入。编辑:只有单个神经元的输出。

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.emb = nn.Embedding(3, 2)
        _emb_init(self.emb)
        self.fc1 = nn.Linear(2, 10)
        self.fc2 = nn.Linear(10, 1)

    def forward(self, x):
        x = torch.sum(x, dim=1)
        x = self.emb(x)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        return x

初始化模型、优化器和损失函数。编辑:更改损失以匹配单个神经元输出。

model = Net()
opt = optim.SGD(model.parameters(), lr=1e-3)
loss_func = nn.BCEWithLogitsLoss()
num_epochs = 10000

device = "cpu"

火车模型。

for epoch in range(num_epochs):
    for i,(inputs, labels) in enumerate(boolDL):
        inputs = inputs.to(device).long()
        labels = labels.to(device).float()

        opt.zero_grad()

        output = model(inputs)
        loss = loss_func(output.view(-1), labels)
        loss.backward()
        opt.step()
        with torch.no_grad():
            if epoch % 2000 == 0: print(loss.item())
0.004416308831423521
0.002891995944082737
0.004371378570795059
0.0017852336168289185

测试模型。

inputs = torch.tensor([[0,0],[0,1],[0,0]])

def check_model(inputs):
    out = model(inputs)
    preds = torch.sigmoid(out).round()
    return preds.detach().numpy()

check_model(inputs)
array([[0.],
       [0.],
       [0.]], dtype=float32)

推荐阅读