Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 前向传递在迭代一段时间后会慢10000x_Python_Deep Learning_Gpu_Pytorch - Fatal编程技术网

Python 前向传递在迭代一段时间后会慢10000x

Python 前向传递在迭代一段时间后会慢10000x,python,deep-learning,gpu,pytorch,Python,Deep Learning,Gpu,Pytorch,我实现了一个简单的Deconv网络,就像pytorch的官方DCGAN教程一样。 我反复向它传递一个零向量。一段时间后,所用的时间明显减慢。我想知道原因是什么,我怎样才能解决它 代码: 导入火炬 导入torch.nn作为nn 导入时间 #只是为了测量时间 类计时器: 定义初始化(self,msg): self.msg=msg 定义输入(自我): self.start=time.process\u time() 回归自我 定义退出(自我,*args): self.end=time.process\

我实现了一个简单的Deconv网络,就像pytorch的官方DCGAN教程一样。 我反复向它传递一个
向量。一段时间后,所用的时间明显减慢。我想知道原因是什么,我怎样才能解决它

代码:

导入火炬
导入torch.nn作为nn
导入时间
#只是为了测量时间
类计时器:
定义初始化(self,msg):
self.msg=msg
定义输入(自我):
self.start=time.process\u time()
回归自我
定义退出(自我,*args):
self.end=time.process\u time()
self.interval=self.end-self.start
打印(“{}:{:.5f}.”格式(self.msg,self.interval))
装置=火炬装置(“cuda”)

ngf,nc,nz,batchSize=64,1,6,1我在Titan RTX上尝试了相同的代码,得到了完全相同的行为

所有gpu调用都是异步的(正如jodag在注释中指出的),并且只有在需要时才同步,如果存在依赖项的话。为了测试它,我对代码做了一点修改,这样网络的输出就被实际使用了,并创建了一个依赖项,比如依赖项。因此,在下一次迭代开始之前,现在需要输出

为True时:
使用计时器(“经过的时间”):
使用手电筒。无梯度()
输出=netG(火炬零点([batchSize,nz,1,1],设备=设备))
打印(output.mean())

现在总需要12.8秒。所以乔达格是完全正确的。它与对GPU的异步调用以及pytorch如何在内部处理所有事情有关。

这是python2.7吗?您的代码可能保留了一个变量,该变量通常在后面的prob中被删除,因此最终只有很少的内存来使用它的python3。如果你的猜测是正确的,那么我应该如何修复?奇怪的是,我没有在python3中看到
super
。我对pytorch了解不多,但可能会有所帮助。我从pytorch教程中复制了该模块,
super
显示Python3没有问题。仅供参考,我可以在TITAN RTX上复制该模块,尽管我不完全清楚为什么会发生这种情况。我认为这是由于pytorch的异步行为造成的,因为如果您通过
y=netG(…
捕获输出,然后调用
torch.cuda.synchronize()
,那么每个迭代都需要相同的时间(大约12秒)。如果您添加
torch.cuda.synchronize()
,而不分配
netG的输出(…
然后它仍然没有等待,但我认为这是因为没有等待更新的变量。
import torch
import torch.nn as nn
import time

# JUST TO MEASURE TIME
class Timer:
    def __init__(self, msg):
        self.msg = msg

    def __enter__(self):
        self.start = time.process_time()
        return self

    def __exit__(self, *args):
        self.end = time.process_time()
        self.interval = self.end - self.start

        print('{}: {:.5f}'.format(self.msg, self.interval))

device = torch.device("cuda")

ngf, nc, nz, batchSize = 64, 1, 6, 1<<16
class Generator(nn.Module):
    def __init__(self):
        super(Generator, self).__init__()
        self.main = nn.Sequential(
            # input is Z, going into a convolution
            nn.ConvTranspose2d( nz, ngf * 4, 4, 1, 0, bias=False),
            nn.BatchNorm2d(ngf * 4),
            nn.ReLU(True),
            # state size. (ngf*4) x 4 x 4
            nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 2),
            nn.ReLU(True),
            # state size. (ngf*2) x 8 x 8
            nn.ConvTranspose2d( ngf * 2, ngf, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf),
            nn.ReLU(True),
            # state size. (ngf) x 16 x 16
            nn.ConvTranspose2d( ngf, nc, 4, 2, 1, bias=False),
            nn.Tanh()
            # state size. (nc) x 32 x 32
        )

    def forward(self, input):
        return self.main(input)

# Create the generator
netG = Generator().to(device)

def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        nn.init.normal_(m.weight.data, 0.0, 0.02)
    elif classname.find('BatchNorm') != -1:
        nn.init.normal_(m.weight.data, 1.0, 0.02)
        nn.init.constant_(m.bias.data, 0)

netG.apply(weights_init)

# torch.backends.cudnn.benchmark=True

while True:
    with Timer('Time elapsed'):
        with torch.no_grad():
            netG(torch.zeros([batchSize, nz, 1, 1], device=device))