페이지

2022년 7월 20일 수요일

2.3.1 원소별 연산

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

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

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

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

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

import numpy as np

z = x + y ...... 원소별 덧셈

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

댓글 없음: