Реализация Dropconnect в Pytorch - PullRequest
1 голос
/ 29 января 2020

Я пытаюсь кодировать dropconnect для Conv2D и уровня transposeconv2D. Следуйте учебнику в https://pytorchnlp.readthedocs.io/en/latest/_modules/torchnlp/nn/weight_drop.html, чтобы создать его.

import torch
from torch.nn import Parameter

def _weight_drop(module, weights, dropout):
    for name_w in weights:
        w = getattr(module, name_w)
        del module._parameters[name_w]
        module.register_parameter(name_w + '_raw', Parameter(w))
    original_module_forward = module.forward

    def forward(*args, **kwargs):
        for name_w in weights:
            raw_w = getattr(module, name_w + '_raw')
            w = torch.nn.functional.dropout(raw_w, p=dropout, training=module.training)
            setattr(module, name_w, w)
        return original_module_forward(*args, **kwargs)
    setattr(module, 'forward', forward)

class WeightDropConv2d(torch.nn.Conv2d):
    def __init__(self, *args, weight_dropout=0.0, **kwargs):
        super().__init__(*args, **kwargs)
        weights = ['weight']
        _weight_drop(self, weights, weight_dropout)

class WeightDropConvTranspose2d(torch.nn.ConvTranspose2d):
    def __init__(self, *args, weight_dropout=0.0, **kwargs):
        super().__init__(*args, **kwargs)
        weights = ['weight']
        _weight_drop(self, weights, weight_dropout)

torch.version.cuda: 1.1.0 torch. версия : 9.0.176

Я получаю следующую ошибку во 2-й эпохе:

Traceback (most recent call last):
  File "dropconnect.py", line 110, in <module>
    out = model(image)
  File "/home/sbhand2s/.local/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in __call__
    result = self.forward(*input, **kwargs)
  File "dropconnect.py", line 73, in forward
    out = self.c1(x)
  File "/home/sbhand2s/.local/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in __call__
    result = self.forward(*input, **kwargs)
  File "dropconnect.py", line 34, in forward
    setattr(module, name_w, w)
  File "/home/sbhand2s/.local/lib/python3.6/site-packages/torch/nn/modules/module.py", line 558, in __setattr__
    .format(torch.typename(value), name))
TypeError: cannot assign 'torch.cuda.FloatTensor' as parameter 'weight' (torch.nn.Parameter or None expected)

Эта ошибка возникает во второй эпохе, когда я переключаюсь с .eval () на .train (). Эта ошибка не возникает, если я не вызываю .eval ()

Любые предложения о том, почему происходит эта ошибка или как лучше реализовать dropconnect?

Код для репликации проблемы:

from collections import OrderedDict
import torch
from torch import nn

layers = []
layers.append(("conv_1", WeightDropConv2d(1,3,3,1,1,weight_dropout=0.5)))
layers.append(("conv_2", WeightDropConv2d(3,3,3,1,1,weight_dropout=0.5)))
layers.append(("conv_3", WeightDropConv2d(3,1,3,1,1,weight_dropout=0.5)))

model = nn.Sequential(OrderedDict(layers))

pred = model(torch.randn([1,1,3,3]))

model.eval()
pred = model(torch.randn([1,1,3,3]))

model.train()
pred = model(torch.randn([1,1,3,3]))

1 Ответ

0 голосов
/ 24 февраля 2020

Я тоже не смог заставить этот метод работать (хотя и с другой ошибкой), но вот более простой метод, который, кажется, работает:

for i in range(num_batches):

    orig_params = []
    for n, p in model.named_parameters():
        orig_params.append(p.clone())
        p.copy_(F.dropout(p.data, p=drop_prob) * (1 - drop_prob))

    output = model(input)
    loss = nn.CrossEntropyLoss()(output, label)
    optimizer.zero_grad()
    loss.backward()

    for orig_p, (n, p) in zip(orig_params, model.named_parameters()):  
        p.copy_(orig_p)

    optimizer.step()

(протестировано в Pytorch 1.4)

...