Pytorch 中的批量学习是如何进行的?

Inf*_*yyy 5 python neural-network pytorch

当您查看 pytorch 代码内部如何构建网络架构时,我们需要扩展torch.nn.Module和 内部__init__,我们定义了网络模块,pytorch 将跟踪这些模块的参数梯度。然后在forward函数内部,我们定义应该如何为我们的网络完成前向传递。

我在这里不明白的是批量学习将如何发生。在包括forward函数在内的上述定义中,我们都不关心网络输入的批次维度。为了执行批量学习,我们唯一需要设置的是向输入添加一个与批量大小相对应的额外维度,但如果我们使用批量学习,网络定义中的任何内容都不会改变。至少,这是我在这里的代码中看到的

因此,如果到目前为止我解释的所有内容都是正确的(如果您让我知道我是否误解了某些内容,我将不胜感激),如果在我们的网络类的定义中没有声明关于批量大小的任何内容,则如何执行批量学习(继承的类torch.nn.Module)?具体来说,我很想知道当我们只设置nn.MSELoss批量维度时,如何在pytorch中实现批量梯度下降算法。

pro*_*sti 2

检查一下:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super().__init__()         

    def forward(self, x):
        print("Hi ma")        
        print(x)
        x = F.relu(x)
        return x

n = Net()
r = n(torch.tensor(-1))
print(r)
r = n.forward(torch.tensor(1)) #not planned to call directly
print(r)
Run Code Online (Sandbox Code Playgroud)

出去:

Hi ma
tensor(-1)
tensor(0)
Hi ma
tensor(1)
tensor(1)
Run Code Online (Sandbox Code Playgroud)

要记住的是forward不应该直接调用。PyTorch 使该 Module 对象n可调用。他们实现了可调用的,例如:

 def __call__(self, *input, **kwargs):
    for hook in self._forward_pre_hooks.values():
        hook(self, input)
    if torch._C._get_tracing_state():
        result = self._slow_forward(*input, **kwargs)
    else:
        result = self.forward(*input, **kwargs)
    for hook in self._forward_hooks.values():
        hook_result = hook(self, input, result)
        if hook_result is not None:
            raise RuntimeError(
                "forward hooks should never return any values, but '{}'"
                "didn't return None".format(hook))
    if len(self._backward_hooks) > 0:
        var = result
        while not isinstance(var, torch.Tensor):
            if isinstance(var, dict):
                var = next((v for v in var.values() if isinstance(v, torch.Tensor)))
            else:
                var = var[0]
        grad_fn = var.grad_fn
        if grad_fn is not None:
            for hook in self._backward_hooks.values():
                wrapper = functools.partial(hook, self)
                functools.update_wrapper(wrapper, hook)
                grad_fn.register_hook(wrapper)
    return result
Run Code Online (Sandbox Code Playgroud)

并且只会自动n()调用forward

一般来说,__init__定义模块结构并forward()定义单个批次的操作。

如果某些结构元素需要,可以重复该操作,或者您可以像我们一样直接调用张量上的函数x = F.relu(x)

太棒了,PyTorch 中的所有内容都将以批量(小批量)的方式完成,因为 PyTorch 已针对这种方式进行了优化。

这意味着当您读取图像时,您不会读取单个图像,而是读取一批bs图像。