この記事は古川研究室 Advent_calendar 8日目の記事です。
本記事は古川研究室の学生が学習の一環として書いたものです。内容が曖昧であったり表現が多少異なったりする場合があります。
はじめに
同じタスクの機械学習のアルゴリズムを比較する軸として、学習の安定性(初期値の依存度)・説明可能かどうか・(教師あり学習では正解率 (Accuracy)・適合率 (Precision)・再現率 (Recall)という指標もあります)そして、「計算量」があります。
メモリに載らないくらい計算量が大きくなりやすいアルゴリズムだと状況(時間・計算リソース)によっては採用しづらいですね. (ex: $\mathcal{O}(データ数^3)$ だと一回の学習のデータ数はせいぜい1000($1000^3=10 Billion \fallingdotseq 10GB$)に押さえないとですね.
また、計算量が少なくても実装的にその計算になっていない場合もあります.
本記事では、pythonのプログラムのメモリ消費量を確認する方法を記します。
No package
@shiracamus さんに何もimportなしにメモリサイズがわかる方法を明記していただいたので、ちゃっかり本文にも追記させていただきます。
import numpy as np
N = 1000
D = 3
X = np.random.randn(N,D)
X.__sizeof__()
# 24112
番外: 変数以外のメモリ消費量確認方法
X = [X]
X.__sizeof__()
# 48
def f():
pass
f.__sizeof__()
# 112
class A():
pass
A.__sizeof__()
# File "<stdin>", line 1, in <module>
# TypeError: descriptor '__sizeof__' of 'object' object needs an argument
# 後述する sys.getsizeof()なら可能
sys
import sys
import numpy as np
N = 1000
D = 3
X = np.random.randn(N,D)
print(sys.getsizeof(X))
# 24112
ちなみに pytorchの場合は変数の後に.storage()をつけないとちゃんと持ってきくれません(一敗)
import sys
import torch
N = 1000
D = 3
X = torch.randn(N,D)
print(sys.getsizeof(X))
# 72
print(sys.getsizeof(X.storage()))
# 12064
memory_profiler
見たい変数ごとにsys.getsizeofを呼ぶのは骨がおれます。
そこでmemory_profiler です。標準パッケージではないのでインストールしてくる必要はあります。
ちなみに@profileで対象のメソッドの中身はpycharmのデバッグモードで止まってくれません(一敗)
from memory_profiler import profile
import numpy as np
@profile()
def test():
N = 10000000
D = 3
X = np.random.randn(N, D)
test()
とすると出力で
Line # Mem usage Increment Line Contents
================================================
5 62.3 MiB 62.3 MiB @profile()
6 def test():
7 62.3 MiB 0.0 MiB N = 10000000
8 62.3 MiB 0.0 MiB D = 3
9 291.2 MiB 228.9 MiB X = np.random.randn(N, D)
をだしてくれます.
Mem usageが Totalで, Incrementがその行で追加されたメモリ量です。
実装次第ではあまり信用ができないみたいですが、軽い確認には自分がこれを使っています。