Keras/TensorFlow PlatoBlockchain 데이터 인텔리전스에서 코사인 감쇠를 사용한 학습률 워밍업. 수직 검색. 일체 포함.

Keras/TensorFlow에서 코사인 감쇠를 사용한 학습률 워밍업

학습률은 딥 러닝 네트워크에서 중요한 하이퍼파라미터입니다. 정도 어떤 주어진 손실 함수를 최소화하는 것으로 추정되는 가중치에 대한 업데이트가 수행됩니다. 싱가포르 달러:

$$
Weight_{t+1} = Weight_t – lr * frac{derror}{dweight_t}
$$

학습률로 0, 업데이트된 가중치가 다시 자체적으로 - 무게t. 학습률은 학습을 활성화 또는 비활성화하기 위해 돌릴 수 있는 효과적인 노브이며 가중치 업데이트 정도를 직접 제어하여 학습이 얼마나 많이 발생하는지에 큰 영향을 미칩니다.

옵티마이저는 학습률을 다르게 활용하지만 기본 개념은 동일하게 유지됩니다. 말할 필요도 없이, 학습률은 많은 연구, 논문 및 실무자의 벤치마크의 대상이었습니다.

일반적으로 말하면, 거의 모든 사람들이 정적 학습률이 그것을 줄이지 않을 것이라는 데 동의하며, 학습률이 단조, 코사인, 삼각형 또는 기타 유형이든 간에 훈련 중에 학습률을 조정하는 대부분의 기술에서 일부 유형의 학습률 감소가 발생합니다. 절감.

최근 몇 년 동안 발판을 마련한 기술은 학습률 워밍업, 이는 거의 모든 다른 감소 기술과 짝을 이룰 수 있습니다.

학습률 워밍업

학습률 워밍업에 대한 아이디어는 간단합니다. 훈련의 초기 단계에서 무게는 이상적인 상태와 거리가 멀습니다. 이는 전반적으로 대규모 업데이트를 의미하며, 이는 각 가중치에 대한 "과다 수정"으로 볼 수 있습니다. 여기서 다른 가중치의 급격한 업데이트는 다른 가중치의 업데이트를 무효화하여 훈련의 초기 단계를 더 불안정하게 만들 수 있습니다.

이러한 변경 사항은 해결되지만 처음에는 학습률을 낮추고 보다 안정적인 차선책 상태에 도달한 다음 더 큰 학습률을 적용하면 피할 수 있습니다. 네트워크를 업데이트하기보다 쉽게 ​​업데이트할 수 있습니다.

학습률 워밍업입니다! 낮은(또는 0) 학습률로 시작하여 시작 학습률(어쨌든 시작할 수 있는 수준)까지 증가합니다. 이 증가는 실제로 모든 기능을 따를 수 있지만 일반적으로 선형입니다.

초기 속도에 도달한 후 코사인 감쇠, 선형 감소 등과 같은 다른 일정을 적용하여 훈련이 끝날 때까지 속도를 점진적으로 낮출 수 있습니다. 학습률 워밍업은 일반적으로 LR 워밍업이 첫 번째이고 비율이 시작점에 도달한 후 다른 일정이 인계되는 두 가지 일정 일정의 일부입니다.

이 가이드에서는 Keras/TensorFlow에서 학습률 워밍업을 keras.optimizers.schedules.LearningRateSchedule 하위 클래스 및 keras.callbacks.Callback 콜백. 학습률은 다음에서 증가합니다. 0target_lr 매우 일반적인 XNUMX차 일정이므로 코사인 감쇠를 적용합니다. 평소와 같이 Keras를 사용하면 다양한 방식으로 유연한 솔루션을 간단하게 구현하고 네트워크와 함께 제공할 수 있습니다.

참고 : 구현은 일반적이며 다음에서 영감을 받았습니다. Tony의 Keras 구현 "에 설명된 트릭 중Convolutional Neural Networks를 사용한 이미지 분류를 위한 트릭 백”.

Keras 콜백을 사용한 학습률

학습률 일정을 구현하는 가장 간단한 방법은 다음을 수행하는 함수를 만드는 것입니다. lr 매개 변수 (float32), 일부 변환을 통해 전달하고 반환합니다. 이 기능은 다음으로 전달됩니다. LearningRateScheduler 학습률에 함수를 적용하는 콜백.

지금, tf.keras.callbacks.LearningRateScheduler() epoch 번호를 학습률을 계산하는 데 사용하는 함수에 전달합니다. 이는 매우 조악합니다. 각각에 대해 LR 워밍업을 수행해야 합니다. 단계 (배치), 에포크가 아니므로 다음을 도출해야 합니다. global_step (모든 시대에 걸쳐) 대신 학습률을 계산하고 Callback 각 호출마다 인수를 전달해야 하기 때문에 함수를 전달하는 대신 사용자 정의 콜백을 생성하는 클래스를 사용합니다. 이는 함수를 전달할 때 불가능합니다.

def func():
    return ...
    
keras.callbacks.LearningRateScheduler(func)

이 접근 방식은 높은 수준의 사용자 지정을 원하지 않고 Keras가 처리하는 방식을 방해하고 싶지 않을 때 유리합니다. lr, 특히 다음과 같은 콜백을 사용하려는 경우 ReduceLROnPlateau() float 기반에서만 작동할 수 있기 때문에 lr. 편의 기능으로 시작하여 Keras 콜백을 사용하여 학습률 워밍업을 구현해 보겠습니다.

def lr_warmup_cosine_decay(global_step,
                           warmup_steps,
                           hold = 0,
                           total_steps=0,
                           start_lr=0.0,
                           target_lr=1e-3):
    
    learning_rate = 0.5 * target_lr * (1 + np.cos(np.pi * (global_step - warmup_steps - hold) / float(total_steps - warmup_steps - hold)))

    
    warmup_lr = target_lr * (global_step / warmup_steps)

    
    
    if hold > 0:
        learning_rate = np.where(global_step > warmup_steps + hold,
                                 learning_rate, target_lr)
    
    learning_rate = np.where(global_step < warmup_steps, warmup_lr, learning_rate)
    return learning_rate

각 단계에서 학습률과 워밍업 학습률(스케줄의 두 요소 모두)을 계산합니다. start_lrtarget_lr. start_lr 일반적으로 시작됩니다 0.0반면, target_lr 네트워크 및 옵티마이저에 따라 다릅니다. 1e-3 좋은 기본값이 아닐 수 있으므로 메서드를 호출할 때 LR을 시작하는 대상을 설정해야 합니다.

경우 global_step 훈련에서 더 높은 warmup_steps 우리는 설정했습니다 – 우리는 코사인 감쇠 일정 LR을 사용합니다. 그렇지 않은 경우 아직 워밍업 중이므로 워밍업 LR이 사용됩니다. 만약 hold 인수가 설정되었습니다. target_lr 워밍업 후 및 코사인 감쇠 전의 해당 단계 수에 대해. np.where() 이에 대한 훌륭한 구문을 제공합니다.

np.where(condition, value_if_true, value_if_false)

다음을 사용하여 함수를 시각화할 수 있습니다.

steps = np.arange(0, 1000, 1)
lrs = []

for step in steps:
  lrs.append(lr_warmup_cosine_decay(step, total_steps=len(steps), warmup_steps=100, hold=10))
plt.plot(lrs)

이제 이 함수를 콜백의 일부로 사용하고 최적화 단계를 global_step 임의의 배열 요소가 아닌 클래스 내에서 계산을 수행할 수 있습니다. 서브클래스를 하자 Callback 수업:

from keras import backend as K

class WarmupCosineDecay(keras.callbacks.Callback):
    def __init__(self, total_steps=0, warmup_steps=0, start_lr=0.0, target_lr=1e-3, hold=0):

        super(WarmupCosineDecay, self).__init__()
        self.start_lr = start_lr
        self.hold = hold
        self.total_steps = total_steps
        self.global_step = 0
        self.target_lr = target_lr
        self.warmup_steps = warmup_steps
        self.lrs = []

    def on_batch_end(self, batch, logs=None):
        self.global_step = self.global_step + 1
        lr = model.optimizer.lr.numpy()
        self.lrs.append(lr)

    def on_batch_begin(self, batch, logs=None):
        lr = lr_warmup_cosine_decay(global_step=self.global_step,
                                    total_steps=self.total_steps,
                                    warmup_steps=self.warmup_steps,
                                    start_lr=self.start_lr,
                                    target_lr=self.target_lr,
                                    hold=self.hold)
        K.set_value(self.model.optimizer.lr, lr)

모범 사례, 업계에서 인정하는 표준 및 포함된 치트 시트가 포함된 Git 학습에 대한 실습 가이드를 확인하십시오. 인터넷 검색 Git 명령을 중지하고 실제로 배움 이것!

먼저 클래스의 생성자를 정의하고 해당 필드를 추적합니다. 종료된 각 배치에서 전역 단계를 늘리고 현재 LR을 기록해 지금까지의 LR 목록에 추가합니다. 각 배치 시작 시 – 다음을 사용하여 LR을 계산합니다. lr_warmup_cosine_decay() 기능을 설정하고 해당 LR을 최적화 프로그램의 현재 LR로 설정합니다. 이것은 백엔드로 수행됩니다. set_value().

완료되면 총 단계(length/batch_size*epochs)를 계산하고 해당 숫자의 일부를 귀하의 warmup_steps:


total_steps = len(train_set)*config['EPOCHS']



warmup_steps = int(0.05*total_steps)

callback = WarmupCosineDecay(total_steps=total_steps, 
                             warmup_steps=warmup_steps,
                             hold=int(warmup_steps/2), 
                             start_lr=0.0, 
                             target_lr=1e-3)

마지막으로 모델을 구성하고 콜백을 fit() 요구:

model = keras.applications.EfficientNetV2B0(weights=None, 
                                            classes=n_classes, 
                                            input_shape=[224, 224, 3])
  
model.compile(loss="sparse_categorical_crossentropy",
                  optimizer='adam',
                  jit_compile=True,
                  metrics=['accuracy'])

교육이 끝나면 다음을 통해 변경된 LR을 얻고 시각화할 수 있습니다.

lrs = callback.lrs 
plt.plot(lrs)

Keras/TensorFlow PlatoBlockchain 데이터 인텔리전스에서 코사인 감쇠를 사용한 학습률 워밍업. 수직 검색. 일체 포함.

LR 워밍업을 사용하거나 사용하지 않고 훈련된 모델의 이력을 플롯하면 훈련의 안정성에 뚜렷한 차이가 있음을 알 수 있습니다.

Keras/TensorFlow PlatoBlockchain 데이터 인텔리전스에서 코사인 감쇠를 사용한 학습률 워밍업. 수직 검색. 일체 포함.

LearningRateSchedule 하위 클래스를 사용한 학습률

콜백 생성의 대안은 LearningRateSchedule LR을 조작하지 않는 하위 클래스 - 대체합니다. 이 접근 방식을 사용하면 Keras/TensorFlow의 백엔드에 대해 더 많은 정보를 제공할 수 있지만 사용할 경우 다음과 같은 다른 LR 관련 콜백과 결합할 수 없습니다. ReduceLROnPlateau(), LR을 부동 소수점 숫자로 처리합니다.

또한 하위 클래스를 사용하려면 직렬화 가능하게 만들어야 합니다(오버로드 get_config()) 모델의 일부가 되므로 모델 가중치를 저장합니다. 주목해야 할 또 다른 점은 클래스는 tf.Tensor에스. 고맙게도 우리가 일하는 방식의 유일한 차이점은 tf.func() 대신 np.func() TensorFlow와 NumPy API는 놀라울 정도로 유사하고 호환되기 때문입니다.

편리함을 다시 쓰자 lr_warmup_cosine_decay() 대신 TensorFlow 작업을 사용하는 함수:

def lr_warmup_cosine_decay(global_step,
                           warmup_steps,
                           hold = 0,
                           total_steps=0,
                           start_lr=0.0,
                           target_lr=1e-3):
    
    
    learning_rate = 0.5 * target_lr * (1 + tf.cos(tf.constant(np.pi) * (global_step - warmup_steps - hold) / float(total_steps - warmup_steps - hold)))

    
    warmup_lr = target_lr * (global_step / warmup_steps)

    
    
    if hold > 0:
        learning_rate = tf.where(global_step > warmup_steps + hold,
                                 learning_rate, target_lr)
    
    learning_rate = tf.where(global_step < warmup_steps, warmup_lr, learning_rate)
    return learning_rate

convinience 함수를 사용하여 하위 분류할 수 있습니다. LearningRateSchedule 수업. 각각에 __call__() (배치), 함수를 사용하여 LR을 계산하고 반환합니다. 서브클래싱된 클래스 내에서 자연스럽게 계산을 패키징할 수도 있습니다.

구문은 다음보다 깨끗합니다. Callback sublcass, 주로 우리가 액세스할 수 있기 때문에 step 필드를 자체적으로 추적하기보다는 클래스 속성으로 작업하기가 다소 어렵게 만듭니다. 특히 추출하기 어렵게 만듭니다. lr 에서 tf.Tensor() 목록에서 추적하기 위해 다른 유형으로 변환합니다. 이것은 Eager 모드에서 실행하여 기술적으로 우회할 수 있지만 디버깅 목적으로 LR을 추적하는 데 성가심을 나타내므로 피하는 것이 가장 좋습니다.

class WarmUpCosineDecay(keras.optimizers.schedules.LearningRateSchedule):
    def __init__(self, start_lr, target_lr, warmup_steps, total_steps, hold):
        super().__init__()
        self.start_lr = start_lr
        self.target_lr = target_lr
        self.warmup_steps = warmup_steps
        self.total_steps = total_steps
        self.hold = hold

    def __call__(self, step):
        lr = lr_warmup_cosine_decay(global_step=step,
                                    total_steps=self.total_steps,
                                    warmup_steps=self.warmup_steps,
                                    start_lr=self.start_lr,
                                    target_lr=self.target_lr,
                                    hold=self.hold)

        return tf.where(
            step > self.total_steps, 0.0, lr, name="learning_rate"
        )

매개변수는 동일하며 이전과 거의 동일한 방식으로 계산할 수 있습니다.


total_steps = len(train_set)*config['EPOCHS']



warmup_steps = int(0.05*total_steps)

schedule = WarmUpCosineDecay(start_lr=0.0, target_lr=1e-3, warmup_steps=warmup_steps, total_steps=total_steps, hold=warmup_steps)

그리고 훈련 파이프라인은 옵티마이저의 LR을 schedule:

model = keras.applications.EfficientNetV2B0(weights=None, 
                                            classes=n_classes, 
                                            input_shape=[224, 224, 3])
  
model.compile(loss="sparse_categorical_crossentropy",
                  optimizer=tf.keras.optimizers.Adam(learning_rate=schedule),
                  jit_compile=True,
                  metrics=['accuracy'])

history3 = model.fit(train_set,
                    epochs = config['EPOCHS'],
                    validation_data=valid_set)

모델을 저장하려면 WarmupCosineDecay 일정은 재정의해야 합니다 get_config() 방법:

    def get_config(self):
        config = {
          'start_lr': self.start_lr,
          'target_lr': self.target_lr,
          'warmup_steps': self.warmup_steps,
          'total_steps': self.total_steps,
          'hold': self.hold
        }
        return config

마지막으로 모델을 로드할 때 다음을 전달해야 합니다. WarmupCosineDecay 사용자 정의 개체로:

model = keras.models.load_model('weights.h5', 
                                custom_objects={'WarmupCosineDecay', WarmupCosineDecay})

결론

이 가이드에서는 신경망을 훈련하는 동안 학습률을 조작하는 일반적인 기술인 학습률 워밍업 이면의 직관을 살펴보았습니다.

워밍업과 짝을 이루는 가장 일반적인 유형의 LR 감소인 코사인 감쇠로 학습률 워밍업을 구현했습니다. 감소를 위해 다른 기능을 구현하거나 학습률을 전혀 줄이지 않고 다음과 같은 다른 콜백에 맡길 수 있습니다. ReduceLROnPlateau(). Keras Callback과 Keras Optimizer Schedule로 학습률 워밍업을 구현하고 에포크를 통해 학습률을 플로팅했습니다.

타임 스탬프 :

더보기 스택카부스