Ejemplo n.º 1
0
def main():
    args = hyperparameters()

    train_path = os.path.join(args.path, 'train')
    test_path = os.path.join(args.path, 'test')

    # gpu or cpu 설정
    device = torch.device(
        f'cuda:{args.device}' if torch.cuda.is_available() else 'cpu')

    # train dataset load
    train_dataset = CRNN_dataset(path=train_path,
                                 w=args.img_width,
                                 h=args.img_height)
    train_dataloader = DataLoader(train_dataset,
                                  batch_size=args.batch_size,
                                  shuffle=True)

    # test dataset load
    test_dataset = CRNN_dataset(path=test_path,
                                w=args.img_width,
                                h=args.img_height)
    test_dataloader = DataLoader(test_dataset,
                                 batch_size=args.batch_size,
                                 shuffle=True)

    # model 정의
    model = CRNN(args.img_height, 1, 37, 256)  # nc=1, nclass=37, nh=256

    # loss 정의
    criterion = nn.CTCLoss()

    if args.optim == 'adam':
        optimizer = optim.Adam(model.parameters(),
                               lr=args.lr,
                               betas=(0.5, 0.999))
    elif args.optim == 'rmsprop':
        optimizer = optim.RMSprop(model.parameters(), lr=args.lr)
    else:
        assert False, "옵티마이저를 다시 입력해주세요. :("

    model = model.to(device)
    best_test_loss = 100000000

    for i in range(args.epochs):

        print('epochs: ', i)

        print("<----training---->")
        model.train()
        for inputs, targets in tqdm(train_dataloader):
            inputs = inputs.permute(
                0, 1, 3, 2
            )  # inputs의 dimension을 (batch, channel, h, w)로 바꿔주세요. hint: pytorch tensor에 제공되는 함수 사용
            batch_size = inputs.size(0)
            inputs = inputs.to(device)
            target_text, target_length = targets
            target_text, target_length = target_text.to(
                device), target_length.to(device)
            preds = model(inputs)
            preds = F.log_softmax(preds, dim=-1)
            preds_length = Variable(
                torch.IntTensor([preds.size(0)] * batch_size))
            """
            CTCLoss의 설명과 해당 로스의 input에 대해 설명해주세요.

            CTC(Connectionist Temporal Classification)이란, 입력 프레임 시퀀스와 타겟 시퀀스 간에
            명시적으로 할당해주지 않아도 모델을 학습할 수 있는 기법을 말한다. 
            CRNN을 살펴보면, 입력 이미지 feature vector sequence의 길이는 가변적이고 실제 단어의 글자수와도 맞지 않는다.
            기존의 CNN은 라벨 할당으로 학습한 것과 달리, 입력 sequence가 주어졌을 때 각 시점별로 본래 label sequence로 향하는 모든 가능한 경로를 고려하여 우도를 구하여 학습한다. 
            연산량의 감소를 위해 dynamic programming (앞에서 계산한 경로의 우도를 기억해두는 방법) 알고리즘을 활용한다는 특징이 있고,
            CTC layer는 RNN 출력 확률 벡터 sequence를 입력받아 loss를 계산하여 grandient를 통해 학습을 가능하게 만든다.
            
            loss의 input은 RNN layer의 출력 확률 벡터 sequence라고 할 수 있다.

            """

            loss = criterion(preds, target_text, preds_length,
                             target_length) / batch_size

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        print("\n<----evaluation---->")
        """
        model.train(), model.eval()의 차이에 대해 설명해주세요.
        .eval()을 하는 이유가 무엇일까요?
        train은 말 그대로 학습 모드 , eval은 test 모드를 의미한다. 학습이 끝났으니 test 모드에 들어가자~! 하고 모델에게 알려주는 것이다.

        """

        model.eval()
        loss = 0.0

        for inputs, targets in tqdm(test_dataloader):
            inputs = inputs.permute(0, 1, 3, 2)
            batch_size = inputs.size(0)
            inputs = inputs.to(device)
            target_text, target_length = targets
            target_text, target_length = target_text.to(
                device), target_length.to(device)
            preds = model(inputs)
            preds = F.log_softmax(preds, dim=-1)
            preds_length = Variable(
                torch.IntTensor([preds.size(0)] * batch_size))

            loss += criterion(
                preds, target_text, preds_length, target_length
            ) / batch_size  # 학습이 아니라 test loss이니 밑에서 찍으려면 이 한 줄이 더 있어야 한다.

        print("\ntest loss: ", loss)
        if loss < best_test_loss:
            # loss가 bset_test_loss보다 작다면 지금의 loss가 best loss가 되겠죠?
            best_test_loss = loss
            # args.savepath을 이용하여 best model 저장하기
            torch.save(model.state_dict(), args.savepath)
            print("best model 저장 성공")
Ejemplo n.º 2
0
                    GRU_NUM_LAYERS,
                    HIDDEN_SIZE,
                    device=device)

        validation(full_model,
                   val_loader,
                   melspec_val,
                   GRU_NUM_LAYERS,
                   HIDDEN_SIZE,
                   device=device)

        print('END OF EPOCH', n)

    ### Save model
    torch.save({
        'model_state_dict': CRNN_model.state_dict(),
    }, 'crnn_final')

    torch.save({
        'model_state_dict': attn_layer.state_dict(),
    }, 'attn_1')

    torch.save({
        'model_state_dict': apply_attn.state_dict(),
    }, 'apply_attn_1')

    validation(full_model,
               val_loader,
               melspec_val,
               GRU_NUM_LAYERS,
               HIDDEN_SIZE,
Ejemplo n.º 3
0
    crnn.zero_grad()
    cost.backward()
    optimizer.step()
    return cost


for epoch in range(opt.nepoch):
    train_iter = iter(train_loader)
    i = 0
    while i < len(train_loader):
        for p in crnn.parameters():
            p.requires_grad = True
        crnn.train()

        cost = trainBatch(crnn, criterion, optimizer)
        loss_avg.add(cost)
        i += 1

        if i % opt.displayInterval == 0:
            print('[%d/%d][%d/%d] Loss: %f' %
                  (epoch, opt.nepoch, i, len(train_loader), loss_avg.val()))
            loss_avg.reset()

        if i % opt.valInterval == 0:
            val(crnn, test_dataset, criterion)

        # do checkpointing
        if i % opt.saveInterval == 0:
            torch.save(
                crnn.state_dict(),
                '{0}/netCRNN_{1}_{2}.pth'.format(opt.expr_dir, epoch, i))
Ejemplo n.º 4
0
def main(opts):
  alphabet = '0123456789.'
  nclass = len(alphabet) + 1
  model_name = 'crnn'
  net = CRNN(nclass)
  print("Using {0}".format(model_name))

  if opts.cuda:
    net.cuda()
  learning_rate = opts.base_lr
  optimizer = torch.optim.Adam(net.parameters(), lr=opts.base_lr, weight_decay=weight_decay)

  if os.path.exists(opts.model):
    print('loading model from %s' % args.model)
    step_start, learning_rate = net_utils.load_net(args.model, net, optimizer)

  ## 数据集
  converter = strLabelConverter(alphabet)
  dataset = ImgDataset(
      root='/home/yangna/deepblue/OCR/mech_demo2/dataset/imgs/image',
      csv_root='/home/yangna/deepblue/OCR/mech_demo2/dataset/imgs/train_list.txt',
      transform=None,
      target_transform=converter.encode
  )
  ocrdataloader = torch.utils.data.DataLoader(
      dataset, batch_size=opts.batch_size, shuffle=True, collate_fn=own_collate
  )
  
  step_start = 0
  net.train()

  converter = strLabelConverter(alphabet)
  ctc_loss = CTCLoss()

  for step in range(step_start, opts.max_iters):

    try:
    data = next(data_iter)
    except:
    data_iter = iter(ocrdataloader)
    data = next(data_iter)
    
    im_data, gt_boxes, text = data
    im_data = im_data.cuda()
       
    try:
      loss= process_crnn(im_data, gt_boxes, text, net, ctc_loss, converter, training=True)

      net.zero_grad()
      optimizer.zero_grad()
      loss.backward()
      optimizer.step()
    except:
      import sys, traceback
      traceback.print_exc(file=sys.stdout)
      pass


    if step % disp_interval == 0:
      try:
    print('step:%d || loss %.4f' % (step, loss))
      except:
    import sys, traceback
    traceback.print_exc(file=sys.stdout)
    pass
    
    if step > step_start and (step % batch_per_epoch == 0):
      save_name = os.path.join(opts.save_path, '{}_{}.h5'.format(model_name, step))
      state = {'step': step,
           'learning_rate': learning_rate,
          'state_dict': net.state_dict(),
          'optimizer': optimizer.state_dict()}
      torch.save(state, save_name)
      print('save model: {}'.format(save_name))
Ejemplo n.º 5
0
def main():
    args = hyperparameters()

    train_path = os.path.join(args.path, 'train')
    test_path = os.path.join(args.path, 'test')

    # gpu or cpu 설정
    device = torch.device(
        f'cuda:{args.device}' if torch.cuda.is_available() else 'cpu')

    # train dataset load
    train_dataset = CRNN_dataset(path=train_path,
                                 w=args.img_width,
                                 h=args.img_height)
    train_dataloader = DataLoader(train_dataset,
                                  batch_size=args.batch_size,
                                  shuffle=True)

    # test dataset load
    test_dataset = CRNN_dataset(path=test_path,
                                w=args.img_width,
                                h=args.img_height)
    test_dataloader = DataLoader(test_dataset,
                                 batch_size=args.batch_size,
                                 shuffle=True)

    # model 정의
    model = CRNN(
        nc=1, nclass=37, nh=256,
        imgH=args.img_height)  #nc =1 ,nclass = 36, nh = 100, #args.img_height

    # loss 정의
    criterion = nn.CTCLoss()

    if args.optim == 'adam':
        optimizer = optim.Adam(model.parameters(),
                               lr=args.lr,
                               betas=(0.5, 0.999))
    elif args.optim == 'rmsprop':
        optimizer = optim.RMSprop(model.parameters(), lr=args.lr)
    else:
        assert False, "옵티마이저를 다시 입력해주세요. :("

    model = model.to(device)
    best_test_loss = 100000000
    for i in range(args.epochs):

        print('epochs: ', i)

        print("<----training---->")
        model.train()
        for inputs, targets in tqdm(train_dataloader):
            # ---?--- # inputs의 dimension을 (batch, channel, h, w)로 바꿔주세요. hint: pytorch tensor에 제공되는 함수 사용
            inputs = inputs.permute(0, 1, 3, 2)
            batch_size = inputs.size(0)
            inputs = inputs.to(device)
            target_text, target_length = targets
            target_text, target_length = target_text.to(
                device), target_length.to(device)
            preds = model(inputs)
            preds = preds.log_softmax(2)
            preds_length = Variable(
                torch.IntTensor([preds.size(0)] * batch_size))
            """
            CTCLoss의 설명과 해당 로스의 input에 대해 설명해주세요.

            학습데이터에 클래스 라벨만 순서대로 있고 각 클래스의 위치는 어디있는지 모르는 unsegmented
            시퀀스 데이터의 학습을 위해서 사용하는 알고리즘
            ocr(광학 문자 인식)이나 음성 인식등에 널리 사용된다
            input: 예측값, 정답값, 예측 시퀀스의 길이, 정답 시퀀스의 길이

            """

            loss = criterion(preds, target_text, preds_length,
                             target_length) / batch_size

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        print("<----evaluation---->")
        """
        model.train(), model.eval()의 차이에 대해 설명해주세요.
        .eval()을 하는 이유가 무엇일까요?

        모델을 학습할 때 train/eval에 맞게 모델을 변경시킨다
        Dropout이나 batchNormalization을 쓰는 모델은 학습시킬 때와 평가할 때
        구조/역할이 다르기 때문이다.

        """

        model.eval()
        loss = 0.0

        for inputs, targets in tqdm(test_dataloader):
            inputs = inputs.permute(0, 1, 3, 2)
            batch_size = inputs.size(0)
            inputs = inputs.to(device)
            target_text, target_length = targets
            target_text, target_length = target_text.to(
                device), target_length.to(device)
            preds = model(inputs)
            preds = preds.log_softmax(2)
            preds_length = Variable(
                torch.IntTensor([preds.size(0)] * batch_size))
            loss += criterion(preds, target_text, preds_length,
                              target_length) / batch_size

        print("test loss: ", loss / len(test_dataloader))
        if loss < best_test_loss:
            # loss가 bset_test_loss보다 작다면 지금의 loss가 best loss가 되겠죠?
            best_test_loss = loss.clone()
            # args.savepath을 이용하여 best model 저장하기
            torch.save(model.state_dict(), args.savepath)
            print("best model 저장 성공")