PyTorch或TensorFlow 2中的自定义优化器,12.0

ttisahbt  于 2023-04-30  发布在  其他
关注(0)|答案(3)|浏览(217)

我正在尝试在PyTorch或TensorFlow 2中实现我的自定义优化器。12.0.在ChatGPT的帮助下,我总是得到有错误的代码,更重要的是我找不到任何有用的例子。
我想实现自定义优化器为:
d1包含当前导数的符号
d2包含先前导数的符号
step_size为1。0
step_size除以2。如果d1的符号为0!= PyTorch中的d2
我知道代码应该是这样的:

import torch.optim as optim

class MyOpt(optim.Optimizer):
   def __init__(self, params, lr=1.0):
      defaults = dict(lr=lr, d1=None, d2=None)
      super(MyOpt, slef).__init__(params, defaults)

   def step(self):
      ???

有谁能帮我编码一下吗?

r6l8ljro

r6l8ljro1#

这绝对高于ChatGPT的工资等级,顺便说一句,ChatGPT的bug可能相当模糊。如果你不能自己编写代码,最好让别人为你编写代码。关于这个问题:
步骤方法自解释地实现优化器的步骤。在步骤中,您必须编写优化器核心函数。您可以获取存储在方法self下的对象中的参数。param_groups如果你从e.g. pytorch SGD。然后你可以用d_p_list来执行你的操作,它是一组self。param_groups。
在核心函数之前,还应该通过调用闭包来初始化loss,并在step函数结束时返回loss。
有关更多信息,您可以查看 www.example.com
祝你好运

jhdbpxl9

jhdbpxl92#

pytorch优化器很复杂,因为它们是通用的,并且针对性能进行了优化。如果您不需要它特别健壮,那么实现您自己的方法相对简单。例如,一个非常简单的带有动量的梯度下降的实现可能看起来像这样。

from torch.optim import Optimizer

class SimpleGD(Optimizer):
    def __init__(self, params, lr, momentum=0.0):
        defaults = dict(lr=lr, momentum=momentum)
        super().__init__(params, defaults)

    @torch.no_grad()
    def step(self, closure=None):
        loss = None
        if closure is not None:
            loss = closure()
        for group in self.param_groups:
            for param in group['params']:
                grad = param.grad + group['momentum'] * self.state[param].get('momentum_buffer', 0)
                self.state[param]['momentum_buffer'] = grad
                param -= group['lr'] * grad
        return loss

它应该与PyTorch的SGDmomentum的结果相匹配(以及所有默认值)。
对于您的情况,您需要计算渐变的符号并在每一步缓存它们,类似于上面示例中缓存momentum_buffer的方式。

5t7ly7z5

5t7ly7z53#

我做到了

class MyOptimizer(optim.Optimizer):
    def __init__(self, params, lr=1.0):
        defaults = dict(lr=lr)
        super(MyOptimizer, self).__init__(params, defaults)
        self.lr = {}
        self.d2 = {}

        for group in self.param_groups:
            for param in group['params']:
                self.lr[param] = torch.ones_like(param.data) * lr
                self.d2[param] = torch.ones_like(param.data)

    def step(self, closure=None):
        loss = None
        if closure is not None:
            loss = closure()

        for group in self.param_groups:
            for param in group['params']:
                if param.grad is None:
                    continue

                d1 = torch.sign(param.grad.data)
                t = torch.where(torch.sign(self.d2[param]) == d1, 1.0, 2.0)

                lr = self.lr[param]
                lr = lr / t

                self.lr[param] = lr
                param.data -= d1 * lr

                self.d2[param] = d1

        return loss

相关问题