Pytorch 실험용 코드 세그먼트 요약

1. Pytorch의 훈련 속도를 대폭 향상
device = torch.device("cuda"if torch.cuda.is_available() else "cpu")
torch.backends.cudnn.benchmark = True
그러나 이 줄을 더하면 운행 결과가 다른 것 같다.
2. 기존 기록 파일에 접미사를 붙여서 로 변경한다.bak 파일, 직접 덮어쓰기 방지

# from co-teaching train codetxtfile = save_dir + "/" + model_str + "_%s.txt"%str(args.optimizer)  ## good job!
nowTime=datetime.datetime.now().strftime('%Y-%m-%d-%H:%M:%S')
if os.path.exists(txtfile):
  os.system('mv %s %s' % (txtfile, txtfile+".bak-%s" % nowTime)) # bakeup  
3. Accuracy가 list를 반환하고 함수를 호출할 때 list를 추출하지 않고 직접 값을 추출합니다.

# from co-teaching code but MixMatch_pytorch code also has itdef accuracy(logit, target, topk=(1,)):
  """Computes the precision@k for the specified values of k"""
  output = F.softmax(logit, dim=1) # but actually not need it 
  maxk = max(topk)
  batch_size = target.size(0)

  _, pred = output.topk(maxk, 1, True, True) # _, pred = logit.topk(maxk, 1, True, True)
  pred = pred.t()
  correct = pred.eq(target.view(1, -1).expand_as(pred))

  res = []
  for k in topk:
    correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
    res.append(correct_k.mul_(100.0 / batch_size)) # it seems this is a bug, when not all batch has same size, the mean of accuracy of each batch is not the mean of accu of all dataset
  return res

prec1, = accuracy(logit, labels, topk=(1,)) # , indicate tuple unpackage
prec1, prec5 = accuracy(logits, labels, topk=(1, 5))
4. logger 파일을 이용하여 모든 epoch의 실험 값을 기록하는 데 능숙하다

# from Pytorch_MixMatch codeclass Logger(object):
  '''Save training process to log file with simple plot function.'''
  def __init__(self, fpath, title=None, resume=False): 
    self.file = None
    self.resume = resume
    self.title = '' if title == None else title
    if fpath is not None:
      if resume: 
        self.file = open(fpath, 'r') 
        name = self.file.readline()
        self.names = name.rstrip().split('\t')
        self.numbers = {}
        for _, name in enumerate(self.names):
          self.numbers[name] = []

        for numbers in self.file:
          numbers = numbers.rstrip().split('\t')
          for i in range(0, len(numbers)):
            self.numbers[self.names[i]].append(numbers[i])
        self.file.close()
        self.file = open(fpath, 'a') 
      else:
        self.file = open(fpath, 'w')

  def set_names(self, names):
    if self.resume: 
      pass
    # initialize numbers as empty list
    self.numbers = {}
    self.names = names
    for _, name in enumerate(self.names):
      self.file.write(name)
      self.file.write('\t')
      self.numbers[name] = []
    self.file.write('
') self.file.flush() def append(self, numbers): assert len(self.names) == len(numbers), 'Numbers do not match names' for index, num in enumerate(numbers): self.file.write("{0:.4f}".format(num)) self.file.write('\t') self.numbers[self.names[index]].append(num) self.file.write('
') self.file.flush() def plot(self, names=None): names = self.names if names == None else names numbers = self.numbers for _, name in enumerate(names): x = np.arange(len(numbers[name])) plt.plot(x, np.asarray(numbers[name])) plt.legend([self.title + '(' + name + ')' for name in names]) plt.grid(True) def close(self): if self.file is not None: self.file.close() # usage logger = Logger(new_folder+'/log_for_%s_WebVision1M.txt'%data_type, title=title) logger.set_names(['epoch', 'val_acc', 'val_acc_ImageNet']) for epoch in range(100): logger.append([epoch, val_acc, val_acc_ImageNet]) logger.close()
5.argparser 명령행 도구를 이용하여 코드 재구성을 하고 서로 다른 매개 변수를 사용하여 서로 다른 데이터 집합, 서로 다른 최적화 방식, 서로 다른setting을 사용하여 여러 개의 고도로 불필요한 중복 코드를 피한다
#argparser 명령행 도구에 구멍이 하나 있는 곳은 bool 변수, flag=FALSE를 설정할 수 없는 곳입니다. 그리고 문자열로 해석되어 여전히 True로 간주됩니다.
ICML-19-SGC에서 다음 명령을 사용하여 패치할 수 있습니다github 코드
parser.add_argument('--test', action='store_true', default=False, help='inductive training.')
명령줄에test 문자가 나타나면args입니다.test = true
테스트 글자가 나타나지 않으면args입니다.test = false
6. 셸 변수를 사용하여 사용하는 그래픽카드를 설정하면 셸 스크립트를 이용하여 프로그램의 직렬을 진행하여 걸어서 달릴 수 있다.또는 여러 개의 화면을 더 켜서 같은 카드에 여러 개의 프로그램을 병행하여 그래픽의 메모리를 충분히 활용한다.
명령줄에서 다음 문장을 사용하거나 셸 스크립트에 문장을 쓰거나 #export를 잊지 마세요
export CUDA_VISIBLE_DEVICES=1# 현재 사용 가능한 그래픽이 1번인 그래픽(0부터 번호)을 설정하면 0번에서 뛰지 않습니다.
export CUDA_VISIBlE_DEVICES=0,1# 현재 사용 가능한 그래픽을 0,1 그래픽으로 설정하고 0이 가득 차면 자동으로 1 그래픽을 사용합니다.
일반적인 경험에 의하면 여러 프로그램이 병행해서 달릴 때 메모리가 충분해도 한 프로그램의 속도가 느려진다. 이것은 cpu와 메모리의 제한이 있기 때문일 것이다.
여기에서 메모리 사용은 장애가 되지 않으며 주로 GPU 이용률(즉 계산 단위의 사용이 99%에 이르면 프로그램이 너무 많다는 것을 의미한다)을 보아야 한다.
watch nvidia-smi를 사용하여 모든 프로그램이 현재 정상적으로 뛰고 있는지 모니터링합니다.
7.python 타임 스탬프를 사용하여 다른result 파일을 저장하고 구별합니다
자기가 오래 전에 쓴co-training 코드를 참조하세요.
8. 훈련 시 명령줄 창의 print 출력을 모두 log 파일에 저장합니다: (DIEN 참조)
mkdir dnn_save_path
mkdir dnn_best_model
CUDA_VISIBLE_DEVICES=0/usr/bin/python2.7 script/train.py train DIEN >train_dein2.log 2>&1 &
또한 다음 명령 | tee 명령을 사용하면 파일에 저장하고 명령행 출력에 쓸 수 있습니다.
python script/train.py train DIEN | tee train_dein2.log
9.gitclone은github의 코드를 다운로드할 수 있어 더 빠르다.(DIEN 다운로드)
git clone  https://github.com/mouna99/dien.git 이 명령을 사용하면github의 코드 라이브러리를 다운로드할 수 있습니다.
10. (DIEN에서) 명령행 매개 변수에 대해argparser를 사용하지 않고 sys를 직접 사용할 수 있습니다.argv에서 읽지만 이렇게 하면 키워드 파라미터를 지정할 수 없고 위치 파라미터만 사용할 수 있습니다.

### run.sh ###
CUDA_VISIBLE_DEVICES=0 /usr/bin/python2.7 script/train.py train DIEN >train_dein2.log 2>&1 &
#############

if __name__ == '__main__':
  if len(sys.argv) == 4:
    SEED = int(sys.argv[3]) # 0,1,2,3
  else:
    SEED = 3
  tf.set_random_seed(SEED)
  numpy.random.seed(SEED)
  random.seed(SEED)
  if sys.argv[1] == 'train':
    train(model_type=sys.argv[2], seed=SEED)
  elif sys.argv[1] == 'test':
    test(model_type=sys.argv[2], seed=SEED)
  else:
    print('do nothing...')
11. 코드의 논리:time_point는 매개 변수로 두 가지 방안을 처리할 수 있습니다
일종의 직접 밖에서 판단하는 것이다.

# 
if time_point:
  A, B, C = f1(x, y, time_point=True)
else:
  A, B = f1(x, y, time_point=False)
#  
C, D = f2(x, y, time_point=time_point)
12. 초변수를 조절하기 위해 셸 스크립트 파일을 작성합니다[NIPS-20 Grand]

mkdir cora
for num in $(seq 0 99) do
  python train_grand.py --hidden 32 --lr 0.01 --patience 200 --seed $num --dropnode_rate 0.5 > cora/"$num".txt
done
13. cuda를 사용하거나 사용하지 않으면 실행 결과가 달라질 수 있습니다. 미세한 차이가 있습니다.
cuda도 관련 랜덤 씨앗의 매개 변수가 있습니다. cuda를 사용하지 않을 때 이 랜덤 씨앗은 작용하지 않기 때문에 다른 결과를 얻을 수 있습니다.
NIPS-20 Grand(2020.11.18)의 실험 결과
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.

좋은 웹페이지 즐겨찾기