[Rust] Ownership, Scope, Transfer Ownership 과 Borrowing

Scope, Ownership, Transfer

Rust에서 사용하는 영역, 소유, 소유권 이전, 복사, 빌림을 요약해 보는 것이 목적이다. 소유(Ownership)은 Java, Go와 같은 백그라운드에서 실행하는 garbage collector가 없다는 것이다.

Rust Ownership의 주요 키워드

  • Move: Trasnferring Ownership
  • Copy
  • Borrowing
  • Mutable Borrowing

Scope와 Ownership, Lifetime

  • 문맥에서 소유와 빌림(borrowing)은 다름을 명심하다.
  • 모든 변수는 반듯이 하나 소유해야 한다. 2개, 3개도 불허한다
    • 영역의 정의
      • 시작은 '{' (대괄호) 시작한다.
      • 끝은 '}' 또는 return 위치이다.
  • 소유 영역에서 벗어나면 파기된다.
  • lifetime은 변수가 생성되고, 삭제되는 기간을 이야기 한다.
  • 소유를 다른 영역으로 전송할 수 있다.

소유권 이전(Transferring Ownership)

  • 한 영역의 변수의 소유권을 다른 영역으로 이전(moving)하는 것이다.

복사(Copying)

  • 원시 타입같은 경우는 소유권 이전보다 복사를 한다.
    • 예) interger, floating-point, bytes(스택의) 
  • Ownership에 의존하지 않는 타입을 Copy trait이 있다.

빌림(Borrowing)

  • 만약 데이터를 이동(moving)한다면, 소유권이 새로운 변수로 바뀐다. 이 것은 다른말로 새로이 받은 변수가 영역이 삭제될 경우, 메모리상의 데이터가 삭제가 된다.
  • 소유권은 이전하지 않고, 값을 참조할 때 사용한다.
    • 참조 형태: 
      • mutable: 
        • 빌림 변수의 영역이 끝나면, 소유한 영역의 변수 값이 바뀔 수 있다.
        • mutable borrowing이 되어 살아 있다면, 다른 영역에서 immutable borrowing을 생성 할 수 없다.
      • immutable(기본): 일기 전용 변수이다.
    • 표현은 '&'를 같이 정의한다
  • 컴파일러는 모든 빌림 변수에 lifetime을 추적한다.

Rust에서 Rc와 Box

박스 변수

개발자는 변수를 스택(stack)에 할당할지, 힙(heap)에 할당할지 변수 타입을 먼저 결정 해야한다. 본 내용은 힙을 사용하는 경우이다. 

Rc<T>, Box<T>는 다음과 같다:

  • 공통
    • 힙 사용: 실제값이 저장되는 공간이다.
    • 힙 포인터 사용(usize): 힙 공간을 참조하는 변수가 스택 공간에 할당된다.
    • 재귀적 정의타입이여서 컴파일 시간에 크기를 알 수 없을 때 사용한다. 예) List
  • 차이점:
    • 데이터 소유권 개수
      • Box<T>는 1개
      • Rc<T>는 여러개
  • Box<T>: 
    • 변수 영역이 벗어나면 자동 해제가 된다. 컴파일 시간에 변수의 생명주기가 계산 가능하다.
    • 힙 내부 데이터 수정이 가능하다.
  • Rc<T>: 
    • 불변 참조(immutable reference): 
      • 힙 내부의 값을 수정할 수는 없다.
    • 여러 영역에서 소유권을 가질 수 있다:
      • 소유권이 동적으로 공유한다. 내부적으로 참조 횟수를 세고 있어서, 0이되면 할당된 메모리가 해제가 된다.
    • 순환 참조를 조심해야 한다. 대안으로 Weak<T>를 쓸 수 있다.

스택

부연하면, 스택을 사용할 경우, 짧은 생의 작은 크기를 보통 사용하기 위해서 활용한다. 그리고 FILO(first-in, last-out)의 특성을 가진다. 스택에 변수를 조작하면, 사용하는 변수의 크기를 이미 알 고 있어야 한다. 스택에 있는 변수를 함수의 인자로 넘길경우, 보통 값으로 주고 받는다. 즉, 스택에 값을 복제한다. 

큰 크기를 공간을 할당할때 사용하고, 순서가 없다. 또한 힙의 접근은 주소를 사용해서 한다. 보통 이 주소를 가지고 있는 변수를 포인터라고 한다. 하지만, 힙에 접근하기위한 포인터(레퍼런스)는 스택에 저장된다. 그러므로 컴파일 시간에 포인터 변수 자체의 크기는 알 수 있다. 다만, 힙에 저장된 데이터의 크기는 런타임 시간에 알 수 밖에 없다.

Generative Model을 왜 할까?

Generative Model의 요약

- generative model: joint probability distribution, $p_(x)$ 이다. 

- 조건이 있다면, conditional generative model, $p_(x|c)$ 이다.


활용 분야

1. 데이터 생성: 새로운 데이터 샘플을 생성할 때이다. 예를들면, 가상의 얼굴 사진을 만들때 사용한다.

2. Oulier 검출기, 데이터 압축, generative classifier, 모델 비교에 사용한다. 즉, 데이터의 분포를 추정함으로서 발생하는 모든 작업들이다.

3.Missing value 처리, Inpainting: 

    - Missing value: 관측 등의 손실로 일부의 데이터를 관찰하였을 때, 분포에 근거해서, 손실한 부분을 채우는 과정이다. 단순한 랜덤은 현실에 없는 데이터를 생성할 가능성이 있다.

    - In-painting: 영상 내에 가려진 부분을 채워넣는 작업이다. 예를들면, 2d영상으로부터 3d로 복원할 경우, 관측되지 않는 영역을 generative model로 채워 넣는 작업을 한다.

4. Latent 변수 추정 

    - 문서의 주제(latent variable)가 무엇인가? Bayesian Model에서 사용가능 하다. 관측된 데이터로부터 잠재 토픽을 추정하는 것이다. 예를들면, 문서의 토픽을 추정하는 것이다.

    - 두 영상의 latent 변수 2개를 추출하고, 이 중간의 영상은 무엇이 될까? 를 생성할 수 있다. 예를들면, 무표정 얼굴 사진과 여우를 섞은 모습은 어떻게 될 것인가를 할 수 있다.

5. Representation Learning: 수십 문장을 학습하여, 문장을 가장 잘 설명하는 latent 변수(=feature)를 학습하는 분야이다. 향후에 downstream(supervised task)에 사용된다.


관련 키워드

- GAN, AR, VAE(Variational autencoder), EBM, Normalizing flow, Diffusion Model, ELBO

[베이지안] Bayesian 확률에서 Belief 의미란

불확실한 상황에서  최적의 의사 결정 방법

베이지안 학파의 관점에서 나온 어원이다.

의사 결정을 한다는 것은 다음의 상황을 예측을 해야 한다는 것이다. 현재 관측된 데이터를 근거로 어떤 사건의 발생 확률(=불확실성)을 추정할 수 있다. 우리는 현재 추정된 확률을 믿을 수 밖에 없고, 그 믿음하에서 미래의 사건 예측하여 최적의 의사 결정을 해야 한다.

예를들면 동전 던지기 상황을 고려해보자. 동전의 앞과 뒤가 나올 확률이 반반이다. 다음 동전의 앞면이 나올 확률은 어떻게 될 것인가? 나는 다음의 시도에서도 동전은 앞과 뒤가 반반이 나올 확률을 믿어! 라고 할 것이다. 이때 믿음이 생겨야만 한다.

그래서 Belief이다.


[Rust] Ownership, Scope, Transfer Ownership 과 Borrowing

Scope, Ownership, Transfer Rust에서 사용하는 영역, 소유, 소유권 이전, 복사, 빌림을 요약해 보는 것이 목적이다. 소유(Ownership)은 Java, Go와 같은 백그라운드에서 실행하는 garbage collector가 없...