앞서 설명한 VAE, GAN, AR모델은 분포 p(x)모델링문제해결을 위해 Sampling가능한 latent variable이나 (=VAE Decoder, GAN Generator) 이전 pixel값에 대한 함수로 분포를 모델링(=AR)한다. Normalizing Flow와의 공통점: ∙ AR처럼 다루기 쉽고 명시적인 data생성분포 p(x)를 모델링 ∙ VAE처럼 data를 Gaussian분포처럼 간단한 분포에 mapping
Normalizing Flow의 다른점: ∙ mapping함수의 형태에 제약을 둔다. (= 이 함수는 반전가능해야하고, 이를 이용해 새 data point생성이 가능해야함.)
1. Normalizing Flow
Normalizing Flow는 VAE와 상당히 유사하다.
VAE
Encoder학습 → 복잡한 분포와 sampling가능한 간단한 분포를 mapping → Decoder학습 → 단순한분포에서 복잡한 분포로 mapping ∴ 단순한 분포에서 point z를 sampling, 학습된 변환을 적용 시, 새 data point를 얻음. 즉, Decoder는 p(x|z)를 모델링. Encoder는 p(z|x)의 근사치인 q(z|x)로 둘은 완전히 다른 신경망임.
Normalizing Flows
Decoding함수 = Encoding함수의 역함수 (= 계산이 용이함.) But❗️신경망은 기본적으로 반전가능한 함수가 아니다! 이를 위해 변수변환이라는 기법이 필요한 것.
Change of Variables
변수변환:
px(x)가 2차원 x = (x1, x2) 직사각형 X위에 정의되어있다 가정하자.
이 함수를 주어진 분포영역에서 적분하면 1이 된다. (x1의 범위: [1,4] , x2:[0.2]) 따라서 아래와 같이 잘 정의된 확률분포를 정의할 수 있다: 이 분포를 이동하고 scaling하여 단위 정사각형 Z에 대해 정의한다 가정하자. 이를 위해 새로운 z=(z1, z2)변수와 X의 각 point를 정확히 Z의 한 Point에 mapping하는 함수 f를 정의할 수 있다: 이런 함수를 가역함수(invertible function)라 한다. 즉, 모든 z를 이에 해당하는 x로 다시 mapping가능한 g함수가 존재한다. (변수변환에 필수적.) 이 g함수가 없으면 두 공간사이를 mapping할 수 없다. 이때, pz(z) = ((3z1+1)-1)(2z2)/9 = 2z1z2/3로 변환가능하다. 다만, pz(z)를 단위면적에 대해 적분하면 아래와 같은 문제에 봉착한다: 1/6값이 나왔기에, 더이상 유효한 확률분포가 아니다. (적분결과가 1이 되어야함.) 원인:변환된 확률분포 영역이 원본의 1/6로 작아졌기 때문. 해결:새로운 확률분포의 상대적면적변화에 해당하는 정규화계수를 곱해야함 → 변환에 의한 부피변환 = Jacobian Matrix의 절댓값.
Jacobian Matrix:
z = f(x)의 Jacobain Matrix는 1계 편미분도함수의 행렬이다.
x1에 대한 z1의 편미분은 1/3이고, x1에 대한 z2의 편미분은 0이며, x2에 대한 z2의 편미분은 0이고, x2에 대한 z2의 편미분은 1/2이다.
따라서 함수 f(x)의 Jacobian Matrix는 아래와 같다. 행렬식(determinant)은 정방행렬(square matrix)에서만 정의된다. 해당행렬로 표현되는 변환을 단위 초입방체에 적용해 만들어진 평행육면체 부피와 같다. 즉, 2차원 행렬로 표현되는 변환을 단위 정사각형에 적용해 만들어진 평행사변형의 면적에 해당한다.
앞선 예시를 보자. det(a b c d) = ad - bc이므로 위 예시에서 Jacobian 행렬식은 1/3 × 1/2 = 1/6이다. 이값이 바로 scaling계수이다.
변수 변환 방정식
하나의 방정식으로 X와 Z사이 변수변환과정을 설명할 수 있다. 이를 "변수변환방정식(change of variables equation)"이라 한다.
간단한 분포라면, X→Z로 mapping할 적절한 가역함수 f(x)와 sampling된 z를 기존 domain point x로 다시 mapping 시 사용할 역함수 g(z)를 찾으면 된다. 이를 위해, 필요한 2가지 문제가 존재한다.
① 고차원 행렬식은 Too Hight Cost. O(n3)시간이 든다. ② f(x)의 역함수 계산이 명확하지 않다.
위의 문제들 해결을 위해 RealNVP라는 변환기법으로 수행가능하다.
2. RealNVP
prev.
RealNVP는 복잡한 data분포를 간단한 Gaussian분포로 변환하는 신경망을 만들 수 있다. 또한, 역변환이 가능하고 Jacobian Matrix를 쉽게 계산할 수 있다.
Coupling Layer
Coupling층은 input원소에 대해 scale계수와 translation계수를 만든다.
아래 예시처럼 Linear층으로 Scale출력을 만들고, 또다른 Linearfh translation계수를 만든다.
Coupling Layer는 input data가 들어갈 때, Masking 후 변환되는 방식이 독특하다.
Step 1.처음 d차원만 Coupling Layer에 주입. Step 2.남은 D-d차원은 완전히 Masking(= 0으로 설정.)
이때, 많은 정보를 Masking하는 이유가 뭘까? 이를 알기위해, 이 함수의 Jacobian Matrix를 살펴보면 알 수 있다.
장점 1
하삼각행렬형태로 하삼각행렬의 행렬식은 단순히 대각원소의 곱과 같다. 즉, 좌측하단의 복잡한 도함수와 상관이 없어진다!
장점 2
아래 그림 및 식을 보면, 쉽게 역전할 수 있는 함수라는 목표달성이 가능하다. 정방향계산을 재정렬하면, 아래와 같은 역함수식을 만들 수 있다.
Step 3. 그러면 이제 처음 입력의 d개 원소를 어떻게 update해야할까?
Coupling Layer 쌓기
선형대수학의 행렬식 조건 따라서 위의 선형대수학 행렬식조건에 따라 Coupling Layer를 쌓고, 매번 Masking을 뒤집으면, 간단한 Jacobian Matrix와 가역성이라는 필수속성을 유지하며 전체 input tensor를 변환하는 신경망을 만들 수 있다.
RealNVP 모델훈련
class RealNVP(nn.Module):
def __init__(self, input_dim, output_dim, hid_dim, mask, n_layers = 6):
super().__init__()
assert n_layers >= 2, 'num of coupling layers should be greater or equal to 2'
self.modules = []
self.modules.append(CouplingLayer(input_dim, output_dim, hid_dim, mask))
for _ in range(n_layers-2):
mask = 1 - mask
self.modules.append(CouplingLayer(input_dim, output_dim, hid_dim, mask))
self.modules.append(CouplingLayer(input_dim, output_dim, hid_dim, 1 - mask))
self.module_list = nn.ModuleList(self.modules)
def forward(self, x):
ldj_sum = 0 # sum of log determinant of jacobian
for module in self.module_list:
x, ldj= module(x)
ldj_sum += ldj
return x, ldj_sum
def backward(self, z):
for module in reversed(self.module_list):
z = module.backward(z)
return z
mask = torch.from_numpy(np.array([0, 1]).astype(np.float32))
model = RealNVP(INPUT_DIM, OUTPUT_DIM, HIDDEN_DIM, mask, N_COUPLE_LAYERS)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
prior_z = distributions.MultivariateNormal(torch.zeros(2), torch.eye(2))
Loss functions: NLL Loss
def train(epoch):
model.train()
train_loss = 0
for batch_idx, data in enumerate(train_loader):
optimizer.zero_grad()
z, log_det_j_sum = model(data)
loss = -(prior_z.log_prob(z)+log_det_j_sum).mean()
loss.backward()
cur_loss = loss.item()
train_loss += cur_loss
optimizer.step()
if batch_idx % LOG_INTERVAL == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100.*batch_idx / len(train_loader),
cur_loss/len(data)))
print('====> Epoch: {} Average loss: {:.4f}'.format(
epoch, train_loss / len(train_loader.dataset)
))
[train 결과]:
복잡한 input이 단순한 Gaussian분포형태로 mapping됨.
3. GLOW &. FFJORD
GLOW
고품질 sample생성 및 유의미한 latent space 생성간으. 핵심: 역마스킹 설정을 반전가능한 1×1 conv로 대체 오죽하면 논문제목도 Glow: Generative Flow with Invertible 1x1 Convolutions 이를 이용해 모델이 원하는 채널순으로 조합생성 가능.
FFJORD
Discrete time Normalizing Flows: RealNVP, GLOW Continuous time Normalizing Flows: FFJORD
즉, Normalizing Flow의 단계수가 무한대이고, 단계크기가 0에 가깝기에 신경망에 의해 parameter가 정의되는 상미분방정식(ODE)을 사용해 data분포와 표준정규분포사이 변환을 모델링:
4. 요약
Normalizing Flow란, 다루기 쉬운 data밀도함수를 만들면서 고품질 sample을 생성하는 강력한 생성모델링방법이다. 이를 위해 신경망의 형태를 제한해 가역성과 계산하기 쉬운 Jacobian determinant를 계산한다.
VAE와 GAN: latent variable을 활용. 두 경우 모두 sampling이 쉬운 분포를 갖는 새로운변수를 도입, 이 변수를 기존 domain으로 다시 decoding하는 방식.
AR Model:생성모델링을 순차적과정으로 진행. 즉, latent variable이 아닌, sequence에 있는 이전값을 바탕으로 예측. 그렇기에 Data생성분포를 근사하는것이 아닌, 명시적으로 Data생성분포를 모델링한다.
이번에는 2가지 AR모델인 LSTM과 PixelCNN을 살펴볼 것이다. ∙ LSTM: text data ∙ PixelCNN: img data
이후, 또다른 성공적인 AR모델인 Transformer에 대해 논의할 것이다.
1. LSTM
Tokenization
LSTM은 RNN의 한 종류로 sequential data처리에 용이하다. tokenization은 텍스트를 단어나 문자같은 개별단위로 나누는 작업이다.
텍스트생성모델로 만들려는 종류에 따라 text tokenization방법이 달라지는데, word와 sentence token은 각기 장단점이 존재한다.
word token의 경우:
vocab이 매우 크며, 단어의 stem(어간)추출이 가능하다. ex) browse, browsing, browses는 모두 어간이 brows이다. 단어토큰화는 train_vocab에 없는 단어는 모델이 예측불가능하다.
character token의 경우:
모델이 문자의 sequence를 생성, train_vocab에 없는 새로운 단어 생성. 대문자를 소문자로 바꾸거나 별도의 token으로 남길 수 있다. 문자토큰화는 vocab_size가 비교적 매우 작아 마지막층에서 학습할 가중치 수가 적어 빠른 훈련속도를 갖는다.
2. PixelCNN
prev.
이전 픽셀을 기반으로 픽셀단위로 img를 생성하는 모델이다. [Aaron;2016] 이를 PixelCNN이라하며, AR방식으로 img를 생성하도록 훈련시킨다.
AR모델은 뛰어난 품질의 결과물을 얻을 수 있지만 PixelCNN같은 AR모델의 주요단점은 순차적인 sampling과정으로 인해 sampling속도가 느리다는 점이다. (∵ VAE는 한번의 예측으로 충분하지만 PixelCNN은 이전의 모든 픽셀을 기반으로 다음 픽셀을 예측하기 때문.)
PixelCNN을 이해하기 위해 필요한 2가지 개념 이해가 필요하다. ∙ Masked Convolution Layer ∙ Residual Block
Masked Convolution Layer
Conv층은 feature탐지에는 유용하나 pixel에 순서가 지정되지 않는다. 따라서 Auto-Regressive방식을 직접적으로 사용할 수 없다.
그렇기에 Conv층에 AR방식으로 이미지생성에 적용하기 위해 ① pixel순서를 지정하고 filter가 해당 pixel앞의 픽셀만 볼 수 있게 해야한다. ② 현재 img에 conv_filter를 적용하고 ③ 앞의 모든 Pixel로부터 다음 pixel의 값을 예측해 한번에 하나의 pixel씩 img를 생성한다.
Zig-Zag순으로 Masking을 진행하며, 1과 0으로 구성된 mask에 fitler weight matrix를 곱해 현재 pixel뒤에 있는 모든 pixel값이 0이 되게한다. 아래그림을 보면, 2종류의 Mask가 있음을 알 수 있다. ∙ Mask A: 중앙 pixel값이 Masking되는 유형 ∙ Mask B: 중앙 pixel값이 Masking되지 않는 유형 좌) 중심픽셀값 분포 예측을 위해 일련의 픽셀에 적용된 마스크 / 우) Masked Conv filter
초기 Masked Conv층(= input image에 직접적용되는 층)에서는 중앙픽셀=신경망이 예측해야할 픽셀이기에 해당 중앙픽셀을 사용할 수 없다. (= Mask A) 하지만 후속층(= Mask B)에서는 중앙픽셀을 활용할 수 있다.
이는 기존 input img의 이전 pixel에서 얻은 정보만으로 계산된 결과이기 때문이다.
핵심구성요소 중 하나로 Residual Block이 사용된다. residual block은 input signal을 그대로 유지하는데, 이는 최적의 변환일 때 중간층의 가중치를 0으로 만들어 쉽게 달성가능하기 때문이다. (Skip Connection이 없으면 신경망이 중간층으로 input과 동일해지는 mapping을 찾아야하는데 Cost가 너무 많이 든다.) 이때, 중간의 3x3 Conv는 MaskedConv2D를 사용한다.
2017년, PixelCNN의 느린 훈련과정 완화를 위해 이산 픽셀값에 대한 softmax출력대신 혼합분포로 만들었다. (즉, 혼합분포에서 Sampling을 한다는 의미.)
이를 위해서 다음 단계를 거친다. 1. 먼저 categorical분포에서 sampling 2. 특정 하위분포를 선택 3. 일반적인 방법으로 이 분포에서 sampling.
이전과의 큰 차이점: 픽셀값의 전체 범위를 활용한다는 점.
3.1. Transformers
prev.
LSTM, GRU같은 순환신경망 종류들은 텍스트를 순차적으로 만드는 AR model들이다. 이런 AR모델은 sequential data를 한번에 하나씩 처리하여 hidden vector를 지속해서 update한다.
Transformer는 순환구조가 필요없고, 순차모델링을 위해 Attention Mechanism에만 의존한다. RNN은 병렬화가 어려우나 Transformer는 병렬화가 용이해 Large Dataset에서 훈련할 수 있다.
이번에는 OpenAI의 핵심 AR모델인 GPT를 살펴볼 것이다.
Attention Mechanism (Attention Head)
문장의 특정단어에 attention을 하며, 다른 단어들은 거의 무시하는 뉘앙스로 작동한다. 즉, 관련없는 detail로 유용한 정보가 가려지는 것을 막고, 효율적으로 추출하기위해 입력의 어느위치에서 정보를 가져올 지 결정하는 것으로 추론 시 정보를 찾을 위치를 결정할 수 있다.
Query, Key, Value
Attention Head는 일종의 정보검색시스템으로 생각할 수 있다. Q가 K/V로 만들어지고, 출력은 Q와 각 K간의 유사성에 따라 가중치가 부여된 값의 합이다. Q: 현재 당면한 작업에 대한 표현 K: 문장의 각 단어에 대한 표현 V: 문장에 있는 단어의 표현 attention의 출력은 context vector이다.
Decoder에서 미래의 단어정보누출을 방지하기위해 QK dot곱에 Mask를 적용해야한다. 이를 Causal Masking이라 한다. Huggingface GPT2 구현 일부: cf) 참고코드
if attention_mask is not None:
assert batch_size > 0, "batch_size has to be defined and > 0"
attention_mask = attention_mask.view(batch_size, -1)
attention_mask = attention_mask.unsqueeze(1).unsqueeze(2)
attention_mask = attention_mask.to(dtype=next(self.parameters()).dtype) # fp16 compatibility
attention_mask = (1.0 - attention_mask) * -10000.0
Batch Norm v.s Layer Norm
Transformer는 학습과정안정성을 위해 Layer Normalization을 사용한다. Batch Norm: 각 채널의 출력의 평균이 0, 표준편차가 1이 되도록 정규화하는 방법. (이때, batch차원과 공간차원에 걸쳐 정규화 통계치가 계산된다.)
Layer Norm:채널차원에 대해 정규화 통계치가 계산된다. 따라서 batch에 있는 각 sequence위치마다 정규화한다. (이때, 정규화 통계치 계산방식이 BN과 완전히 반대이다.)
Positional Encoding
MHA층에서 K의 순서를 고려하는 부분이 없는데, 각 K와 Q의 dot곱에서 순차적 계산이 아닌, 병렬로 계산된다. 이를 위해 Transformer블록의 input을 위해 Positional Encoding을 사용한다.
token embedding
또한, token embedding을 사용해 token만 encoding하지 않고 positional encoding으로 token의 위치도 encoding한다.
3.2. Transformer etc.
T5 (Encoder-Decoder)
Encoder-Decoder구조를 이용한 최근 Transformer의 예시로 Google에서 발표한 T5(Text-To-Text Transfer Transformer)모델은 NMT, Linguistic Acceptability(언어적 적합성), Similarity, Summarization을 포함한 다양한 작업을 수행한다. T5의 주요 특징은 다음과 같다:
1. Text-To-Text Framework: - T5는 "문장을 문장으로"라는 원칙을 따르며, 모든 NLP 작업을 텍스트 입력으로 받아들이고 텍스트 출력으로 생성하는 일관된 프레임워크를 가지고 있는데, 이로써 다양한 자연어 처리 작업을 통일된 방식으로 다룰 수 있다.
2. Transformer Architecture: - T5는 Transformer 아키텍처를 기반이기에 Transformer는 Attention 메커니즘을 사용하여 시퀀스 데이터의 긴 범위의 의존 관계를 모델링하는데 효과적이다.
3. Pretraining and Fine-tuning: - T5는 대규모 텍스트 코퍼스에서 사전 훈련되었으며, 이렇게 사전 훈련된 모델은 다양한 자연어 처리 작업에 대해 효과적인 전이 학습을 가능하게 한다.
4. Task-Agnostic Representation: - T5는 작업에 특화된 task-specific한 head를 추가하지 않고, 단일 통합된 모델을 사용한다. - 이런 특성은 모델을 다양한 작업에 적용하는 것을 용이하게 한다.
5. Scalability: - T5는 다양한 모델 크기로 사용 가능하며, 작은 모델에서부터 매우 큰 모델까지 다양한 크기의 모델이 제공된다.
T5는 자연어 생성, 기계 번역, 질문 응답, 감정 분석, 문서 분류 등 다양한 NLP 작업에 사용될 수 있다.
ChatGPT
GPT-3보다 강력하고, 대화형식에 맞게 fine-tuning된 모델인 GPT-3.5가 사용된다.
ChatGPT가 GPT-3.5를 Fine-Tuning할 때, "RLHF(Reinforcement Learning from Human Feedback)"라는 테크닉을 사용한다.
ChatGPT train과정 (RLHF)
Step 1. Supervised Learning Fine Tuning 사람이 작성한 대화형 입력프롬프트 + 원하는 출력으로 구성된 dataset 수집 이 dataset으로 Supervised Learning의 기본언어모델(GPT-3.5)를 Fine-Tuning
Step 2. Reward Modeling label을 부여할 사람에게 prompt와 몇가지 sampling 모델출력을 제시. worst~best까지 출력순위를 지정하도록 요청. 대화기록이 주어지면 각 출력의 score를 예측하는 reward model을 학습.
Step 3. Reinforcement Learning 1단계에서 Fine tuning된 모델로 초기화된 LM이 policy가 되는 RL로 대화를 처리. 현재 state(= 대화기록)이 주어지면, policy는 action(= token sequence)를 출력.
2단계에서 학습된 Reward model로 해당출력의 score를 매긴 후 PPO로 보상 극대화하도록 LM의 가중치 조정
ChatGPT가 GPT-3.5를 Fine-Tuning할 때, "RLHF"라는 테크닉을 사용한다.
- Chapter 4 읽고 공부하기(短) - Chapter 5 읽고 공부하기(短) - Chapter 11 읽고 공부하기 - Chapter 13 읽고 공부하기 - Chapter 14읽고 공부하기 - Chapter 15읽고 공부하기 - Chapter 16읽고 공부하기
3. Generative Deep Learning Part 1. Intro. Generative Deep Learning - Chapter 1. Generative Modeling - Chapter 2. 딥러닝
Part 2. Six Generative Modeling Method. - Chapter 3. VAE - Chapter 4. GAN - Chapter 5. AR Model - Chapter 6. Normalizing Flow Model - Chapter 7. Energy Based Model - Chapter 8. Diffusion Model
마찬가지로 서편제(한식): 걍 앞으로는 고기많이 나오는 동편제 먹어야지... 후식으로는 내돈내산 녹차프라푸치노!! << 솔직히 이게 제일 맛도리임
📖 공부! (13:30-18:00)
GAI 이어서 진행!
🚍 퇴근! (18:30 - 19:00)
퇴근이 제일 좋다는 직장인의 말에 공감이 점점된다ㅋㅋㅋ 아침출근때문에 그냥 졸리다ㅋㅋ 피곤🩸하고ㅠㅠ
🏋🏻 운동! (19:00 -)
이제 3대 운동보단 좀 더 세분화해서 A,B루틴 안하는 날에는 가슴,삼두, 등,이두, 어께 위주로 해봐야겠다. 아 그리고 데드나 스쿼트의 경우에는 조금 텀을 둬야겠다... 격일마다 무겁게만 하다보니 오히려 퍼포먼스가 안나오는 느낌? 그래서스쿼트와 데드의 경우에는 일주일에 1~2번정도만 본세트무게로❗️ 나머지는 평소드는 무게의 8~90%정도의 중량만들어야겠당
[정리]: 5x5 Strength + Local Muscle Strength Training for me
<해석 끝> - Chapter 6 읽고 공부하기 - Chapter 7 읽고 공부하기(短) - Chapter 8 읽고 공부하기(短) - Chapter 9 읽고 공부하기(短) - Chapter 10 읽고 공부하기 - Chapter 12 읽고 공부하기 - Chapter 17 읽고 공부하기(短) - Chapter 18 읽고 공부하기(短) - Chapter 19 읽고 공부하기(短) - Chapter 20 읽고 공부하기
<해석도 해야할 것.> - Chapter 5 읽고 공부하기(短) - Chapter 11 읽고 공부하기 - Chapter 13 읽고 공부하기 - Chapter 14읽고 공부하기 - Chapter 15읽고 공부하기 - Chapter 16읽고 공부하기
3. Generative Deep Learning Part 1. Intro. Generative Deep Learning - Chapter 1. Generative Modeling - Chapter 2. 딥러닝
Part 2. Six Generative Modeling Method. - Chapter 3. VAE - Chapter 4. GAN - Chapter 5. AR Model - Chapter 6. Normalizing Flow Model - Chapter 7. Energy Based Model - Chapter 8. Diffusion Model
- Chapter 4 읽고 공부하기(短) - Chapter 5 읽고 공부하기(短) - Chapter 11 읽고 공부하기 - Chapter 13 읽고 공부하기 - Chapter 14읽고 공부하기 - Chapter 15읽고 공부하기 - Chapter 16읽고 공부하기
3. Generative Deep Learning Part 1. Intro. Generative Deep Learning - Chapter 1. Generative Modeling - Chapter 2. 딥러닝
Part 2. Six Generative Modeling Method. - Chapter 3. VAE - Chapter 4. GAN - Chapter 5. AR Model - Chapter 6. Normalizing Flow Model - Chapter 7. Energy Based Model - Chapter 8. Diffusion Model
마찬가지로 서편제(한식): 걍 앞으로는 고기많이 나오는 동편제 먹어야지... 후식으로는 내돈내산 녹차프라푸치노!! << 솔직히 이게 제일 맛도리임
📖 공부! (13:30-18:00)
🚍 퇴근! (18:30 - 19:00)
퇴근이 제일 좋다는 직장인의 말에 공감이 점점된다ㅋㅋㅋ 아침출근때문에 그냥 졸리다ㅋㅋ 피곤🩸하고ㅠㅠ
🏋🏻 운동! (19:00 -)
이제 3대 운동보단 좀 더 세분화해서 A,B루틴 안하는 날에는 가슴,삼두, 등,이두, 어께 위주로 해봐야겠다. 아 그리고 데드나 스쿼트의 경우에는 조금 텀을 둬야겠다... 격일마다 무겁게만 하다보니 오히려 퍼포먼스가 안나오는 느낌? 그래서스쿼트와 데드의 경우에는 일주일에 1~2번정도만 본세트무게로❗️ 나머지는 평소드는 무게의 8~90%정도의 중량만들어야겠당
[정리]: 5x5 Strength + Local Muscle Strength Training for me
목표: 판별자가 판별 불가능한 img생성 input: 다변량표준정규분포에서 뽑은 벡터 output: 원본 train data에 있는 img와 동일한 크기의 img 위 설명이 마치 VAE같다면? 실제로 VAE의 Decoder와 동일한 목적을 수행한다. latent space의 벡터를 조작, 기존 domain에서 img의 고수준 특성을 바꾸는 기능을 제공하기 때문.
batch img생성→판별자에 통과→각 img에 대한 점수 get. ∙ G_Loss: BCELoss (0: fake img / 1: real img) ∙ D_Loss: BCELoss (0: fake img / 1: real img) 이때, 한번에 한 신경망 가중치만 update되도록 두 신경망을 번갈아 train해줘야함.
이때, DCGAN훈련과정이 불안정할 수 있다. (∵ 판별자와 생성자가 우위를 차지하려 서로 계속 경쟁하기 때문.) 시간이 충분히 지나면, 판별자가 우세해지는 경향이 있다. 다만, 이시점에는 생성자가 충분히 고품질 Img생성이 가능해서 큰 문제는 되지 않는다.
Label Smoothing
또한, GAN에 random noise를 조금 추가하면 유용한데, train과정의 안정성 개성 및 img선명도가 증가한다. (마치 Denoise Auto Encoder와 같은 느낌.)
GAN 훈련 팁 & Trick
∙ D >> G 인 경우.
판별자가 너무 강하면 Loss신호가 너무 약해진다. 이로 인해 생성자에서 의미있는 향상을 도모하기 어려워진다. 따라서 다음과 같이 판별자를 약화할 방법이 필요하다.
∙ 판별자에 Dropout rate 증가.
∙ 판별자의 LR 감소.
∙ 판별자의 Conv filter 수 감소.
∙ 판별자 훈련 시, Label에 Noise추가. (Label Smoothing)
∙ 판별자 훈련 시, 일부 img의 label을 random으로 뒤집는다.
∙ G >> D 인 경우.
mode collapse: 생성자가 거의 동일한 몇개의 img로 판별자를 "쉽게 속이는 방법" mode: 판별자를 항상 속이는 하나의 sample.
생성자는 이런 mode를 찾으려는 경향이 있고, latent space의 모든 point를 이 img에 mapping가능하다. 또한, 손실함수의 Gradient가 0에 가까운값으로 붕괴(collapse)하기에 이상태에서 벗어나기 어려워진다.
∙ 유용하지 않은 Loss
손실이 작을수록 생성된 img품질이 더 좋을 것이라 생각할 수 있다. 하지만 생성자는 현재 판별자에 의해서만 평가된다. 판별자는 계속 향상되기에 train과정의 다른지점에서 평가된 손실을 비교할 수 없다. 즉, 판별Loss는 감소하고, 생성Loss는 증가한다.→ GAN train과정 모니터링이 어려운 이유.
2. WGAN-GP (Wasserstein GAN with Gradient Penalty)
GAN Loss
GAN의 판별자∙생성자 훈련 시 사용한 BCE Loss를 살펴보자. 판별자 D훈련: real_img에 대한 예측 pi=D(xi)와 target yi=1을 비교. 생성자 G훈련: 생성_img에 대한 예측 pi=D(G(zi))와 target yi=0을 비교.
[GAN D_Loss 최대화 식]: [GAN G_Loss 최소화 식]:
Wesserstein Loss
[GAN Loss와의 차이점]: ∙ 1과 0대신, yi = 1, yi = -1을 사용. ∙ D의 마지막층에서 sigmoid제거. → 예측 pi가 [0,1]범위에 국한되지 않고 [-∞,∞] 범위의 어떤 숫자도 될 수 있게함. 위의 이유들로 WGAN의 판별자는 보통 비평자(Critic)라 부르며, 확률대신 점수"score"를 반환한다.
[Wesserstein Loss함수]:
WGAN의 critic D를 훈련하기위해 real_img에 대한 예측(D(xi))과 타겟(= 1)을 비교. 생성_img에 대한 예측(D(G(zi)))과 타겟(= -1)을 비교. ∴ 손실을 계산
[WGAN Critic D_Loss 최소화]: real과 생성간의 예측차이 최대화. [WGAN G_Loss 최소화]: Critic에서 가능한 높은 점수를 받는 img생성. (= Critic을 속여 real_img라 생각하게 만드는 것.)
1-Lipshitz Continuous function
sigmoid로 [0,1]범위에 국한하지 않고 Critic이 [-∞,∞] 범위의 어떤 숫자도 될 수 있게한다는 점은 Wessertein Loss가 제한없이 아주 큰 값일 수 있다는 것인데, 보통 신경망에서 큰 수는 피해야한다.
그렇기에, "Critic에 추가적인 제약이 필요"하다. 특히, Critic은 1-Lipshitz 연속함수여야 하는데, 이에대해 살펴보자.
Critic은 하나의 img를 하나의 예측으로 변환하는 함수 D이다. 임의의 두 input_img x1, x2에 대해 다음 부등식을 만족하면, 이 함수를 1-Lipshitz라 한다: |x1-x2| : 두 img 픽셀의 평균적인 절댓값 차이 |D(x1) - D(x2)| : Critic 예측간의 절댓값 차이 Lipshitz Continuous Function 기본적으로 기울기의 절댓값이 어디에서나 최대 1이어야한다 = 두 img간 Critic예측변화비율 제한이 필요하다는 의미.
WGAN-GP
WGAN의 Critic의 가중치를 작은 [-0.01, 0.01]범위에 놓이도록 train batch 이후 weight clipping으로 Lipshitz제약을 부과한다.
이때, 학습속도가 크게 감소하기에 Lipshitz제약을 위해 다른 방법을 적용한다: 바로 Wesserstein GAN-Gradient Penalty이다.
[WGAN-GP]: Gradient Norm이 1에서 벗어나면 모델에 불이익을 주는 방식이다. [Gradient Penalty Loss]: input_img에 대한 예측의 Gradient Norm과 1사이 차이를 제곱한 것. 모델은 자연스레 GP항을 최소화하는 가중치를 찾으려하기에 이 모델은 립시츠 제약을 따르게 한다.
Train과정동안 모든곳에서 Gradient계산은 힘들기에 WGAN-GP는 일부지점에서만 Gradient를 계산한다. 이때, real_img와 fake_img쌍 간의 interpolation img를 사용한다.
from torch.autograd import Variable
from torch.autograd import grad as torch_grad
def gradient_penalty(self, real_data, generated_data):
batch_size = real_data.size()[0]
# Calculate interpolation
alpha = torch.rand(batch_size, 1, 1, 1)
alpha = alpha.expand_as(real_data)
interpolated = alpha*real_data.data + (1 - alpha)*generated_data.data
interpolated = Variable(interpolated, requires_grad=True)
# Calculate probability of interpolated examples
prob_interpolated = self.D(interpolated)
# Calculate gradients of probabilities with respect to examples
gradients = torch_grad(outputs=prob_interpolated, inputs=interpolated,
grad_outputs=torch.ones(prob_interpolated.size()).cuda() if self.use_cuda else torch.ones(
prob_interpolated.size()),
create_graph=True, retain_graph=True)[0]
# Gradients have shape (B,C,W,H)
# so flatten to easily take norm per example in batch
gradients = gradients.view(batch_size, -1)
self.losses['gradient_norm'].append(gradients.norm(2, dim=1).mean().data[0])
# Derivatives of the gradient close to 0 can cause problems because of
# the square root, so manually calculate norm and add epsilon
gradients_norm = torch.sqrt(torch.sum(gradients**2, dim=1) + 1e-12)
# Return gradient penalty
return self.gp_weight * ((gradients_norm-1)**2).mean()
[WGAN-GP에서의 Batch Normalization]
BN은 같은 batch안의 img간의 correlation을 만든다. 그렇기에 gradient penalty loss의 효과가 떨어지에 WGAN-GP는 Critic에서 BN을 사용해서는 안된다.
3. CGAN (Conditional GAN)
prev.
앞서 설명한 모델들은 "주어진 trainset에서 사실적인 img를 생성하는 GAN"이었다. 하지만, "생성하려는 img의 유형을 제어할 수 는 없었다." (ex. 생성하려는 img유형: 크거나 작은 벽돌, 흑발/금발 등등)
latent space에서 random한 하나의 point sampling은 가능하다. latent variable을 선택하면 어떤 종류의 img가 생성될 지 쉽게 파악가능하다.
CGAN
[GAN v.s CGAN]: CGAN은 GAN과 달리 "label과 관련된 추가정보를 생성자와 critic에 전달한다는 점"이다. ∙ 생성자: 이 정보를 one-hot encoding vector로 latent space sample에 단순히 추가. ∙ Critic: label 정보를 RGB img의 채널에 추가채널로 추가. → input img가 동일한 크기가 될 때 까지 one-hot encoding vector를 반복. [유일한 구조 변경사항]: label정보를 G,D의 기존 입력에 연결하는 것.
Encoding: Data를 저차원 latent space의 특정 point에 mapping시키는 것. Decoding: 이 point의 위치를 받아 해당 Data를 다시 생성하려 시도하는 것. encoder는 decoder가 정확하게 재구성하도록 가능한 많은 정보를 내포시키려 하는데, 이 벡터를 embedding이라 한다.
Auto Encoder: encoding과 decoding작업을 수행하도록 훈련된 신경망. → 원본에 가까워지도록 train시킨다. 보통 Loss function으론 원본과 재구성 img의 pixel간의 RMSE나 BCE를 사용한다. input은 latent embedding vector z로 encoding, 원본픽셀공간으로 decoding
🤔 이미 갖고 있는 img를 왜 재구성?
이미 갖고있는 img를 왜 재구성해야할까? "Auto Encoder 사용이유": Embedding공간(latent space) 때문! latent space에서 sampling하여 새로운 img를 생성할 수 있기 때문.
cf) test_set을 encoder에 통과시켜 만들어진 embedding을 그래프(scatter 등)로 나타내면, img가 latent space에 어떻게 embedding되는지 시각화가능하다.
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 예시: Autoencoder 모델 정의
class Autoencoder(nn.Module):
def __init__(self, input_size, hidden_size):
super(Autoencoder, self).__init__()
self.encoder = nn.Linear(input_size, hidden_size)
self.decoder = nn.Linear(hidden_size, input_size)
def forward(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return encoded, decoded
# 예시: 잠재 공간 시각화 함수
def visualize_latent_space(data_loader, model, device):
model.eval()
latent_space, labels = [], []
with torch.no_grad():
for images, labels_batch in data_loader:
images = images.view(images.size(0), -1).to(device)
encoded, _ = model(images)
latent_space.append(encoded.cpu().numpy())
labels.append(labels_batch.numpy())
latent_space = torch.cat(latent_space, dim=0)
labels = torch.cat(labels, dim=0)
plt.figure(figsize=(10, 8))
plt.scatter(latent_space[:, 0], latent_space[:, 1], c=labels, cmap='viridis')
plt.colorbar()
plt.title('Latent Space Visualization')
plt.show()
# 예시: 데이터 로딩
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
mnist_data = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
data_loader = DataLoader(mnist_data, batch_size=64, shuffle=True)
# 예시: 모델 및 학습 설정
input_size = 28 * 28 # MNIST 이미지 크기
hidden_size = 2 # 잠재 공간 차원
autoencoder_model = Autoencoder(input_size, hidden_size)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
autoencoder_model.to(device)
# 예시: 학습된 모델의 가중치 로드
autoencoder_model.load_state_dict(torch.load('autoencoder_model.pth'))
autoencoder_model.eval()
# 예시: 잠재 공간 시각화
visualize_latent_space(data_loader, autoencoder_model, device)
이에대해, Decoder를 사용해 다시 pixel공간으로 변환하면 새로운 img를 생성할 수 있다.
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 예시: Autoencoder 모델 정의
class Autoencoder(nn.Module):
def __init__(self, input_size, hidden_size):
super(Autoencoder, self).__init__()
self.encoder = nn.Linear(input_size, hidden_size)
self.decoder = nn.Linear(hidden_size, input_size)
def forward(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return encoded, decoded
# 예시: 이미지 생성 함수
def generate_image_from_latent_space(latent_vector, model, device):
model.eval()
with torch.no_grad():
latent_vector = torch.tensor(latent_vector).float().to(device)
reconstructed_image = model.decoder(latent_vector)
reconstructed_image = reconstructed_image.view(1, 1, 28, 28) # MNIST 이미지 크기
return reconstructed_image
# 예시: 이미지 시각화 함수
def visualize_image(image):
plt.imshow(image.squeeze().cpu().numpy(), cmap='gray')
plt.axis('off')
plt.show()
# 예시: 데이터 로딩
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
mnist_data = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
data_loader = DataLoader(mnist_data, batch_size=64, shuffle=True)
# 예시: 모델 및 학습 설정
input_size = 28 * 28 # MNIST 이미지 크기
hidden_size = 2 # 잠재 공간 차원
autoencoder_model = Autoencoder(input_size, hidden_size)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
autoencoder_model.to(device)
# 예시: 학습된 모델의 가중치 로드
autoencoder_model.load_state_dict(torch.load('autoencoder_model.pth'))
autoencoder_model.eval()
# 예시: 잠재 공간에서 샘플링하여 이미지 생성 및 시각화
latent_vector_sample = [0.5, 0.5] # 잠재 공간에서 샘플링한 값
generated_image = generate_image_from_latent_space(latent_vector_sample, autoencoder_model, device)
visualize_image(generated_image)
2. Variational Auto Encoder
Auto Encoder의 문제점.
Auto Encoder는 latent space가 연속적인지 강제하지 않기에, 다룰 수 있는 차원 수가 적다. 그렇기에, 더 복잡한 img생성 시, latent space에 더 많은 차원 사용 시, 이 문제는 뚜렷해진다. 즉, encoding 시, latent space를 자유롭게 사용하면 비슷한 point가 모인 그룹간의 큰 간격이 발생한다. 이런 간격이 발생한 공간에서는 잘 형성된 img를 생성할 가능성이 낮다.
이를 위해 Auto Encoder 대신, Variational Auto Encoder로 바꿔야한다.
VAE
AE: 각 img가 latent space의 한 point에 직접 mapping됨. VAE: 각 img가 latent space point주변의 다변량정규분포에 mapping됨. 다변량 정규분포 N(0,I)는 평균벡터가 0, 공분산행렬이 단위벡터이다. 즉, 요약해보면 Encoder는 input을 받아 latent space의 다변량정규분포를 정의하는 2개의 벡터로 encoding한다. ∙ z_mean: 이 분포의 평균벡터 ∙ z_log_var: 차원별 분산의 로그값
이런 작은 변화로 어떻게 Encoder를 향상시킬 수 있었을까? 이전 AE: latent space를 연속적으로 만들필요❌ VAE: z_mean주변영역에서 random point를 sampling하기에 재구성손실이 작게 유지되도록 동일영역의 Point의 img와 매우 비슷하게 decoding.
cf) reparameterization trick이란?
mean과 log_var로 정의된 정규분포에서 직접 sampling하는 대신, 표준정규분포에서 epsilon을 sampling → 올바른 평균과 분산을 갖도록 sample수동조정.
이 방법은 epsilon을 포함함으로써 출력의 편도함수를 결정론적(= random epsilon과 무관함)으로 표시할 수 있어 역전파를 위해 필수적이다.
🧐 Loss Function
AE의 손실함수: Src_img와 AE통과한 출력간의 Reconstruction Loss VAE: Reconstruction Loss + KL-Divergence (Latent Loss)
KL Divergence는 z_mean과 z_log_var가 표준정규분포와 얼마나 다른지를 측정한다.
∙ sample dataset X를 가지고
∙ sample이 알지 못하는 어떤 p_data분포로 생성되었다 가정.
∙ p_data를 흉내내는 생성모델 p_model을 만들자.
이를위해 p_model에서 sampling해 p_data에서 추출한 것 같은 sample을 생성.
∴ p_model의 ideal한 속성:
- 정확도:
생성된 sample의 p_model이 높으면 p_data에서 추출한 것 같아야함.
- 생성:
p_model에서 새로운 sample이 쉽게 sampling가능해야함.
- 표현:
data의 다양한 high-level feature가 p_model로 어떻게 표현되는지 이해가능해야함.
∙ Representation Learning
"고차원 data의 표현(representation)"을 배운다는 것은 무슨 의미일까? 고차원 표본공간을 직접모델링❌ 저차원의 잠재공간을 이용 → trainset의 각 sample을 표현 → 원본 공간의 point에 mapping latent space의 각 point = 어떤 고차원 Image에 대한 표현.
즉, 수학적으로 Encoder-Decoder기법은 data가 놓여있는 고차원 비선형 manifold를 sampling가능한 단순한 Latent space로 변환한다. cf) Manifold는 local로는 저차원의 euclidean distance로 볼 수 있는 고차원공간을 의미.
🔔 핵심 확률이론
∙ 표본공간(sample space): sample x가 갖는 모든 값의 집합.
∙ 확률밀도함수 p(x):point x를 0과 1사이 숫자로 mapping하는 함수 표본공간에 있는 모든 point에 대해 p(x) 적분 시, 1이 되면 잘 정의된 확률분포. 또한, pdata(x)는 하나이지만 pmodel(x)는 무수히 많이 존재.
∙ 모수 모델링(parametric modeling):안정적인 pmodel(x) 찾기위한 기법. 유한개의 parameter θ를 사용해 기술가능한 밀도함수 pθ(x)의 한 종류.
∙parameter집합 θ의 likelihood함수: 𝐿(θ|x) = pθ(x)= ∏x∈X pθ(x) x가 주어졌을 때, θ의 타당성을 측정하는 함수 cf) Log Likelihood: 𝑙(θ|X)=∑x∈Xlog pθ(x) 이때, 모수모델링의 관심은 dataset X가 관측될 가능도를 최대화하는 parameter θ̂의 최적값을 찾는것.
∙MLE(Maximum Likelihood Estimation):θ̂ 추정 기법. θ̂ = argmaxx𝑙(θ|x) 신경망은 보통 손실함수를 최소화 = NLL 최소화하는 parameter집합을 찾는 것 즉, θ̂ = argminθ(-𝑙(θ|x)) = argminθ(-𝑙ogpθ(X))
다만, 일반 고차원문제에서 pθ(X)를 직접 계산하긴 어렵기에 생성모델마다 다른방법으로 이를 해결한다.
생성모델 분류.
prev.
생성모델은 밀도함수 pθ(x)를 모델링하는 방식이 조금씩 다르다. ∙ 방식 ①: 명시적으로 밀도함수 모델링. (다만 밀도함수를 쉽게 다루기 위해=계산가능하도록 모델을 제약) -ex) VAE, Energy-based, Diffusion
2. 주중에 할 것: Deep Learning 2024(Bishop) - Chapter 2: Exercise 풀기. - Chapter 3: Exercise 풀기.
- Chapter 6 읽고 공부하기 - Chapter 7 읽고 공부하기(短) - Chapter 8 읽고 공부하기(短) - Chapter 9 읽고 공부하기(短) - Chapter 10 읽고 공부하기 - Chapter 12 읽고 공부하기 - Chapter 17 읽고 공부하기(短) - Chapter 18 읽고 공부하기(短) - Chapter 19 읽고 공부하기(短) - Chapter 20 읽고 공부하기
- Chapter 5 읽고 공부하기(短) - Chapter 11 읽고 공부하기 - Chapter 13 읽고 공부하기 - Chapter 14읽고 공부하기 - Chapter 15읽고 공부하기 - Chapter 16읽고 공부하기
3. 표본분포
4. 통계
5. 통계적 추론
🚲 출근! (8:00 - 8:30)
어제 10시정도에 자서 오늘은 3시 40분정도에? 기상하였다.
확실히 일찍자고 일찍일어나니 충분히 잘수도 있었고 좋았던 것 같다.
📖 공부! (9:00-12:00)
∙ Deep Learning(Bishop 2024): 번역 진행. - Chapter 6 읽고 공부하기 - Chapter 7 읽고 공부하기(短) - Chapter 8 읽고 공부하기(短) - Chapter 9 읽고 공부하기(短) - Chapter 10 읽고 공부하기 - Chapter 12 읽고 공부하기 - Chapter 17 읽고 공부하기(短) - Chapter 18 읽고 공부하기(短) - Chapter 19 읽고 공부하기(短) - Chapter 20 읽고 공부하기(短)
🍚 밥이다 밥! (12:30~13:00)
마찬가지로 서편제(한식): 걍 앞으로는 고기많이 나오는 동편제 먹어야지... 후식으로는 내돈내산 녹차프라푸치노!! << 솔직히 이게 제일 맛도리임
📖 공부! (13:30-18:00)
DAOD이어서 진행!
🚍 퇴근! (18:30 - 19:00)
퇴근이 제일 좋다는 직장인의 말에 공감이 점점된다ㅋㅋㅋ 아침출근때문에 그냥 졸리다ㅋㅋ 피곤🩸하고ㅠㅠ
🏋🏻 운동! (19:00 -)
이제 3대 운동보단 좀 더 세분화해서 A,B루틴 안하는 날에는 가슴,삼두, 등,이두, 어께 위주로 해봐야겠다. 아 그리고 데드나 스쿼트의 경우에는 조금 텀을 둬야겠다... 격일마다 무겁게만 하다보니 오히려 퍼포먼스가 안나오는 느낌? 그래서스쿼트와 데드의 경우에는 일주일에 1~2번정도만 본세트무게로❗️ 나머지는 평소드는 무게의 8~90%정도의 중량만들어야겠당
[정리]: 5x5 Strength + Local Muscle Strength Training for me
2. 주중에 할 것: Deep Learning 2024(Bishop) - Chapter 2: Exercise 풀기. - Chapter 3: Exercise 풀기.
- Chapter 6 읽고 공부하기 - Chapter 7 읽고 공부하기(短) - Chapter 8 읽고 공부하기(短) - Chapter 9 읽고 공부하기(短) - Chapter 10 읽고 공부하기 - Chapter 12 읽고 공부하기 - Chapter 17 읽고 공부하기(短) - Chapter 18 읽고 공부하기(短) - Chapter 19 읽고 공부하기(短) - Chapter 20 읽고 공부하기
- Chapter 5 읽고 공부하기(短) - Chapter 11 읽고 공부하기 - Chapter 13 읽고 공부하기 - Chapter 14읽고 공부하기 - Chapter 15읽고 공부하기 - Chapter 16읽고 공부하기
3. 표본분포
4. 통계
5. 통계적 추론
🚍 출근! (8:00 - 8:30)
어제 10시정도에 자서 오늘은 3시 40분정도에? 기상하였다.
확실히 일찍자고 일찍일어나니 충분히 잘수도 있었고 좋았던 것 같다.
📖 공부! (9:00-12:00)
∙ Deep Learning(Bishop 2024): 번역 진행. - Chapter 6 읽고 공부하기 - Chapter 7 읽고 공부하기(短) - Chapter 8 읽고 공부하기(短) - Chapter 9 읽고 공부하기(短) - Chapter 10 읽고 공부하기 - Chapter 12 읽고 공부하기 - Chapter 17 읽고 공부하기(短) - Chapter 18 읽고 공부하기(短) - Chapter 19 읽고 공부하기(短) - Chapter 20 읽고 공부하기(短)
🍚 밥이다 밥! (12:30~13:00)
마찬가지로 서편제(한식): 동편제 치킨 나왔는데...ㅠㅠ 다 떨어져서 서편제 받아버렸다... 후식으로는 내돈내산 레몬요거트스무디!!
📖 공부! (13:30-18:00)
이어서 진행!
🚍 퇴근! (18:30 - 19:00)
퇴근이 제일 좋다는 직장인의 말에 공감이 점점된다ㅋㅋㅋ 아침출근때문에 그냥 졸리다ㅋㅋ 피곤🩸하고ㅠㅠ
🏋🏻 운동! (19:00 -)
이제 3대 운동보단 좀 더 세분화해서 A,B루틴 안하는 날에는 가슴,삼두, 등,이두, 어께 위주로 해봐야겠다. 아 그리고 데드나 스쿼트의 경우에는 조금 텀을 둬야겠다... 격일마다 무겁게만 하다보니 오히려 퍼포먼스가 안나오는 느낌? 그래서스쿼트와 데드의 경우에는 일주일에 1~2번정도만 본세트무게로❗️ 나머지는 평소드는 무게의 8~90%정도의 중량만들어야겠당
∙ Deep Learning(Bishop 2024): Chapter 3 이다. 3.1. Discrete Variables 3.2. The Multivariate Gaussian: 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3. Periodic Variables 3.4. The Exponential Family 3.5. Nonparametric Methods 3.5.1 3.5.2 3.5.3
하하... 끝났다 하하하하
🍚 밥이다 밥! (12:30~13:00)
마찬가지로 동편제(한식): 돈까스... 뭐 그런게 나왔다. 후식으로는 내돈내산 에스프레소프라푸치노(실수로 생크림 추가해버렸다ㅋㅋㅋ)
📖 공부! (13:30-18:00)
이어서 진행!
🚍 퇴근! (18:30 - 19:00)
퇴근이 제일 좋다는 직장인의 말에 공감이 점점된다ㅋㅋㅋ 아침출근때문에 그냥 졸리다ㅋㅋ 피곤🩸하고ㅠㅠ
🏋🏻 운동! (19:00 -)
이제 3대 운동보단 좀 더 세분화해서 A,B루틴 안하는 날에는 가슴,삼두, 등,이두, 어께 위주로 해봐야겠다. 아 그리고 데드나 스쿼트의 경우에는 조금 텀을 둬야겠다... 격일마다 무겁게만 하다보니 오히려 퍼포먼스가 안나오는 느낌? 그래서스쿼트와 데드의 경우에는 일주일에 1~2번정도만 본세트무게로❗️ 나머지는 평소드는 무게의 8~90%정도의 중량만들어야겠당
2. 주중에 할 것: Deep Learning 2024(Bishop) - Chapter 2: Exercise 풀기. - Chapter 3: Exercise 풀기.
- Chapter 6 읽고 공부하기 - Chapter 7 읽고 공부하기(短) - Chapter 8 읽고 공부하기(短) - Chapter 9 읽고 공부하기(短) - Chapter 10 읽고 공부하기 - Chapter 12 읽고 공부하기 - Chapter 17 읽고 공부하기(短) - Chapter 18 읽고 공부하기(短) - Chapter 19 읽고 공부하기(短) - Chapter 20 읽고 공부하기