바뀜

둘러보기로 가기 검색하러 가기
3,354 바이트 추가됨 ,  2022년 4월 11일 (월) 10:17
잔글
2번째 줄: 2번째 줄:  
케라스 자체적으로도 데이터 전처리를 제공한다.
 
케라스 자체적으로도 데이터 전처리를 제공한다.
   −
== 전처리 ==
+
=== 배치사이즈 ===
 +
한 번에 몇 개의 데이터를 교육할 것인가. 숫자가 크면 계산이 빨라지지만, 메모리 부하가 커진다. 때문에 양날의 검.
 +
 
 +
== 전처리 예시 ==
 
{| class="wikitable"
 
{| class="wikitable"
 
!의도
 
!의도
82번째 줄: 85번째 줄:     
= 데이터 제너레이터 =
 
= 데이터 제너레이터 =
데이터의 크기가 커지면 이게 RAM에 다 안올라가서 에러가 뜬다. 때문에 제너레이털로 데이터를 입력해주는 편이 좋다.
+
데이터의 크기가 커지면 이게 RAM에 다 안올라가서 에러가 뜬다.(시계열 데이터는 window의 수많큼 데이터가 커지고, image같은 것들은 하드에 저장했던걸 불러오는데, 이걸 RAM에 올리는 건..힘들다.)
 +
 
 +
때문에 제너레이터로 데이터를 입력해주는 편이 제한된 RAM을 잘 활용할 수 있다.
 +
 
 +
게다가 GPU의 작업과 쓰레드로 분리되어 데이터 처리는 CPU에서 동시에 처리된다. 즉, 더 빠른 처리를 기대할 수 있다.
    
=== 유의 ===
 
=== 유의 ===
제너레이터는 다 쓰면 학습이 이루어지지 않기에, 다 쓰게 되면 다시 처음으로 loopback 해주는 기능을 함께 넣는 편이 좋다.
+
 
 +
* 제너레이터는 다 쓰면 학습이 이루어지지 않기에, 다 쓰게 되면 다시 처음으로 loopback 해주는 기능을 함께 넣는 편이 좋다.
 +
* 사용자가 처음부터 임의로 짠 제너레이터는... 끝지점을 설정하기도 어렵고, 기타 세부사항을 놓치는 경우가 많다.
 +
 
 +
- 최근엔 케라스에서 제너레이터의 기본 틀을 제공한다. tf.keras.utils.Sequence를 상속하는 클레스를 만들어주는 것으로부터 시작한다.(멀티프로세싱이나 이런저런 세부사항을 지키기에 안전하기에 권장된다.)
 +
 
 +
== 케라스 제공 클래스로 만들기 ==
 +
쓰레드로 진행되어 CPU나 GPU에 바로 먹여진다.
 +
 
 +
=== 필수 메서드 ===
 +
__getitem__과 __len__ 메서드가 필수적으로 정의되어야 한다. 아, __init__은 클래서에선 기본이고.
 +
{| class="wikitable"
 +
!메서드
 +
!설명
 +
!코드예시
 +
|-
 +
|<code>__init__</code>
 +
|객체가 처음 만들어질 때 변수를 어떻게 할당할지. 딱히 이렇다 할 제약은 없다.
 +
|<syntaxhighlight lang="python">
 +
class CIFAR10Sequence(Sequence):
 +
 
 +
    def __init__(self, x_set, y_set, batch_size):
 +
        self.x, self.y = x_set, y_set
 +
        self.batch_size = batch_size
 +
</syntaxhighlight>
 +
|-
 +
|<code>__getitem__</code>
 +
|배치 하나의 데이터를 뱉어낼 수 있어야 한다.
 +
x, y 형태로.
 +
 
 +
x는 넘파이 배열 (배치사이즈, 인풋) 형태로,
 +
 
 +
y는 2개의 배열이 합쳐진 튜플로.(예시를 보니 그냥 레이블을 뱉어내면 되는듯.)
 +
|<syntaxhighlight lang="python">
 +
def __getitem__(self, idx):
 +
        batch_x = self.x[idx * self.batch_size:(idx + 1) *
 +
        self.batch_size]
 +
        batch_y = self.y[idx * self.batch_size:(idx + 1) *
 +
        self.batch_size]
 +
 
 +
        return np.array([
 +
            resize(imread(file_name), (200, 200))
 +
              for file_name in batch_x]), np.array(batch_y)
 +
</syntaxhighlight>
 +
|-
 +
|<code>__len__</code>
 +
|제너레이터의 길이를 반환한다.
 +
일반적으로 총 길이를 배치사이즈로 나눈 후 숫자 올림 한 것.
 +
 
 +
항상 int 타입을 반환해야 한다.
 +
|<syntaxhighlight lang="python">
 +
def __len__(self):
 +
        return math.ceil(len(self.x) / self.batch_size)
 +
</syntaxhighlight>
 +
|}
 +
 
 +
=== 정의된 메서드 ===
 +
{| class="wikitable"
 +
!메서드
 +
!설명
 +
!코드예시
 +
|-
 +
|on_epoch_end
 +
|각 에폭의 끝에서 수행할 일을 지정한다. 데이터셋을 바꾼다든가...
 +
|<syntaxhighlight lang="python">
 +
def on_epoch_end(self):
 +
    if self.shuffle:
 +
        self.df = self.df.sample(frac=1).reset_index(drop=True)
 +
</syntaxhighlight>
 +
|}
 +
 
 +
=== 사용 ===
 +
x, y = generator[133] 형태로 사용할 수 있다. 확인에도 직관적이어서 좋다.<syntaxhighlight lang="python">
 +
generator = DataGenerator(각종 파라미터.)
 +
 
 +
import matplotlib.pyplot as plt
 +
 
 +
for i, (x, y) in enumerate(generator):
 +
    if(i <= 1):
 +
        x_first = x[0]
 +
        plt.title(y[0])
 +
        plt.imshow(x_first)
 +
</syntaxhighlight>
 
[[분류:Keras]]
 
[[분류:Keras]]
 
[[분류:데이터 전처리]]
 
[[분류:데이터 전처리]]

둘러보기 메뉴