求 Y = aX 形式的线性方程的系数“a”

问题描述 投票:0回答:1

假设我有两个集合,X 和 Y,以及一些已知的系数“a”。

设置 Y 取决于 X 和“a”,如下所示: Y = aX

import numpy as np

a = 2
X = np.random.randint(1, 10, 10)
Y = a * X

print(f"{X = }")
print(f"{Y = }")

>>> X = array([9, 2, 7, 8, 8, 9, 5, 8, 4, 1])
>>> Y = array([18,  4, 14, 16, 16, 18, 10, 16,  8,  2])

任务: 使用 PyTorch 工具包仅使用 X 和 Y 找到系数“a”

我尝试做什么以及问题是什么:

我正在尝试将 X[i] 传递给模型并期望从中获得系数 a_pred。然后我找到 y_pred = a_pred * X[i]。最后我比较 y[i] 和 y_pred。 显然,模型没有“看到”a_pred、“a”、y_pred 和 Y[i] 之间的关系。因此问题是:模型的架构应该是什么,才能找到正确的“a”系数?

我刚刚开始学习 PyTorch,不幸的是,到目前为止,我还没有找到这个问题的明确答案。到目前为止,在我看来,这个问题的解决方案一定与 GAN 有关,但不幸的是我不知道到底是如何相关的

我当前的代码:

import numpy as np
from torch.nn import Module, Linear, ReLU, Sequential, CrossEntropyLoss
from torch.optim import Adam
from torch import from_numpy

from random import randint


class FindParameter(Module):
    def __init__(self):
        super(FindParameter, self).__init__()
        self.layers = Sequential(
            Linear(1, 10),
            ReLU(),
            Linear(10, 100),
            ReLU(),
            Linear(100, 10),
            ReLU(),
            Linear(10, 1),
        )

    def forward(self, input):
        return self.layers(input)


a = 5.0
x = []
y = []
train_dataset_size = 10000
for i in range(train_dataset_size):
    x.append(randint(0, 10000))
    y.append(x[i] * a)

X = [from_numpy(np.array([c], dtype=np.float32)) for c in x]
Y = [from_numpy(np.array([c], dtype=np.float32)) for c in y]
A = from_numpy(np.array([a], dtype=np.float32))

epochs = range(100)

model = FindParameter()
loss_f = CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=1e-3)


for epoch in epochs:
    for x, y in zip(X, Y):
        optimizer.zero_grad()
        a_pred = model(x)
        y_pred = a_pred * x

        loss = loss_f(y_pred, y)
        loss.backward()
        optimizer.step()
python pytorch neural-network
1个回答
0
投票

我们在 R 包“cito”(简化了神经网络的训练)中展示了如何使用神经网络来优化任意函数(唯一的要求是它们必须是可微分的并用 Torch 编写)。您的问题与我们的示例类似:

模拟线性模型的一些数据(真实斜率 = 2,真实西格玛 = 0.4)

library torch
library(cito)  
X = runif(200)
Y = 2*X + rnorm(200, sd = 0.4)
df = data.frame(X = X, Y = Y)

我们要优化的函数(线性模型):

Xt = torch_tensor(matrix(X))
Yt = torch_tensor(matrix(Y))

model_lm = function(par) {
  pred = Xt$matmul(par[,1,drop=FALSE])
  loss = -torch::distr_normal(pred, scale = torch::torch_exp(par[,2,drop=FALSE]))$log_prob(Yt)
  return(loss$mean())
}

实际损失函数:

custom_loss = function(pred, true, ...) {
  if(nrow(pred) > 1) return(torch_zeros(1L)) # disable loss calculation
  loss = model_lm(pred)
  return(loss)
}

X 和 Y 值并不重要,Y 中的列数必须与我们要优化的参数数量相匹配,这里有两列,一列用于斜率参数,一列用于 sigma 参数。我们向神经网络输入噪声,它会预测两个参数(类似于 GAN 中的生成器):

noise = matrix(runif(300*5), 300, 5)
noise_y = matrix(runif(300*2), 300, 2)
df = data.frame(y1 = noise_y[,1], y2 = noise_y[,2], noise)

拟合最终模型:

m = dnn(cbind(y1, y2)~., data = df, loss = custom_loss, batchsize = 1L, epochs = 20L, verbose = FALSE) 

结果:

# Effect:
mean(predict(m)[,1])
#> [1] 2.02776
# SD
mean(exp(predict(m)[,2]))
#> [1] 0.3864421
© www.soinside.com 2019 - 2024. All rights reserved.