안경잡이개발자

728x90
반응형

  유튜브(YouTube)에서 구독자가 10만 명이 넘으면 실버 버튼을 신청할 수 있습니다. 예를 들어 필자의 채널은 구독자 수가 141,000명이 넘었는데, 아직 귀찮아서 실버 버튼을 신청하지 않았습니다. 그런데 주변의 유튜버 친구들이 실버 버튼을 신청하라고 말해주어서 이번 기회에 신청하고자 합니다.

 

 

※ 크리에이터 어워즈 프로그램 소개 ※

 

  간단하게 크리에이터 어워즈 프로그램에 대해 알아봅시다. 크리에이터 어워즈(Creator Awards)란 말 그대로 크리에이터를 위한 수상을 의미합니다. 구독자 수가 일정 수준을 넘으면 유튜브에서 버튼을 보내줍니다.

 

  ▶ 크리에이터 어워즈 프로그램 참여https://support.google.com/youtube/answer/7682560?hl=ko 

 

크리에이터 어워즈 프로그램 참여 - YouTube 고객센터

도움이 되었나요? 어떻게 하면 개선할 수 있을까요? 예아니요

support.google.com

 

  안내 페이지에 접속하면 다음과 같이 [어워즈 신청] 안내 문구를 확인할 수 있습니다. 기본적으로 크리에이터 어워즈 수상 자격(구독자 수 등)이 인정되면 YouTube 스튜디오 대시보드에 알림이 뜨게 됩니다. 해당 알림에는 [고유 신청 코드]가 포함되고, 해당 코드를 [크리에이터 어워즈 신청 웹사이트]에 입력하면 됩니다.

 

 

  하지만 구독자 수를 만족하였음에도, 알림이나 신청 코드를 받지 못했다면 [크리에이터 지원팀]에 문의하면 됩니다.

 

 

  혹은 기본적으로 [도움말] 버튼을 누른 뒤에 [YouTube 크리에이터 지원팀에 문의]를 누르면 됩니다. 사실 여기에서 바로 [문의하기] 버튼을 눌러도 문의에 대한 답변을 받을 수 있습니다.

 

 

  YouTube 크리에이터 지원팀에 문의하는 방법은 크게 ① 채팅② 이메일이 있습니다. 여기에서 [이메일]을 선택하면 다음과 같이 이메일 문의가 가능한 페이지를 알려줍니다.

 

 

 

  이때 다음과 같이 [문의하기] 버튼을 누르면 됩니다.

 

 

  가장 먼저 문의 내용을 입력합니다. 저는 "실버 버튼을 신청하고 싶습니다"라고 입력했습니다.

 

 

  이후에 리소스를 확인하고 [다음 단계]를 누르면 됩니다.

 

 

  이후에 문의 옵션을 선택합니다. 필자의 경우 [이메일]을 선택했습니다.

 

 

  이후에 다음과 같이 상세 문의 내용을 입력하여 [제출] 버튼을 누르면 됩니다.

 

 

  문의 내용을 작성하고 제출하면 다음과 같이 이메일이 발송됩니다.

 

 

  이후에 기다리면 다음과 같이 메일이 도착합니다.

 

 

  그리고 필자의 경우 하루가 경과한 뒤에 [신청코드]가 도착했습니다. 신청코드를 복사한 뒤에 [크리에이터 어워즈 사이트]로 이동하여 인증을 수행할 수 있습니다.

 

 

  이후에 다음과 같이 입력 칸에 인증코드를 넣고 [Redeem award] 버튼을 누르면 됩니다.

 

 

  이후에 채널 이름을 기입하면 됩니다. 제 채널명은 "동빈나"이지만, 그냥 "나동빈(Dongbin Na)"으로 기입했습니다. 제가 알기로는 단순히 자신이 넣은 내용으로 실버 버튼이 주문 제작되는 것으로 알고 있습니다.

 

 

  이제 배송을 받기 위한 상세 주소를 기입합니다. 저는 기본적으로 Country를 [South Korea]로 변경한 뒤에, 이름을 영어로 기입했습니다.

 

 

  ▶ Street Address: 구체적인 주소(상세 도로명 주소) 및 동/호를 넣으면 됩니다.

  ▶ City: 시, 군, 구 단위를 넣을 수 있습니다. (안양시 만안구, 성남시 분당구 등)

  ▶ State: 서울특별시나 경기도 단위를 넣을 수 있습니다. (서울, 대구, 부산, 경기도 등)

  ▶ Zip/Postal Code: 우편번호를 넣으면 됩니다. (37673 등)

  ▶ Phone Number 예시: +82)10-1234-5678

 

  참고로 상세 주소를 기입할 때는 네이버 영문 주소 서비스를 이용하는 것이 제일 편리합니다. 예를 들어 포항공대의 영문 주소를 알고 싶다면 다음과 같이 검색하면 됩니다.

 

 

  이후에 최종적으로 실버 버튼에 들어갈 채널명과 배송지를 확인한 뒤에 [Place Order] 버튼을 누르면 됩니다. 아래 그림과 같이 처음 실버 버튼을 신청할 때는 무료입니다.

 

 

  신청한 뒤에는 다음과 같이 주문이 완료되었다는 메시지가 나옵니다.

 

728x90
반응형

Comment +0

728x90
반응형

  구글 크롬(Google Chrome) 브라우저를 사용하는 사람은 현재 크롬 브라우저에 열려 있는 모든 탭을 저장한 뒤에, 나중에 한꺼번에 열 수 있습니다. 실제로 웹 브라우저를 실행하여 일을 하다 보면 탭을 50개 이상 열어 놓고 일을 하다가, 나중에 이전에 보았던 탭들을 다시 확인해야 하는 일이 생깁니다. 특히 이전에 보았던 탭들 중에서 일부를 자기도 모르게 끄는 경우가 생길 수 있으므로, 현재 열린 탭들을 저장해 놓는 기능을 효과적으로 사용할 수 있습니다.

 

  방법은 간단합니다. 다음과 같이 [북마크] - [모든 탭 북마크] 버튼을 누릅니다.

 

 

  필자는 개인적으로 다음과 같이 날짜를 기준으로 저장하는 것이 편리합니다. 따라서 [새 폴더]를 누른 뒤에 날짜를 폴더의 이름으로 설정했습니다.

 

 

  이후에 다음과 같이 [저장] 버튼을 누르면 자신이 설정한 이름으로 폴더가 생성됩니다. 저는 그냥 [새 폴더]라는 이름을 그대로 사용했습니다.

 

 

  결과적으로 북마크가 생성되었습니다. 나중에 북마크에 저장된 탭(링크)들을 한꺼번에 불러와 열고자 한다면, 다음과 같이 저장된 북마크를 우클릭하여 [모두 열기] 버튼을 누르면 됩니다.

 

 

  나중에 북마크를 삭제하고 싶을 때는 마찬가지로 우클릭 이후에 [삭제]를 누르면 됩니다.

 

728x90
반응형

Comment +0

728x90
반응형

  최근에 PyTorch를 이용하여 딥러닝 소스 코드를 실행하려고 하는데, 다음과 같이 NVIDIA driver 관련 오류가 출력되었다. 아래 오류는 기본적으로 자신이 설치한 PyTorch의 버전이 NVIDIA driver의 버전과 호환되지 않기 때문에 오류가 발생한다. 이 경우 ① NVIDIA driver를 업데이트하여 PyTorch 버전과 맞추거나 ② PyTorch를 재설치하여 NVIDIA driver의 버전을 맞추는 방법이 있다.

 

  전체 오류 메시지는 일반적으로 다음과 같이 출력된다.

 

 

  가장 먼저, 다음과 같은 명령어를 이용해 자신의 GPU 노드에 설치되어 있는 CUDA 버전을 확인하자.

 

cat /usr/local/cuda/version.txt

 

  실행 결과 다음과 같이 CUDA 버전이 출력된다. 필자의 GPU 노드의 CUDA 버전은 10.1.168이다.

 

 

  필자는 CUDA 버전을 업데이트하는 것이 번거로운 상황이라서 기존의 torch 및 torchvision을 제거했다.

 

pip3 uninstall torch torchvision


  이후에 CUDA 버전에 맞는 torch와 torchvision으로 다시 설치했다. CUDA 버전이 10.1이기 때문에, 이와 같이 CUDA 10.1을 위한 torch와 torchvision을 사용하면 되는 것이다. 현재 시점으로 PyTorch로 작성된 상당수의 딥러닝 소스 코드는 PyTorch 1.7.0 버전으로 실행할 수 있기 때문에, 필자는 이 버전으로 설치했다.

pip3 install torch==1.7.0+cu101 torchvision==0.8.1+cu101 -f https://download.pytorch.org/whl/torch_stable.html

 

  참고로 너무 예전 버전의 torch와 torchvision을 쓰게 되면 최신 코드를 실행하지 못하는 경우가 있으므로, 최대한 최신 버전의 PyTorch부터 설치해 보고 실행해 보는 방식으로 문제를 해결할 수 있다. 필자 또한 문제를 해결하는 과정에서 여러 번 torch와 torchvision을 설치하고 삭제하는 과정을 반복했다.

728x90
반응형

Comment +0

728x90
반응형

  유튜브에서는 [인증 배지]라는 것이 있습니다. 인증 배지는 인증된 채널에 부여되는 배지로, 인증을 받은 채널은 유튜브(YouTube) 채널의 이름 옆에 체크 표시가 나타납니다. 특별한 혜택은 별도로 없지만, 공식적인 채널이라는 표시를 할 수 있습니다. 유튜브 채널의 인증 배지에 대한 설명은 다음의 페이지에서 확인할 수 있습니다.

 

  ▶ 유튜브 채널 인증 배지 설명: https://support.google.com/youtube/answer/3046484?hl=ko 

 

채널의 인증 배지 - YouTube 고객센터

도움이 되었나요? 어떻게 하면 개선할 수 있을까요? 예아니요

support.google.com

 

  웹 사이트에 접속한 뒤에 설명을 확인해 보면 다음과 같이 채널의 구독자 수가 100,000명 이상이면 신청이 가능하다고 합니다. 신청할 때는 [지금 신청하기] 버튼을 누르면 되고, 채널 이름을 변경하지 않는 이상 인증 상태가 유지된다고 합니다.

 

 

  결과적으로 다음과 같이 채널 인증 신청을 진행할 수 있습니다. 이때 구독자가 100,000명 이상인 유튜브 계정으로 접속했을 때 아래와 같은 화면을 확인할 수 있습니다. [채널 이름][채널 ID]를 입력하여 [제출] 버튼을 누르면 됩니다.

 

 

  제출을 완료하면 다음과 같이 [이메일이 발송됨]이라는 안내 메시지가 등장합니다.

 

 

  이후에 다음과 같은 메일이 도착합니다. 채널 인증 신청(Channel Verification Application)이 완료되었다는 것을 확인할 수 있습니다. 이제 채널 인증이 완료될 때까지 기다리면 됩니다.

 

 

728x90
반응형

Comment +0

728x90
반응형

  구글 크롬(Google Chrome)을 이용할 때, 현재 페이지에 있는 내용을 캡처(capture)하여 인쇄하고 싶을 때가 있다. 하지만 단순히 인쇄를 진행하면, 여러 개의 페이지로 나누어서 PDF가 만들어지는 문제가 있다. 이때 GoFullPage 확장 프로그램을 이용하면, 하나의 페이지에 모든 내용을(모든 스크롤에 대한 내용) 담은 형태로 저장할 수 있다. Google Chrome에서는 다음의 확장 프로그램을 이용하면 편리하다.

 

▶ GoFullPage 확장 프로그램 다운로드 경로: https://chrome.google.com/webstore/detail/gofullpage-full-page-scre/fdpohaocaechififmbbbbbknoalclacl?hl=ko 

 

GoFullPage - Full Page Screen Capture

추가 권한을 요청하지 않고 현재 페이지의 스크린샷을 전체적으로 캡처하고 신뢰할 수 있습니다!

chrome.google.com

 

  GoFullPage에 접속한 뒤에 [Chrome에 추가] 버튼을 눌러 다운로드를 진행한다.

 

 

  GoFullPage 확장 프로그램을 클릭하여 실행하면 다음과 같이 현재 페이지에 대하여 화면 캡처(Screen Capture)가 진행된다.

 

 

  캡처 이후에는 [PDF] 다운로드 버튼을 누르거나, 마우스 우클릭 이후에 [Save Image As...]와 같은 기능을 사용하여 저장하면 된다.

 

728x90
반응형

Comment +0

728x90
반응형

  어도비 포토샵(Adobe Photoshop)을 설치하지 않고, 무료온라인에서 포토샵과 유사하게 간단히 이미지를 편집할 수 있는 기능을 제공하는 웹 사이트가 있습니다. 바로 픽슬러(Pixlr)라는 웹 사이트로, 흔히 인터넷 포토샵이라고 잘 알려져 있습니다. 일반적으로 많이 사용되는 서비스는 바로 Pixlr X로, 초보자용 픽슬러로 간단한 기능들을 제공합니다.

 

  ▶ 픽슬러(Pixlr) 웹 사이트: https://pixlr.com/kr/x/

 

사진 에디터 : Pixlr.com - 온라인 무료 사진 편집 툴

Pixlr X를 통해 브라우저에서 고급 사진 편집 툴을 바로 실행할 수 있어요. 별도의 설치 또는 회원가입이 불필요! 컴퓨터, 태블릿, 스마트폰에서 언제 어디서나 무료로 이용하세요.

pixlr.com

 

  픽슬러에 접속하면 다음과 같은 화면이 나옵니다. 이제 이미지를 불러와 편집을 진행할 수 있습니다.

 

 

  사용 방법은 간단합니다. 심지어 그림판 등에서 복사된 이미지를 그냥 웹 사이트에 붙여넣기(Ctrl + V)해도 다음과 같이 이미지가 붙여넣기 되는 것을 알 수 있습니다. 이후에 일반적으로 포토샵에서 제공하는 기능을 거의 유사하게 사용할 수 있습니다.

 

 

  편집을 완료한 뒤에는 [저장] 버튼을 눌러 이미지를 저장할 수 있습니다.

 

 

  다음과 같이 이미지 파일을 저장할 수 있습니다. 원하는 이미지 파일 유형을 선택한 뒤에 [다운로드] 버튼을 누르면 됩니다.

 

728x90
반응형

Comment +0

728x90
반응형

※ WandB 서비스 소개 ※

 

  WandB는 기계학습/딥러닝 개발자를 위한 종합적인 보조 도구다. 가장 대표적인 기능으로는 우리가 딥러닝 모델을 학습할 때 학습 과정에 대해서 로깅(logging)을 진행해 준다. 그래서 손실(loss) 값의 감소하는 형태를 쉽게 파악할 수 있다. TensorBoard를 사용해 본 사람이라면, 학습 과정을 적절히 로깅하는 것이 실험/연구에 있어서 얼마나 중요한지 알 것이다. 특히 WandB팀 단위로 실험 결과를 추적할 수 있도록 해주기 때문에, 웹 상에서 보다 편리하게 분석이 가능하다.

  ▶ WandB 공식 홈페이지: https://wandb.ai/

 

  웹 사이트에 접속한 뒤에는 간단한 과정으로 회원가입 및 로그인을 진행할 수 있다. 먼저 [Sign Up] 버튼을 눌러 회원가입을 진행할 수 있다.

 

 

  회원가입을 진행할 때는 깃허브를 이용하는 것이 편리하다. [Sign up with GitHub]을 눌러 회원가입을 진행하면 된다.

 

 

  초기 인증을 위해 깃허브 계정 연동을 허용할 것인지 물어보는 과정이 포함된다.

 

 

  이후에 이름과 사용자명(Username)을 포함한 개인 정보를 기입하여 회원가입을 진행할 수 있다.

 

 

  회원가입 이후에는 다음과 같은 안내 페이지가 등장하며 Quickstart 탭의 [PyTorch]에 접속하여 바로 예제 코드를 이용해 WandB를 이용해 볼 수 있다.

 

 

※ WandB 예제 코드 사용해 보기 ※

 

  가장 먼저 파이썬 패키지 매니저인 pip 명령어를 이용하여 wandb를 설치한다.

 

pip3 install wandb

 

  이후에 wandb login 명령어를 입력하여 로그인을 진행할 수 있다. 참고로 이때 인증을 위해 본인의 API Key를 입력해야 하는데, wandb 웹 사이트에 로그인 이후에 등장하는 API Key를 복사하여 붙여넣기 하면 된다.

 

 

※ PyTorch 예제 코드를 통해 WandB 사용 방법 이해하기 ※

 

  PyTorch 공식 문서에서 제공하는 MNIST 학습 코드를 가져와 실행해 보자.

 

  ▶ PyTorch 공식 MNIST 코드: https://github.com/pytorch/examples/blob/master/mnist/main.py

from __future__ import print_function
import argparse
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.optim.lr_scheduler import StepLR


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.dropout1 = nn.Dropout(0.25)
        self.dropout2 = nn.Dropout(0.5)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        output = F.log_softmax(x, dim=1)
        return output


def train(args, model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()
        if batch_idx % args.log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))
            if args.dry_run:
                break


def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()  # sum up batch loss
            pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)

    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))


def main():
    # Training settings
    parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
    parser.add_argument('--batch-size', type=int, default=64, metavar='N',
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs', type=int, default=14, metavar='N',
                        help='number of epochs to train (default: 14)')
    parser.add_argument('--lr', type=float, default=1.0, metavar='LR',
                        help='learning rate (default: 1.0)')
    parser.add_argument('--gamma', type=float, default=0.7, metavar='M',
                        help='Learning rate step gamma (default: 0.7)')
    parser.add_argument('--no-cuda', action='store_true', default=False,
                        help='disables CUDA training')
    parser.add_argument('--dry-run', action='store_true', default=False,
                        help='quickly check a single pass')
    parser.add_argument('--seed', type=int, default=1, metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                        help='how many batches to wait before logging training status')
    parser.add_argument('--save-model', action='store_true', default=False,
                        help='For Saving the current Model')
    args = parser.parse_args()
    use_cuda = not args.no_cuda and torch.cuda.is_available()

    torch.manual_seed(args.seed)

    device = torch.device("cuda" if use_cuda else "cpu")

    train_kwargs = {'batch_size': args.batch_size}
    test_kwargs = {'batch_size': args.test_batch_size}
    if use_cuda:
        cuda_kwargs = {'num_workers': 1,
                       'pin_memory': True,
                       'shuffle': True}
        train_kwargs.update(cuda_kwargs)
        test_kwargs.update(cuda_kwargs)

    transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
        ])
    dataset1 = datasets.MNIST('../data', train=True, download=True,
                       transform=transform)
    dataset2 = datasets.MNIST('../data', train=False,
                       transform=transform)
    train_loader = torch.utils.data.DataLoader(dataset1,**train_kwargs)
    test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs)

    model = Net().to(device)
    optimizer = optim.Adadelta(model.parameters(), lr=args.lr)

    scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma)
    for epoch in range(1, args.epochs + 1):
        train(args, model, device, train_loader, optimizer, epoch)
        test(model, device, test_loader)
        scheduler.step()

    if args.save_model:
        torch.save(model.state_dict(), "mnist_cnn.pt")


if __name__ == '__main__':
    main()


  다음과 같은 명령어를 입력해 코드를 실행하면 콘솔 창에는 다음과 같이 내용이 출력된다.

 

python3 mnist_example.py

 


  정상적으로 코드가 실행이 되는 것을 확인할 수 있다. 하지만 기본적으로 loss와 같은 로그 정보가 콘솔 창에 그대로 출력되므로, 손실 값을 자세히 분석하기에는 시각적으로 다소 불편한 감이 있다.


※ WandB 사용해보기 ※

  앞서 사용했던 코드를 다음과 같이 wandb 라이브러리를 사용하는 형태로 바꿀 수 있다. 기본적으로 변경된 부분은 wandb가 포함된 부분이므로, 이 부분만을 확인하면 된다.

from __future__ import print_function
import wandb
import argparse
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.optim.lr_scheduler import StepLR


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.dropout1 = nn.Dropout(0.25)
        self.dropout2 = nn.Dropout(0.5)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        output = F.log_softmax(x, dim=1)
        return output


def train(args, model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()
        if batch_idx % args.log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))
            if args.dry_run:
                break


def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0

    # wandb에 기록할 테스트 이미지들
    tested_images = []
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()  # sum up batch loss
            pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
            correct += pred.eq(target.view_as(pred)).sum().item()
            # wandb에 현재 배치에 포함된 첫 번째 이미지에 대한 추론 결과 기록
            tested_images.append(
                wandb.Image(data[0], caption=f'Predicted: {pred[0].item()}, Ground-truth: {target[0]}'
            ))

    test_loss /= len(test_loader.dataset)

    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))
    # wandb에 로깅 진행
    wandb.log({
        "Tested Images": tested_images,
        "Test Average Loss": test_loss,
        "Test Accuarcy": 100. * correct / len(test_loader.dataset)
    })


def main():
    # Training settings
    parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
    parser.add_argument('--batch-size', type=int, default=64, metavar='N',
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs', type=int, default=14, metavar='N',
                        help='number of epochs to train (default: 14)')
    parser.add_argument('--lr', type=float, default=1.0, metavar='LR',
                        help='learning rate (default: 1.0)')
    parser.add_argument('--gamma', type=float, default=0.7, metavar='M',
                        help='Learning rate step gamma (default: 0.7)')
    parser.add_argument('--no-cuda', action='store_true', default=False,
                        help='disables CUDA training')
    parser.add_argument('--dry-run', action='store_true', default=False,
                        help='quickly check a single pass')
    parser.add_argument('--seed', type=int, default=1, metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                        help='how many batches to wait before logging training status')
    parser.add_argument('--save-model', action='store_true', default=False,
                        help='For Saving the current Model')
    args = parser.parse_args()

    # wandb 프로젝트 초기화
    wandb.init(project='mnist-example', entity='dongbin_na')
    # wandb에 하이퍼파라미터 configuration 정보 기록
    wandb.config.update(args)

    use_cuda = not args.no_cuda and torch.cuda.is_available()

    torch.manual_seed(args.seed)

    device = torch.device("cuda" if use_cuda else "cpu")

    train_kwargs = {'batch_size': args.batch_size}
    test_kwargs = {'batch_size': args.test_batch_size}
    if use_cuda:
        cuda_kwargs = {'num_workers': 1,
                       'pin_memory': True,
                       'shuffle': True}
        train_kwargs.update(cuda_kwargs)
        test_kwargs.update(cuda_kwargs)

    transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
        ])
    dataset1 = datasets.MNIST('../data', train=True, download=True,
                       transform=transform)
    dataset2 = datasets.MNIST('../data', train=False,
                       transform=transform)
    train_loader = torch.utils.data.DataLoader(dataset1,**train_kwargs)
    test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs)

    model = Net().to(device)
    # wandb에서 학습할 모델 정보 추적
    wandb.watch(model)
    optimizer = optim.Adadelta(model.parameters(), lr=args.lr)

    scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma)
    for epoch in range(1, args.epochs + 1):
        train(args, model, device, train_loader, optimizer, epoch)
        test(model, device, test_loader)
        scheduler.step()

    if args.save_model:
        torch.save(model.state_dict(), "mnist_cnn.pt")


if __name__ == '__main__':
    main()


  실행하는 코드는 동일하다. (wandb 라이브러리를 사용했다고 해서 특별히 더 해 줄 것은 없다.) wandb를 이용해 실행 결과가 로깅되는 경우 다음과 같이 실행된다.


  이후에 wandb.ai/home에 다시 접속하면 자신의 프로젝트 리스트가 등장한다. 여기에서 본인의 프로젝트를 클릭하면 다음과 같이 나온다.

 

 

  참고로 코드를 실행한 폴더에도 wandb 관련 log 폴더가 생성되며 (실행할 때마다 한 번의 run 폴더가 생긴다.) 기본적으로 wandb 서버에 학습할 때의 로그 데이터가 모두 업로드 되기 때문에, 나중에 웹 사이트에 접속해 내용을 확인할 수도 있다. 실제로 사용해 보면 웹 상에서 즉시 확인할 수 있다는 측면에서 매우 편리하다는 것을 느낄 수 있다.

728x90
반응형

Comment +0

728x90
반응형

※ 특정한 웹 사이트에 서로 다른 계정으로 동시에 로그인하는 방법 ※

 

  일반적인 경우 특정한 웹 사이트에 여러 개의 계정으로 동시에 로그인하기 위해서는 여러 개의 서로 다른 브라우저를 별도로 실행해야 한다. 예를 들어 크롬(Chrome) 브라우저에서는 [1번 계정]으로 네이버에 로그인하고, 웨일(Whale) 브라우저에서는 [2번 계정]으로 네이버에 로그인하는 방법을 사용할 수 있다. 하지만 이를 위해 여러 개의 서로 다른 브라우저를 설치하는 것은 불편하다. 구글 크롬(Chrome)에서는 사용자를 추가하여 브라우저를 분리하여 사용이 가능하다.

 

  다시 말해 크롬에서는 프로필(사용자)을 추가하여, 사용자마다 모든 Chrome 데이터를 분리할 수 있다. 가족이나 친구를 위한 별도의 프로필을 만들거나, 업무용 및 개인용 프로필을 구분하기 위해 효과적으로 사용할 수 있다. 필자의 경우에는 동시에 서로 다른 계정의 메일을 확인해야 하는 일이 있었는데, 매번 로그아웃 이후에 다른 계정으로 로그인을 하는 과정이 불편하여 프로필을 별도로 생성했다.

 

※ 크롬(Chrome) [사용자 추가] 방법 ※

 

  크롬(Chrome)에서 사용자를 추가할 때는 오른쪽 위에 [현재 사용자] 버튼을 누른다. 이후에 [추가] 버튼을 눌러 프로필(사용자) 추가를 진행한다.

 

 

  이후에 다음과 같이 [Chrome 사용자 선택] 창이 나올 수 있는데, 이때 [추가] 버튼을 눌러 사용자 추가를 진행하면 된다.

 

 

  이후에 [로그인] 버튼을 눌러 새로운 사용자(프로필)로 로그인을 진행하면 된다.

 

 

  로그인 이후에는 다음과 같이 새로운 Chrome 프로필로 접속이 완료된 것을 알 수 있다. 일반 프로필에서 사용하던 확장 프로그램이나 북마크는 확인할 수 없는 것을 알 수 있다. 또한 [Chrome 맞춤설정] 버튼을 눌러 해당 프로필에 대한 맞춤 설정을 진행할 수 있다.

 

 

  결과적으로 아래와 같이 작업 표시줄에 각각의 사용자마다 Chrome 브라우저가 개별적으로 실행되고 있는 것을 알 수 있다. 이제 브라우저가 구분되었으므로, 동일한 사이트에 서로 다른 계정으로 로그인할 수 있다.

 

 

※ 사용자별로 바탕화면 바로가기 만들기 ※

 

  사용자를 추가한 뒤에는 사용자별로 바탕화면 바로가기를 생성할 수 있다.

 

 

  이후에 [Chrome 프로필 맞춤설정] 페이지로 이동한다.

 

 

  이후에 다음과 같이 [바탕화면 바로가기 만들기] 항목에 체크하면 된다.

 

 

  결과적으로 바탕화면에 바로가기가 생성되었으면, 아이콘을 클릭하여 손쉽게 크롬 브라우저를 실행할 수 있다. 추가적으로 아이콘을 마우스 우클릭하여 [작업 표시줄에 고정(K)]을 진행하면 더욱 쉽게 다수의 프로필로 구분된 크롬 브라우저들을 효율적으로 사용할 수 있다. 필자의 경우 이러한 방법으로 3개 정도의 Chrome 사용자를 사용하고 있다.

 

※ 크롬(Chrome) 게스트(Guest) 모드 ※

 

  참고로 게스트(Guest) 사용자로 접속하면, 게스트 모드가 실행된다. 게스트 모드에서 접속한 페이지는 [방문 기록]에 남지 않으며, 컴퓨터 내부에 쿠키(Cookie) 정보를 남기지 않는다. 다시 말해 로컬 컴퓨터 측면에서 기본적인 개인정보 보호가 진행되는 것이다. (반면에 다운로드한 파일은 저장된다.) 설명만 들으면 Chrome이 기본적으로 제공하는 시크릿 모드(Ctrl + Shift + N)와 상당히 유사하다.

 

  게스트 모드와 시크릿 모드와의 대표적인 차이점을 설명하자면 다음과 같다.

 

  ▶ 게스트 모드에서는 일반 크롬에서 사용했던 확장 프로그램이 보이지 않는다.

  ▶ 게스트 모드에서는 일반 크롬에서 접속했던 방문 사이트가 보이지 않는다.

 

  그렇기 때문에 게스트 모드는 일반적으로 내가 다른 사람의 컴퓨터를 잠시 사용하거나, 내 컴퓨터를 다른 사람에게 잠시 빌려줄 때 사용하기에 적합한 기능이다. 게스트 모드로 접속해 보면, 사실상 크롬을 처음 설치했을 때와 비슷한 환경인 것을 알 수 있다. 게스트 모드에 접속하면 다음과 같은 화면이 나온다.

 

728x90
반응형

Comment +0

728x90
반응형

※ 필자의 경험에 근거하여 쓴 글이므로, 잘못된 정보가 포함되어 있을 수 있습니다. ※

 

  필자는 사실 옷을 주문한 뒤에 웬만큼 사이즈가 맞는다면 그냥 입는 편이다. 하지만 쿠팡에서는 교환, 반품 서비스가 편하게 되어 있다고 했다고 잘 알려져 있다. 난 쿠팡을 어렸을 때부터 많이 써온 편인데, 정작 교환/반품을 신청해 본 적이 없다. 그래서 이번 기회에 쿠팡에 대해서 조금 조사해 보고, 옷 교환을 신청해 보았다.

 

※ 쿠팡(Coupang) 개요 ※

 

  쿠팡(Coupang)은 대표적인 온라인 쇼핑몰 서비스를 운영하는 회사다. 현재 국내에서는 네이버와 함께 전자상거래(E-commerce) 시장을 이끌어가고 있는 기업 중 하나다. "쿠팡" 하면 떠오르는 이미지로는 로켓배송이 있는데, 말 그대로 로켓처럼 빠르게 배송해주는 서비스로 실제로 로켓배송으로 상품을 주문해보면 빠르게 도착하는 것을 알 수 있다. (사실 나는 상품 배송 기간에 민감하지 않아서, 지금까지 모든 제품이 예정된 시각에 도착했는지는 확실치 않다. 하지만 웬만하면 굉장히 빠르게 배송되었다는 인식이 존재한다.)

 

  쿠팡은 몇 년 전부터 로켓배송 서비스를 필두로 국내에서 이커머스(E-commerce) 사업을 확장했다. 재미있는 점은 쿠팡에서는 다른 택배 업체를 사용하지 않고, 자체 배송 서비스를 운영한다는 점이다. 쿠팡은 자체적인 물류센터에 상품들을 보관해 놓고, 주문이 들어왔을 때 빠르게 출고하는 시스템을 갖추고 있다. 그래서 밤 12시에 주문하면, 그다음 날에 바로 배송해준다고 한다. 인터넷에 검색해 보면 간혹 배송 문제를 경험했다는 글을 찾아볼 수 있지만, 필자의 경우 수십 번 주문을 했을 때 대체로 예정된 시간에 도착하긴 했다. (내가 시간에 민감하지 않아서 헷갈리는 것일 수도 있다.)

 

  참고로 쿠팡에서는 로켓와우 서비스도 제공하고 있는데, 로켓와우의 경우 월정액제 상품으로 매달 일정 금액을 내면, 로켓와우 회원이 될 수 있다. 로켓와우 회원인 경우 주문 금액이 작다고 하더라도 로켓배송 제품을 무료로 배송받을 수 있다. 필자는 로켓와우 멤버십에 언제 가입했는지 모르겠지만, 알고 보니 멤버십이었다. 통장을 잘 확인하고 살지 않아서 신경을 안 쓰고 있었는데, 매달 2,900원씩 결제를 하고 있었다. [My 쇼핑] - [와우 멤버십] 탭으로 이동해 보니 다음과 같이 나왔다. 로켓와우 멤버십의 경우 30일 무료 반품 기능도 있는데, 듣기로는 사유가 단순 변심이어도 거의 대부분 반품이 가능해서 혜자라고 알려져 있다.

 

 

※ 쿠팡에서 주문한 상품 교환 및 반품하는 방법 ※

 

  필자의 경우 쿠팡의 로켓배송이 편리한 것 같아서 자주 주문하는 것 같다. 더불어 특유의 귀찮음 때문에 한 번 구매할 때 여러 개의 물건을 한꺼번에 구매한다. 그래서 물건을 받고 나서 예상과 달랐던 경우가 많았던 것 같다. 따라서 반품이 필요한 경우에는 쿠팡 홈페이지에 접속하여 반품을 진행하면 된다.

 

1. 쿠팡 배송 상품인 경우

 

  필자는 최근에 아래와 같은 패딩을 구매했다. 다만 옷을 받아보니, XL 사이즈가 생각보다 커서 L 사이즈로 변경하고 싶어졌다. 상품 설명 페이지에 접속해 보니, 현재 나는 [와우회원]이라는 점에서 무조건 무료 배송이 가능하고, 무료 반품이 가능하다고 한다.

 

 

  교환이나 반품을 신청하기 위해서는 [주문 목록] 페이지로 이동한 뒤에 [교환, 반품 신청] 버튼을 누르면 된다.

 

 

  이후에 어떤 상품을 교환 혹은 반품 신청할 건지 결정하면 된다.

 

 

  필자는 [같은 상품의 다른 옵션으로 교환] 버튼을 눌렀다.

 

 

  그러면 다음과 같이 교환할 옵션을 선택할 수 있게 된다. 같은 색상의 L 사이즈가 없길래 그냥 블랙 색상의 L 사이즈를 선택했다.

 

 

  결과적으로 다음과 같이 [교환, 반품 신청서]를 작성할 수 있다. 토요일에 교환 신청을 하니까 바로 그다음날인 일요일을 기준으로 배송과 회수가 이루어진다고 한다. 매우 편리한 것 같다.

 

 

  참고로 [신청하기] 버튼을 눌러서 교환 신청이 완료되면 다음과 같이 나온다. 이때 교환할 제품을 어떻게 수거해 갈 수 있는지에 대한 내용이 자세하게 나온다. 교환 상품이 여러 개인 경우 같은 박스에 포장해도 되고, 쿠팡 상자가 아닌 다른 상자로 포장해도 된다고 나온다.

 

 

2. 택배사가 다른 경우

 

  필자의 경우에는 택배사가 쿠팡이 아닌 경우에 대해서도 옷을 주문한 적이 있다. 상품 상세 페이지에 이동해 보면 다음과 같이 다른 택배사 이름이 적힌 것을 알 수 있다. 필자의 경우 아래와 같은 옷을 주문했는데, 사진상에는 [아이보리] 색상인데, 이름은 [블러디레드]로 적혀 있었다. 결과적으로 주문을 [블러디레드] 색상으로 해서 원하는 색상의 옷이 오지 않은 경우다. (결국에는 반품하기 귀찮아서 입기로 했다.)

 

 

  마찬가지로 [주문 목록] 페이지에 접속하여 [교환, 반품 신청] 버튼을 눌러 신청을 진행할 수 있다.

 

 

  마찬가지로 원하는 상품을 선택해 반품 신청을 진행할 수 있다.

 

 

  양식은 대략 다음과 같다. (필자는 그냥 빨간색 옷 하나 정도는 있어도 되겠다 싶어서 결국에는 환불 신청을 안 했다.)

 

 

※ 반품할 때 택배 박스/봉투 포장 방법 ※

 

  필자가 개인적으로 궁금했던 것인데, 위와 같이 교환 및 반품을 신청한 뒤에는 상품을 택배 기사님께 전달하면 된다. 기본적으로 택배 박스/봉투 받았던 것을 활용하면 편하다. 하지만 운송장이나 택배 봉투를 모두 버린 상황이라고 해도, 자기가 개인적으로 가지고 있던 봉투나 박스를 이용해도 된다고 한다.

 

  그래서 교환 및 반품할 때는 가지고 있는 박스 등을 활용하여 해당 상품을 잘 담아서 [쿠팡 반품]이라고 적어서 두면 된다. 필자는 상품 회수지가 집 문 앞이라서, 그냥 문 앞에 두었다. 봉투에 담거나, 신문지나 종이를 이용해서 상품을 돌돌 만 뒤에 집에 있는 상자로 감싼 뒤에 매직으로 "쿠팡 반품"이라고 적는 방식이다. 주변에 다른 사례를 찾아보니까 그냥 종이 쇼핑백에 테이프로 밀봉해서 [쿠팡 반품]이라고 적어서 문 앞에 내놓아도 잘 수거해 가셨다고 한다. 참고로 옷의 경우에는 일반적으로 상품의 내용물을 확인하기 위해 포장을 개봉해야 하기 때문에 포장을 뜯었다고 해서 문제가 없는 경우가 많지만, 상품 포장지도 상품의 가치 중 하나로 인정받는 상품을 때는 환불에 어려움이 있을 수도 있다고 한다.

728x90
반응형

Comment +0

728x90
반응형

  마이크로소프트(Microsoft) 제품군을 사용하는 회사나 학교가 많다. 마이크로소프트에서 제공하는 제품들 중에서 대표적인 것들로는 다음과 같은 서비스들이 존재하는데, 학교나 회사가 마이크로소프트 제품군을 이용하는 경우 아래 제품들을 한꺼번에 통합적으로 사용하곤 한다.


  ▶ Microsoft 아웃룩(Outlook): 메일, 일정 및 연락처 관리

  ▶ Microsoft 원 드라이브(One Drive): 파일 업로드용 저장소 서비스
  ▶ Microsoft 팀즈(Teams): 채팅 및 회의(화상 통화)

 

  팀즈(Teams)는 팀 내에서 채팅이나 화상 회의와 같이 커뮤니케이션 목적으로 사용할 수 있는 서비스다. 그중에서도 팀즈는 "채팅" 목적으로 가장 많이 사용된다고 보면 된다. 국내 많은 스타트업이 사용하는 슬랙(Slack)과 유사한 기능을 제공한다. 실제로 Teams의 채팅 기능을 이용해 보면 대략 다음과 같은 형태로 사용할 수 있게 된다. (이미지는 공식 홈페이지에서 가져왔다.)

 

https://www.microsoft.com/ko-kr/microsoft-teams/instant-messaging

 

  물론 Teams는 채팅 이외에도 다양한 기능을 제공하는데, 몇 시에 어떤 회의실에서 미팅이 있는지 [회의 예약]을 진행할 수 있고, 해당 시간대에 직접 참석하지 못하는 사람들을 위해 편리한 화면 공유 및 화상 채팅 기능을 제공한다. 실제로 다수의 인원과 동시에 화상 채팅을 해도 크게 끊김 없이 진행할 수 있었던 기억이 있다.

 

 

https://www.microsoft.com/ko-kr/microsoft-teams/online-meetings

 

  그리고 Teams의 경우 [공동 작업] 기능도 제공한다. 동시에 같은 화면을 보면서 문서 작업을 할 수 있고, 상대방의 화상 캠(얼굴)을 보면서 그와 동시에 통화를 진행할 수 있다. 필자의 경우에는 면접을 볼 때 특정한 회사에서 이러한 공동 문서를 이용해 코딩 테스트를 봤던 기억이 있다. 화상 면접에 참여했더니 공동 문서에 문제가 몇 개 적혀 있고, 해당 면접관과 화면을 공유하는 상황에서 문제를 푸는 과정을 보여주는 방식의 면접이었다. 이런식으로 재미있게 공동 작업 기능을 활용할 수도 있다는게 신기했다.

 

https://www.microsoft.com/ko-kr/microsoft-teams/collaboration

 

※ Microsoft Teams 설치 방법 ※

 

  Microsoft Teams를 설치하기 위해서는 공식 다운로드 홈페이지로 이동하면 된다.

 

  ▶ Microsoft Teams 다운로드 페이지: https://www.microsoft.com/ko-kr/microsoft-teams/download-app

 

  이후에 자신의 디바이스에 맞는 앱을 다운로드한다. 노트북이나 데스크탑 PC를 쓰고 있다면, [데스크톱용 다운로드] 버튼을 눌러 해당 링크로 들어간다.

 

 

  Microsoft Teams의 경우 데스크톱 버전과 스마트 폰 버전의 기능이 사실상 동일하다. 예를 들어 가정에서 Teams를 사용하는 경우 [Windows 10용 다운로드] 버튼을 눌러 다운로드 및 설치를 진행할 수 있다. 설치 프로그램은 별다른 복잡한 과정 없이 쉽게 실행할 수 있다.

 

 

  이후에 로그인을 진행한다. 이때 특정한 학교나 회사의 이메일 주소로 로그인을 하게 되면, 자동으로 해당 조직(학교 및 회사)에 맞게 접속이 진행된다.

 

 

  설치 이후에 로그인을 진행하면, 다음과 같이 [모든 앱에 로그인 상태 유지]라는 메시지가 등장한다. 개인적으로는 이때 학교나 회사에서 별도의 요구 사항이 없다면, 조직이 내 디바이스(컴퓨터)를 관리하지 못하도록 하고, 해당 앱(Teams 데스크톱 프로그램)에만 로그인을 하도록 하는 것을 추천한다.

 

 

※ Teams 사용 방법 ※

 

  Teams 프로그램을 설치 완료하고, 로그인 및 접속하면 다음과 같은 화면이 등장한다. 이때 각 탭 별로 기능을 소개하자면 다음과 같다.

 

 

  ▶ 활동: 나를 언급한 사람이 있거나, 내가 작성한 글에 반응(좋아요 등)을 보인 사람이 있다면, 해당 사항에 대한 알림이 온다.

  ▶ 채팅: [단체 채팅] [개인 채팅]을 주고받을 수 있다. 말 그대로 카카오톡의 채팅과 같은 채팅 기능이다. 그냥 채팅방을 하나 만든 뒤에, 원하는 사람(조직원)을 추가하여 해당 사람이 모인 방에서 자유롭게 대화를 진행할 수 있다. 인스타그램의 DM과 유사하다.

  ▶ 팀: 조직 내에 존재하는 다양한 팀 중에서 자신이 원하는 [팀에 참가]하거나, 새롭게 [팀 생성]을 진행할 수 있다. 팀을 만들면 팀에 새로운 멤버를 추가할 수 있고, 팀 내에서 다양하게 여러 개로 [채널 추가]를 할 수 있다. 이때 채널(channel)이란, 슬랙에서의 채널과 동일한 기능이라고 보면 된다. 다르게 비유하자면 페이스북 그룹과 유사하다. 해당 채널 내에서 다양한 게시물을 올릴 수 있고, 그렇게 업로드 된 게시물에 여러 명이 댓글을 달 수 있다.

  ▶ 일정: 자신이 참여해야 하는 회의(자신이 포함되어 있는 회의)를 포함하여 본인의 [일정]을 관리할 수 있다. 예를 들어 다른 사람이 특정한 날짜에 미팅을 잡은 뒤에 나를 초대했다면, 내 일정에도 해당 내용이 보이게 된다.

  ▶ 통화: 조직 내에서 원하는 사람을 선택하여 [통화]를 진행할 수 있다.

  ▶ 파일: 나에게 공유되었던 파일들을 확인하고 다운로드할 수 있다.

728x90
반응형

Comment +0