Pytorch1.4 ATEN/native 코드 분석

4254 단어
Note: Pytorch4 코드, 1.0과 약간의 차이를 발견하고native 이 산자에 대한 코드 해석 문장을 찾지 못해 스스로 억지로 보았다.첫 접촉이기 때문에 잘못이 있으면 지적해 주십시오.

ATEN/native 소개


코드 경로: pytorch/aten/src/ATEN/nativeaten/THNN(즉TH 시리즈)과 구별되는 라이브러리는 공식 문서를 인용하면native:
ATen "native"functions are the modern mechanism for adding operators and functions to ATen (they are "native"in contrast to legacy functions, which are bound via TH/THC cwrap metadata). Native functions are declared in native_functions.yaml and have implementations defined in one of the cpp files in this directory.
즉, ATEN/native 아래의 파일은 C++로 이루어진 것이다operaters (또는'층')

특징

  • C++ 및python API 있음
  • C++에서namespace는at::

  • 사용자 정의operator 정보:


    operator를 추가하려면:


    native 폴더 아래의 Readme 보기

    사용자 정의operator의 자동 미분

  • 다른 (자동 미분화 지원)op를 사용하여 합친 산자라면 백워드 함수를 실현할 필요가 없음
  • 자신이 실현한 코드라면foobackward 및 추가tools/autograd/derivatives.yaml
  • activation을 예로 들면 다음과 같습니다.


    native/Activation.cpp


    나는 이것이'입구'라는 것을 이해하고activation의 각 실현을 포장한다
  • hardtanh
  • elu & celu & selu & rrelu & prelu
  • softplus
  • threshold
  • hardshrink & softshrink
  • 그리고 상기 산자의 다른 조작 형식 변체(inplace 여부)

    엘루를 예로 들다

    native/Activation.cpp는 다음과 같은 인터페이스를 정의합니다.
  • elu: 전방향
  • elu_ & elu_out :inplace elu

  • elu_백워드:반전
  • elu_backward_out : inplace

  • Tensor elu(
        const Tensor& self,
        Scalar alpha,
        Scalar scale,
        Scalar input_scale) {
      Tensor result;
      auto iter = TensorIterator::unary_op(result, self);
      elu_stub(iter.device_type(), iter, alpha, scale, input_scale);
      return iter.output();
    }

    전방향 코드가 호출된 것은 elu_stub정의:
  • native/cpu/Activation.cpp : REGISTER_DISPATCH(elu_stub, &elu_kernel);
  • native/cuda/Activation.cu : REGISTER_DISPATCH(elu_stub, &elu_kernel);

  • 역방향 코드도 유사합니다. 등록된 것을 호출합니다_backward_stub.
    Tensor elu_backward(
        const Tensor& grad_output,
        Scalar alpha,
        Scalar scale,
        Scalar input_scale,
        const Tensor& output) {
      Tensor result;
      auto iter = TensorIterator::binary_op(result, grad_output, output);
      elu_backward_stub(iter.device_type(), iter, alpha, scale, input_scale);
      return iter.output();
    }

    native/cpu/Activation.cpp


    이 파일은 함수를 활성화하는 cpu 코드입니다.
    void elu_kernel(TensorIterator& it, Scalar alpha, Scalar scale, Scalar input_scale) {
      AT_DISPATCH_FLOATING_TYPES(it.dtype(), "elu_cpu", [&]() {
        auto negcoef = alpha.to() * scale.to();
        auto poscoef = scale.to();
        auto negiptcoef = input_scale.to();
        cpu_kernel(it, [=](scalar_t a) -> scalar_t {
          return a <= scalar_t(0) ? (std::exp(a * negiptcoef) - scalar_t(1)) * negcoef : a * poscoef;
        });
      });
    }

    전방향:
  • x > 0 : x*scale
  • x <= 0 : negcoef*(e^(x*neginputcoef) - 1)
  • void elu_backward_kernel(TensorIterator& it, Scalar alpha, Scalar scale, Scalar input_scale) {
      AT_DISPATCH_FLOATING_TYPES(it.dtype(), "elu_backward_cpu", [&]() {
        auto negcoef = alpha.to() * scale.to();
        auto poscoef = scale.to();
        auto negiptcoef = input_scale.to();
        cpu_kernel(it, [=](scalar_t a, scalar_t b) -> scalar_t {
          return b <= scalar_t(0) ? a * negiptcoef * (b + negcoef) : a * poscoef;
        });
      });
    }

    여기에 a, b 두 개의 매개 변수가 있는데, 각각grad 이어야 한다.output, output
    elu의 사다리꼴:
  • output <= 0 : grad_output*neginputcoef*output
  • output > 0 : output*scale
  • 좋은 웹페이지 즐겨찾기