๊ทธ๋ฆผ ์ฐธ๊ณ 1:
๊ทธ๋ฆผ ์ฐธ๊ณ 2:
Understanding 1D and 3D Convolution Neural Network | Keras | by Shiva Verma | Towards Data Science
1. ๋ฐ์ดํฐ์ ๊ฐ์
Batch size : 100000
Sequence : 10
Feature : 3 (x-axis, y-axis, z-axis)
Dataset shape : (100000, 10, 3) = (Batch size, Sequence, Feature) = (B, S, F)
2. ๋ชจ๋ธ ๊ตฌ์ฑ
1. Conv1D
CNN์ convolution layer, pooling layer, fully connected layer๋ก ์ฃผ๋ก ๊ตฌ์ฑ๋๋ค. ๊ทธ ์ค convolution layer์ pooling layer๋ ๋ ๊ฐ์ ํน์ ์ ๊ฒฝ๋ง ๋ ์ด์ด๋ก ์ฃผ๋ก ์ ํจ ํน์ง ์ถ์ถ์ ๋ด๋นํ๋ค. ์๋ณธ ๋ฐ์ดํฐ์์ ๋ฒกํฐ๋ฅผ ์ถ์ถํ๊ณ ์๋ณธ ๊ธฐ๋ฅ์ ๊ณต๊ฐ์ ์ ๋ณด๋ฅผ ๋ง์ด๋ํ ์ ์๋ค. ๊ฐ์๋๊ณ์ ๊ฐ์ 1์ฐจ์ ๋ฐ์ดํฐ๋ฅผ 1์ฐจ์ ์ปจ๋ณผ๋ฃจ์ ์ ๊ฒฝ๋ง(Conv1D)์ ์ฌ์ฉํ์ฌ ์๋ก ๋ค๋ฅธ ๋ณ์๋ฅผ ๊ฒฐํฉํ๊ณ ๋ณ์ ๊ฐ์ ๊ณต๊ฐ์ ์๊ด ๊ด๊ณ๋ฅผ ์ถ์ถํ๋ค.
Conv1D๋ ๊ทธ๋ฆผ 2์ ๊ฐ์ด ํ ์ฐจ์์ ๋ํด ์ปค๋ ์ฌ๋ผ์ด๋ฉ์ ํตํด ๊ณต๊ฐ์ ์๊ด ๊ด๊ณ๋ฅผ ์ถ์ถํ๋ค.
2. LSTM
LSTM์ ์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ณ ์ ์ ์ธ ๋ฅ ๋ฌ๋ ๋คํธ์ํฌ์ด๋ค. ์ํ ์ ๊ฒฝ๋ง์ด ๊ธด ์๊ณ์ด์ ์ด๋ ์ ๋ ์ฒ๋ฆฌํ ๋ ๊ธฐ์ธ๊ธฐ ์์ค(Vanishing gradient) ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ํ ์ ๊ฒฝ๋ง์ ๋ณํ์ ๋๋ค. ์ฅ๊ธฐ ๋ฐ ๋จ๊ธฐ ๊ธฐ์ต ๋คํธ์ํฌ์ ์ ๊ตฌ์กฐ๋ ๊ทธ๋ฆผ 3๊ณผ ๊ฐ์ด ๋ง๊ฐ ๊ฒ์ดํธ, ์ ๋ ฅ ๊ฒ์ดํธ ๋ฐ ์ถ๋ ฅ ๊ฒ์ดํธ๊ฐ ์๋ค.
3. Conv1D + LSTM
Conv1D + LSTM ๋ชจ๋ธ์ ๊ทธ๋ฆผ 1๊ณผ ๊ฐ์ด Conv1D ๊ธฐ๋ฐ์ ํน์ง ์ตํฉ ๋ ์ด์ด, LSTM ๊ธฐ๋ฐ ์๊ณ์ด ์์ธก ๋ ์ด์ด, output layer๋ก ๊ตฌ์ฑ๋๋ค. Input layer์๋ ๊ทธ๋ฆผ 0๊ณผ ๊ฐ์ ์๊ณต๊ฐ์ ํน์ฑํ๋ ฌ์ด ์ ๋ ฅ๋๋ค. ๊ฐ ๋ณ์๋ CNN์ ์ํด โโ๊ฐ์ค์น๊ฐ ๋ถ์ฌ๋๊ณ ๋ณ์ ๊ฐ์ ์ ๋ณด๊ฐ ๊ฒฐํฉ๋๋ค. ๊ณผ์ ํฉ(Overfitting)์ ํผํ๊ธฐ ์ํด dropout layer๊ฐ ๋คํธ์ํฌ์ ์ถ๊ฐ๋ฉ๋๋ค. ๋ชจ๋ธ ํ๋ผ๋ฏธํฐ๋ ๊ทธ๋ฆผ 4์ ๊ฐ์ด ๊ตฌ์ฑํ๋ค.
๋ชจ๋ธ์ ๊ตฌ์ฑํ๊ฒ ๋๋ฉด ์๋์ ์ฝ๋์ ๊ฐ์ด ๊ตฌํํ ์ ์๋ค.
import torch.nn as nn
class Conv1d_LSTM(nn.Module):
def __init__(self, in_channel=3, out_channel=1):
super(Conv1d_LSTM, self).__init__()
self.conv1d_1 = nn.Conv1d(in_channels=in_channel,
out_channels=16,
kernel_size=3,
stride=1,
padding=1)
self.conv1d_2 = nn.Conv1d(in_channels=16,
out_channels=32,
kernel_size=3,
stride=1,
padding=1)
self.lstm = nn.LSTM(input_size=32,
hidden_size=50,
num_layers=1,
bias=True,
bidirectional=False,
batch_first=True)
self.dropout = nn.Dropout(0.5)
self.dense1 = nn.Linear(50, 32)
self.dense2 = nn.Linear(32, out_channel)
def forward(self, x):
# Raw x shape : (B, S, F) => (B, 10, 3)
# Shape : (B, F, S) => (B, 3, 10)
x = x.transpose(1, 2)
# Shape : (B, F, S) == (B, C, S) // C = channel => (B, 16, 10)
x = self.conv1d_1(x)
# Shape : (B, C, S) => (B, 32, 10)
x = self.conv1d_2(x)
# Shape : (B, S, C) == (B, S, F) => (B, 10, 32)
x = x.transpose(1, 2)
self.lstm.flatten_parameters()
# Shape : (B, S, H) // H = hidden_size => (B, 10, 50)
_, (hidden, _) = self.lstm(x)
# Shape : (B, H) // -1 means the last sequence => (B, 50)
x = hidden[-1]
# Shape : (B, H) => (B, 50)
x = self.dropout(x)
# Shape : (B, 32)
x = self.fc_layer1(x)
# Shape : (B, O) // O = output => (B, 1)
x = self.fc_layer2(x)
return x