data augmentation๊ณผ dropout์ ์ด์ฉํ ์ฑ๋ฅ ๋์ด๊ธฐ(๊ณผ์ ํฉ ์ค์ด๊ธฐ)
convolution filter์ ์ฌ์ฉํ ์ด๋ฏธ์ง ์ฒ๋ฆฌ
convolution Layer
: ์ด๋ฏธ์ง ํน์ง ์ถ์ถpooling Layer
: ํํฐ๋ฅผ ๊ฑฐ์น ์ฌ๋ฌ ํน์ง ์ค ๊ฐ์ฅ ์ค์ํ ํน์ง ํ๋๋ฅผ ๊ณ ๋ฅด๊ธฐ (๋ ์ค์ํ ํน์ง์ ๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ์ง ์ฐจ์์ด ์ถ์)
์ปจ๋ณผ๋ฃจ์ ์ปค๋์ ์ฌ๋ฌ๊ฒน ๊ฒน์น๋ฉฐ ๋ณต์กํ ๋ฐ์ดํฐ์๋ ์ฌ์ฉ๊ฐ๋ฅ
- shortcut ๋ชจ๋์ ์ฆํญํ ๋๋ง ๋ฐ๋ก ๊ฐ๊ฒ ๋จ
class BasicBlock(nn.Module):
...
def forward(self,x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x)
out = F.relu(out)
return out
class ResNet(nn.Module):
...
def _make_layer(self, planes, num_blocks, stride):
strides = [stride] + [1]*(num_blocks - 1)
layers = []
for stride in strides:
layers.append(BasicBlock(self.in_planes, planes, stride))
self.in_planes = planes
return nn.Sequential(*layers)
...
์ฌ๋์ ์ง๋ ์์ด ํ์ต(encoder + decoder), ์ ์ฌ๋ณ์ ์๊ฐํ, ์ก์์ ํตํ์ฌ ํน์ง ์ถ์ถ ์ฐ์ ์์ ํ์ธ
- tokenizing, word dictionary, word embedding
- RNN์ gradient vanishing์ ํด๊ฒฐํ๊ธฐ ์ํ์ฌ GRU ์ฌ์ฉ
update gate
์ด์ ์๋ ๋ฒกํฐ๊ฐ ์ง๋ ์ ๋ณด๋ฅผ ์๋ก์ด ์๋ ๋ฒกํฐ๊ฐ ์ผ๋ง๋ ์ ์งํ ์งreset gate
์๋ก์ด ์ ๋ ฅ์ด ์ด์ ์๋ ๋ฒกํฐ์ ์ด๋ป๊ฒ ์กฐํฉํ๋์ง ๊ฒฐ์
- ์ธ์ฝ๋ RNN + ๋์ฝ๋ RNN
โ Teacher Forcing
- ๋ง์ ๋ฐ์ดํฐ์์๋ ๋์ฝ๋๊ฐ ์์ธกํ ํ ํฐ์ ๋ค์ ๋ฐ๋ณต์์ ์ ๋ ฅ๋ ํ ํฐ์ผ๋ก ๊ฐฑ์ ํด์ฃผ๋ ๊ฒ์ด ์ ์
- ํ์ง๋ง ํ์ต์ด ์์ง ๋์ง ์์ ์ํ์ ๋ชจ๋ธ์ ์๋ชป๋ ์์ธก ํ ํฐ์ ์ ๋ ฅ์ผ๋ก ์ฌ์ฉ๋ ์ ์์ผ๋ฏ๋ก, Teacher Forcing ์ฌ์ฉ
- ๋์ฝ๋ ํ์ต ์ ์ค์ ๋ฒ์ญ๋ฌธ์ ํ ํฐ์ ๋์ฝ๋์ ์ ์ถ๋ ฅ ๊ฐ ๋์ ์ ๋ ฅ์ผ๋ก ์ฌ์ฉํด ํ์ต์ ๊ฐ์ํ๋ ๋ฐฉ๋ฒ
- ๋ฒ์ญ๋ฌธ์ i๋ฒ์งธ ํ ํฐ์ ํด๋นํ๋ ๊ฐ targets[i] ๋ฅผ ๋์ฝ๋์ ์ ๋ ฅ๊ฐ์ผ๋ก ์ค์
def __init__(self, vocab_size, hidden_size):
...
self.embedding = nn.Embedding(vocab_size, hidden_size)
self.encoder = nn.GRU(hidden_size, hidden_size)
self.decoder = nn.GRU(hidden_size, hidden_size)
self.project = nn.Linear(hidden_size, vocab_size)
def forward(self, inputs, targets):
...
embedding = self.embedding(inputs).unsqueeze(1) #์๋ฒ ๋ฉ
encoder_output, encoder_state = self.encoder(embedding, initial_state)
# encoder_state: ๋ฌธ๋งฅ๋ฒกํฐ >> decoder์์ ์ฒซ๋ฒ์งธ ์๋๋ฒกํฐ๋ก ์ฐ์
# encoder_output: y >> ์ค์ output ๊ฐ
decoder_state = encoder_state
...
decoder_output, decoder_state = self.decoder(decoder_input, decoder_state)
# ๋์ฝ๋์ ์ถ๋ ฅ๊ฐ์ผ๋ก ๋ค์ ๊ธ์ ์์ธกํ๊ธฐ
projection = self.project(decoder_output)
outputs.append(projection)
#ํผ์ฒ ํฌ์ฑ์ ์ด์ฉํ ๋์ฝ๋ ์
๋ ฅ ๊ฐฑ์
decoder_input = torch.LongTensor([targets[i]])
...
FGSM ๊ณต๊ฒฉ
1.AdversialAttack
์๋ก์ด ์ด๋ฏธ์ง ์์ฑ
cGAN์ ๋ ์ด๋ธ ์ ๋ณด ์ถ๊ฐ
# '์ง์ง'์ '๊ฐ์ง' ๋ ์ด๋ธ ์์ฑ
real_labels = torch.ones(BATCH_SIZE, 1)
fake_labels = torch.zeros(BATCH_SIZE, 1)
#์ง์ง์ ๊ฐ์ง ์ด๋ฏธ์ง๋ฅผ ๊ฐ๊ณ ๋ธ ์ค์ฐจ๋ฅผ ๋ํด์ ํ๋ณ์์ ์ค์ฐจ ๊ณ์ฐํ๋ค
d_loss = criterion(D(images), real_labels) + criterion(D(G(z)), fake_labels)
๊ฒ์ํ๊ฒฝ์์ ์ค์ค๋ก ์ฑ์ฅ
- DQN-cartpole
memory๋ฅผ deque์ ๋ฃ์ด์ ์ค๋๋ ๊ฒฝํ(๋ฉ์ฒญํ ๋์ ๊ฒฝํ)์ ์ญ์ ๋จ
act() ํจ์๋ epsilon๊ฐ์ ๋ฃ์ด์ฃผ์ด ๋ฌด์์ ํ๋์ ํ๋๋ก ํจ
self.model(state)
- ํ๋๋ค์ ๋ํ ๊ฐ์น๊ฐ
action
์ epsilon ํฉ์ณ์ ธ์ 1,0 ๋ ์ค ํ๋ action ๊ณ ๋ฆ
loss๋ ํ์ฌ ๊ฐ์น๊ฐ(์ ๋ต)๊ณผ ์์ธก๋ ๊ฐ์น๊ฐ(์์ธก, ํ ์ธํด์ค)์ ์ฐจ์ด๋ก ๊ตฌํด์ค
env= gym.make('CartPole-v0')
agent = DQNAgent()
for e in range(1, EPISODES+1):
state= env.reset()
...
while True:
env.render() # ๊ฒ์ ํ๋ฉด ๋์ฐ๊ธฐ
torch.Tensor([[1,2,3],[4,5,6]], dtype = torch.int32, device = device)
# torch์์ dtype ๋ device ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ
y = torch.as_tensor(x, dtype = torch.half, device = 'cpu')
y = x.to(device, dtype = torch.float.64)
# start๋ถํฐ end๊น์ง step๋ณ๋ก tensor
torch.arange(start = 0, end, step = 1, dtype = None, requires_grad = True)
torch.from_numpy() #numpy array์ธ ndarray๋ก๋ถํฐ ํ
์๋ฅผ ๋ง๋ฆ
# N(0,1) ์ ๊ท๋ถํฌ๋ฅผ ๋ฐ๋ฅด๋ random ํจ์ ์ถ์ถ
torch.randn(*sizes, dtype = , device = , requires_grad = )
torch.Tensor
์ Autogradํจํค์ง๋ ๋ชจ๋ ์ฐ์ฐ์ ๋ํด ์๋๋ฏธ๋ถ์ ์ ๊ณต
ํ
์์ ์์ฑ ์ค ํ๋์ธ x.requires_grad = True
๋ก ํ๋ฉด ํ
์์ ๋ชจ๋ ์ฐ์ฐ์ ๋ํด์ ์ถ์ ์ ์์
๊ณ์ฐ ์์
ํ x.backward()
๋ฅผ ํธ์ถํ๋ฉด ๋ชจ๋ ๊ทธ๋ ์ด๋์ธํธ๋ฅผ ์๋์ผ๋ก ๊ณ์ฐํ ์ ์๋๋ก ํจ
ํ
์์ ๋ํ ๊ธฐ๋ก(history) ์ถ์ ์ค์งํ๋ ค๋ฉด x.detach()
ํธ์ถ
: ํ์ฌ ๊ณ์ฐ ๊ธฐ๋ก์ผ๋ก๋ถํฐ ๋ถ๋ฆฌ์ํค๊ณ ์ดํ ์ผ์ด๋๋ ๊ณ์ฐ๋ค์ ์ถ์ ๋์ง ์๋๋ค.
๊ธฐ๋ก ์ถ์ (๋ฐ ๋ฉ๋ก๋ฆฌ ์ฌ์ฉ)์ ๋ํด ๋ฐฉ์ง๋ฅผ ํ๋ ค๋ฉด with.no_grad()
๋ฅผ wrap ๊ฐ๋ฅ
์ด ํ
์์ ๋ณํ๋๋ x.grad
์์ฑ์ ๋์ ๋๋ค
: with.no_grad()๋ ๋ณํ๋(gradient)๋ ํ์์์ง๋ง requires_grad = True
๊ฐ ์ค์ ๋์ด ํ์ต๊ฐ๋ฅํ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ๋ ๋ชจ๋ธ์ ํ๊ฐํ ๋ ์ ์ฉ
x.data
๋ x.detach()
์ ๋น์ทํ ๊ธฐ๋ฅ
x.detach()
: ๊ธฐ์กด ํ
์์์ gradient๊ฐ ์ ํ๊ฐ ์๋๋ ํ
์
x.clone()
: ๊ธฐ์กด ํ
์์ ๋ด์ฉ ๋ณต์ฌํ tensor ์์ฑ
torch.new_tensor(x, requires_grad=True)
์ x.clone().detach().requires_grad(True)
๋ ๊ฐ์ ์๋ฏธ
โ GRU ๋ด torch ์ฐ์ฐ [iterator ์ฐ์ฐ]
- parameters() ํจ์๋ ๊ทธ ์ ๊ฒฝ๋ง ๋ชจ๋์ ๊ฐ์ค์น ์ ๋ณด๋ค์ iterator ํํ๋ก ๋ฐํํ๊ฒ ๋๋ค
- next(self.parameters() (๊ทธ ์ธ, iter(~), new()๋ฑ)
# nn.GRU ๋ชจ๋์ ์ฒซ ๋ฒ์งธ ๊ฐ์ค์น ํ
์๋ฅผ ์ถ์ถ > ์ด ํ
์๋ ๋ชจ๋ธ์ ๊ฐ์ค์นํ
์์ ๊ฐ์ ๋ฐ์ดํฐ ํ์
# new๋ฅผ ํตํ์ฌ ๋ชจ๋ธ์ ๊ฐ์ค์น์ ๊ฐ์ ๋ชจ์์ธ (n_layers, batch_size, hidden_dum) ๋ชจ์์ ํ
์ ๋ณํ
def _init_state(self, batch_size = 1):
weight = next(self.parameter()).data
return weight.new(self.n_layers, batch_size, self.hidden_dim).zero_()
- squeeze() & unsqueeze() : 1์ธ ์ฐจ์์ ์์ฑ or ์ ๊ฑฐ
squeeze()
ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋น ์ธ๋ฑ์ค์ ๊ฐ squeeze
unsqueeze()
ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋น ์ธ๋ฑ์ค์ ๊ฐ์ 1์ฐจ์ ์ถ๊ฐ - contiguous() ์ฐ์๊ณผ์ ์์ Tensor๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ ค์ง ์์ ์ ์งํ๋ ค๋ฉด congiguous()์ฌ์ฉ
- transpose(), permute()
transpose()
์๋ณธ tensor์ data๋ฅผ ๊ณต์ ํ๋ฉด์ ์๋ก์ด tensor ๋ฐํpermute()
๋ ๋ชจ๋ ์ฐจ์์์ ๋ง๊ตํํ ์ ์์(transpose()๋ ๋ ๊ฐ์ ์ฐจ์์ ๋ง๊ตํ) - reshape(), view()
reshape()
์ ์๋ณธ tensor์ ๋ณต์ฌ๋ณธ ํน์ view๋ฅผ ๋ฐํํ๋ค
transpose()
์ view()
์ ์ฐจ์ด์ ์ viewํจ์๋ ์ค์ง contiguous tensor์์๋ง ์๋, ๋ฐํํ๋ tensor ์ญ์ contiguousํ๋ค
transpose()๋ non-contiguous์ contiguous tensor ๋๋ค์์ ์๋ ๊ฐ๋ฅ
contiguous ํ๊ณ ์ถ๋ค๋ฉด transpose().contiguous()ํด์ฃผ์ด์ผํจ(permute๋ ๋์ผ)
### ๋ฐ์ดํฐ ๋ก๋ ###
trainset = datasets.FashionMNIST( root = './.data/', train = True,download = True, transform = transform)
## transform: ํ
์๋ก ๋ณํ, ํฌ๊ธฐ ์กฐ์ (resize), ํฌ๋กญ(crop), ๋ฐ๊ธฐ(brightness), ๋๋น(contrast)๋ฑ ์ฌ์ฉ ๊ฐ๋ฅ
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))
])
### DATALOADER ###
## DataLoader๋ ํ์ต ์ด๋ฏธ์ง์ ๋ ์ด๋ธ์ (์ด๋ฏธ์ง, ๋ ์ด๋ธ) ํํ ํํ๋ก ๋ฐํํด์ค
# Dataloader > ํ
์ํ & ์ ๊ทํ
train_loader = data.DataLoader(
dataset= trainset,
batch_size = batch_size )
โ iter(), next()
- for๋ฌธ์ ์ฌ์ฉํ์ง ์๊ณ iter() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ๋ณต๋ฌธ ์์์ ์ด์ฉํ ์ ์๋๋ก ํจ
- next() ํจ์๋ฅผ ์ด์ฉํ์ฌ ๋ฐฐ์น 1๊ฐ๋ฅผ ๊ฐ์ง๊ณ ์ด
dataiter = iter(train_loader)
images, labels = next(dataiter)
โ ์๊ฐํ (make_grid())
img = utils.make_grid(images, padding=0)
: ์ฌ๋ฌ ์ด๋ฏธ์ง๋ฅผ ๋ชจ์ ํ๋์ ์ด๋ฏธ์ง๋ก ๋ง๋ค ์ ์์- ํ์ดํ ์น์ ํ ์์์ numpy๋ก ๋ฐ๊พธ์ด์ผ ์๊ฐํ ๊ฐ๋ฅ
### TRAIN ###
optimizer = torch.optim.SGD(model.parameters(), lr = 0.02..)
## weight_decay ๊ฐ์ด ์ปค์ง์๋ก ๊ฐ์ค์น ๊ฐ์ด ์์์ง๊ฒ ๋๊ณ , Overfitting ํ์์ ํด์ but underfitting ์ํ
# optimizer = optim.SGD(model.parameters(), lr = 0.1, momentum = 0.9, weight_decay = 0.0005)
# scheduler = optim.lr_scheduler.StepLR(optimizer, step_size = 50, gamma = 0.1)
criterion = nn.BCELoss()
loss = criterion(model(x_test).squeeze(), y_test)
# loss = F.cross_entropy(output, target)
optimizer.zero_grad() #optimizer ์ด๊ธฐํ
train_loss.backward() #๊ทธ๋ ์ด๋์ธํธ ๊ณ์ฐ
optimizer.step() #step๋ณ๋ก ๊ณ์ฐ
### EVALUATE ###
with torch.no_grad():
for data, target in test_loader:
output = model(data)
test_loss += F.cross_entropy(output, target, reduction='sum').item()
pred = output.max(1, keepdim = True)[1]
correct += pred.eq(target.view_as(pred)).sum().item()
โ torch.max(1) -> 1์ฐจ์์ ๊ธฐ์ค์ผ๋ก max ๊ฐ์ ์ ํจ
ex) x = tensor(2,40,8)์ฐจ์ -> x.max(1) -> 40 x 2(ํ๋๋ ์ธ๋ฑ์ค๊ฐ, ํ๋๋ ๊ฐ)
โ F.nll_loss(output, torch.tensor([263]))
- Negative log likelihood_loss
F.logsoftmax
+F.null_loss
=F.crossEntropy
โ torch.clamp(input, min, max)
- ํด๋น ๋ฒ์ฃผ ๊ฐ ์ด์ ์ดํ๊ฐ ๋์ง ์๋๋ก ์ก๋ ๋ช ๋ น์ด
โ weight decay
- L2 regularization์ ๊ฐ์ฅ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ regularization๊ธฐ๋ฒ
- ์ค๋ฒํผํ ์ ๊ฐ์ค์น ๋งค๊ฐ๋ณ์์ ๊ฐ์ด ์ปค์ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ ๊ฐ์ค์น๊ฐ ํด ์๋ก ํฐ ํจ๋ํฐ๋ฅผ ๋ถ๊ณผ
- L1 regularization๋ ๋์์ ์ฌ์ฉ๊ฐ๋ฅ
ํ์ต๋ ๋ชจ๋ธ์ state_dict() ํจ์ ํํ๋ก ๋ฐ๊พธ์ด์ค ํ .pt ํ์ผ๋ก ์ ์ฅ
state_dict() ํจ์๋ ๋ชจ๋ธ ๋ด ๊ฐ์ค์น๋ค์ด ๋์
๋๋ฆฌ ํํ๋ก {์ฐ์ฐ ์ด๋ฆ: ๊ฐ์ค์น ํ
์์ ํธํฅ ํ
์} ์ ๊ฐ์ด ํํ๋ ๋ฐ์ดํฐ
# ํ์ต๋ ๊ฐ์ค์น ์ ์ฅ
torch.save(model.state_dict(), './model.pt')
# ์ดํ ๋ก๋ [์ ์ดํ์ต]
new_model = NeuralNet(2,5)
new_model.load_state_dict(torch.load('./model.pt'))
๋ถ๋ฅ์ฉ ๊ฐ์ ๋ฐ์ดํฐ ์์ฑ : ๋ฑ๋ฐฉ์ฑ ๊ฐ์ฐ์์ ์ ๊ท๋ถํฌ๋ฅผ ์ด์ฉํด ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ค (๋ฑ๋ฐฉ์ฑ: ๋ชจ๋ ๋ฐฉํฅ์ผ๋ก ๊ฐ์ ์ฑ์ง์ ๊ฐ์ง๋ค๋ ๋ป)
from sklearn.datasets import make_blobs
x_train, y_train = make_blobs(n_samples = 80, n_features = 2,
centers = [[1,1],[1,-1],[-1,1],[-1,-1]],
shuffle = True, cluster_std = 0.3)
- ํ์ต ์ค๊ฐ์ค๊ฐ ๊ฒ์ฆ์ฉ ๋ฐ์ดํฐ์ ์ผ๋ก ๋ชจ๋ธ์ด ํ์ต ๋ฐ์ดํฐ์๋ง ๊ณผ์ ํฉ๋์ง ์์๋์ง ํ์ธ
- ๊ฒ์ฆ ๋ฐ์ดํฐ์ ์ ๋ํ ์ฑ๋ฅ์ด ๋๋น ์ง๊ธฐ ์์ํ๊ธฐ ์ง์ ์ด ๊ฐ์ฅ ์ ํฉํ ๋ชจ๋ธ
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('./.data',
train = True,
download = True,
transform = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))
])),
batch_size = BATCH_SIZE, shuffle = True)
- ์ฌ์ค layer๊ฐ ์์๊ฑฐ ์๋๋ฉด dropout๋ณด๋จ batch normalization์ด ๋ ๋์
## nn.Dropout & F.dropout
# forward ํจ์ ๋ด
x = F.dropout(x, training = self.training, p = self.dropout
# main ํจ์ ๋ด
model = Net(dropout_p = 0.2)
best_val_loss = None
for e in range(1, EPOCHS +1):
train(model, optimizer, train_iter)
val_loss, val_accuracy = evaluate(model, val_iter)
# ๊ฒ์ฆ ์ค์ฐจ๊ฐ ๊ฐ์ฅ ์ ์ ์ต์ ์ ๋ชจ๋ธ ์ ์ฅ
if not best_val_Loss or val_loss < best_val_loss:
# ๊ฒฝ๋ก๊ฐ ์์๋ ๊ฒฝ๋ก๋ฅผ ๋ง๋ค์ด์ค
if not os.path.isdir("snapshot"):
os.makedirs("snapshot")
# ์ ์ฅ
torch.save(model.state_dict(), './snapshot/txtclassification.pt')
best_val_loss = val_loss
โ K-Fold (๊ต์ฐจ ๊ฒ์ฆ)
- ๋์๊ฐ๋ฉด์ ๋ชจ๋ธ์ ํ๋ จ์์ผ ์ต์ ์ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ์ฐพ๋๋ค
ํญ๊ท๋ธ๋ก์ 3๋ถ ๋ฅ๋ฌ๋ (ํ์ดํ ์น ๋ง)