<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Pytorch 實(shí)驗(yàn)中非常有效的代碼段

      1. 大幅度提升 Pytorch 的訓(xùn)練速度

      device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
      torch.backends.cudnn.benchmark = True

      但加了這一行,似乎運(yùn)行結(jié)果可能會(huì)存在細(xì)微差異,由于隨機(jī)數(shù)種子帶來的不同。

       

      2. 把原有的記錄文件加個(gè)后綴變?yōu)?.bak 文件,避免直接覆蓋

      # from co-teaching train code
      txtfile = 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. 計(jì)算 Accuracy 返回list, 調(diào)用函數(shù)時(shí),直接提取值,而非提取list

      # from co-teaching code but MixMatch_pytorch code also has it
      def 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 文件來記錄每一個(gè) epoch 的實(shí)驗(yàn)值

       

      # from Pytorch_MixMatch code
      class
      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('\n') 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('\n') 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()

       

      也可以使用如下方法記錄, (2020.12.15) 利用到 pandas.DataFrame:

      #來自 https://colab.research.google.com/github/facebookresearch/moco/blob/colab-notebook/colab/moco_cifar10_demo.ipynb#scrollTo=dvuxcmejkKt8
      # logging
      results = {'train_loss': [], 'test_acc@1': []}
      if not os.path.exists(args.results_dir):
          os.mkdir(args.results_dir)
      # dump args
      with open(args.results_dir + '/args.json', 'w') as fid:
          json.dump(args.__dict__, fid, indent=2)
      
      # training loop
      for epoch in range(epoch_start, args.epochs + 1):
          train_loss = train(model, train_loader, optimizer, epoch, args)
          results['train_loss'].append(train_loss)      
          test_acc_1 = test(model.encoder_q, memory_loader, test_loader, epoch, args)
          results['test_acc@1'].append(test_acc_1)
          # guixj append
          print("epoch: %d"%epoch, "test_acc_1:", test_acc_1)
      
          # save statistics
          data_frame = pd.DataFrame(data=results, index=range(epoch_start, epoch + 1))
          data_frame.to_csv(args.results_dir + '/log.csv', index_label='epoch')

       

       

      5. 利用 argparser 命令行工具來進(jìn)行代碼重構(gòu),使用不同參數(shù)適配不同數(shù)據(jù)集,不同優(yōu)化方式,不同setting, 避免多個(gè)高度冗余的重復(fù)代碼 

       # argparser 命令行工具有一個(gè)坑的地方是,無法設(shè)置 bool 變量, --flag FALSE, 然后會(huì)解釋為 字符串,仍然當(dāng)做 True

      但最近發(fā)現(xiàn)可以使用如下命令來進(jìn)行修補(bǔ),來自 ICML-19-SGC github 上代碼

      [一個(gè)非常好的解釋]

      1 parser.add_argument('--test', action='store_true', default=False, help='inductive training.')
      • 當(dāng)命令行出現(xiàn) test 字樣時(shí),則為 args.test = true
      • 若未出現(xiàn) test 字樣,則為 args.test = false

       

      import argparse  # from https://github.com/Diego999/pyGAT/blob/master/train.py
       
      parser = argparse.ArgumentParser()
      parser.add_argument('--no-cuda', action='store_true', default=False, help='Disables CUDA training.')
      parser.add_argument('--fastmode', action='store_true', default=False, help='Validate during training pass.')
      parser.add_argument('--sparse', action='store_true', default=False, help='GAT with sparse version or not.')
      parser.add_argument('--seed', type=int, default=72, help='Random seed.')
      parser.add_argument('--epochs', type=int, default=10000, help='Number of epochs to train.')
      parser.add_argument('--lr', type=float, default=0.005, help='Initial learning rate.')
      parser.add_argument('--weight_decay', type=float, default=5e-4, help='Weight decay (L2 loss on parameters).')
      parser.add_argument('--hidden', type=int, default=8, help='Number of hidden units.')
      parser.add_argument('--nb_heads', type=int, default=8, help='Number of head attentions.')
      parser.add_argument('--dropout', type=float, default=0.6, help='Dropout rate (1 - keep probability).')
      parser.add_argument('--alpha', type=float, default=0.2, help='Alpha for the leaky_relu.')
      parser.add_argument('--patience', type=int, default=100, help='Patience')
      
      args = parser.parse_args()
      args.cuda
      = not args.no_cuda and torch.cuda.is_available() # args.cuda 是可以臨時(shí)定義的,不過需要定義在 parser.parse_args() 后面
      # 也出現(xiàn)在 https://colab.research.google.com/github/facebookresearch/moco/blob/colab-notebook/colab/moco_cifar10_demo.ipynb#scrollTo=dvuxcmejkKt8

       

      # 來自 https://github.com/PatrickHua/SimSiam/blob/main/arguments.py 的高級(jí)用法   
      vars(args)['aug_kwargs'] = { # 增加一個(gè)參數(shù)值對(duì)象,非常高級(jí)的用法 'name':args.model.name, 'image_size': args.dataset.image_size }

       

       

      6. 使用shell 變量來設(shè)置所使用的顯卡, 便于利用shell 腳本進(jìn)行程序的串行,從而掛起來跑。或者多開幾個(gè) screen 進(jìn)行同一張卡上多個(gè)程序并行跑,充分利用顯卡的內(nèi)存。

          命令行中使用如下語句,或者把語句寫在 shell 腳本中 # 不要忘了 export

      export CUDA_VISIBLE_DEVICES=1  #設(shè)置當(dāng)前可用顯卡為編號(hào)為1的顯卡(從 0 開始編號(hào)),即不在 0 號(hào)上跑
      export CUDA_VISIBlE_DEVICES=0,1 # 設(shè)置當(dāng)前可用顯卡為 0,1 顯卡,當(dāng) 0 用滿后,就會(huì)自動(dòng)使用 1 顯卡

      一般經(jīng)驗(yàn),即使多個(gè)程序并行跑時(shí),即使顯存完全足夠,單個(gè)程序的速度也會(huì)變慢,這可能是由于還有 cpu 和內(nèi)存的限制。 

      這里顯存占用不是阻礙,應(yīng)該主要看GPU 利用率(也就是計(jì)算單元的使用,如果達(dá)到了 99% 就說明程序過多了。)

      使用 watch nvidia-smi 來監(jiān)測(cè)每個(gè)程序當(dāng)前是否在正常跑。

       

      7. 使用 python 時(shí)間戳來保存并進(jìn)行區(qū)別不同的 result 文件

      • 參照自己很早之前寫的 co-training 的代碼
      • 參考 MoCoV2 的代碼 
        if args.results_dir == '':
            args.results_dir = './cache-' + datetime.now().strftime("%Y-%m-%d-%H-%M-%S-moco")

         

      8. 把訓(xùn)練時(shí)命令行窗口的 print 輸出全部保存到一個(gè) log 文件:(參照 DIEN 代碼)

      mkdir dnn_save_path
      mkdir dnn_best_model
      CUDA_VISIBLE_DEVICES=0  
      /usr/bin/python2.7 script/train.py train DIEN >train_dien2.log 2>&1 & # 最后一個(gè) & 似乎是讓進(jìn)程在后臺(tái)運(yùn)行,參見《Linux命令行大全》第10章

      這里的 2>&1 表示把 標(biāo)準(zhǔn)錯(cuò)誤 導(dǎo)出到 標(biāo)準(zhǔn)輸出 中, 與前面的 > train_dien2.log 組合起來則相當(dāng)于把 python 程序的標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤都導(dǎo)入到文件 train_dien2.log 中。

      并且使用如下命令  | tee  命令則可以同時(shí)保存到文件并且寫到命令行輸出:

      python  script/train.py train DIEN  | tee train_dein2.log 

       PS:hanzy 最早就是用此來記錄實(shí)驗(yàn)結(jié)果,我可能在實(shí)習(xí)之前就學(xué)會(huì)了此,應(yīng)該是在之前的某個(gè)代碼庫里有此。跑類別不平衡代碼就已經(jīng)會(huì)此。

       

      9. git clone 可以用來下載 github 上的代碼,更快。(由 DIEN 的下載)

      git clone https://github.com/mouna99/dien.git 使用這個(gè)命令可以下載 github 上的代碼庫

       

      10. (來自 DIEN ) 對(duì)于命令行參數(shù)不一定要使用 argparser 來讀取,也可以直接使用 sys.argv 讀取,不過這樣的話,就無法指定關(guān)鍵字參數(shù),只能使用位置參數(shù)。 

        

       1 ### run.sh ###
       2 CUDA_VISIBLE_DEVICES=0  /usr/bin/python2.7  script/train.py train DIEN  >train_dein2.log 2>&1 &
       3 #############
       4 
       5 if __name__ == '__main__':
       6     if len(sys.argv) == 4:
       7         SEED = int(sys.argv[3]) # 0,1,2,3
       8     else:
       9         SEED = 3 
      10     tf.set_random_seed(SEED)
      11     numpy.random.seed(SEED)
      12     random.seed(SEED)
      13     if sys.argv[1] == 'train':
      14         train(model_type=sys.argv[2], seed=SEED)
      15     elif sys.argv[1] == 'test':
      16         test(model_type=sys.argv[2], seed=SEED)
      17     else:
      18         print('do nothing...')

       

      參考 https://blog.csdn.net/dcrmg/article/details/51987413

      argc 是 argument count 的縮寫,表示傳入main函數(shù)的參數(shù)個(gè)數(shù);

      argv 是 argument vector 的縮寫,表示傳入main函數(shù)的參數(shù)序列或指針,并且第一個(gè)參數(shù)argv[0]一定是程序的名稱,并且包含了程序所在的完整路徑,所以確切的說需要我們輸入的main函數(shù)的參數(shù)個(gè)數(shù)應(yīng)該是argc - 1個(gè);

       

       

       

       

       

      11.代碼的一種邏輯:time_point 是一個(gè)參數(shù)變量,可以有兩種方案來處理

      一種直接在外面判斷:

      1 #適用于輸出變量的個(gè)數(shù)不同的情況
      2 if time_point:
      3   A, B, C = f1(x, y, time_point=True)
      4 else:
      5   A, B = f1(x, y, time_point=False)
      6 
      7 # 適用于輸出變量個(gè)數(shù)和類型相同的情況
      8 
      9 C, D = f2(x, y, time_point=time_point)

       

      12. 寫一個(gè) shell 腳本文件來進(jìn)行調(diào)節(jié)超參數(shù), 來自 [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 運(yùn)行結(jié)果可能會(huì)不一樣,有細(xì)微差別。

           cuda 也有一個(gè)相關(guān)的隨機(jī)數(shù)種子的參數(shù),當(dāng)不使用 cuda 時(shí),這一個(gè)隨機(jī)數(shù)種子沒有起到作用,因此可能會(huì)得到不同的結(jié)果。

        來自 NIPS-20 Grand (2020.11.18)的實(shí)驗(yàn)結(jié)果發(fā)現(xiàn)。

       

      14. 在 ipython 交互式界面中是無法使用讀取命令行參數(shù)的,需要使用一個(gè)空字符讀取默認(rèn)值:

      '''  # https://colab.research.google.com/github/facebookresearch/moco/blob/colab-notebook/colab/moco_cifar10_demo.ipynb#scrollTo=dvuxcmejkKt8
      args = parser.parse_args()  # running in command line, 為空也讀取默認(rèn)值
      '''
      args = parser.parse_args('')  # running in ipynb, 全部會(huì)使用默認(rèn)值

       

      15. 保存模型的所有超參數(shù):來自 MoCo_CIFAR10

      print(args)
      
      # load model if resume
      epoch_start = 1
      if args.resume is not '':
          checkpoint = torch.load(args.resume)
          model.load_state_dict(checkpoint['state_dict'])
          optimizer.load_state_dict(checkpoint['optimizer'])
          epoch_start = checkpoint['epoch'] + 1
          print('Loaded from: {}'.format(args.resume))
          
          
      # logging
      results = {'train_loss': [], 'test_acc@1': []}
      if not os.path.exists(args.results_dir):
          os.mkdir(args.results_dir)
      
      # dump args
      with open(args.results_dir + '/args.json', 'w') as fid:
          json.dump(args.__dict__, fid, indent=2)

       先前的 LDAM 的代碼似乎也記錄了很多,幾乎全部把所有的實(shí)驗(yàn)設(shè)置全部都記錄下來了,后面有空可以看一下。

       

      16. 利用 tqdm 的 bar, 似乎還有一個(gè) progress 也有類似的功能?

       

      # MoCo 代碼
      from
      tqdm import tqdm def train(): train_bar = tqdm(data_loader) for im_1, im_2 in train_bar: loss = net(im_1, im_2) train_optimizer.zero_grad() loss.backward() train_optimizer.step() total_num += data_loader.batch_size total_loss += loss.item() * data_loader.batch_size train_bar.set_description('Train Epoch: [{}/{}], lr: {:.6f}, Loss: {:.4f}'.format(epoch, args.epochs, optimizer.param_groups[0]['lr'], total_loss / total_num)) return total_loss / total_num

      # SimSiam 代碼也用此

       

      17. 最近看到 SimSiam 的實(shí)現(xiàn)也用到 AverageMeter() 函數(shù),所以準(zhǔn)備記錄一下。google 搜索發(fā)現(xiàn) MixMatch 代碼庫的作者也用了此,并給出了出處,原來是參考 pytorch 官方訓(xùn)練 ImageNet 的代碼,看來這些人都讀過非常優(yōu)秀的 pytorch 官方源代碼庫,所以能夠?qū)懗鲞@么簡(jiǎn)潔有力的代碼。

      class AverageMeter(object):
          """Computes and stores the average and current value
             Imported from https://github.com/pytorch/examples/blob/master/imagenet/main.py#L247-L262
          """
          def __init__(self):
              self.reset()
      
          def reset(self):
              self.val = 0
              self.avg = 0
              self.sum = 0
              self.count = 0
      
          def update(self, val, n=1):
              self.val = val
              self.sum += val * n
              self.count += n
              self.avg = self.sum / self.count

       

      不過一些代碼庫關(guān)于AverageMeter 的用法有一些錯(cuò)誤,當(dāng)前的用法是:

      acc_meter = AverageMeter(name='Accuracy')
      acc_meter.reset()
      for images, labels, indices in testloader:
          with torch.no_grad():
              feature = model(images.to(args.device))
              preds = classifier(feature).argmax(dim=1)
              correct = (preds == labels.to(args.device)).sum().item()
              acc_meter.update(correct/preds.shape[0])  # 這里讀入每個(gè) batch 的平均后的 accuracy
      print(f'Accuracy = {acc_meter.avg*100:.2f}')

      注意到,例如設(shè)置 batch_size = 128, 但一般測(cè)試集的大小無法恰好整除 128, 就會(huì)導(dǎo)致最后一個(gè) batch 樣本數(shù)小于 128,這樣直接計(jì)算 batch 的平均后的 accuracy, 再進(jìn)行平均,算出來的值有問題。除非 test_loader 設(shè)置了 drop_last=True, 把最后一個(gè)大小不為 128 的 batch 直接丟掉,但這樣不合理,相當(dāng)于改變了 test_loader。一般只會(huì)在 train_loader 設(shè)置 drop_last=True。

      修復(fù)方法例如,可以改為如下代碼: 

      acc_meter.update(correct, preds.shape[0])  

       

       

      The End.

      posted @ 2020-01-04 09:35  Gelthin  閱讀(1898)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 久久香蕉国产线看观看怡红院妓院 | 精品无码国产一区二区三区av| 日韩有码av中文字幕| 午夜国产精品福利一二| 亚洲日本国产精品一区| 国产午夜福利大片免费看| 免费无码成人AV在线播放不卡| 无码精品人妻一区二区三区中| 亚洲女同精品久久女同| 无码粉嫩虎白一线天在线观看| 亚洲日本va午夜中文字幕久久| 色综合天天色综合久久网| 伊人蕉久影院| 日本一区二区三区免费播放视频站| 熟女乱一区二区三区四区| 九九热视频在线观看一区| 日韩亚av无码一区二区三区| 日韩中文字幕精品人妻| 亚洲男人第一无码av网| 色偷偷www.8888在线观看| 国产综合视频一区二区三区| 国产精品 自在自线| 在线播放深夜精品三级| 少妇裸交aa大片| 久色伊人激情文学你懂的| 一本久道久久综合久久鬼色| 亚洲青青草视频在线播放| 久久香蕉国产线看观看猫咪av| 国产精品一国产精品亚洲| 真实单亲乱l仑对白视频| 人妻无码久久久久久久久久久| 精品国产亚洲av麻豆特色| 亚洲最大福利视频网| 99久久精品一区二区国产| 国产一区二区三区综合视频| 久久99精品久久久久久琪琪| 日韩永久永久永久黄色大片| gogogo在线播放中国| av中文字幕国产精品| 看黄a大片日本真人视频直播| 中文字幕一区二区久久综合|