머신러닝 및 딥러닝/자연어처리

난수 ・ random seed

viamemine 2024. 5. 13. 14:44
728x90
반응형

 

Random seed

 

랜덤시드는 한국에서 난수 생성기라고 부르며, 랜덤한 값을 생성해낸다.

마치 무작위 시드 값을 생성하는 것 같지만 반은 맞고 반은 틀린 말이다.

임의의 값을 랜덤하게 생성해낸다는 점에서는 맞지만, 

한번 정해진 시드 값은 다음 랜덤시드에서도 동일하게 산출된다.

따라서 랜덤 시드란 랜덤하게 컴퓨터가 시드 값을 정하는 것을 의미하며

랜덤하게 시드 값이 계속 바뀌는 것을 의미하지는 않는다.

 

또한 랜덤 시드값은 사실 무작위로 정해지는 것은 아니다.

인간의 뇌에서 무작위 숫자를 선택해서 결정할 수 있지만, 

컴퓨터는 자율적으로 생각해서 랜덤한 숫자를 선택하지 못한다.

한마디로 랜덤한 숫자를 출력하도록 알고리즘화를 해줘야 하는데, 이것이 쉽지 않은 과정이다.

왜냐하면 컴퓨터에게 랜덤이라는 것을 할 수 있도록 명령을 내려줘야 하는데

랜덤이라는 것을 계산적으로 나타내기가 어렵기 때문이다.

결국 랜덤 시드값은 랜덤하게 나오는 것이 아니라 시간을 기준으로 출력되는 값이다.

이것이 마치 랜덤한 숫자처럼 보이는 이유는 ms초로 결정이 되다보니 시드 값들이 랜덤하게 보이는 것이다. 


왜 random seed를 고정해야 할까 ? 

딥러닝에서 학습을 시키다보면 '시드를 고정'하라는 말을 들을 때가 있다.

가중치의 초기값을 어떻게 주는지에 따라 학습의 성능이 달라지기 때문이다. 즉, 초기값이 다르면 학습 결과도 다르다는 것이다.

 

그렇다면 딥러닝에서 시드를 고정하는 이유가 무엇일까 ? 시드 고정은 가중치 초기값 설정의 랜덤성을 고정(하나의 값으로 설정)한다는 개념이다.이는 모델의 재현성, 안정성 및 신뢰성을 보장하는데 중요한 역할을 하기 때문이다.

 

1. 재현성딥러닝 모델 훈련 과정에서 시드를 고정하지 않으면 무작위성 때문에 다시 결과를 재현하기가 어렵다.시드를 고정하면 모델이 훈련될 때마다 동일한 초기값이 사용되어 결과 복제 및 비교가 쉬워진다.

 

2. 모델 안정성무작위성은 훈련 중에 모델 성능에 영향을 줄 수 있다.시드 고정을 통해 학습 과정을 더 효과적으로 제어할 수 있어서,모델을 미세 조정하거나 다양한 아키텍처를 비교할 때 특히 중요한 역할을 한다.

 

3. 디버깅 및 문제 해결 예상치 못한 결과나 오류가 발생할 경우에도 시드를 고정한다.이렇게 하면 디버깅 프로세스가 단순화된다.분석가와 개발자는 문제 식별 및 해결에만 집중함으로써 문제를 보다 효과적으로 찾아낼 수 있다.

 

4. 하이퍼파라미터 튜닝하이퍼파라미터 튜닝할 때 시드를 고정하는 것이 원칙이다.그래야 하이퍼파라미터의 다양한 구성 세트를 공정하게 비교할 수 있다.이 방법을 사용하면 모델 성능에서 발생한 차이가 하이퍼파라미터로 인해 발생한 것들만 볼 수 있다.하이퍼파라미터 최적값이 모델을 돌릴 때마다 다른 값이 나오는 경우를 방지할 수 있다는 것이다.

 

import torch

torch.manual_seed(42) # 삶과 우주, 그리고 모든 것에 대한 답은 42이다 ...

난수 생성

python에서는 random 모듈로 난수 생성을 할 수 있다.

 

random.random()은 [0, 1) 사이의 실수로 난수를 구하며,

random.ranint(a,b)는 [a,b] 사이의 정수로 난수를 구한다. 

>>> import random
>>> random.random()
0.0705821259174515
>>> random.random()
0.9647091416741986
>>> random.randint(0,10)
2
>>> random.randint(0,10)
4

 

 

random.randint(a,b)와 비슷한 함수로 random.randrange(a,b)가 있다.

이 함수는 [a,b) 사이의 정수를 난수로 발생시킨다.

 

random.uniform(a,b)는 random.random()을 이용해 구현한 함수로

[a,b] 사이에 실수형 난수를 발생시킨다.

 

random.triagular(low, high, mode)

random.betavariate(alpah, beta)

random.expovariate(lambda) 등 분포에 따른 난수 생성도 가능하다.

 


 

경우에 따라서(보통 디버깅을 위해) 동일한 순서로 난수를 발생시켜야 할 경우가 있다.

난수 발생을 위해서는 적절한 시드를 난수발생기에 주어야 한다.

만약 시드가 같다면 동일한 난수를 발생시키게 된다. (ex. random.seed(a))

 

random.random()은 현재의 시드에 근거하여 다음 난수를 발생시키는 함수


 

random.seed()안의 값이 같으면 같은 난수가 생성된다. 

import random

random.seed(10)
print(random.random()) # 0.5714025946899135

random.seed(5)
print(random.random()) # 0.6229016948897019

random.seed(10)
print(random.random()) # 0.5714025946899135

 

 

import numpy를 사용한 random seed 예제

import numpy as np

np.random.seed(10)
np.random.rand(5) 
# array([0.77132064, 0.02075195, 0.63364823, 0.74880388, 0.49850701])


np.random.rand(10)
# array([0.22479665, 0.19806286, 0.76053071, 0.16911084, 0.08833981,
       0.68535982, 0.95339335, 0.00394827, 0.51219226, 0.81262096])
       

np.random.seed(10)
np.random.rand(5)
# array([0.77132064, 0.02075195, 0.63364823, 0.74880388, 0.49850701])


np.random.rand(10)
# array([0.22479665, 0.19806286, 0.76053071, 0.16911084, 0.08833981,
       0.68535982, 0.95339335, 0.00394827, 0.51219226, 0.81262096])

 

 

 

 

 

728x90