繁体   English   中英

用简单的神经网络逼近指数拟合

[英]Approximating an exponential fit with a simple neural network

我一直在尝试训练一个网络来解决s(t) = s0 * e^(-t/decay_constant)形式的指数拟合。 作为输入,网络需要st ,并且作为 output 它应该返回s0decay_constant 这似乎是一个足够简单的问题,我希望网络能够令人满意地近似。

但是,我无法让它工作。 损失确实 go 下降,结果看起来并不完全随机,但它们肯定比我简单的对数线性拟合所能达到的要差。

我的设置是(在 CPU 上大约需要 20 秒)

  1. 具有 ReLU 激活的密集网络
  2. 基于对数线性 LSQ 的损失
  3. 训练随机指数衰减示例
import torch

net = torch.nn.Sequential(
    torch.nn.Linear(10, 64), torch.nn.ReLU(),
    torch.nn.Linear(64, 64), torch.nn.ReLU(),
    torch.nn.Linear(64, 32), torch.nn.ReLU(),
    torch.nn.Linear(32, 2), torch.nn.ReLU(),  # Want outputs to always be positive.
)

loss = torch.nn.MSELoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.005)

def signal_model(x, s0, decay):
    return s0 * torch.exp(-x / decay)

# Generate some datapoints
batch_size = 4096

for episode in range(1000):
    # Generate random time, decay_constant s0.
    t = t = (torch.arange(5, 55, 10.) + (torch.rand(batch_size, 5) * 10)).T
    decay_constant = torch.rand(batch_size) * 70 + 10
    s0 = (torch.rand(batch_size) * 2 - 1) * 50 + 100

    # Generate random input data
    y = signal_model(t, s0, decay_constant)
    data = torch.vstack((t, y)).T

    # Make a prediction and calculate loss
    coefficients = net(data)
    l = loss(-torch.log(signal_model(t, *coefficients.T) + 1e-20), -torch.log(y + 1e-20))

    optimizer.zero_grad(); l.backward(); optimizer.step()

可视化结果

import matplotlib.pyplot as plt

t_ = torch.tensor([5, 15, 25, 35, 45], dtype=torch.float32)
plotgrid = torch.arange(0, 50, 0.1)
s = signal_model(t_, 20, 30)

fig, ax = plt.subplots()
ax.plot(plotgrid, signal_model(plotgrid, 20, 30).detach().numpy())
ax.scatter(t_, s.detach().numpy(), label="True")
ax.scatter(
    t_,
    signal_model(t_, *net(torch.hstack((t_, s)).T)).detach().numpy(),
    label="Predicted",
)
ax.legend()

合身

我想知道是否有人对为什么这不起作用有见解。 逼近简单函数是否有一些基本限制? 还是有什么东西让人眼前一亮,因为它本质上是错误的? 希望有任何见解。

什么不起作用:

  • 调整学习率
  • 调整每层的层数/单位
  • 调整 batch_size
  • 在系数或信号上直接将损失更改为 MSE,无需对数
  • 用 L1loss 正则化
  • 始终使用与输入相同的t

有点相关的问题: https://stats.stackexchange.com/questions/379884/why-cant-a-single-relu-learn-a-relu

s0decay_constant不是您生成的数据中的固定参数值。 model 没有一个真正的参数向量可以收敛。 您可能会认为,给它提供来自不同参数的各种不同的指数输出示例意味着它正在被训练以从任何给定的数据集中预测适当的指数拟合系数,但这是错误的。 相反,它只是被训练来重现指数拟合系数的特定分布(看起来像正态分布的数据,对于衰减常数,平均值为 10,方差为 490,对于decay_constant ,平均值为 100,方差为s0 )。 作为一个思想实验,如果我们输入一个示例数据集,其参数远远超出这些分布的尾部,该怎么办? model 无法充分猜测这种关系,因为随机训练集中基本上完全丢失了(s0, decay_constant)空间的那一部分。 想想所有可能的指数曲线的空间......

您缺少的关键是您无法制作单个 model 来预测任何可能数据集的系数。 相反,您可以在任何数据集上训练model 以预测该数据集的系数。 如果训练数据是从那些系数固定的样本中生成的,那么模型的损失优化将导致预测系数收敛到该数据集的真实系数。 您实际上是在劫持 NN 优化器来执行更常见的优化器仅使用您通常会执行的确定性方程求解来执行的操作。

但是,如果您处理一个没有固定参数的数据集,则输出最多只能表示根据您在制作合成训练数据时定义的参数分布 因为不可能制作一个充分包含所有可能的指数曲线的训练集,所以 model 通常表现不佳。 对于参数接近您所做的合成训练分布的曲线拟合,它可能执行得很好,但这将取决于很多方差和收敛质量。

我做了一个类似类型的 model 用于线性回归系数预测。 注意:拟合线性 model,而是直接从一组固定的真实系数生成的数据集中预测线性 model 的系数。 它在精神上与您在此处尝试执行的操作非常相似,但请注意必须如何在您想要系数的单个数据集上对其进行训练 它无法预测所有可能的线性关系中的通用系数。 要获得有意义的输出,您不仅要做出单一的预测——而是要对测试集中的预测进行平均,这些预测来自由固定的真实参数生成的相同数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM