前提
Pytorchで画像分類をしています。(ResNet200Dモデル)
交差検証で事前に訓練したモデルが5fold分あり、
それらのモデルを使ってテストデータの予測を5つ分行い、
アンサンブルをしようとしています。
発生している問題
下記ソースコード中の、inference()を実行すると、
各fold毎に、RAMメモリが増加していき、
最終的にメモリが解放されないまま終了して困っています。
具体的には、RAMメモリの使用状況が、
(実行前) 0.2 GB
(1ループ目)2.5 GB
(2ループ目) 3.3 GB
・・・
(5ループ目) 6.0 GB
(実行後) 5.5 GB
のように遷移しています。
GPUメモリについても、2GBほど増えたまま解放されません。
・fold毎にRAMメモリ使用量が増加するのはなぜか。また、その解決策。
・実行後に、RAMメモリ・GPUメモリが解放されないのはなぜか。また、その解決策。
以上、ご教示いただければ幸いです。
該当のソースコード
python
1 2device = torch.device('cuda') 3df_test = pd.read_csv(CSV_PATH) 4 5def inference_one_loop(model, loader, device): 6 7 model.to(device) 8 model.eval() 9 pred_list = [] 10 with torch.no_grad(): 11 for x in tqdm(loader): 12 y = model(x.to(device)) 13 pred_list.append(y.sigmoid().detach().cpu().numpy()) 14 15 pred_arr = np.concatenate(pred_list) 16 17 # del pred_list 18 # torch.cuda.empty_cache() 19 # gc.collect() 20 21 return pred_arr 22 23 24def inference(): 25 26 n_fold = 5 27 n_class = 11 28 batch_size = 32 29 image_size = 512 30 31 Model = ResNet200D 32 model_name = 'resnet200d' 33 model_paths = ['./fold0.pth','./fold1.pth','./fold2.pth','./fold3.pth','./fold4.pth','./fold5.pth'] 34 35 test_dataset = TestDataset(df_test, transform=get_transforms(image_size=image_size)) 36 test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=4 , pin_memory=True, drop_last=False) 37 38 ### 各foldごとにメモリが増加する ### 39 40 test_preds_arr = np.zeros((n_fold, len(df_test), n_class)) 41 for fold in range(n_fold): 42 logger.info(f"[fold {fold}]") 43 44 model = Model(model_name=model_name) 45 model.load_state_dict(torch.load(model_paths[fold], map_location=device)) 46 47 test_pred = inference_one_loop(model, test_loader, device) 48 test_preds_arr[fold] = test_pred 49 50 # del model 51 # torch.cuda.empty_cache() 52 # gc.collect() 53 54 return test_preds_arr.mean(axis=0) 55 56 57### 関数を抜けてもメモリが解放されない。 58preds = inference() 59
試したこと
ソースコード中でコメントアウトしているように、
del による変数の参照の削除や、
torch.cuda.empty_cache()を実施しましたが、
結果は変わりませんでした。
また、下記の記事を参考にしましたが、
メモリを多く占有している変数は見つかりませんでした。
https://qiita.com/AnchorBlues/items/883790e43417640140aa
inference()の実行後は、
メソッド内のローカル変数を参照することは当然ながらできないようです。
補足情報(FW/ツールのバージョンなど)
環境: Jupyter Notebook (Kaggle上のnotebook環境)
ライブラリ:
・torch 1.7.0
・timm (https://github.com/rwightman/pytorch-image-models)
モデルやDatasetの定義:
python
1class ResNet200D(nn.Module): 2 def __init__(self, model_name): 3 super().__init__() 4 self.model = timm.create_model(model_name, pretrained=False) 5 n_features = self.model.fc.in_features 6 self.model.global_pool = nn.Identity() 7 self.model.fc = nn.Identity() 8 self.pooling = nn.AdaptiveAvgPool2d(1) 9 self.fc = nn.Linear(n_features, 11) 10 11 def forward(self, x): 12 bs = x.size(0) 13 features = self.model(x) 14 pooled_features = self.pooling(features).view(bs, -1) 15 output = self.fc(pooled_features) 16 return output 17 18def get_transforms(image_size=640): 19 return Compose([ 20 Resize(image_size, image_size), 21 Normalize(), 22 ToTensorV2(), 23 ]) 24 25class TestDataset(Dataset): 26 def __init__(self, df, transform=None): 27 self.df = df 28 self.file_names = df['StudyInstanceUID'].values 29 self.transform = transform 30 31 def __len__(self): 32 return len(self.df) 33 34 def __getitem__(self, idx): 35 file_name = self.file_names[idx] 36 file_path = f'{TEST_DIR}/{file_name}.jpg' 37 image = cv2.imread(file_path) 38 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 39 if self.transform: 40 augmented = self.transform(image=image) 41 image = augmented['image'] 42 return image
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。