Posts
All the articles I've posted.
# nn layers
linear1 = torch.nn.Linear(784, 256, bias=True)
linear2 = torch.nn.Linear(256, 256, bias=True)
linear3 = torch.nn.Linear(256, 10, bias=True)
relu = torch.nn.ReLU()
# xavier initialization
torch.nn.init.xavier_uniform_(linear1.weight) # not torch.nn.init.normal_()
torch.nn.init.xavier_uniform_(linear2.weight)
torch.nn.init.xavier_uniform_(linear3.weight)
'''output
Parameter containing:
tensor([[-0.0215, -0.0894, 0.0598, ..., 0.0200, 0.0203, 0.1212],
[ 0.0078, 0.1378, 0.0920, ..., 0.0975, 0.1458, -0.0302],
[ 0.1270, -0.1296, 0.1049, ..., 0.0124, 0.1173, -0.0901],
...,
[ 0.0661, -0.1025, 0.1437, ..., 0.0784, 0.0977, -0.0396],
[ 0.0430, -0.1274, -0.0134, ..., -0.0582, 0.1201, 0.1479],
[-0.1433, 0.0200, -0.0568, ..., 0.0787, 0.0428, -0.0036]],
requires_grad=True)
'''Weight Initialization
초기 weight의 설정은 크게 중요하지 않아 보이지만 실제로는 큰 영향을 미친다. 위 그래프에서도 볼 수 있듯이 적절한 초기화 기법으로 초기화를 해준 경우(N이 붙어있는 곡선) 실제로 오차가 줄어든 것을 확인할 수 있다.
criterion = torch.nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.Adam(linear.parameters(), lr=learning_rate) # Adam optimizer
total_batch = len(data_loader)
for epoch in range(training_epochs):
avg_cost = 0
for X, Y in data_loader:
# reshape input image into [batch_size by 784]
# label is not one-hot encoded
X = X.view(-1, 28 * 28).to(device)
Y = Y.to(device)
optimizer.zero_grad()
hypothesis = linear(X)
cost = criterion(hypothesis, Y)
cost.backward()
optimizer.step()
avg_cost += cost / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print('Learning finished')
'''output
Epoch: 0001 cost = 4.848181248
Epoch: 0002 cost = 1.464641452
Epoch: 0003 cost = 0.977406502
Epoch: 0004 cost = 0.790303528
Epoch: 0005 cost = 0.686833322
Epoch: 0006 cost = 0.618483305
Epoch: 0007 cost = 0.568978667
Epoch: 0008 cost = 0.531290889
Epoch: 0009 cost = 0.501056492
Epoch: 0010 cost = 0.476258427
Epoch: 0011 cost = 0.455025405
Epoch: 0012 cost = 0.437031567
Epoch: 0013 cost = 0.421489984
Epoch: 0014 cost = 0.408599794
Epoch: 0015 cost = 0.396514893
Learning finished
'''ReLU
시그모이드 함수의 문제는 backpropagation과정에서 발생한다. backpropagation을 수행할 때 activation의 미분값 곱해가면서 사용하게 되는데 이때 기울기가 소실되는 gradient vanishing문제가 발생한다. 다음 그림은 시그모이드 함수
는 chain rule을 통해 위와 같이 미분이 바로 되는 형식으로 표현할 수 있다. 한 번 더 거슬러 올라가 보자.
이번에는 과 를 구할 차례이다. 먼저 을 구해보자.
Backpropagation
데이터를 레이어의 노드들을 통과시키면서 설정된 weight에 따라 예측 결과값을 계산하는 것을 forward pass라고 한다.
linear1 = torch.nn.Linear(2, 10, bias=True)
linear2 = torch.nn.Linear(10, 10, bias=True)
linear3 = torch.nn.Linear(10, 10, bias=True)
linear4 = torch.nn.Linear(10, 1, bias=True)
sigmoid = torch.nn.Sigmoid()
model = torch.nn.Sequential(linear1, sigmoid, linear2, sigmoid, linear3, sigmoid, linear4, sigmoid).to(device)
for step in range(10001):
optimizer.zero_grad()
hypothesis = model(X)
# cost/loss function
cost = criterion(hypothesis, Y)
cost.backward()
optimizer.step()
if step % 100 == 0:
print(step, cost.item())
'''output
0 0.6948983669281006
100 0.6931558847427368
200 0.6931535005569458
300 0.6931513547897339
400 0.6931493282318115
500 0.6931473016738892
600 0.6931453943252563
700 0.6931434869766235
800 0.6931416988372803
900 0.6931397914886475
1000 0.6931380033493042
...
9700 0.00016829342348501086
9800 0.00016415018762927502
9900 0.00016021561168599874
10000 0.0001565046259202063
'''Multi Layer Perceptron
MLP는 단일 퍼셉트론을 여러개 쌓은 것으로 단일 퍼셉트론으로 해결하지 못한 XOR과 같은 문제를 해결하기 위해 제안된 구조이다.
linear = torch.nn.Linear(2, 1, bias=True)
sigmoid = torch.nn.Sigmoid()
# Sequential로 여러 모듈을 묶어 하나의 레이어로 사용
model = torch.nn.Sequential(linear, sigmoid).to(device)
criterion = torch.nn.BCELoss().to(device)
optimizer = torch.optim.SGD(model.parameters(), lr=1)
'''output
0 0.7273974418640137
100 0.6931475400924683
200 0.6931471824645996
300 0.6931471824645996
400 0.6931471824645996
500 0.6931471824645996
600 0.6931471824645996
...
9700 0.6931471824645996
9800 0.6931471824645996
9900 0.6931471824645996
10000 0.6931471824645996
'''Perceptron
먼저 퍼셉트론의 컨셉이 된 뉴런에 대해 알아보자. 뉴런은 동물의 신경계를 구성하는 세포로 다음과 같은 형태이다.
# MNIST data image of shape 28 * 28 = 784
linear = torch.nn.Linear(784, 10, bias=True).to(device)
# define cost/loss & optimizer
criterion = torch.nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.SGD(linear.parameters(), lr=0.1)
모델은 선형모델을 사용하며 이미지의 크기가 28x28이므로 28*28=784의 차원을 가지는 입력을 받도록 정의한다.
for epoch in range(training_epochs):
avg_cost = 0
total_batch = len(data_loader)
for X, Y in data_loader:
# reshape input image into [batch_size by 784]
# label is not one-hot encoded
X = X.view(-1, 28 * 28).to(device)
Y = Y.to(device)
hypothesis = linear(X)
cost = criterion(hypothesis, Y)
optimizer.zero_grad()
cost.backward()
optimizer.step()
avg_cost += cost / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print('Learning finished')
'''output
Epoch: 0001 cost = 0.535468459
Epoch: 0002 cost = 0.359274179
Epoch: 0003 cost = 0.331187516
Epoch: 0004 cost = 0.316578031
Epoch: 0005 cost = 0.307158142
Epoch: 0006 cost = 0.300180674
Epoch: 0007 cost = 0.295130163
Epoch: 0008 cost = 0.290851504
Epoch: 0009 cost = 0.287417084
Epoch: 0010 cost = 0.284379542
Epoch: 0011 cost = 0.281825215
Epoch: 0012 cost = 0.279800713
Epoch: 0013 cost = 0.277809024
Epoch: 0014 cost = 0.276154280
Epoch: 0015 cost = 0.274440825
Learning finished
'''MNIST Introduction
MNIST 데이터 셋은 숫자 손글씨를 모아놓은 데이터 셋이다. 사람들이 적은 숫자들을 우체국에서 자동으로 처리하기 위해 만들어진 것이 이 셋의 시작점이라고 한다.
model = SoftmaxClassifierModel()
optimizer = optim.SGD(model.parameters(), lr=1e5)
train(model, optimizer, x_train, y_train)
'''output
Epoch 0/20 Cost: 1.280268
Epoch 1/20 Cost: 976950.812500
Epoch 2/20 Cost: 1279135.125000
Epoch 3/20 Cost: 1198379.000000
Epoch 4/20 Cost: 1098825.875000
Epoch 5/20 Cost: 1968197.625000
Epoch 6/20 Cost: 284763.250000
Epoch 7/20 Cost: 1532260.125000
Epoch 8/20 Cost: 1651504.000000
Epoch 9/20 Cost: 521878.500000
Epoch 10/20 Cost: 1397263.250000
Epoch 11/20 Cost: 750986.250000
Epoch 12/20 Cost: 918691.500000
Epoch 13/20 Cost: 1487888.250000
Epoch 14/20 Cost: 1582260.125000
Epoch 15/20 Cost: 685818.062500
Epoch 16/20 Cost: 1140048.750000
Epoch 17/20 Cost: 940566.500000
Epoch 18/20 Cost: 931638.250000
Epoch 19/20 Cost: 1971322.625000
'''Tips
Probalility(확률)는 우리가 잘 알고 있듯이 어떤 관측값이 발생할 정도를 뜻하는데, 이는 다르게 말하면 한 확률분포에서 해당 관측값 또는 관측 구간이 얼마의 확률을 가지는가를 뜻한다. 이에 반해 Likelihood(우도, 가능도)는 이 관측값이 주어진 확률 분
Introduction
Autoencoder
오토인코더는 인풋과 아웃풋이 같은 네트워크를 의미한다. Auto-associators, Diabolo networks, Sandglass-shaped net 등의 이명으로 불리기도 하며 가장 많이 불리는 이름은 역시 Autoencoder이다.

오토인코더는 다음과 같이 중간의 은닉층이 잘록한 모습의 네트워크인데, 이때 중간 은닉층을 라고 부르며 Code, Latent Variable, Feature, Hidden representation 등으로 불린다. 그래서 를 어떻게 생각하냐에 따라 오토인코더에서 학습하는 과정을 Representation Learning, Efficient Code Learning 등으로 부르기도 하지만, 결국 이들은 모두 노드를 배우는 학습을 이르는 말들이다.
오토인코더의 모든 것 - 3. Autoencoders
오토인코더는 인풋과 아웃풋이 같은 네트워크를 의미한다. Auto-associators, Diabolo networks, Sandglass-shaped net 등의 이명으로 불리기도 하며 가장 많이 불리는 이름은 역시 Autoencoder이다.
class SoftmaxClassifierModel(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(4, 3) # Output이 3!
def forward(self, x):
return self.linear(x)
이때도 마찬가지로 softmax가 cross entropy에 속해 있기 때문에 class를 정의할 때는 선형 함수 부분만 정의해 준 것을 볼 수 있다.
model = SoftmaxClassifierModel()
optimizer = optim.SGD(model.parameters(), lr=0.1)
nb_epochs = 1000
for epoch in range(nb_epochs + 1):
prediction = model(x_train)
cost = F.cross_entropy(prediction, y_train)
optimizer.zero_grad()
cost.backward()
optimizer.step()
if epoch % 100 == 0:
print('Epoch {:4d}/{} Cost: {:.6f}'.format(
epoch, nb_epochs, cost.item()
))모두를 위한 딥러닝 2 - Lab6: Softmax Classification
이전 포스팅에서는 이진 분류 문제에 대해 알아봤다. 이번에는 분류해야 할 범주가 2개(0, 1)가 아니라 여러개인 다중 분류에 대해 알아보려 한다.