Pytorch_visdom으로_Loss_plot그리기

Visdom에 관하여 & Loss plot 그리기

모두를 위한 딥러닝 - 파이토치 강의 참고

  • visdom을 사용하기 위해서는 서버를 실행시켜줘야 한다.

  • jupyter notebook의 경우, New –> Terminal –> 실행된 터미널 창에서 다음의 명령어를 입력한다.

1
>>>python -m visdom.server
  • pycharm을 이용한다면 파이참 하단의 terminal을 클릭해 위의 명령어를 입력하면된다.

  • 다만, visdom의 기본 포트가 사용중이라면 에러가 발생하는데 이때는 visdom 포트변경 포스트를 확인해 해결할 수 있다.

  • 서버가 정상적으로 실행됐다면, visdom 객체를 아래와 같이 생성하고 이를 이용해 text, 이미지, 그래프 등을 나타낼 수 있다.

1
2
import visdom
vis = visdom.Visdom()
  • 아래에서 진행하는 예제는 실행된 local서버를 접속해 확인할 수 있다.

  • Text 출력하기

    • text를 출력하기 위해서 text()를 사용한다.

      1
      vis.text('hello world', env='main')
    • 이때 env='main'은 실행문의 이름을 지정해 추후에 main으로 실행된 모든 창을 한번에 종료할 수 있게 해준다.

  • Image 출력하기

    • image 출력은 image()를 사용한다.

    • 랜덤한 이미지를 출력해보자.

      1
      2
      ex = torch.randn(3, 200, 200)
      vis.image(ex)
    • 여러장의 이미지를 출력하기 위해서는 images()를 사용한다.

      1
      vis.images(torch.Tensor(3,3,28,28))
    • CIFAR10의 이미지를 가져와 출력해보자.

      1
      2
      3
      4
      cifar10 = 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
      11
      MNIST = 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
      3
      Y_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
      4
      Y_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
      6
      num = 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
      6
      def 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
      21
      total_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이 실시간으로 업데이트되는 모습을 확인할 수 있다.

Full Code

Full Code - Visdom Example
Full Code - Loss tracker

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×