2024_하계 모각코를 진행하였다.

1회차: 2024-07-14

2회차: 2024-07-21

3회차: 2024-08-01

4회차: 2024-08-05

5회차: 2024-08-08

6회차: 2024-08-18

Binary Cross-Entropy (BCE) Loss(BCE 손실함수)

머신 러닝 및 최적화 에서 손실 함수를 정의하는 데 사용할 수 있습니다.

BCELoss 크로스 엔트로피 손실 함수는 정보 이론에서 크로스 엔트로피 개념을 기계 학습에 적용한 것이다. 이 함수는 두 확률 분포 간의 차이를 측정하는 방법으로, BCE 손실 함수는 크로스 엔트로피 손실 함수를 이진 분류 문제에 적용한 형태이다.

[ H(P, Q) = -\sum_{x} P(x) \log Q(x) ]

BCELoss는 모델의 구조 상에 마지막 Layer가 Sigmoid 혹은 Softmax로 되어 있는 경우 이를 사용한다. 즉, 모델의 출력이 각 라벨에 대한 확률값으로 구성되었을 때 사용이 가능하다. torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')

import torch import torch.nn as nn m = nn.Sigmoid() loss = nn.BCELoss() input = torch.randn(3, 2, requires_grad=True) target = torch.rand(3, 2) output = loss(m(input), target) output.backward()

BCEWithLogitsLoss torch.nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction='mean', pos_weight=None)

BCEWithLogitsLoss는 이름에서도 유추해볼 수 있듯 BCELoss를 위 과정에서 확률값(Logits)으로 변환하지 않더라도 계산되는 것을 의미한다. 기본적인 BCE 손실 함수는 모델의 출력이 시그모이드 함수를 통과한 확률 값이어야 한다. 그러나 이 경우수치적 불안정성(시그모이드 함수의 출력은 0과 1 사이의 값이기 때문에, 극단적인 값(예: 매우 큰 음수나 양수)에 대해 수치적으로 불안정할 수 있다.) 효율성 문제(시그모이드 함수와 BCE 손실 함수를 따로 적용하면 계산 비용이 증가할 수 있다.)가 존재할 수 있다

따라서 BCEWithLogitsLoss는 시그모이드 활성화 함수를 적용한 후 BCE 손실을 계산하는 과정을 하나의 함수로 처리한다. 내부적으로 시그모이드 함수를 적용하고 BCE 손실을 계산하므로, 더 안정적이고 효율적이다.

[ \text{BCEWithLogitsLoss} = -\frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log(\sigma(z_i)) + (1 - y_i) \log(1 - \sigma(z_i)) \right] ]

여기서:

  • ( N )은 샘플의 수
  • ( y_i )는 실제 레이블 (0 또는 1)
  • ( z_i )는 모델의 출력(로그 확률)
  • ( \sigma(z) )는 시그모이드 함수로, (\sigma(z) = \frac{1}{1 + e^{-z}} )

CrossEntropyLoss torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean', label_smoothing=0.0) weight:

타입: Tensor, 선택 사항 설명: 각 클래스에 대한 가중치를 지정할 수 있습니다. 클래스 불균형 문제를 해결하기 위해 사용됩니다. None으로 설정하면 모든 클래스에 동일한 가중치가 적용됩니다. size_average:

타입: bool, 선택 사항 (기본값: None) 설명: 이 파라미터는 더 이상 사용되지 않습니다. reduction 파라미터로 대체되었습니다. True로 설정하면 손실이 평균화되고, False로 설정하면 합산됩니다. ignore_index:

타입: int, 선택 사항 설명: 특정 클래스 인덱스를 무시할 수 있습니다. 주로 시퀀스 모델링에서 패딩 토큰을 무시하는 데 사용됩니다. 기본값은 -100입니다. reduce:

타입: bool, 선택 사항 (기본값: None) 설명: 이 파라미터도 더 이상 사용되지 않습니다. reduction 파라미터로 대체되었습니다. True로 설정하면 손실이 축소되고, False로 설정하면 축소되지 않습니다. reduction:

타입: str, 선택 사항 설명: 손실 결과를 어떻게 축소할지를 정의합니다. 세 가지 옵션이 있습니다: ‘none’: 손실을 축소하지 않고 각 샘플에 대한 손실을 반환합니다. ‘mean’: 손실을 평균화합니다. (size_average=True와 동일) ‘sum’: 손실을 합산합니다. (reduce=False와 동일) label_smoothing:

타입: float, 선택 사항 설명: 라벨 스무딩을 적용합니다. label_smoothing 값을 [0, 1] 사이로 설정하면, 라벨을 약간의 확률로 스무딩합니다. 이는 모델이 과도하게 확신하는 것을 방지하고 일반화 성능을 향상시킬 수 있습니다. 기본값은 0.0입니다.

이전에 다룬 BCELoss와 BCEWithLogitsLoss는 Binary Classification을 위한 손실 함수다. 반면에 CrossEntropyLoss는 다중 분류를 위한 손실 함수다. 예를 들어, 라벨이 5개라고 한다면 입력은 각 라벨에 대한 확률값을 표현하고, 정답 라벨은 라벨 값 혹은 라벨에 대한 확률값으로 표현할 수 있다. 소프트맥스 활성화 함수와 크로스 엔트로피 손실을 결합한 함수로 예측 값과 실제 값 간의 차이를 직관적으로 표현할 수 있지만, 확률이 매우 작은 경우, 로그 함수로 인해 수치적 불안정성이 발생할 수 있고, 클래스가 불균형한 경우 성능이 저하될 수 있습니다. 이 문제를 해결하기 위해 가중치 조정 등을 사용할 수 있다.

[ \text{CrossEntropyLoss} = -\sum_{i=1}^{N} \sum_{c=1}^{C} y_{ic} \log(p_{ic}) ]

  • ( N )은 샘플의 수
  • ( C )는 클래스의 수
  • ( y_{ic} )는 실제 레이블의 원-핫 인코딩 (실제 레이블이 ( c ) 클래스일 때 1, 그렇지 않으면 0)
  • ( p_{ic} )는 모델이 샘플 ( i )에 대해 클래스 ( c )일 확률로 예측한 값 (소프트맥스 함수의 출력)

3회차: 2024-08-01

Binary Cross-Entropy (BCE) Loss의 수식을 수학적으로 설명하겠습니다. BCE Loss는 이진 분류 문제에서 모델의 예측 확률과 실제 라벨 간의 차이를 측정하는 손실 함수입니다. 이를 통해 모델의 성능을 평가하고, 최적화할 수 있습니다.

BCE Loss:

[ L = - 1/N {sum_i=1~N} [ y_i * log(p_i) + (1 - y_i) * log(1 - p_i) ]

  • ( L )은 손실 함수의 값
  • ( N )은 총 샘플 수
  • ( y_i )는 i번째 샘플의 실제 라벨(이진 분류 문제에서는 0 또는 1)
  • ( p_i )는 i번째 샘플이 클래스 1일 확률로 모델이 예측한 값 (0과 1 사이의 값)
  1. 로그항 (( log(p_i) )와 ( log(1 - p_i) )):
    • 로그는 정보 이론에서 엔트로피를 계산할 때 사용됩니다. 여기서 로그를 사용하는 이유는 예측 확률이 낮을 때 페널티를 크게 주기 위함입니다.
    • ( \log(p_i) ): 모델이 클래스 1일 확률을 예측한 값에 로그를 취한다.
    • ( \log(1 - p_i) ): 모델이 클래스 0일 확률을 예측한 값에 로그를 취합니다.

( p_i )가 1에 가까워질수록 ( \log(p_i) )는 0에 가까워지고, ( p_i )가 0에 가까워질수록 ( \log(p_i) )는 음의 무한대로 커진다. 로그 함수를 사용하면 예측 확률이 낮을 때 손실 값이 급격히 커지게 된다. 이는 모델이 잘못된 예측을 할 경우 큰 페널티를 부과하여, 모델이 더 정확한 예측을 하도록 유도한다.

  1. 실제 라벨 (( y_i ))에 따른 조건부 손실:
    • ( y_i = 1 )일 때, 손실 항목은 ( \log(p_i) )가 된다. 이는 모델이 클래스 1일 확률을 얼마나 잘 예측했는지를 나타낸다.
    • ( y_i = 0 )일 때, 손실 항목은 ( \log(1 - p_i) )가 된다. 이는 모델이 클래스 0일 확률을 얼마나 잘 예측했는지를 나타낸다.
  2. 전체 손실 계산:
    • ( -[ y_i * log(p_i) + (1 - y_i) * log(1 - p_i) ] )는 i번째 샘플의 손실을 계산한다.
    • 각 샘플의 손실을 모두 더한 후, ( N )으로 나누어 평균 손실을 구한다. 이는 샘플 수에 관계없이 일관된 손실 값을 제공한다.
  3. 부호:
    • 확률p가 0.5보다 작으면 로그 값은 음수가 되기 때문에 해석하기 어려워질 수 있고, 해석이 일관되게 하기 위해서, BCE Loss는 로그 값의 음수를 취하여 손실 값을 양수로 만든다. ( 손실 값을 양수로 만들기 위해 전체에 -1을 곱합니다.)

BCE Loss는 모델이 예측한 확률 ( p_i )와 실제 라벨 ( y_i ) 간의 차이를 로그 함수와 결합하여 측정하며, 이를 통해 모델이 얼마나 잘 예측하는지를 평가한다. 이 손실 함수를 최소화함으로써 모델의 성능을 최적화할 수 있다.

Energy-Based Model (EBM) Energy-Based Models (EBMs)는 데이터 x의 에너지를 계산하여 확률 분포를 모델링하는 방식의 생성 모델이다. 확률을 에너지 함수로 표현하고, 이 에너지를 최소화하는 데이터를 더 높은 확률로 간주하는 것.

데이터의 에너지 (Energy of Data) 에너지 기반 모델(Energy-Based Model, EBM)에서 “에너지”는 데이터 x가 특정 상태에 있을 때의 “비용” 또는 “불일치”를 나타내는 값이다. 에너지가 낮을수록 해당 데이터가 모델이 예상하는 더 가능성 있는 상태를 나타냅니다. 즉, 에너지가 낮은 데이터는 모델에 의해 더 높은 확률로 간주됩니다. 에너지 함수 (Energy Function) 에너지 함수 E(x)는 주어진 데이터 x의 에너지를 계산하는 함수입니다. 이 함수는 데이터 x와 모델 파라미터 θ를 입력으로 받아 에너지 값을 출력합니다. 에너지 함수는 모델의 학습 과정에서 중요한 역할을 하며, 데이터의 패턴이나 구조를 반영하도록 설계됩니다.

Energy-Based Models (EBMs)의 학습 목적은 주어진 데이터 분포를 잘 모델링하고, 이를 통해 새로운 데이터를 생성하거나, 주어진 데이터의 패턴과 구조를 이해하는 것입니다. 에너지 함수 정의:

데이터 𝑥 에 대한 에너지 함수 𝐸(𝑥: 𝜃) 를 정의 이 함수는 모델의 파라미터 𝜃를 포함, 데이터의 패턴과 구조를 반영

데이터는 모델이 학습할 분포를 대표할 수 있어야한다.

에너지 함수 최적화: 에너지 함수의 파라미터 θ를 최적화하여, 낮은 에너지를 가지는 데이터가 높은 확률을 갖도록 이 과정에서 손실 함수(Loss Function)를 정의하고, 이를 최소화하는 방향으로 파라미터를 업데이트

정규화 상수 근사: 정규화 상수 (Z)는 직접 계산하기 어려운 경우가 많아, Markov Chain Monte Carlo (MCMC)와 같은 샘플링 기법을 사용하여 근사 모델의 확률 분포를 정규화

4회차: 2024-08-05

Energy-Based Model (EBM) Energy-Based Model은 데이터 x의 에너지를 계산하여 확률 분포를 모델링하는 방식의 생성 모델이다. 확률을 에너지 함수로 표현하고, 이 에너지를 최소화하는 데이터를 더 높은 확률로 간주하는 것.

데이터의 에너지 (Energy of Data) 에너지 기반 모델(Energy-Based Model, EBM)에서 “에너지”는 데이터 x가 특정 상태에 있을 때의 “비용” 또는 “불일치”를 나타내는 값이다. 에너지가 낮을수록 해당 데이터가 모델이 예상하는 더 가능성 있는 상태를 나타냅니다. 즉, 에너지가 낮은 데이터는 모델에 의해 더 높은 확률로 간주됩니다. 에너지 함수 (Energy Function) 에너지 함수 E(x)는 주어진 데이터 x의 에너지를 계산하는 함수입니다. 이 함수는 데이터 x와 모델 파라미터 θ를 입력으로 받아 에너지 값을 출력합니다. 에너지 함수는 모델의 학습 과정에서 중요한 역할을 하며, 데이터의 패턴이나 구조를 반영하도록 설계됩니다.

Energy-Based Models (EBMs)의 학습 목적은 주어진 데이터 분포를 잘 모델링하고, 이를 통해 새로운 데이터를 생성하거나, 주어진 데이터의 패턴과 구조를 이해하는 것입니다. 에너지 함수 정의:

데이터 𝑥 에 대한 에너지 함수 𝐸(𝑥: 𝜃) 를 정의 이 함수는 모델의 파라미터 𝜃를 포함, 데이터의 패턴과 구조를 반영

데이터는 모델이 학습할 분포를 대표할 수 있어야한다.

에너지 함수 최적화: 에너지 함수의 파라미터 θ를 최적화하여, 낮은 에너지를 가지는 데이터가 높은 확률을 갖도록 이 과정에서 손실 함수(Loss Function)를 정의하고, 이를 최소화하는 방향으로 파라미터를 업데이트

정규화 상수 근사: 정규화 상수 (Z)는 직접 계산하기 어려운 경우가 많아, Markov Chain Monte Carlo (MCMC)와 같은 샘플링 기법을 사용하여 근사 모델의 확률 분포를 정규화

5회차: 2024-08-08

에너지 기반 모델(EBM, Energy-Based Model)은 머신러닝과 통계물리학의 중요한 개념을 바탕으로 한 모델. EBM의 핵심 아이디어는 뉴럴 네트워크가 어떤 스칼라 값을 출력하고, 이 값이 볼츠만 분포(Boltzmann distribution: 해당 상태의 에너지와 온도의 함수로 특정 상태 에 있을 확률을 제공 하는 확률 분포 )를 따르는 방식으로 로스를 정의한다는 점이다.

에너지 기반 모델의 장점

범용성 EBM은 특정 모델 구조에 국한되지 않고 다양한 모델에 적용할 수 있습니다. 오토인코더(AE), 정규 흐름(NF) 등 다양한 머신러닝 모델과 조합하여 사용할 수 있다. loss 의 형태가 중요하기 때문에 모델 설계의 유연성이 높다.

다양한 트레이닝 방식 Positive/Negative 에너지 그라디언트: 긍정/부정 에너지의 차이를 줄이는 방식으로 트레이닝이 가능하다. Positive/Partition 함수: 볼츠만 분포의 정의를 사용하여 직접 학습하는 방식이다. Score Matching: 데이터의 기울기를 맞추는 방식으로 트레이닝을 수행할 수 있다.

이러한 다양한 학습 방식은 EBM의 트레이닝을 상황에 맞게 최적화할 수 있게 해준다.

샘플 생성의 용이성 EBM을 사용하면 샘플 생성이 비교적 용이하다. 해밀토니안 몬테카를로(HMC)나 랑주뱅 다이내믹스(Langevin dynamics)와 같은 방법을 통해 효과적으로 샘플을 생성할 수 있다. 이로 인해 모델이 데이터 분포를 잘 학습하고 새로운 데이터를 생성할 수 있는 능력이 향상된다.

에너지 기반 해석 가능성 모델의 출력 값을 에너지로 해석할 수 있으므로, 모델의 동작을 이해하고 설명하는 데 용이하다. 이는 모델의 투명성과 신뢰성을 높이는 데 기여한다.

확률 분포 학습 EBM은 데이터의 확률 분포를 직접 학습할 수 있다. 복잡한 데이터 분포를 효과적으로 모델링할 수 있게 해주며, 생성 모델로서의 성능을 강화한다.

불확실성 평가 EBM은 모델 출력의 에너지 값을 통해 불확실성을 평가할 수 있다. 모델이 예측할 때 어느 정도의 신뢰도를 갖는지 평가할 수 있게 해준다.

트레이닝 안정성 다양한 트레이닝 방법을 통해 모델의 안정성을 높일 수 있으며, 에너지 기반 그라디언트 방법은 안정적인 학습을 가능하게 한다. 기존 모델과의 통합

EBM은 기존의 딥러닝 모델과 통합하여 성능을 향상시킬 수 있습니다. 이는 EBM이 다양한 애플리케이션에 적용될 수 있는 중요한 이유 중 하나입니다.

단점

높은 계산 비용 에너지 기반 모델의 학습과 샘플링 과정은 계산 비용이 매우 높을 수 있다. 특히 해밀토니안 몬테카를로(HMC)나 랑주뱅 다이내믹스(Langevin dynamics)와 같은 샘플링 기법은 많은 계산 자원을 요구한다.

해밀토니안 몬테카를로 (Hamiltonian Monte Carlo, HMC)
물리학의 해밀토니안 역학(Hamiltonian dynamics)을 기반으로 한 마코프 체인 몬테카를로(MCMC) 방법. 
고차원 확률 분포의 샘플링을 개선하기 위해 설계되었다.
장점
효율적인 샘플링: 샘플링 경로를 길게 만들어 샘플 간의 상관성을 줄이고, 고차원 공간에서도 효율적으로 샘플링할 수 있다.
빠른 수렴: 에너지 경사를 이용해 샘플을 이동시키므로, 분포의 고차원 공간에서 빠르게 수렴할 수 있다.
단점
복잡한 구현: 해밀토니안 역학과 보존 법칙을 이용한 복잡한 수학적 개념을 필요로 하므로 구현이 어려울 수 있다.
조정이 어렵다: Leapfrog 스텝 사이즈와 같은 하이퍼파라미터를 잘 조정해야 효과적인 샘플링이 가능하다.
과정
잠재 변수 생성: 대상 변수에 대해 잠재 변수를 도입
해밀토니안 설정: 잠재 변수와 대상 변수의 결합 분포를 나타내는 해밀토니안을 설정
Leapfrog 통합: 해밀토니안 역학을 따라 잠재 변수와 대상 변수를 업데이트
메트로폴리스-헤이스팅스 알고리즘: 새로운 샘플을 수락하거나 거부하는 기준을 적용


랑주뱅 다이내믹스 (Langevin Dynamics)

확률론적 접근 방식으로, 대상 확률 분포에 노이즈를 추가하여 샘플을 생성하는 방법으로, 확률적 경사 하강법(Stochastic Gradient Descent, SGD)의 확장으로 볼 수 있다.

장점
단순한 구현: HMC에 비해 수학적 개념이 덜 복잡하여 구현이 비교적 쉽다.
노이즈 추가: 모델에 노이즈를 추가하여 다양한 샘플을 생성할 수 있다.
단점
효율성 저하: HMC에 비해 고차원 공간에서 샘플링 효율이 떨어질 수 있다.
적절한 스텝 사이즈 필요: 너무 큰 스텝 사이즈는 정확한 샘플링을 방해하고, 너무 작은 스텝 사이즈는 수렴 속도를 느리게 한다.
과정
초기화: 샘플 초기값을 설정한다.
확률적 경사 계산: 현재 샘플 위치에서 확률적 경사를 계산한다.
노이즈 추가: 샘플 이동 시 노이즈를 추가한다.
샘플 업데이트: 경사와 노이즈를 사용하여 샘플을 업데이트한다.


HMC는 해밀토니안 역학을 활용하여 고차원 분포에서 효율적으로 샘플링할 수 있지만, 구현과 조정이 어려울 수 있다.
Langevin dynamics는 구현이 비교적 쉬운 대신 고차원에서의 샘플링 효율이 떨어질 수 있다.

학습의 어려움 에너지 함수의 최적화를 위한 학습 과정은 복잡하고 까다로울 수 있습니다. 특히, 학습 과정에서 발생하는 수렴 문제나 에너지 경사 하강법의 불안정성은 모델 학습을 어렵게 할 수 있다.

정규화 상수 계산의 어려움 에너지 기반 모델에서 정규화 상수(Z)를 계산하는 것은 매우 어려운 문제이다. 이 상수는 분포를 정상화하는 데 필요하지만, 고차원 공간에서는 계산이 거의 불가능할 수 있다.

모델 평가의 복잡성 에너지 기반 모델의 성능을 평가하는 것은 다른 모델에 비해 더 복잡할 수 있다. 에너지 함수의 값만으로는 모델의 품질을 직관적으로 평가하기 어려울 수 있다.

샘플링의 어려움 샘플링 과정이 복잡하고 시간이 많이 소요될 수 있다. 특히 고차원 데이터에서는 효율적인 샘플링이 어려워질 수 있다.

해석의 어려움 에너지 함수의 형태나 모델의 구조가 복잡한 경우, 모델의 동작을 해석하고 이해하는 것이 어려울 수 있다. 이는 모델의 투명성과 설명 가능성을 저하시킬 수 있다.

하이퍼파라미터 튜닝의 복잡성 EBM은 여러 하이퍼파라미터를 가지고 있으며, 이들의 적절한 값을 찾는 것이 까다로울 수 있다. 잘못된 하이퍼파라미터 설정은 모델의 성능에 큰 영향을 미칠 수 있다.

학습 데이터의 의존성 EBM은 충분한 양의 고품질 학습 데이터가 필요하다. 데이터가 부족하거나 품질이 낮은 경우, 모델의 성능이 크게 저하될 수 있다. 이러한 단점들은 EBM을 실제로 적용할 때 고려해야 할 중요한 요소들이다. 모델의 강점을 최대한 활용하면서도 단점을 보완하는 방법을 찾는 것이 성공적인 EBM 응용의 핵심이다.

6회차: 2024-08-18

대조 학습에서 주로 사용되는 방식 중 긍정(positive) 쌍과 부정(negative) 쌍을 구분하여 손실을 계산 ‘’’ import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim

간단한 대조 학습 모델 정의

class SimpleContrastiveModel(nn.Module): def init(self, embedding_dim=128): super(SimpleContrastiveModel, self).init() # CNN 기반 인코더 정의: 입력 이미지를 임베딩 벡터로 변환 self.encoder = nn.Sequential( nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1), # 1번째 레이어 (3 -> 64) nn.ReLU(), # 활성화 함수 ReLU nn.MaxPool2d(kernel_size=2, stride=2), # 풀링 레이어 nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1), # 2번째 레이어 (64 -> 128) nn.ReLU(), # 활성화 함수 ReLU nn.MaxPool2d(kernel_size=2, stride=2), # 풀링 레이어 nn.Flatten(), # 출력 데이터를 1차원 벡터로 변환 nn.Linear(128 * 8 * 8, embedding_dim) # 완전 연결 레이어, 임베딩 차원으로 변환 )

def forward(self, x):
    # 입력 이미지 x를 임베딩 벡터로 변환하고 정규화
    return F.normalize(self.encoder(x), dim=-1)

대조 학습 손실 함수 정의

def contrastive_loss(out1, out2, label): # 코사인 유사도 계산: 두 임베딩 벡터 간의 유사도 측정 cosine_similarity = F.cosine_similarity(out1, out2) # BCEWithLogitsLoss를 사용하여 대조 학습 손실 계산 bce_loss = nn.BCEWithLogitsLoss() # 코사인 유사도와 실제 lable을 사용하여 손실 계산 loss = bce_loss(cosine_similarity, label) return lossine_similarity, label) return loss

모델 초기화

model = SimpleContrastiveModel(embedding_dim=128)

Adam 옵티마이저 설정

optimizer = optim.Adam(model.parameters(), lr=0.001)

예제 데이터 생성 (batch size: 16, channel: 3, height: 32, width: 32)

batch_size = 16 x1 = torch.randn(batch_size, 3, 32, 32) x2 = torch.randn(batch_size, 3, 32, 32)

labels = torch.randint(0, 2, (batch_size,)).float() # 1: 같은 클래스, 0: 다른 클래스

모델 출력 계산

out1 = model(x1) out2 = model(x2)

대조 학습 손실 계산

loss = contrastive_loss(out1, out2, labels)

역전파 및 파라미터 업데이트

optimizer.zero_grad() loss.backward() optimizer.step()

print(f’Loss: {loss.item()}’) ‘’’ ————————————————————————————————– ‘’’ import torch import torch.nn as nn import torch.optim as optim

SimpleContrastiveModel 클래스와 contrastive_loss 함수가 정의되어 있다고 가정합니다.

모델 초기화

model = SimpleContrastiveModel(embedding_dim=128)

옵티마이저 설정

optimizer = optim.Adam(model.parameters(), lr=0.001)

훈련 데이터 생성 (배치 크기: 16, 채널: 3, 높이: 32, 너비: 32)

batch_size = 16 x1_train = torch.randn(batch_size, 3, 32, 32) x2_train = torch.randn(batch_size, 3, 32, 32) train_labels = torch.randint(0, 2, (batch_size,)).float()

테스트 데이터 생성 (배치 크기: 8, 채널: 3, 높이: 32, 너비: 32)

x1_test = torch.randn(8, 3, 32, 32) x2_test = torch.randn(8, 3, 32, 32) test_labels = torch.randint(0, 2, (8,)).float()

모델 훈련

num_epochs = 10 for epoch in range(num_epochs): # 모델 출력 계산 out1_train = model(x1_train) out2_train = model(x2_train)

# 대조 학습 손실 계산
loss = contrastive_loss(out1_train, out2_train, train_labels)

# 역전파 및 파라미터 업데이트
optimizer.zero_grad()
loss.backward()
optimizer.step()

print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}')

모델 테스트

with torch.no_grad(): out1_test = model(x1_test) out2_test = model(x2_test)

# 코사인 유사도 계산
cosine_similarity_test = torch.sigmoid(F.cosine_similarity(out1_test, out2_test))

# 예측 결과
predictions = (cosine_similarity_test > 0.5).float()

# 정확도 계산
accuracy = (predictions == test_labels).float().mean()

print(f'Test Accuracy: {accuracy.item() * 100:.2f}%')

# 각 테스트 샘플에 대한 코사인 유사도와 실제 레이블 출력
print("Cosine Similarity and Labels:")
for i in range(len(test_labels)):
    print(f"Sample {i+1}: Cosine Similarity = {cosine_similarity_test[i].item():.4f}, Label = {test_labels[i].item()}, Prediction = {predictions[i].item()}")

’’’ Epoch [1/10], Loss: 0.8842123746871948 Epoch [2/10], Loss: 0.9274642467498779 Epoch [3/10], Loss: 0.9250276684761047 Epoch [4/10], Loss: 0.9145865440368652 Epoch [5/10], Loss: 0.866182267665863 Epoch [6/10], Loss: 0.5781313180923462 Epoch [7/10], Loss: 0.557551383972168 Epoch [8/10], Loss: 0.5832924842834473 Epoch [9/10], Loss: 0.41409537196159363 Epoch [10/10], Loss: 0.4382629096508026 Test Accuracy: 12.50% Cosine Similarity and Labels: Sample 1: Cosine Similarity = 0.7111, Label = 0.0, Prediction = 1.0 Sample 2: Cosine Similarity = 0.7042, Label = 0.0, Prediction = 1.0 Sample 3: Cosine Similarity = 0.7109, Label = 0.0, Prediction = 1.0 Sample 4: Cosine Similarity = 0.7049, Label = 0.0, Prediction = 1.0 Sample 5: Cosine Similarity = 0.7111, Label = 1.0, Prediction = 1.0 Sample 6: Cosine Similarity = 0.7117, Label = 0.0, Prediction = 1.0 Sample 7: Cosine Similarity = 0.7063, Label = 0.0, Prediction = 1.0 Sample 8: Cosine Similarity = 0.7098, Label = 0.0, Prediction = 1.0

문제점 손실 값 감소 훈련 중 손실 값이 감소하는 것은 모델이 훈련 데이터에 대해 학습하고 있음을 나타낸다. 그러나 손실 값의 감소가 매우 불규칙하고, 손실 값이 매우 높고 후반부에 급격히 감소하는 모양이다. 이는 모델이 안정적으로 학습되지 않았거나 데이터의 질과 양에 문제가 있을 수 있음을 의미한다.

테스트 정확도 테스트 정확도가 매우 낮다. 이는 모델이 테스트 데이터에 대해 거의 무작위로 예측하고 있음을 의미한다.

코사인 유사도 및 예측 코사인 유사도 값이 모든 샘플에서 매우 유사하게 높게 나타나고 있으며, 이는 모델이 제대로 된 임베딩을 학습하지 못하고 있다는 이야기다. 모든 샘플에 대해 거의 동일한 값을 출력하고 있으며, 이로 인해 예측이 실제 레이블과 일치하지 않는 상황이 발생한다.

해결 방안 데이터셋 품질 개선 가상 데이터셋 대신 실제 데이터셋으로 모델을 훈련 가상 데이터는 모델 학습에 필요한 다양성과 복잡성이 부족할 수 있다.

모델 구조 수정 모델이 너무 단순하여 데이터의 복잡한 패턴을 학습하지 못할 수 있다. 더 깊고 복잡한 모델을 사용하거나, 현재 아키텍처에 더 많은 층을 추가하여 모델의 구조를 변경할 수 있다.

학습 하이퍼파라미터 조정 학습률을 조정하여 모델의 학습 속도를 최적화할 수 있다. 에포크 수를 늘려 더 오랜 시간 동안 학습하게 하여 성능을 개선 배치사이즈를 조정하여 학습 안정성을 도모 커널 사이즈를 조정하여 모델의 복잡성 및 특징에 대하여 학습

손실 함수 및 학습 방식 검토 BCEWithLogitsLoss를 사용하는 방법이 적절한지 확인해야 한다. 공부한 내용이라 사용하긴 하였지만, 적절한 방법인지에 대한 고려 없이 사용하여 잘못된 결과가 도출되었을 수도 있다. 코사인 유사도가 매우 좁은 범위에 몰려 있다면, 모델이 효과적으로 학습하지 못할 수 있다. 이를 위해 대조 학습 손실의 다른 변형을 사용하거나, 추가적인 정규화 기법을 도입할 수 있다.

느낀점 및 후기

기존 목표: 인공지능의 학습에 관해 직접 구현해보고 공부하기

느낀점: 생각보다 수학적인 내용이 사용되는 부분이 꽤 있어서 공부하는데 좀 어려움이 있었다.


Table of contents