2.3.1 원소별 연산

2.3 신경망의 톱니바퀴: 텐서 연산 | 목차 | 2.3.2 브로드캐스팅

 

relu 함수와 덧셈은 원소별 연산element-wise operation입니다. 이 연산은 텐서에 있는 각 원소에 독립적으로 적용됩니다. 이 말은 고도의 병렬 구현(1970~1990년대 슈퍼컴퓨터의 구조인 벡터 프로세서vector processor에서 온 용어인 벡터화된 구현을 말합니다)이 가능한 연산이라는 의미입니다. 파이썬으로 단순한 원소별 연산을 구현한다면 다음 relu 연산 구현처럼 for 반복문을 사용할 것입니다.19

def naive_relu(x):
    assert len(x.shape) == 2    # x는 2D 넘파이 배열입니다.
    x = x.copy()                # 입력 텐서 자체를 바꾸지 않도록 복사합니다.
    for i in range(x.shape[0]):
        for j in range(x.shape[1]):
            x[i, j] = max(x[i, j], 0)
    return x

덧셈도 동일합니다.

def naive_add(x, y):
    assert len(x.shape) == 2     # x와 y는 2D 넘파이 배열입니다.
    assert x.shape == y.shape

    x = x.copy()                 # 입력 텐서 자체를 바꾸지 않도록 복사합니다.
        for i in range(x.shape[0]):
            for j in range(x.shape[1]):
                x[i, j] += y[i, j]
    return x

같은 원리로 원소별 곱셈, 뺄셈 등을 할 수 있습니다.

사실 넘파이 배열을 다룰 때는 최적화된 넘파이 내장 함수로 이런 연산들을 처리할 수 있습니다. 넘파이는 시스템에 설치된 BLASBasic Linear Algebra Subprogram 구현에 복잡한 일들을 위임합니다.20 BLAS는 고도로 병렬화되고 효율적인 저수준의 텐서 조작 루틴이며, 전형적으로 포트란Fortran이나 C 언어로 구현되어 있습니다.

넘파이는 다음과 같은 원소별 연산을 엄청난 속도로 처리합니다

import numpy as np

z = x + y               # 원소별 덧셈

z = np.maximum(z, 0.)   # 원소별 렐루 함수

 


 

19 역주 파이썬의 함수 매개변수는 수정 가능한mutable 데이터 타입(리스트, 딕셔너리 등)일 경우 참조에 의한 호출call by reference처럼 작동하기 때문에 입력 배열 원본을 변경시키지 않으려면 예제 코드처럼 복사하여 사용해야 합니다.
20 역주 대표적인 BLAS 구현으로는 OpenBLAS, 인텔 MKL, ATLAS 등이 있습니다. 아나콘다 파이썬 배포판은 기본적으로 MKL 라이브러 리를 사용합니다.

 

2.3 신경망의 톱니바퀴: 텐서 연산 | 목차 | 2.3.2 브로드캐스팅

 

이 글은 도서출판 길벗에서 출간한  “케라스 창시자에게 배우는 딥러닝“의 1장~3장입니다. 이 책의 저작권은 (주)도서출판 길벗에 있으므로 무단 복제 및 무단 전제를 금합니다.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

This site uses Akismet to reduce spam. Learn how your comment data is processed.