λ°μν
NLPλ₯Ό μ€λλ§μ 곡λΆν΄λ³΄λ€ AutoEncoderμ λν λ΄μ©μ΄ μλκ±° κ°μ νλ² μ€λͺ ν΄ λ³΄κ² μ΅λλ€.
μ€ν μΈμ½λ(Autoencoder)λ?
AutoEncoder(μ€ν μΈμ½λ)λ μΈκ³΅μ κ²½λ§μ κΈ°λ°μΌλ‘ ν λΉμ§λ νμ΅ λͺ¨λΈλ‘, μ£Όμ΄μ§ λ°μ΄ν°μ ν¨μ¨μ μΈ ννμ νμ΅νλ λ° μ€μ μ λ‘λλ€. μ΄λ λ°μ΄ν°λ₯Ό μμΆνκ³ μ°¨μμ μΆμνκ±°λ, λ Έμ΄μ¦λ₯Ό μ κ±°νκ³ μ΄μ νμ§μ κ°μ λ€μν μμ© λΆμΌμ μ¬μ©λ©λλ€.
μ€ν μΈμ½λ(Autoencoder)μ μλ μ리
μ€ν μΈμ½λλ μ λ ₯ λ°μ΄ν°λ₯Ό μμΆνμ¬ μ μ¬ κ³΅κ°(latent space)μ΄λΌλ μ μ°¨μ ννμΌλ‘ λ³νν λ€μ, μ΄λ₯Ό λ€μ μλμ λ°μ΄ν°λ‘ 볡μνλ κ³Όμ μ ν΅ν΄ νμ΅ν©λλ€. μ΄λ¬ν κ³Όμ μ μ£Όλ‘ λ€μ λ κ°μ§ μ£Όμ κ΅¬μ± μμλ‘ μ΄λ£¨μ΄μ§λλ€.
- μΈμ½λ(Encoder): μ λ ₯ λ°μ΄ν°λ₯Ό μ μ°¨μ μ μ¬ κ³΅κ° λ²‘ν°λ‘ λ³ννλ κ³Όμ μ λλ€. μΈμ½λλ μ λ ₯μΈ΅μμ μμνμ¬ μ¬λ¬ κ°μ μλμΈ΅μ κ±°μ³, μ΅μ’ μ μΌλ‘ μ μ¬ κ³΅κ° λ²‘ν°λ₯Ό μΆλ ₯ν©λλ€. μ΄ κ³Όμ μμ μ λ ₯ λ°μ΄ν°μ μ€μν νΉμ§μ μ μ°¨μμΌλ‘ μμΆνκ² λ©λλ€.
- λμ½λ(Decoder): μΈμ½λμμ μμ±λ μ μ°¨μ μ μ¬ κ³΅κ° λ²‘ν°λ₯Ό λ€μ μλμ λ°μ΄ν°λ‘ 볡μνλ κ³Όμ μ λλ€. λμ½λλ μ μ¬ κ³΅κ° ννμμ μμνμ¬ μ¬λ¬ μΈ΅μ μ κ²½λ§μ ν΅ν΄ μΆλ ₯μΈ΅κΉμ§ λλ¬ν©λλ€. λμ½λμ λͺ©νλ μ λ ₯ λ°μ΄ν°μ μ΅λν λΉμ·ν μΆλ ₯μ μμ±νλ κ²μ λλ€.
μ€ν μΈμ½λ(Autoencoder)μ μ ν
μ€ν μΈμ½λλ κ·Έ ꡬ쑰μ λͺ©μ μ λ°λΌ λ€μν μ νμΌλ‘ λλ©λλ€.
- κΈ°λ³Έ μ€ν μΈμ½λ (Basic Autoencoder): κ°μ₯ κΈ°λ³Έμ μΈ ννλ‘, νλμ μΈμ½λμ νλμ λμ½λλ‘ κ΅¬μ±λ©λλ€. μ£Όλ‘ κ°λ¨ν λ°μ΄ν° νν νμ΅μ μ¬μ©λ©λλ€.
- λ₯ μ€ν μΈμ½λ (Deep Autoencoder): μ¬λ¬ κ°μ μλμΈ΅μ κ°μ§λ μ¬μΈ΅ μ κ²½λ§ κ΅¬μ‘°λ‘, 볡μ‘ν λ°μ΄ν°μ νΉμ§μ λ κΉμ΄ νμ΅ν μ μμ΅λλ€. μ΄λ λ°μ΄ν°μ λ μ κ΅ν ννμ κ°λ₯νκ² ν©λλ€.
- ν¬μ μ€ν μΈμ½λ (Sparse Autoencoder): μ μ¬ κ³΅κ° λ²‘ν°μ μμ μ€ μΌλΆκ° 0μ΄ λλλ‘ μ μ½μ κ°νμ¬, λ°μ΄ν°μ μ€μν νΉμ§μ λ μ νμ΅ν μ μλλ‘ ν©λλ€. μ΄λ κ³ μ°¨μ λ°μ΄ν°μμ μ€μν νΉμ§λ§μ μΆμΆνλ λ° μ μ©ν©λλ€.
- λ³μ΄ν μ€ν μΈμ½λ (Variational Autoencoder, VAE): μ μ¬ κ³΅κ°μ νλ₯ λΆν¬λ‘ λͺ¨λΈλ§νμ¬, λ°μ΄ν°μ μ μ¬ κ΅¬μ‘°λ₯Ό λ μ νμ ν μ μκ² ν©λλ€. μ΄λ μλ‘μ΄ λ°μ΄ν°λ₯Ό μμ±νλ λ°μλ μ¬μ©λλ©°, μμ± λͺ¨λΈλ‘λ λ§μ΄ νμ©λ©λλ€.
- μ‘μ μ κ±° μ€ν μΈμ½λ (Denoising Autoencoder): μ λ ₯ λ°μ΄ν°μ λ Έμ΄μ¦λ₯Ό μΆκ°ν ν, μ΄λ₯Ό μλμ κΉ¨λν λ°μ΄ν°λ‘ 볡μνλ λ°©λ²μ νμ΅ν©λλ€. μ΄λ₯Ό ν΅ν΄ λ°μ΄ν°μ λ Έμ΄μ¦λ₯Ό μ κ±°νκ³ λ κ°μΈν νΉμ§μ νμ΅ν μ μμ΅λλ€.
μ€ν μΈμ½λ(Autoencoder)μ μμ©λΆμΌ
μ€ν μΈμ½λλ λ€μν λΆμΌμμ νμ©λ©λλ€:
- λ°μ΄ν° μμΆ (Data Compression): μ λ ₯ λ°μ΄ν°λ₯Ό μ μ°¨μ 벑ν°λ‘ μμΆνμ¬ μ μ₯ 곡κ°μ μ μ½νκ±°λ μ μ‘ μκ°μ λ¨μΆν μ μμ΅λλ€.
- μ°¨μ μΆμ (Dimensionality Reduction): κ³ μ°¨μ λ°μ΄ν°λ₯Ό μ μ°¨μμΌλ‘ μΆμνμ¬ μκ°ννκ±°λ, λ€λ₯Έ λ¨Έμ λ¬λ μκ³ λ¦¬μ¦μ μ±λ₯μ ν₯μμν¬ μ μμ΅λλ€.
- λ Έμ΄μ¦ μ κ±° (Noise Reduction): μ‘μ μ κ±° μ€ν μΈμ½λλ₯Ό μ¬μ©ν΄ λ°μ΄ν°μ λ Έμ΄μ¦λ₯Ό μ κ±°νκ³ κΉ¨λν λ°μ΄ν°λ₯Ό 볡μν μ μμ΅λλ€.
- μ΄μ νμ§ (Anomaly Detection): μ μ λ°μ΄ν°λ‘ νμ΅ν μ€ν μΈμ½λκ° μ΄μ λ°μ΄ν°λ₯Ό 볡μνμ§ λͺ»νλ νΉμ±μ μ΄μ©ν΄, λΉμ μ λ°μ΄ν°λ₯Ό νμ§ν μ μμ΅λλ€.
- μμ± λͺ¨λΈ (Generative Model): λ³μ΄ν μ€ν μΈμ½λλ₯Ό μ¬μ©ν΄ μλ‘μ΄ λ°μ΄ν°λ₯Ό μμ±ν μ μμΌλ©°, μ΄λ μ΄λ―Έμ§ μμ±, λ°μ΄ν° μ¦κ° λ±μ νμ©λ©λλ€.
μ€ν μΈμ½λ(Autoencoder)μ μ₯, λ¨μ
μ₯μ
- λΉμ§λ νμ΅: λ μ΄λΈμ΄ μλ λ°μ΄ν°λ‘ νμ΅μ΄ κ°λ₯νμ¬ λ€μν μν©μμ μ μ©ν μ μμ΅λλ€.
- λ€μν μμ© λΆμΌ: λ°μ΄ν° μμΆ, λ Έμ΄μ¦ μ κ±°, μ΄μ νμ§ λ± μ¬λ¬ μμ© λΆμΌμ μ¬μ©λ μ μμ΅λλ€.
- λ°μ΄ν°μ μ€μν νΉμ§ νμ : νμ΅λ μ μ¬ κ³΅κ° λ²‘ν°λ₯Ό λΆμνμ¬ λ°μ΄ν°μ μ€μν νΉμ§μ μ΄ν΄ν μ μμ΅λλ€.
λ¨μ
- 볡μ μ νλ: 볡μλ λ°μ΄ν°κ° μλ³Έ λ°μ΄ν°μ μμ ν μΌμΉνμ§ μμ μ μμ΅λλ€.
- 볡μ‘ν λ°μ΄ν° μ²λ¦¬ νκ³: λ§€μ° λ³΅μ‘ν λ°μ΄ν°μ λν΄μλ μ±λ₯μ΄ μ νλ μ μμ΅λλ€.
- κ³Όμ ν© μν: μ μ ν μ κ·νκ° μμ κ²½μ° κ³Όμ ν©μ΄ λ°μν μ μμΌλ©°, μ΄λ μΌλ°ν μ±λ₯μ μ νμν¬ μ μμ΅λλ€.
μ€ν μΈμ½λ(Autoencoder) Example Code
MNIST Datasetμ μμ & PyTorch Frameworkλ₯Ό μ¬μ©νμμ΅λλ€.
import torch # PyTorch λΌμ΄λΈλ¬λ¦¬ μν¬νΈ
import torch.nn as nn # μ κ²½λ§ λͺ¨λ μν¬νΈ
import torch.optim as optim # μ΅μ ν μκ³ λ¦¬μ¦ λͺ¨λ μν¬νΈ
from torchvision import datasets, transforms # λ°μ΄ν°μ
κ³Ό λ°μ΄ν° μ μ²λ¦¬ λ³ν λͺ¨λ μν¬νΈ
import matplotlib.pyplot as plt # λ°μ΄ν° μκ°νλ₯Ό μν matplotlib μν¬νΈ
# λ°μ΄ν°μ
λ‘λ λ° μ μ²λ¦¬
transform = transforms.Compose([
transforms.ToTensor(), # λ°μ΄ν°λ₯Ό ν
μλ‘ λ³ν (μ΄λ―Έμ§λ₯Ό PyTorch ν
μλ‘ λ³ν)
transforms.Normalize((0.5,), (0.5,)) # λ°μ΄ν°λ₯Ό μ κ·ν (νκ· 0.5, νμ€νΈμ°¨ 0.5λ‘ μ κ·ν)
])
# MNIST νλ ¨ λ°μ΄ν°μ
λ‘λ (μκΈμ¨ μ«μ λ°μ΄ν°)
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
# νλ ¨ λ°μ΄ν° λ‘λ μ μ (λ°μ΄ν°μ
μ λ°°μΉ ν¬κΈ° 64λ‘, 무μμλ‘ μμ΄μ λ‘λ)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
# MNIST ν
μ€νΈ λ°μ΄ν°μ
λ‘λ
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
# ν
μ€νΈ λ°μ΄ν° λ‘λ μ μ (λ°μ΄ν°μ
μ λ°°μΉ ν¬κΈ° 64λ‘, μμ°¨μ μΌλ‘ λ‘λ)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
Failed to download (trying next):
HTTP Error 403: Forbidden
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz to ./data/MNIST/raw/train-images-idx3-ubyte.gz
100%|ββββββββββ| 9912422/9912422 [00:11<00:00, 899702.19it/s]
Extracting ./data/MNIST/raw/train-images-idx3-ubyte.gz to ./data/MNIST/raw
Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
Failed to download (trying next):
HTTP Error 403: Forbidden
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz to ./data/MNIST/raw/train-labels-idx1-ubyte.gz
100%|ββββββββββ| 28881/28881 [00:00<00:00, 129719.63it/s]
Extracting ./data/MNIST/raw/train-labels-idx1-ubyte.gz to ./data/MNIST/raw
Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
Failed to download (trying next):
HTTP Error 403: Forbidden
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz to ./data/MNIST/raw/t10k-images-idx3-ubyte.gz
100%|ββββββββββ| 1648877/1648877 [00:01<00:00, 1244815.31it/s]
Extracting ./data/MNIST/raw/t10k-images-idx3-ubyte.gz to ./data/MNIST/raw
Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
Failed to download (trying next):
HTTP Error 403: Forbidden
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-labels-idx1-ubyte.gz
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-labels-idx1-ubyte.gz to ./data/MNIST/raw/t10k-labels-idx1-ubyte.gz
100%|ββββββββββ| 4542/4542 [00:00<00:00, 8819689.24it/s]Extracting ./data/MNIST/raw/t10k-labels-idx1-ubyte.gz to ./data/MNIST/raw
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# μ€ν μΈμ½λ(Autoencoder) ν΄λμ€ μ μ, nn.Moduleμ μμλ°μ
class Autoencoder(nn.Module):
def __init__(self):
super(Autoencoder, self).__init__() # nn.Moduleμ μ΄κΈ°ν ν¨μ νΈμΆ
# μΈμ½λ μ μ: μ
λ ₯ μ΄λ―Έμ§λ₯Ό μ μ°¨μ μ μ¬ κ³΅κ° λ²‘ν°λ‘ μμΆ
self.encoder = nn.Sequential(
nn.Linear(28 * 28, 128), # μ
λ ₯ μ΄λ―Έμ§ ν¬κΈ° 28x28μ 128μ°¨μμΌλ‘ λ³ν
nn.ReLU(), # νμ±ν ν¨μλ‘ ReLU μ¬μ©
nn.Linear(128, 64), # 128μ°¨μμμ 64μ°¨μμΌλ‘ μΆμ
nn.ReLU(), # νμ±ν ν¨μλ‘ ReLU μ¬μ©
nn.Linear(64, 32) # 64μ°¨μμμ 32μ°¨μμΌλ‘ μΆμ
)
# λμ½λ μ μ: μ μ¬ κ³΅κ° λ²‘ν°λ₯Ό μλ μ΄λ―Έμ§ ν¬κΈ°λ‘ 볡μ
self.decoder = nn.Sequential(
nn.Linear(32, 64), # 32μ°¨μμμ 64μ°¨μμΌλ‘ νμ₯
nn.ReLU(), # νμ±ν ν¨μλ‘ ReLU μ¬μ©
nn.Linear(64, 128), # 64μ°¨μμμ 128μ°¨μμΌλ‘ νμ₯
nn.ReLU(), # νμ±ν ν¨μλ‘ ReLU μ¬μ©
nn.Linear(128, 28 * 28), # 128μ°¨μμμ 28x28 ν¬κΈ°μ μλ μ΄λ―Έμ§λ‘ 볡μ
nn.Tanh() # μΆλ ₯ κ°μ -1κ³Ό 1 μ¬μ΄λ‘ μ κ·ν
)
def forward(self, x):
# μμ ν ν¨μ μ μ: μΈμ½λ -> λ
Έμ΄μ¦ μΆκ° -> λμ½λ
x = self.encoder(self.noise(x)) # μ
λ ₯ λ°μ΄ν°μ λ
Έμ΄μ¦λ₯Ό μΆκ°ν ν μΈμ½λ ν΅κ³Ό
x = self.decoder(x) # λμ½λλ₯Ό ν΅ν΄ μλ μ΄λ―Έμ§ ν¬κΈ°λ‘ 볡μ
return x # 볡μλ μ΄λ―Έμ§ λ°ν
def noise(self, x, noise_factor=0.5):
# λ
Έμ΄μ¦ μΆκ° ν¨μ: μ
λ ₯ λ°μ΄ν°μ λ
Έμ΄μ¦λ₯Ό μΆκ°νμ¬ λ κ°μΈν νμ΅μ μ λ
noise = noise_factor * torch.randn_like(x) # μ
λ ₯ λ°μ΄ν°μ κ°μ ν¬κΈ°μ λλ€ λ
Έμ΄μ¦ μμ±
x_noisy = x + noise # μλ³Έ λ°μ΄ν°μ λ
Έμ΄μ¦ μΆκ°
return x_noisy # λ
Έμ΄μ¦κ° μΆκ°λ λ°μ΄ν° λ°ν
# λͺ¨λΈ μ΄κΈ°ν
model = Autoencoder().to(device) # Autoencoder λͺ¨λΈ μΈμ€ν΄μ€ μμ± ν GPU/CPUλ‘ μ΄λ
criterion = nn.MSELoss() # μμ€ ν¨μλ‘ νκ· μ κ³± μ€μ°¨(MSE) μ¬μ©
optimizer = optim.Adam(model.parameters(), lr=0.001) # μ΅ν°λ§μ΄μ λ‘ Adam μ¬μ©, νμ΅λ₯ 0.001λ‘ μ€μ
print(model)
Autoencoder(
(encoder): Sequential(
(0): Linear(in_features=784, out_features=128, bias=True)
(1): ReLU()
(2): Linear(in_features=128, out_features=64, bias=True)
(3): ReLU()
(4): Linear(in_features=64, out_features=32, bias=True)
)
(decoder): Sequential(
(0): Linear(in_features=32, out_features=64, bias=True)
(1): ReLU()
(2): Linear(in_features=64, out_features=128, bias=True)
(3): ReLU()
(4): Linear(in_features=128, out_features=784, bias=True)
(5): Tanh()
)
)
num_epochs = 20 # μ΄ νμ΅ μν μ μ€μ
# νμ΅ λ£¨ν μμ
for epoch in range(num_epochs):
for data, _ in train_loader: # νλ ¨ λ°μ΄ν°μ
μμ λ°°μΉ λ¨μλ‘ λ°μ΄ν°λ₯Ό κ°μ Έμ΄
data = data.view(-1, 28 * 28).to(device) # μ
λ ₯ λ°μ΄ν°λ₯Ό 28x28 ν¬κΈ°μ μ΄λ―Έμ§μμ 1μ°¨μ 벑ν°λ‘ λ³ννκ³ , GPU/CPUλ‘ μ΄λ
# μμ ν: μ
λ ₯ λ°μ΄ν°λ₯Ό λͺ¨λΈμ ν΅κ³ΌμμΌ μΆλ ₯ μμ±
output = model(data)
loss = criterion(output, data) # μΆλ ₯κ³Ό μλ³Έ λ°μ΄ν° κ°μ μμ€(μ€μ°¨)μ κ³μ° (MSE μ¬μ©)
# μμ ν: μμ€μ κΈ°μ€μΌλ‘ λͺ¨λΈμ κ°μ€μΉλ₯Ό μ
λ°μ΄νΈ
optimizer.zero_grad() # μ΄μ λ°°μΉμ κ²½μ¬λλ₯Ό 0μΌλ‘ μ΄κΈ°ν
loss.backward() # μμ€μ λν κ²½μ¬λ κ³μ° (μμ ν)
optimizer.step() # κ³μ°λ κ²½μ¬λλ₯Ό λ°νμΌλ‘ λͺ¨λΈμ κ°μ€μΉλ₯Ό μ
λ°μ΄νΈ
# κ° μνμ΄ λλ λλ§λ€ νμ¬ μνκ³Ό μμ€ κ°μ μΆλ ₯
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
# ν
μ€νΈ λ°μ΄ν°μ
μμ λͺ κ°μ§ μ΄λ―Έμ§λ₯Ό 볡μνμ¬ μκ°ν
model.eval() # λͺ¨λΈμ νκ° λͺ¨λλ‘ μ ν (λλ‘μμ, λ°°μΉ μ κ·ν λ±μ΄ λΉνμ±νλ¨)
with torch.no_grad(): # μμ νλ₯Ό μΆμ νμ§ μλλ‘ no_grad() λΈλ‘ μ¬μ©
for data, _ in test_loader: # ν
μ€νΈ λ°μ΄ν°μ
μμ λ°°μΉ λ¨μλ‘ λ°μ΄ν°λ₯Ό λ‘λ
data = data.view(-1, 28 * 28).to(device) # μ΄λ―Έμ§λ₯Ό 1μ°¨μ 벑ν°λ‘ λ³ννκ³ , GPU/CPUλ‘ μ΄λ
output = model(data) # λͺ¨λΈμ ν΅ν΄ μ
λ ₯ λ°μ΄ν°λ₯Ό 볡μ
output = output.view(-1, 1, 28, 28).cpu() # 볡μλ λ°μ΄ν°λ₯Ό λ€μ 28x28 ν¬κΈ°μ μ΄λ―Έμ§λ‘ λ³ννκ³ CPUλ‘ μ΄λ
break # 첫 λ²μ§Έ λ°°μΉλ§ μ¬μ©νμ¬ λ³΅μ κ²°κ³Ό νμΈ
# μλ³Έ μ΄λ―Έμ§μ 볡μλ μ΄λ―Έμ§ μκ°ν
fig, axes = plt.subplots(nrows=2, ncols=10, sharex=True, sharey=True, figsize=(20, 4)) # 2x10 그리λμ μλΈνλ‘― μμ±
# 첫 λ²μ§Έ νμ μλ³Έ μ΄λ―Έμ§, λ λ²μ§Έ νμ 볡μλ μ΄λ―Έμ§ μκ°ν
for images, row in zip([data.view(-1, 1, 28, 28).cpu(), output], axes): # μλ³Έκ³Ό 볡μλ μ΄λ―Έμ§λ₯Ό κ°κ° νμ ν λΉ
for img, ax in zip(images, row): # κ° μ΄λ―Έμ§μ μΆ(axis)μ μμ°¨μ μΌλ‘ κ°μ Έμ΄
ax.imshow(img.numpy().squeeze(), cmap='gray') # μ΄λ―Έμ§λ₯Ό κ·Έλ μ΄μ€μΌμΌλ‘ μκ°ν
ax.get_xaxis().set_visible(False) # xμΆ μ¨κΉ
ax.get_yaxis().set_visible(False) # yμΆ μ¨κΉ
plt.show() # μκ°νλ κ²°κ³Όλ₯Ό νλ©΄μ μΆλ ₯
Epoch [1/20], Loss: 0.1157
Epoch [2/20], Loss: 0.0861
Epoch [3/20], Loss: 0.0710
Epoch [4/20], Loss: 0.0640
Epoch [5/20], Loss: 0.0600
Epoch [6/20], Loss: 0.0513
Epoch [7/20], Loss: 0.0536
Epoch [8/20], Loss: 0.0501
Epoch [9/20], Loss: 0.0538
Epoch [10/20], Loss: 0.0533
Epoch [11/20], Loss: 0.0480
Epoch [12/20], Loss: 0.0542
Epoch [13/20], Loss: 0.0482
Epoch [14/20], Loss: 0.0386
Epoch [15/20], Loss: 0.0453
Epoch [16/20], Loss: 0.0455
Epoch [17/20], Loss: 0.0428
Epoch [18/20], Loss: 0.0442
Epoch [19/20], Loss: 0.0436
Epoch [20/20], Loss: 0.0414
# ν
μ€νΈ λ°μ΄ν°μ
μμ λͺ κ°μ§ μ΄λ―Έμ§λ₯Ό 볡μνμ¬ μκ°ν
model.eval()
with torch.no_grad():
for data, _ in test_loader:
data = data.view(-1, 28 * 28).to(device)
output = model(data)
output = output.view(-1, 1, 28, 28).cpu()
break
# μλ³Έ μ΄λ―Έμ§μ 볡μλ μ΄λ―Έμ§ μκ°ν
fig, axes = plt.subplots(nrows=2, ncols=10, sharex=True, sharey=True, figsize=(20, 4))
for images, row in zip([data.view(-1, 1, 28, 28).cpu(), output], axes):
for img, ax in zip(images, row):
ax.imshow(img.numpy().squeeze(), cmap='gray')
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
λ°μν
'π NLP (μμ°μ΄μ²λ¦¬) > π Natural Language Processing' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[NLP] BERT (Bidrectional Encoder Representations from Transformers) (0) | 2024.09.19 |
---|---|
[NLP] Generative Adversarial Networks (μμ±μ μ λ μ κ²½λ§, GAN) (0) | 2024.08.30 |
[NLP] RNNLM - RNNμ μ¬μ©ν Language Model (0) | 2024.06.02 |
[NLP] BPTT (Backpropagation Through Time) (0) | 2024.05.23 |
[NLP] μΆλ‘ κΈ°λ° κΈ°λ² & Neural Network (μ κ²½λ§) (0) | 2024.05.22 |