2017-10-26 10 views
0

계산 속도를 높이기 위해 신경망에 대한 커스텀 CUDA 커널을 작성하고 싶지만 수행 할 수있는 패키지가 있다면 손으로 텐서 표현식을 구별하는 데 시간을 투자하고 싶지 않습니다. 자동으로계산 행렬/상징 행렬 미분 표현식 얻기

심볼릭 매트릭스 차별화를위한 표현식을 보여줄 수있는 파이썬 패키지가 있습니까?

내가 sympy이 같은 행렬이 아닌 표현을 위해 그것을 할 수있어 : 함수가 평가 한 후

def func(x): 
    return 1/x 

arg_symbols = sp.symbols(inspect.getfullargspec(func).args) 
sym_func = func(*arg_symbols) 
s = '' 
for arg in arg_symbols: 
    s += '{}\n'.format(arg, sp.Lambda(arg_symbols, sym_func.diff(arg))) 
# this is what I need: 
print(s) 
>>> Lambda(x, -1/x**2) 

내가 행렬의 파생 상품을 계산할 수 autograd 패키지

을 연산 식을 알고, autograd가있다 수행 된 모든 작업 목록 및 해당 노드가 종속 된 노드. 함수 계산에 대한 계산 그래프는 입니다. 파생 상품을 계산하려면 그래프의 각 노드 에 차별화 규칙을 적용하기 만하면됩니다.

그러나이 미분 계산 그래프를 얻을 수있는 방법이 있습니까?

답변

0

인용 한 패키지간에 약간의 차이가 있습니다. 차이점은 자동 차별화 라이브러리에서 계산 그래프를 직접 (AFAIK) 가져올 수없는 이유이지만 심볼 기반 차트에서 가져올 수 있습니다. 요컨대

:

  • 수치 분화 : numpy 충분히
  • 기호 분화이다 sympy
  • 자동 분화 : autograd는 일례

분화 방법의 세 가지 종류가있다 :

  • 숫자 차별화 :이 수치는 Delta(f(x))/Delta(x)입니다. Delta(x)x의 변형을 나타내는 작은 차이이며 f의 도메인에 남아 있습니다. 이것은 당신이 필요로하는 것이 아닙니다. 이를 위해 패키지가 필요하지 않습니다.
  • 상징적 인 차별화 : 함수의 상징적 응용을 나타내는 그래프의 구성을 기반으로합니다 (Ruby의 심볼 엔진 구현에 관한 기사가 있음 here). 이 경우에, 분화는 체인 유도 규칙을 반복적으로 적용을 통해 수행되는이 규칙은, 전체의 심볼 그래프에 적용

    f(g(x))' = f'(g(x)) * g'(x) 
    

    은 어떤 결과 것은 유도체 최신 기호 그래프이다. 장점은 파생물이 정확하다는 사실에 있습니다. 그러나 매우 복잡한 그래프의 경우 최종 파생 그래프는 처리 할 수 ​​없습니다 (너무 깊은 재귀를위한 메모리 제한 또는 스택 제한 초과). 파이썬에서 sympy은 이런 유형의 유도를 구현합니다. 다른면에서 파생 상품의 그래프가있는 경우 단순화 또는 대체와 같은 작업을 수행 할 수 있습니다.

    from sympy import * 
    import numpy as np 
    
    x = symbol('x') 
    f = 1/x 
    df = diff(f, x) 
    print(df) 
    # -1/x**2 
    
    ldf = lambdify((x), df) 
    
    # Now ldf is a lambda 
    x_ary = np.array([ 
        [[1, 2, 3], [1, 2, 3]], 
        [[1, 2, 3], [1, 2, 3]] 
    ]) 
    y_ary = ldf(x_ary) 
    
    print(xn.shape) 
    # (2, 2, 3) 
    print(y_ary) 
    # array([[[-1.  , -0.25  , -0.11111111], 
    #   [-1.  , -0.25  , -0.11111111]], 
    #  [[-1.  , -0.25  , -0.11111111], 
    #   [-1.  , -0.25  , -0.11111111]]]) 
    

    당신은 numpy 작동하지만 (예를 들어, 그렇지 않은 모든 기본 예제의 일부를 포함, 사실 sympy.symbol와 함께 sympy.matrix 특히 그래프를 사용해야 볼 수 있습니다 : 나는 그것을 생각하지 않는다 diff(x.T A x, x) = x.T A + A x)을 직접 처리 할 수 ​​있음).

    export the graph as C code하는 것도 가능하지만, 일부 제한된 기능을 가지고 있으며, 여러분의 응용 프로그램에 대해 당신은 확실히 결과를 수정해야합니다

    from scipy.utilities.codegen import codegen 
    
    [(cf, cc), (hf, hc)] = codegen(("df", df), "C", "df") 
    
    print(hc, cc) 
    

    인쇄 아웃 :

/***************************************************** 
*  Code generated with sympy 1.1.1    * 
* See http://www.sympy.org/ for more information. * 
*  This file is part of 'project'    * 
*****************************************************/ 

#ifndef PROJECT__DIFF__H 
#define PROJECT__DIFF__H 

double df(double x); 

#endif 

/***************************************************** 
*  Code generated with sympy 1.1.1    * 
* See http://www.sympy.org/ for more information. * 
*  This file is part of 'project'    * 
*****************************************************/ 
#include "diff.h" 
#include <math.h> 

double df(double x) { 
    double df_result; 
    df_result = -1/pow(x, 2); 
    return df_result; 
} 
  • 자동 차별화 무엇을하고 있습니까? gh autograd. 이 경우 두 세계 모두의 장점이 통일됩니다. 한 쪽에서는 그래프를 명시 적으로 평가할 필요가 없으며 다른 쪽에서 파생 함수에 대한 추가 연산을 수행 할 수 없으며 파생 정확도는 그대로 유지합니다. 이것은 추가 필드에 미분을 포함하는 추가 필드 (float[2] 이상)를 사용하여 float 정의를 보완하여 수행됩니다 (보통). 자동 차별화 환경에서 예를 들어, sin 기능은 오버로드 될 수있다

    def sin(x): 
        return [sin(x[0]), x[1] * cos(x[0])] 
    

    하지만이 방법으로 이해할 수있는, 어떤 계산 그래프는 사용할 수 없습니다,하지만 당신은 x 따라 정확한 유도체의 값을 직접 얻을 (모든 함수는 오버로드되어야 함). 더 완벽한 예제가 있습니다 (C lang에서는 매크로 만 사용) here. 내부적으로 Tensorflow는 기호식 대신 자동 차별화를 사용하지만 숫자로 불안정한 부분을 처리하는 "명시 적 버전"을 사용자가 직접 제공 할 것을 제안합니다!. 자동 차별화는 대개 수치 불안정성을 처리하지 않습니다.

+0

예, 그렇지만 이러한 패키지 중 일부에서 파생 그래프를 추출 할 수있는 방법이 있습니까? (나는 그것을 CUDA 등에서 하드 코딩 할 필요가있다.) – Bob

+0

최소한의 수정으로 Cuda에서 사용할 수있는 C 코드를 내보낼 수있다. –

+0

어떻게해야할까요? – Bob