質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Google Colaboratory

Google Colaboratoryとは、無償のJupyterノートブック環境。教育や研究機関の機械学習の普及のためのGoogleの研究プロジェクトです。PythonやNumpyといった機械学習で要する大方の環境がすでに構築されており、コードの記述・実行、解析の保存・共有などが可能です。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

解決済

1回答

11673閲覧

MobileNet学習中にTrain関数は動作するが、Validate関数内でCUDA out of memory とエラーが出る

Otom_jp

総合スコア4

CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Google Colaboratory

Google Colaboratoryとは、無償のJupyterノートブック環境。教育や研究機関の機械学習の普及のためのGoogleの研究プロジェクトです。PythonやNumpyといった機械学習で要する大方の環境がすでに構築されており、コードの記述・実行、解析の保存・共有などが可能です。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2020/06/10 03:30

編集2020/06/10 03:40

前提・実現したいこと

前回の質問から引き続き、MobileNet V1を実装中。
学習データはImageNetのスモールデータセットであるImageNetteを用いる。
このデータセットは

!wget https://s3.amazonaws.com/fast-ai-imageclas/imagenette-320.tgz !tar xzf imagenette-320.tgz

コマンドで取得しColab上から対象のGoogleドライブ内のフォルダにアクセスし読み込んでいる。

ベースとなる学習コードはGitHub上の

https://github.com/Z0m6ie/CIFAR-10_PyTorch

を参考にしている。

このデータセットを用いて学習を行いたい。

発生している問題・エラーメッセージ

Train関数(後述)での訓練が終了しValidate関数(後述)を実行時に以下のエラーが発生する。

/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:15: UserWarning: volatile was removed and now has no effect. Use `with torch.no_grad():` instead. from ipykernel import kernelapp as app /usr/local/lib/python3.6/dist-packages/torch/nn/_reduction.py:43: UserWarning: size_average and reduce args will be deprecated, please use reduction='sum' instead. warnings.warn(warning.format(ret)) --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-83-f5e663fb5c57> in <module>() 9 for epoch in range(80): 10 #train(epoch) ---> 11 loss, accuracy = validate(epoch) 12 best_loss, best_acc = save_best(loss, accuracy, best_loss, best_acc) 13 7 frames /usr/local/lib/python3.6/dist-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight) 344 _pair(0), self.dilation, self.groups) 345 return F.conv2d(input, weight, self.bias, self.stride, --> 346 self.padding, self.dilation, self.groups) 347 348 def forward(self, input): RuntimeError: CUDA out of memory. Tried to allocate 196.00 MiB (GPU 0; 7.43 GiB total capacity; 6.80 GiB already allocated; 100.94 MiB free; 6.82 GiB reserved in total by PyTorch)

1epoch回すだけで1時間学習にかかるのでこのエラーは正直つらいです。

該当のソースコード

前回同様、学習データのロード,Train関数,Validate関数,それら関数を実行するコードを記す。

Python

1import argparse 2import torch 3import numpy as np 4import torch.nn as nn 5import torch.nn.functional as F 6import torch.optim as optim 7from torch.optim.lr_scheduler import StepLR 8from torchvision import datasets, transforms 9from torch.autograd import Variable 10from torch.utils.data.sampler import SubsetRandomSampler 11from sklearn.metrics import accuracy_score 12from torchsummary import summary 13 14use_cuda = torch.cuda.is_available() 15dtype = torch.cuda.FloatTensor if use_cuda else torch.FloatTensor 16 17normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], 18 std=[0.229, 0.224, 0.225]) 19 20valid_size=0.1 21 22traindir = 'imagenette-320/train' 23valdir = 'imagenette-320/val' 24 25train_transform = transforms.Compose([ 26 transforms.RandomResizedCrop(224), 27 transforms.RandomHorizontalFlip(), 28 transforms.ToTensor(), 29 normalize 30]) 31 32valid_transform = transforms.Compose([ 33 transforms.Resize(256), 34 transforms.CenterCrop(224), 35 transforms.ToTensor(), 36 normalize 37]) 38 39train_dataset = datasets.ImageFolder(traindir,transform=train_transform) 40valid_dataset = datasets.ImageFolder(valdir,transform=valid_transform) 41 42train_sampler = None 43valid_sampler = None 44 45 46train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=128,sampler=train_sampler,shuffle=True) 47 48valid_loader = torch.utils.data.DataLoader(valid_dataset, batch_size=128,sampler=valid_sampler,shuffle=True) 49

Python

1def train(epoch): 2 model.train() 3 writer = SummaryWriter() 4 for batch_idx, (data, target) in enumerate(train_loader): 5 if use_cuda: 6 data, target = data.cuda(), target.cuda() 7 data, target = Variable(data), Variable(target) 8 optimizer.zero_grad() 9 output = model(data) 10 correct = 0 11 pred = output.data.max(1, keepdim=True)[1] # get the index of the max log-probability 12 correct += pred.eq(target.data.view_as(pred)).sum() 13 loss = criterion(output, target) 14 loss.backward() 15 accuracy = 100 * (int(correct)/ int(len(output))) 16 #accuracy = 100. * correct / len(output) 17 optimizer.step() 18 if batch_idx % 1 == 0: 19 print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}, Accuracy: {:.2f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.data.item(), accuracy)) 20 writer.add_scalar('Loss/Loss', loss.data.item(), epoch) 21 writer.add_scalar('Accuracy/Accuracy', accuracy, epoch) 22 scheduler.step()

Python

1def validate(epoch): 2 valid_loss=0.0 3 accuracy=0.0 4 model.eval() 5 6 writer = SummaryWriter() 7 8 valid_loss = 0 9 correct = 0 10 11 for data, target in valid_loader: 12 if use_cuda: 13 data, target = data.cuda(), target.cuda() 14 15 data, target = Variable(data, volatile=True), Variable(target) 16 output = model(data) 17 valid_loss += F.cross_entropy(output, target, size_average=False).data.item() # sum up batch loss 18 pred = output.data.max(1, keepdim=True)[1] # get the index of the max log-probability 19 correct += pred.eq(target.data.view_as(pred)).sum() 20 21 22 valid_loss /= len(valid_loader.dataset) 23 accuracy = 100. * correct / len(valid_loader.dataset) 24 print('\nValidation set: Average loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\n'.format(valid_loss, correct, len(valid_loader.dataset),100. * correct / len(valid_loader.dataset))) 25 writer.add_scalar('Loss/Validation_Loss', valid_loss, epoch) 26 writer.add_scalar('Accuracy/Validation_Accuracy', accuracy, epoch) 27 28 return valid_loss, accuracy

Python

1!pip install tensorboardX 2from tensorboardX import SummaryWriter 3best_loss = None 4best_acc = None 5 6for epoch in range(80): 7 #train(epoch) 8 loss, accuracy = validate(epoch) 9 best_loss, best_acc = save_best(loss, accuracy, best_loss, best_acc) 10 11writer.export_scalars_to_json("./all_scalars.json") 12 13writer.close()

試したこと

エラーメッセージの前に警告が出ていた。その警告にを知らべると自分と同じようなエラーが出ている人が他にもいたので参考に,**with torch.no_grad():**をValidate関数内に以下のように付け足した。

Python

1def validate(epoch): 2 valid_loss=0.0 3 accuracy=0.0 4 model.eval() 5 6 writer = SummaryWriter() 7 8 valid_loss = 0 9 correct = 0 10 with torch.no_grad(): 11 for data, target in valid_loader: 12 if use_cuda: 13 data, target = data.cuda(), target.cuda() 14 15 data, target = Variable(data, volatile=True), Variable(target) 16 output = model(data) 17 valid_loss += F.cross_entropy(output, target, size_average=False).data.item() # sum up batch loss 18 pred = output.data.max(1, keepdim=True)[1] # get the index of the max log-probability 19 correct += pred.eq(target.data.view_as(pred)).sum() 20 21 22 valid_loss /= len(valid_loader.dataset) 23 accuracy = 100. * correct / len(valid_loader.dataset) 24 print('\nValidation set: Average loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\n'.format(valid_loss, correct, len(valid_loader.dataset),100. * correct / len(valid_loader.dataset))) 25 writer.add_scalar('Loss/Validation_Loss', valid_loss, epoch) 26 writer.add_scalar('Accuracy/Validation_Accuracy', accuracy, epoch) 27 28 return valid_loss, accuracy

警告文は消えたが、同様のエラーが出力された。また、Variable(target)に引数volatile=Trueを入れてみても同様の結果であった。
どなたか原因と対策をご教授頂ければ幸いです。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

CUDA out of memory は GPU メモリが足りないというエラーです。なので、今のままでは実行できないので、ハードを変えられないのであれば、使用するメモリ量を減らす必要があります。
必要なメモリ量は、画像の入力サイズ、バッチサイズ、モデルの種類などの要素で決まります。
Colab で GPU メモリがどのくらい使えるのかわかりませんが、バッチサイズ batch_size=128 というのはかなり大きいので、学習用だけで GPU メモリが専有されて、バリデーション時に追加で GPU メモリを確保しようとした際にメモリが足りないとなっているのではないでしょうか。
batch_size を64, 32, 16のようにメモリが足りないとエラーにならない程度まで減らしていけばよいと思います。

with torch.no_grad():をValidate関数内に以下のように付け足した。

推論時はバックプロパゲーションをしないので、中間層の出力を記録しておく必要がないので、これは有効です。

1epoch回すだけで1時間学習にかかるのでこのエラーは正直つらいです。

学習のほうを1イテレーションだけ回したあとにすぐ break してバリデーションすれば、今の設定でメモリ不足かどうかはすぐに確認できると思います。

投稿2020/06/10 03:46

編集2020/06/10 04:03
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Otom_jp

2020/06/10 03:48

ご回答ありがとうございます。 訓練時は同様のバッチサイズで問題なかったのに、検証時にメモリが足りないということはあり得るのでしょうか。
tiitoi

2020/06/10 03:52 編集

no_grad() を指定していれば、推論時はあまりメモリを使用しないので、推論するタイミングで足りなくなるということは普通あまりないのですが、本当にメモリ使用量が逼迫しているのであれば、足りないということはありえます。 とりあえず、バッチサイズを小さくして、学習は1エポック回さなくても1回だけループしてすぐ break し、バリデーションしてエラーにならないかどうか確認してみてください バッチサイズをかなり小さくしても以前としてエラーになるのであれば、別の原因の可能性もありますが。。
Otom_jp

2020/06/10 03:58

ご回答ありがとうございます。 バッチサイズを64に変更したところ正常にValidate関数が動作し、訓練時の1epochにかかる時間も大幅に改善されました。ありがとうございます。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問