합성곱 신경망(CNN)
순환 신경망(RNN)
어테션(Atention) 메커니즘
자연어 처리(NLP) 모델
회고
☑️ 합성곱 신경망(CNN)
🔎합성곱 신경망(CNN)이란?
- 이미지와 같은 2차원 데이터의 특징을 효과적으로 추출하기 위해 설계 된 신경망
- 필터를 통해 필터 내부의 값들을 학습함으로써
- 합성곱 층, 풀링 층, 완전연결 층으로 구성
- 합성곱 층: - 다차원 데이터의 특징을 효과적으로 추출 - 입력 이미지에 필터(커널)을 적용하여 특징 맵을 생성 - 필터는 이미지의 국소적인 패턴을 학습
- 풀링 층 - 특징 맵의 크기를 줄이고 중요한 특징을 추출 - 주로 Max Pooling 과 Average Pooling이 사용
- 완전 연결 층 - 추출된 특징을 바탕으로 최종 예측을 수행 - CNN이라는 분석레이어를 통해 추출한 특성을 바탕으로 결론을 내리는 부분
🔎 합성곱 연산의 원리와 필터의 역할
- 합성곱 연산은 입력 이미지에 필터(커널)를 적용하여 특징 맵을 생성하는 과정입니다. 필터는 작은 크기의 행렬로, 이미지의 국소적인 패턴을 학습합니다.
- 합성곱 연산:
- 필터를 이미지의 각 위치에 슬라이딩하며, 필터와 이미지의 해당 부분 간의 점곱(dot product)을 계산합니다.
- 계산된 값은 특징 맵의 해당 위치에 저장됩니다.
- 필터의 역할:
- 필터는 이미지의 에지(edge), 코너(corner), 텍스처(texture) 등 다양한 국소적인 패턴을 학습합니다.
- 여러 개의 필터를 사용하여 다양한 특징 맵을 생성할 수 있습니다.
🔎 풀링 레이어의 필요성과 종류
- 풀링 층은 특징 맵의 크기를 줄이고, 중요한 특징을 추출하는 역할을 합니다. 풀링 층은 주로 Max Pooling과 Average Pooling이 사용됩니다.
- Max Pooling:
- 필터 크기 내에서 최대 값을 선택합니다.
- 중요한 특징을 강조하고, 불필요한 정보를 제거합니다.
- Average Pooling:
- 필터 크기 내에서 평균 값을 계산합니다.
- 특징 맵의 크기를 줄이면서, 정보의 손실을 최소화합니다.
🔎 플래튼 레이어의 역할
- 플래튼 층(Flatten Layer)은 2차원 특징 맵을 1차원 벡터로 변환하는 역할을 합니다. 이는 완전 연결 층에 입력으로 사용하기 위해 필요합니다.
📚CNN 모델 정의
calss SimpleCNN(nn.Module): #nn.module을 import
def__init__(self):
super(SimpleCNN, self).__init__()
#nn.Conv2d(입력채널, 출력 채널, 커널크기 3*3)
#입력채널에 흑백사진은 1, RGB(컬러)인 경우에 3
#출력채널이 증가하는 이유는 필터의 개수를 조절할 수 있기 때문
self.conv1 = nn.Conv2d(3, 32, 3, padding=1)
self.pool = nn.MaxPool2d(2, 2)
#다음 레이어의 입력은 그 전의 출력과 동일해야 한다.
self.conv2 = nn.Conv2d(32, 64, 3, padding=1)
self.fc1 = nn.Linear(64 * 8 * 8, 512)
self.fc2 = nn.Linear(512,10)
def forward(self, x):
#relu 컨볼루션할 네트워크 뒤에 활성화 함수가 와야한다.(복잡한 데이터 특성 학습하기 위해)
x = self.pool(torch.relu(self.conv1(x)))
x = self.pool(torch.relu(self.conv2(x)))
x = x.view(-1, 64 * 8 * 8) # 플래튼 (차원 축소 즉. 펼친다)
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
☑️ 순환 신경망(RNN)
🔎 순환 신경망(RNN)
- 시퀀스 데이터를 다루는데 유용 (주가 / 문장 등 데이터가 숱서를 이루고있을 때)
- 시계열 데이터를 처리하기 위해서 각 시점에서 입력을 받는다. tn => 그 때 출력을 바로 다음 시간에 입력으로 받는다 => 이 과정에서 이전 시점의 정보를 저장하는 숨겨진 상태
- RNN의 기본 요소는 순환노드 일반적으로 쉘 각 시점의 입력과 숨겨진 상태를 결합해 새로운 숨겨진 상태와 출력을 만든다 이렇게 새롭게 만들어진 hidden state는 다시 순환을 한다.
- 시퀀스의 각 시간 단계에서 동일한 가중치 공유 (가중치가 전체적으로 업데이트 된다.)
🔎LSTM & GRU
- 기울기 소실 문제 해결 위한 방법
1. LSTM은 셀 + 게이트(입력게이트 / 망각 게이트/출력 게이트)로 구성
- 셀: 각 시점 정보흐름 조절, 정보 장기 유지
- 게이트: 정보를 선택적으로 저장하거나 삭제
- 입력 게이트: 새로운 입력과 이전의 숨겨진 상태를 결합해서 새로운 정보가 새 상태에 얼마나 반영할지 조절해준다.
- 망각 게이트: 새 상태에서 어떤 정보를 잊을지 정해준다.
- 입력 / 망각 게이트의 출력을 바탕으로 쉘상태 업데이트 한다.
- 출력 게이트: 새로운 쉘 상태와 입력 데이터를 바탕으로 출력을 생성
- 그리고 다시 순환한다.
2. GRU
- LSTM의 변형으로 더 간단한 구조
- 쉘상태와 hidden state를 통합한다.
- 리셋/ 업데이트 게이트로 구성
- 리셋 게이트: 새정보와 이전 정보를 결합해 이전 정보를 얼마나 잊어 버리는기 결정하는데 사용
- 업데이트 게이트: 이전 상태와 새로운 입력을 결합 그리고 새로운 정보가 상태에 반영할지 결정
=> RNN은 시퀀스 데이터에 적합하다 이전 단계를 반영할 수 있어서 근데 긴 시퀀스에선 정상적이지 않아 게이트를 활용해 정보를 체계적으로 관리하는 LSTM과 GRU가 나왔다.
🔎시계열 데이터 처리
- 데이터 전처리:
- 시계열 데이터를 적절한 형태로 변환하고, 정규화(normalization)합니다.
- 입력 시퀀스와 출력 시퀀스를 정의합니다.
- 모델 구축:
- RNN, LSTM, GRU 등의 모델을 정의합니다.
- 입력 크기, 은닉 상태 크기, 출력 크기 등을 설정합니다.
- 모델 학습:
- 손실 함수와 최적화 알고리즘을 정의합니다.
- 순전파와 역전파를 통해 모델을 학습시킵니다.
- 모델 평가:
- 테스트 데이터를 사용하여 모델의 성능을 평가합니다.
📚데이터 셋 생성 및 전처리
# Sine 파형 데이터 생성 (sine함수는 위아래로 구불구불하게 반복되는 것)
def create_sine_wave_data(seq_length, num_samples):
X = []
y = []
for _ in range(num_samples):
start = np.random.rand()
x = np.linspace(start, start + 2 * np.pi, seq_length)
X.append(np.sin(x))
y.append(np.sin(x + 0.1))
return np.array(X), np.array(y)
seq_length = 50
num_samples = 1000
X, y = create_sine_wave_data(seq_length, num_samples)
# 데이터셋을 PyTorch 텐서로 변환(pytorch에서tensor라는건 기울기를 계산할 수 있는 자료구조)
X = torch.tensor(X, dtype=torch.float32).unsqueeze(-1)
y = torch.tensor(y, dtype=torch.float32).unsqueeze(-1)
📚RNN 모델 정의
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleRNN, self).__init__()
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True) #RNN만들기( batch_first=True는 첫번째 batch 결정)
self.fc = nn.Linear(hidden_size, output_size) #출력레이어
def forward(self, x):
h0 = torch.zeros(1, x.size(0), hidden_size) # 초기 은닉 상태 (초기 값에는 hidden state가 없기 때문)
out, _ = self.rnn(x, h0) #rnn에 x를 전달해주고 다시 은닉상태 전달
out = self.fc(out[:, -1, :]) # 마지막 시간 단계의 출력
return out
input_size = 1
hidden_size = 32
output_size = 1
model = SimpleRNN(input_size, hidden_size, output_size)
📚LSTM모델 정의
class SimpleLSTM(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleLSTM, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
h0 = torch.zeros(1, x.size(0), hidden_size) # 초기 은닉 상태
c0 = torch.zeros(1, x.size(0), hidden_size) # 초기 셀 상태
out, _ = self.lstm(x, (h0, c0))
out = self.fc(out[:, -1, :]) # 마지막 시간 단계의 출력
return out
model = SimpleLSTM(input_size, hidden_size, output_size)
📚모델학습
# 손실 함수와 최적화 알고리즘 정의
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01) #여기선 Adam을 쓰고있는데 SGD나 다른 것들도 있지만 실험적으로 사요해보아야한다.
# 모델 학습
num_epochs = 100
for epoch in range(num_epochs):
outputs = model(X)
optimizer.zero_grad()
loss = criterion(outputs, y)
loss.backward()
optimizer.step()
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
print('Finished Training')
☑️ 어텐션 (Attention) 메커니즘
🔎 어텐션 (Attention) 메커니즘란?
- 시퀀스 데이터의 중요한 부분에 많은 가중치를 할당해서 종보를 효율적
- 자연어 처리, c계열 데이터에서 사용 (번, 요약, 질의 응답 등)
- 입력의 시퀀스를 보고 중요도를 평가해 가중치로 바뀌어 각 요소에 부여
🔎 어텐션 (Attention) 메커니즘란 동작방식
- Atention score(중요도) = query와 key간의 유사도를 dot product를 사용해 계산
- 계산된 Atention score(중요도)는 Softmax 함수를 통해 확률로 변환
- 모든 Atention score (가중치)의 합은 1이 된다
- 이 Atention score(가중치)를 value에 곱한다
- 그러면 value에는 가중치가 반영된 정보다 된다.(중요한 부분이 어딘지 판별할 수 있게 되는 것이다)
- 비유
- 독서클럽에서 책을 읽는다(책=시퀀스입력데이터)
- 멤버들이 서로 질문을하고 답을 참고하며 중요도를 찾는다
- 답(key), 질문(query쿼리)을 비교해서 얼마나 중요한지 평가 후 가중치 부여
- 최종덕으로 답에 기반해서 최종 요약(value)을 만든다.
🔎 Multi-Head Attention
- Multi-Head Attention은 여러 개의 Self-Attention을 병렬로 수행하는 메커니즘입니다.
- 각 헤드는 서로 다른 부분의 정보를 학습하며, 이를 통해 모델이 다양한 관점에서 데이터를 처리할 수 있습니다.
☑️ 자연어 처리(NLP) 모델
🔎 자연어 처리(NLP)란?
- 자연어를 컴퓨터가 이해하고 처리할 수 있도록 돕는 기술을 자연어 처리(NLP)라고 합니다. 이를 통해 컴퓨터는 사람의 언어를 분석하고, 번역하거나 질문에 답하는 등의 작업을 수행할 수 있습니다
🔎워드 임베딩 기법
- 단어를 고정된 크기의 백터(숫자)로 변환 시킨다.
- 대표적인 워드 임베딩 기법으로는 Word2Vec과 GloVe가 있습니다.
Word2Vec
단어를 백터로 변환하는 2가지 모델 제공
- CBOW (Continuous Bag of Words): 주변 단어(context)로 중심 단어(target)를 예측합니다. ( 나 장한검 백수 라고 하면 "나" 와 "백수"를 사용해 예측한다.)
- Skip-gram: 중심 단어(target)로 주변 단어(context)를 예측합니다. ( 나 장한검 백수에서 "장한검"을 보고 "나"와 "백수" 예측)
GloVe
단어-단어 공기행렬(word-word co-occurrence matrix)을 사용, 단어 벡터를 학습합니다
🔎 Transformer의 구조와 원리
- Transformer는 순차적인 데이터를 병렬로 처리할 수 있는 모델로, 자연어 처리에서 뛰어난 성능을 보입니다.
- Transformer는 인코더-디코더(Encoder-Decoder) 구조로 구성됩니다
인코더
입력 문장을 인코딩(고차원 백터로 변환)
- 입력 백터들이 각각 고정된 크기의 백터(임베딩)으로 변환(이 때 포지셔널 인코딩이라는 것을 포함해서 단어의 순서정보를 백터에 포함 시켜준다)
- Multi-Head의 selfatention이 동작한다. 입력 백터들이 각기 다른 헤드를 통해 서로의 중요도를 평가하고 이 정보로부터 새로운 백터를 만든다.
- selfatention메커니즘을 사용해서 문장 내에 관계를 학습하게 된다.
디코더
- 위 백터를 보고 출력하고자하는 목적에 따라 문장을 생성
- 타겟문장의 각 단어를 고정 된 크기의 백터로 변환한다
- 포지셔널 인코딩을 추가
- 마스크드 멀티헤드 셀프 어텐션이 동작한다. (이전의 단어들만 참고할 수 있도록 selfatention을 마스킹해서 참고한다)
- 인코더 디코더 어텐션이 동작(디코더는 인코더의 출력백터를 참고하고 입력문장의 정보를 바탕으로 타겟문장의 다음 단어를 예측한다.)
- 어텐션으로 변환 된 백터가 나오는데 피드포워드신경망을 통해 추가로 변환된다.
- 이러한걸 여러 층을 통해 반복해서 인코딩 백터를 만들고 이걸 이용해 디코딩 백터를 만든다.
어텐션 메커니즘
- 어텐션 메커니즘은 입력 시퀀스의 각 위치에 가중치를 부여하여, 중요한 정보를 강조합니다.
- 셀프 어텐션은 입력 시퀀스 내의 단어 간의 관계를 학습합니다.
=> 인코더 디코더를 통해 입력문장을 인코딩하고 디코더를 통해 출력을 생성 이 과정에서 어텐션 메커니즘이 사용 되고 이는 단어간의 관계를 학습하는데 사용하게 된다.
인코더 디코더 어텐션을 통해 입력과 출력을 연결하고 모델은 데이터의 의미적 유사성을 학습하고 이를 바탕으로 번역을 진행하게 된다.
🔎 BERT란?
- Transformer 인코더를 기반으로 한 사전 학습된 언어 모델입니다.
- 양방향으로 문맥을 이해할 수 있어, 다양한 자연어 처리 작업에서 뛰어난 성능을 보입니다.
- 사전학습: 대규모 텍스트 코퍼스를 사용해 학습 된다. (마스킹 언어 모델, 다음 문장 예측 작업으로 학습)
- 입력을 처리해서 입력문장은 토큰화해서 단어토큰으로 변환
- 마스킹해서 일부 스퀀시를 마스킹한다.
- 인코더는 마스킹 된 시쿼스를 인코더로 처리해서 각 단어의 컨텍스트를 이해하고 마스킹 된 단어를 예측하고 다음 문장이 올바른지 예측하는 방식으로 동작
=> 사전학습된 bert모델은 특정 작업에 맞게 파인 튜닝 되는에 이를 통해 번역, 질의응답, 분류 등 다양한 목적에 맞춰 모델을 튜닝하게 된다.
☑️회고
최근 회고에는 궁금하거나 새롭게 알게 된 정보가 적게 들어 가는 것 같습니다.
그도그럴게 현재 배우는 부분이 머신러닝 딥러닝이다 보니 정의나 개념 새롭게 보게 되는 코드들이 어떤 작용을 하는지에 대한 부분만 주의 깊게 공부하고있기 때문입니다.
그래서 오전에 공부한 용어 공부 중
마음 속 한켠에 자리잡고있던 궁금증을 해결한 것을 적으려고 합니다.
그것은 바로 차원 배열 ndarray에 대한것 입니다.
1차원 2차원 3차원 4차원 처음 들었을 때는 저게 뭐지 싶었고
설명을 들으면 들을수록 코드를 작동시켜 답을 출력 시켜보아도 어떤 것인지 모르겟고
그냥 저런게 있구나 하고 넘어 갓는데
오늘 어느정도 이해했습니다.
- 3차원에 대한 이해
shape함수로 차원을 확인할 수 있습니다. 1차원 (n,)#(행) / 2차원 (n, n)#(행, 열) / 3차원(n, n, n)#(높이,행,열)
저는 3 차원이 이해가 안 가서
제가 이해하기 쉽게 하려고 엑셀 표 형식을 떠 올려서 정리를 했습니다.
arr_3d = np.array([ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ])
print(arr_3d.shape) #출력: (2, 2, 2)
각 셀마다 한 개의 숫자들이 들어간 2x2표가 2개가 만들어진 것이다.
셀 8개 중에 4개씩 1개의 표를 만들어 2개의 표가 된 것이 3차원
차원의 수로 표의 수가 정해지는 건지 궁금해져서 gpt에 물어보니 그건 또 아니네요
표가 늘어나는건 3차원 (n1,n2,n3)에서 n1인 높이 숫자가 올라가는거라고 하네요
- 브로드캐스팅
브로드캐스팅에서 두 개의 배열 중 하나라도 크기가 1인 것이 없으면 오류가 난다고 했는데 1은 바로 열의 크기였습니다.
쉽게 말해 대괄호[] 안에 1가지의 숫자만 들어간 배열이여야지 차원이 다른 배열끼리 브로드캐스팅이 된다고 합니다.
차원의 수가 올라갈수록 배열에 대괄호가 많아지는 것 같은데 정확히 어떻게 짜야하는 이해가 안되더군요.
그래도 고차원의 배열을 직접 손으로는 칠일은 없겟지 하는 마음으로 대괄호가[] 늘어나는구나 정도로 이해하고 넘어가겟습니다. 감사합니다.
'TIL' 카테고리의 다른 글
내일배움캠프 18일차 TIL + 노션, GITHUB, 머신러닝 코드 분석 (2) | 2024.10.22 |
---|---|
내일배움캠프 17일 차 TIL + 머신러닝 코드 (4) | 2024.10.21 |
내일배움캠프 14일차 TIL + 딥러닝 (1) | 2024.10.17 |
내일배움캠프 13일차 TIL + 비지도학습, 앙상블 학습, GIT (5) | 2024.10.16 |
내일배움캠프 12일차 TIL + 지도학습, GITHUB (0) | 2024.10.15 |