[오늘의 일지]
딥러닝 실시간 강의 - CNN, RNN 실습
[상세 내용]
CNN, RNN 실습
- 실습에 들어가기에 앞서서 수업 때 사용한 라이브러리는 pytorch였습니다. 기존에 tensorflow를 사용해 본 경험이 있어서 그런지 pytorch가 훨씬 더 코드를 짜야할 부분이 많았고 귀찮은 부분이 많았습니다. 그래도 코드를 자주 사용하면서 연습한다는 생각으로 실습을 따라갔습니다.
CNN 실습 코드
# Conv -> ReLU -> Conv -> ReLU -> MaxPool -> fc1 -> fc2 -> fc3(output) (model1)
# Conv block(Conv-ReLU x 2) -> MaxPool -> Conv block -> MaxPool -> fc(output) (model2)
class CNN(nn.Module):
def __init__(self):
# X = (N - F) / S + 1
super().__init__()
self.conv1 = nn.Conv2d(in_channels=3,
out_channels=6, # number of filters
kernel_size=3,
stride=1,
padding=1) # (3, 32, 32) --> (6, 32, 32)
self.conv2 = nn.Conv2d(6, 12, 3, 1, 1) # (6, 32, 32) --> (12, 32, 32)
self.maxpool1 = nn.MaxPool2d(kernel_size=2,
stride=2) # (12, 32, 32) --> (12, 16, 16)
self.conv3 = nn.Conv2d(12, 24, 3, 1, 1) # (12, 16, 16) --> (24, 16, 16)
self.conv4 = nn.Conv2d(24, 48, 3, 1, 1) # (24, 16, 16) -- >(48, 16, 16)
self.maxpool2 = nn.MaxPool2d(2, 2) # (48, 16, 16) --> (48, 8, 8)
self.conv5 = nn.Conv2d(48, 48, 3, 1, 1) # (48, 8, 8) --> (48, 8, 8)
self.conv6 = nn.Conv2d(48, 48, 3, 1, 1) # (48, 8, 8) --> (48, 8, 8)
self.maxpool3 = nn.MaxPool2d(2, 2) # (48, 8, 8) --> (48, 4, 4)
self.fc1 = nn.Linear(in_features=48*4*4, # 768
out_features=128)
#self.fc2 = nn.Linear(1024, 128)
self.fc3 = nn.Linear(128, 10)
self.relu = nn.ReLU()
self.softmax = nn.Softmax(dim=1)
def forward(self, x):
x = self.relu(self.conv1(x))
x = self.relu(self.conv2(x))
x = self.maxpool1(x)
x = self.relu(self.conv3(x))
x = self.relu(self.conv4(x))
x = self.maxpool2(x)
x = self.relu(self.conv5(x))
x = self.relu(self.conv6(x))
x = self.maxpool3(x)
x = torch.flatten(x, 1) # (batch_size, 12, 14, 14) -> (batch_size, 12*14*14)
x = self.relu(self.fc1(x))
#x = self.relu(self.fc2(x))
x = self.softmax(self.fc3(x))
return x
# 학습
for epoch in tqdm(range(epochs)):
n_correct = 0
total_loss = 0.0
for idx, data in enumerate(trainloader):
optimizer.zero_grad() # gradient 초기화.
## ReLU() ---> max(0, x)
## dReLU() --> if x < 0: 0, else: 1
## d(wx)/dw --> x (local gradient)
#### feed forward ####
#images, labels = data[0], data[1] # CPU version
images, labels = data[0].to(device), data[1].to(device) # GPU version
outputs = model(images) # forward(x)
loss = criterion(outputs, labels) # compute loss (tensor)
#print(f"Epoch {epoch} : {idx:4d} iteration -->\t{loss.item():.4f}") # loss value
n_correct = n_correct + (torch.max(model(images), dim=1)[1] == labels).sum() # batch당 맞은 개수.
total_loss += loss.item()
#### back propagation ####
loss.backward() # loss를 가지고 backprop
optimizer.step() # SGD를 이용해서 weight update를 수행함.
print(f"Epoch {epoch}, Train Accuracy : {n_correct/len(trainset):4f}\
| Train (average)Loss : {total_loss/len(trainloader):4f}")
end = time()
print("Training Done.")
print(f"Elasped Time : {end-start:.4f} secs.")
RNN 실습 코드
# 전처리
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# 스케일을 적용할 column을 정의합니다.
scale_cols = ['Open', 'High', 'Low', 'Volume', 'Close']
# 스케일 후 columns
df = samsung.loc[samsung.index > '20200101', scale_cols]
scaled = scaler.fit_transform(df)
scaled
# train와 test 분류
train = df.loc[df.index < '20230101']
###### 분류 시 변경 ######
X_train, y_train = train.drop("Close", axis=1), train.Close
test = df.loc[df.index > '20230101']
X_test, y_test = test.drop("Close", axis=1), test.Close
###### 분류 시 변경 ######
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)
# 데이터 전처리
from torch.utils.data import TensorDataset # 텐서데이터셋
from torch.utils.data import DataLoader # 데이터로더
seq_length = 30
batch_size = 32
# 20200102
# ...
# ...
# 20200214(open,high,low,close)
# -----> 20200215 (close)
# 데이터셋 생성 함수
def build_dataset(X, y, seq_length):
X_data = []
y_data = []
for idx in range(0, len(X)-seq_length):
# idx = 0 ~ len(X)-seq_length-1
_X = X[idx:idx+seq_length] # 30개 feature vectors
_y = y[idx+seq_length] # 1개 (31번째 target value, close)
###### 분류 시 변경 ######
## target value도 잘 만들어봅시다 ##
###### 분류 시 변경 ######
#print(_X, '--->', _y)
X_data.append(_X.values)
y_data.append(_y)
X_data = torch.FloatTensor(np.array(X_data))
y_data = torch.FloatTensor(np.array(y_data))
return X_data, y_data
trainX, trainY = build_dataset(X_train, y_train, seq_length)
testX, testY = build_dataset(X_test, y_test, seq_length)
# 텐서로 변환
# 텐서 형태로 데이터 정의
trainset = TensorDataset(trainX, trainY)
testset = TensorDataset(testX, testY)
# 데이터로더는 기본적으로 2개의 인자를 입력받으며 배치크기는 통상적으로 2의 배수를 사용
trainloader = DataLoader(trainset,
batch_size=batch_size,
shuffle=True,
drop_last=True)
testloader = DataLoader(testset,
batch_size=batch_size,
shuffle=False,
drop_last=True)
# LSTM으로 모델 코드 짜기
class LSTM(nn.Module):
# # 기본변수, layer를 초기화해주는 생성자
def __init__(self, input_dim, hidden_dim, seq_len, output_dim, n_layers):
super().__init__()
self.input_dim = input_dim # input feature vector dim
self.hidden_dim = hidden_dim # hidden layer node 개수 (= hidden state dim)
self.seq_len = seq_len # hidden state 개수 (=input sequence length)
self.output_dim = output_dim # output layer의 node 개수 (=output dim)
self.n_layers = n_layers # multi-layer로 구성할 때, (hidden, LSTM)layer 수
self.lstm = nn.LSTM(input_size=input_dim, # Wxh (input_dim x hidden_dim)
hidden_size=hidden_dim, # Whh (hidden_dim x hidden_dim)
num_layers=n_layers,
batch_first=True,
dropout=0.1, # hidden layer의 node중에 일부를 deactivate 시킴.
bidirectional=False) # (batch_size, ~~~~)
self.fc = nn.Linear(in_features=hidden_dim,
out_features=output_dim) # Why
###### 분류 시 변경 ######
######### TO-DO ###########
# output layer를 디자인해봅시다.
###### 분류 시 변경 ######
# self.rnn = nn.RNN(input_size=4,
# hidden_size=10,
# num_layers=1,
# batch_first=True)
# self.fc = nn.Linear(10, 1)
# 예측을 위한 함수
def forward(self, x): # (N, L, H_in)
# (n_layers, batch_size, hidden_dim)
h0 = torch.zeros(self.n_layers, x.size(0), self.hidden_dim).to(device)
c0 = torch.zeros(self.n_layers, x.size(0), self.hidden_dim).to(device)
# input : (x, (h0, c0))
# output : (x, (hn, cn))
x, (hn, cn) = self.lstm(x, (h0, c0)) # (N, L, H_in) ---(LSTM)---> (N, L, H_out)
# e.g. (batch_size, seq_len, hidden_dim)
## 마지막 출력결과(last_hidden_state) ---> (batch_size, hidden_dim)
x = self.fc(x[:, -1, :]) # (batch_size, hidden_dim) ---> (batch_size, output_dim) ## Linear Regression
return x, (hn, cn)
[마무리]
오늘은 cnn과 rnn의 실습 위주의 수업이 진행되었습니다. 우선은 강사님이 예시로 써주시는 코드를 따라 쓰기에 바빴지만 나중에 실전에서 사용할 때 어느 정도 능숙하게 사용할 수 있게 여러 번 반복해서 사용도 해보고 파라미터들도 많이 바꿔 가면서 기능도 익숙해지도록 노력해야겠습니다.
반응형
'AI > 딥러닝' 카테고리의 다른 글
[AI 부트캠프] DAY 71 - 딥러닝 7 (0) | 2023.11.01 |
---|---|
[AI 부트캠프] DAY 70 - 딥러닝 6 (2) | 2023.10.31 |
[AI 부트캠프] DAY 68 - 딥러닝 4 (0) | 2023.10.27 |
[AI 부트캠프] DAY 67 - 딥러닝 3 (0) | 2023.10.26 |
[AI 부트캠프] DAY 66 - 딥러닝 2 (0) | 2023.10.25 |
댓글