Pytorchレコード
5174 ワード
テスト時out of memoryの問題について
訓練の過程でloss.backward()は計算図の隠れた変数勾配をクリアし、テスト時に空間を解放するメカニズムがないため、テストが進むにつれて中間変数が多くなる可能性があり、out of memoryの発生注:テスト時にまずmodelを使用する.eval()です.そうしないと、テスト時のbatchNorm層とDropout層の結果に影響します.解決策を追加する必要があります.
regular_input = Variable(torch.randn(5, 5))
>>> volatile_input = Variable(torch.randn(5, 5), volatile=True)
>>> model = torchvision.models.resnet18(pretrained=True)
>>> model(regular_input).requires_grad
True
>>> model(volatile_input).requires_grad
False
>>> model(volatile_input).volatile
True
x = torch.tensor([1], requires_grad=True)
>>> with torch.no_grad():
... y = x * 2
>>> y.requires_grad
False
>>> @torch.no_grad()
... def doubler(x):
... return x * 2
>>> z = doubler(x)
>>> z.requires_grad
False
ここにいるno_grad()はpytorchの逆伝播メカニズムに影響し、テスト時に逆伝播が使用されないと判断したため、このモードはメモリ領域の節約に役立ちます.同理対torch.set_grad_enable(grad_mode)もそうです
x = torch.tensor([1], requires_grad=True)
>>> is_train = False
>>> with torch.set_grad_enabled(is_train):
... y = x * 2
>>> y.requires_grad
False
>>> torch.set_grad_enabled(True)
>>> y = x * 2
>>> y.requires_grad
True
>>> torch.set_grad_enabled(False)
>>> y = x * 2
>>> y.requires_grad
False
a= Variable(torch.tensor(np.array([1,2,3],dtype=np.float)),requires_grad=False)
b=Variable(torch.tensor(np.array([4,5,6],dtype=np.float)),requires_grad=False)
c=Variable((a**2).data,requires_grad=True)
d=c+b
d=sum(d)
d.backward()
# c.backward(torch.Tensor([1,1,1]))
print(c.grad)
features_blobs = []
def hook_feature(module, input, output):
features_blobs.append(output.data.cpu().numpy())
net._modules.get(final_conv).register_forward_hook(hook_feature)
レジスター経由forward_hookは中間結果を得て、所望の結果が得られるかどうかを見てみましょう.もしそうすれば、すべての入力がrequireに設定されます.gradはfalseとtorchである.no_grad()に違いがあるかどうか
class Autoencoder(nn.Module):
def __init__(self):
super(Autoencoder, self).__init__()
self.encoder = nn.Sequential(
_ConvLayer(3, 128),
_ConvLayer(128, 256),
_ConvLayer(256, 512),
_ConvLayer(512, 1024),
Flatten(),
nn.Linear(1024 * 4 * 4,1024),
nn.Linear(1024,1024 * 4 * 4),
Reshape(),
_UpScale(1024, 512),
)
...
# net encoder requires_grad
for param in model.encoder.parameters():
print(param.requires_grad)
:
True
True
True
True
True
True
True
True
True
True
True
True
True
True
, net , loss.backward() net 。
カスタム機能
class X(object):
def __init__(self, a, b, range):
self.a = a
self.b = b
self.range = range
def __call__(self, a, b):
self.a = a
self.b = b
print('__call__ with ({}, {})'.format(self.a, self.b))
def __del__(self, a, b, range):
del self.a
del self.b
del self.range
X(1,2,3)(4,5)
__init__ a 1,b 2,range 3 __call__ a 4,b 5 __call__ with (4,5)
pytorchダイナミック接続図
ダイナミックグラフ
余談:0.4.0では0次元テンソル(torch.tensor(3)がtensor(3)を直接生成する、0.4.0より前にtensor([3]))が生成されるため、tensorはnumpyと完全に見なすことができ、0次元ベクトルはnumpyでのnpに対応する.array(0)、戻り値はarray(0)、tensor([1,2])に対してarray([1,2])に対応するnumpyに対してもtensorに対してもitem()を使用して0次元データをPython Number余談2:lossに返すことができる.backward()lossがスカラーである、要素が含まれている場合はlossを必要としない.backward()は、lossに等価なパラメータを指定します.backward(torch.FloatTensor([1.0])) Autograd
pytorchは動的計算図を採用し、各ノードは変数を表し、0.4.0後にVariableを廃棄し、Tensorは元のVariableの機能に直接代わるため、Tensorは現在、ノード(順方向伝播の活性化値と逆方向伝播の勾配を保存するために使用される)を代表し、Functionを表す.以前のVariableのrequired_がTensorに保持されています.gradおよびgrad_fn,leaf Variableと生成変数のrequired_についてgradとgrad_fnは違うleaf variableのrequire_gradは、trueが1つある場合に関連する生成変数がtrueであることを指定できます.
テスト時pytroch処理
with torch.no_grad():
for input,target in test_loader:
......
model.eval()