Visdom에 관하여 & Loss plot 그리기
모두를 위한 딥러닝 - 파이토치 강의 참고
visdom을 사용하기 위해서는 서버를 실행시켜줘야 한다.
jupyter notebook의 경우, New –> Terminal –> 실행된 터미널 창에서 다음의 명령어를 입력한다.
1 | >>>python -m visdom.server |
pycharm을 이용한다면 파이참 하단의 terminal을 클릭해 위의 명령어를 입력하면된다.
다만, visdom의 기본 포트가 사용중이라면 에러가 발생하는데 이때는 visdom 포트변경 포스트를 확인해 해결할 수 있다.
서버가 정상적으로 실행됐다면, visdom 객체를 아래와 같이 생성하고 이를 이용해 text, 이미지, 그래프 등을 나타낼 수 있다.
1 | import visdom |
아래에서 진행하는 예제는 실행된 local서버를 접속해 확인할 수 있다.
Text 출력하기
text를 출력하기 위해서
text()
를 사용한다.1
vis.text('hello world', env='main')
이때
env='main'
은 실행문의 이름을 지정해 추후에 main으로 실행된 모든 창을 한번에 종료할 수 있게 해준다.
Image 출력하기
image 출력은
image()
를 사용한다.랜덤한 이미지를 출력해보자.
1
2ex = torch.randn(3, 200, 200)
vis.image(ex)여러장의 이미지를 출력하기 위해서는
images()
를 사용한다.1
vis.images(torch.Tensor(3,3,28,28))
CIFAR10의 이미지를 가져와 출력해보자.
1
2
3
4cifar10 = dsets.CIFAR10(root="cifar10/",train = True, transform=torchvision.transforms.ToTensor(),download=True)
data = cifar10.__getitem(0)__
vis.images(data[0], env='main')DataLoader로부터 여러개의 이미지를 출력할 수 있다.
1
2
3
4
5
6
7
8
9
10
11MNIST = dsets.MNIST(root="MNIST_data/",train = True,transform=torchvision.transforms.ToTensor(), download=True)
data_loader = torch.utils.data.DataLoader(dataset = MNIST,
batch_size = 32,
shuffle = False)
for num, value in enumerate(data_loader):
value = value[0]
vis.images(value)
break
###>>> batch_size만큼의 이미지가 한번에 출력된다
Line Plot 그리기
line plot은
line()
을 사용한다.임의의 y값을 가지는 그래프를 그려보자.
1
2
3Y_data = torch.randn(5)
X_data = torch.Tensor([1,2,3,4,5])
plt = vis.line(Y=Y_data, X=X_data)위를 통해 plt라는 이름의 그래프가 그려지는 것을 확인할 수 있다. 만약 이때 X 범위를 설정해주지 않았다면 X의 범위는 0과 1사이에서 출력되게 된다.
이미 그려진 line plot을 업데이트도 할 수 있다. 똑같이
line()
을 사용한다. 위에서 그린 plt 그래프에 하나의 값을 업데이트 해보자.1
2
3
4Y_append = torch.randn(1)
X_append = torch.Tensor([6])
vis.line(Y=Y_append, X=X_append, win=plt, update='append')위와같이 업데이트할 plot의 이름을
win
에 지정해주고update='append'
로 지정하면 기존의 그래프에 하나의 값이 추가된 것을 확인할 수 있다.하나의 window에 두개의 line plot을 그릴때도
line()
을 사용한다.1
2
3
4
5
6num = torch.Tensor(list(range(0,10)))
num = num.view(-1,1)
num = torch.cat((num,num),dim=1)
print(num.shape) ###>>> (10,2)
plt = vis.line(Y=torch.randn(10,2), X = num)
Line Plot의 정보 나타내기
line plot에 title과 legend를 나타내기 위해서는 dict형태의 입력값을 사용한다.
위에 그린 그래프에 title과 legned를 나타내보자.
1
plt = vis.line(Y=Y_data, X=X_data, opts=dict(title='test', legend=['1번'], showlegend=True))
두개의 line plot에도 각각의 legend를 나타낼 수 있다.
1
plt = vis.line(Y=torch.randn(10,2), X=num, optes=dict(title='test', legend=['1번','2번'], showlegend=True))
창 닫기
env='main'
으로 지정한 창을 닫기 위해서close()
를 사용한다.1
vis.close(env='main')
기본적인 visdom 사용법을 알아보았으며, 이를 이용해 CNN MNIST의 코드를 조금 변형해 loss plot을 그려보자.
loss plot을 그리기 위해서 line plot을 업데이트해줄 함수를 만들어주자.
1
2
3
4
5
6def loss_tracker(loss_plot, loss_value, num):
### loss_plot : line plot value
### loss_value : Tensor
### num : Tensor
### return : None
vis.line(X=num, Y=loss_value, win=loss_plot, update='append')그리고 loss를 업데이트해줄 빈 line plot을 하나 만들어준다.
1
loss_plot = vis.line(Y=torch.Tensor(1).zero_(), opts=dict(title='loss', legend=['loss'], showlegend=True))
이후 모델 생성은 모두 동일하지만, train을 진행할때 위의 함수를 통해 그래프를 업데이트 해주는 부분이 추가된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21total_batch = len(data_loader)
model.train()
for epoch in range(epochs):
avg_cost = 0
for X, Y in data_loader:
X = X.to(device)
Y = Y.to(device)
optimizer.zero_grad()
hypothesis = model(X)
loss = criterion(hypothesis, Y)
loss.backward()
optimizer.step()
avg_cost += loss / total_batch
print('[Epoch: {:>4}] cost = {:>.9}'.format(epoch + 1, avg_cost))
loss_tracker(loss_plot, torch.Tensor([avg_cost]), torch.Tensor([epoch]))
###>>> loss_tracker함수를 통해 그래프를 업데이트
print('learning finished')학습을 진행하면서 visdom의 line plot이 실시간으로 업데이트되는 모습을 확인할 수 있다.