# 深度卷积GANs# 导入库from __future__ import print_functionimport torchimport torch.nn as nnimport torch.nn.parallelimport torch.optim as optimimport torch.utils.dataimport torchvision.datasets as dsetimport torchvision.transforms as transformsimport torchvision.utils as vutilsfrom torch.autograd import Variable# 设置一些超参数batchSize = 64 # 我们设置批次大小。imageSize = 64 # 我们设置生成图像的大小(64x64)。# 创建变换transform = transforms.Compose([transforms.Scale(imageSize), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),]) # 我们创建一个变换列表(缩放、张量转换、归一化),应用于输入图像。# 加载数据集dataset = dset.CIFAR10(root = './data', download = True, transform = transform) # 我们下载训练集到./data文件夹,并对每张图像应用前面的变换。dataloader = torch.utils.data.DataLoader(dataset, batch_size = batchSize, shuffle = True, num_workers = 2) # 我们使用dataLoader按批次获取训练集的图像。# 定义weights_init函数,该函数接收一个神经网络m作为输入,并初始化其所有权重。def weights_init(m): classname = m.__class__.__name__ if classname.find('Conv') != -1: m.weight.data.normal_(0.0, 0.02) elif classname.find('BatchNorm') != -1: m.weight.data.normal_(1.0, 0.02) m.bias.data.fill_(0)# 定义生成器class G(nn.Module): # 我们引入一个类来定义生成器。 def __init__(self): # 我们引入__init__()函数,用于定义生成器的架构。 super(G, self).__init__() # 我们继承自nn.Module工具。 self.main = nn.Sequential( # 我们创建一个包含一系列模块(卷积、全连接等)的神经网络元模块。 nn.ConvTranspose2d(100, 512, 4, 1, 0, bias = False), # 我们从一个反卷积开始。 nn.BatchNorm2d(512), # 我们沿批次维度对所有特征进行归一化。 nn.ReLU(True), # 我们应用ReLU整流以打破线性。 nn.ConvTranspose2d(512, 256, 4, 2, 1, bias = False), # 我们添加另一个反卷积。 nn.BatchNorm2d(256), # 我们再次归一化。 nn.ReLU(True), # 我们应用另一个ReLU。 nn.ConvTranspose2d(256, 128, 4, 2, 1, bias = False), # 我们添加另一个反卷积。 nn.BatchNorm2d(128), # 我们再次归一化。 nn.ReLU(True), # 我们应用另一个ReLU。 nn.ConvTranspose2d(128, 64, 4, 2, 1, bias = False), # 我们添加另一个反卷积。 nn.BatchNorm2d(64), # 我们再次归一化。 nn.ReLU(True), # 我们应用另一个ReLU。 nn.ConvTranspose2d(64, 3, 4, 2, 1, bias = False), # 我们添加另一个反卷积。 nn.Tanh() # 我们应用Tanh整流以打破线性,并保持在-1和+1之间。 ) def forward(self, input): # 我们定义forward函数,该函数接收一个输入作为参数,该输入将被馈送到神经网络中,并返回包含生成图像的输出。 output = self.main(input) # 我们通过由self.main定义的整个生成器神经网络前向传播信号。 return output # 我们返回包含生成图像的输出。# 创建生成器netG = G() # 我们创建生成器对象。netG.apply(weights_init) # 我们初始化其神经网络的所有权重。# 定义判别器class D(nn.Module): # 我们引入一个类来定义判别器。 def __init__(self): # 我们引入__init__()函数,用于定义判别器的架构。 super(D, self).__init__() # 我们继承自nn.Module工具。 self.main = nn.Sequential( # 我们创建一个包含一系列模块(卷积、全连接等)的神经网络元模块。 nn.Conv2d(3, 64, 4, 2, 1, bias = False), # 我们从一个卷积开始。 nn.LeakyReLU(0.2, inplace = True), # 我们应用一个LeakyReLU。 nn.Conv2d(64, 128, 4, 2, 1, bias = False), # 我们添加另一个卷积。 nn.BatchNorm2d(128), # 我们沿批次维度对所有特征进行归一化。 nn.LeakyReLU(0.2, inplace = True), # 我们应用另一个LeakyReLU。 nn.Conv2d(128, 256, 4, 2, 1, bias = False), # 我们添加另一个卷积。 nn.BatchNorm2d(256), # 我们再次归一化。 nn.LeakyReLU(0.2, inplace = True), # 我们应用另一个LeakyReLU。 nn.Conv2d(256, 512, 4, 2, 1, bias = False), # 我们添加另一个卷积。 nn.BatchNorm2d(512), # 我们再次归一化。 nn.LeakyReLU(0.2, inplace = True), # 我们应用另一个LeakyReLU。 nn.Conv2d(512, 1, 4, 1, 0, bias = False), # 我们添加另一个卷积。 nn.Sigmoid() # 我们应用Sigmoid整流以打破线性,并保持在0和1之间。 ) def forward(self, input): # 我们定义forward函数,该函数接收一个输入作为参数,该输入将被馈送到神经网络中,并返回一个在0和1之间的值作为输出。 output = self.main(input) # 我们通过由self.main定义的整个判别器神经网络前向传播信号。 return output.view(-1) # 我们返回一个在0和1之间的值作为输出。# 创建判别器netD = D() # 我们创建判别器对象。netD.apply(weights_init) # 我们初始化其神经网络的所有权重。# 训练深度卷积GANscriterion = nn.BCELoss() # 我们创建一个criterion对象,用于测量预测与目标之间的误差。optimizerD = optim.Adam(netD.parameters(), lr = 0.0002, betas = (0.5, 0.999)) # 我们创建判别器的优化器对象。optimizerG = optim.Adam(netG.parameters(), lr = 0.0002, betas = (0.5, 0.999)) # 我们创建生成器的优化器对象。for epoch in range(25): # 我们迭代25个epoch。 for i, data in enumerate(dataloader, 0): # 我们迭代数据集的图像。 # 第一步:更新判别器神经网络的权重 netD.zero_grad() # 我们将判别器相对于权重的梯度初始化为0。 # 使用数据集中的真实图像训练判别器 real, _ = data # 我们获取数据集中的一个真实图像,用于训练判别器。 input = Variable(real) # 我们将其包装在一个变量中。 target = Variable(torch.ones(input.size()[0])) # 我们获取目标。 output = netD(input) # 我们将这个真实图像前向传播到判别器的神经网络中,以获得预测值(一个在0和1之间的值)。 errD_real = criterion(output, target) # 我们计算预测值(output)与目标(等于1)之间的损失。 # 使用生成器生成的假图像训练判别器 noise = Variable(torch.randn(input.size()[0], 100, 1, 1)) # 我们为生成器创建一个随机输入向量(噪声)。 fake = netG(noise) # 我们将这个随机输入向量前向传播到生成器的神经网络中,以获得一些假生成图像。 target = Variable(torch.zeros(input.size()[0])) # 我们获取目标。 output = netD(fake.detach()) # 我们将假生成图像前向传播到判别器的神经网络中,以获得预测值(一个在0和1之间的值)。 errD_fake = criterion(output, target) # 我们计算预测值(output)与目标(等于0)之间的损失。 # 反向传播总误差 errD = errD_real + errD_fake # 我们计算判别器的总误差。 errD.backward() # 我们通过计算判别器总误差相对于权重的梯度来反向传播损失误差。 optimizerD.step() # 我们应用优化器,根据判别器的损失误差更新权重。 # 第二步:更新生成器神经网络的权重 netG.zero_grad() # 我们将生成器相对于权重的梯度初始化为0。 target = Variable(torch.ones(input.size()[0])) # 我们获取目标。 output = netD(fake) # 我们将假生成图像前向传播到判别器的神经网络中,以获得预测值(一个在0和1之间的值)。 errG = criterion(output, target) # 我们计算预测值(output在0和1之间)与目标(等于1)之间的损失。 errG.backward() # 我们通过计算生成器总误差相对于权重的梯度来反向传播损失误差。 optimizerG.step() # 我们应用优化器,根据生成器的损失误差更新权重。 # 第三步:每100步打印一次损失,并保存 minibatch 的真实图像和生成图像 print('[%d/%d][%d/%d] Loss_D: %.4f Loss_G: %.4f' % (epoch, 25, i, len(dataloader), errD.data[0], errG.data[0])) # 我们打印判别器(Loss_D)和生成器(Loss_G)的损失。 if i % 100 == 0: # 每100步: vutils.save_image(real, '%s/real_samples.png' % "./results", normalize = True) # 我们保存 minibatch 的真实图像。 fake = netG(noise) # 我们获取我们的假生成图像。 vutils.save_image(fake.data, '%s/fake_samples_epoch_%03d.png' % ("./results", epoch), normalize = True) # 我们也保存 minibatch 的假生成图像。
然而,当我执行这个示例时,返回了错误
BrokenPipeError: [Errno 32] Broken pipe
似乎发生在这一行
for i, data in enumerate(dataloader, 0): # 我们迭代数据集的图像。
这是完整的跟踪信息:
runfile('C:/Users/ncui/Dropbox/JuJu/Base_projects/Udemy/Computer_Vision_A_Z/Module 3 - GANs/dcgan_commented.py', wdir='C:/Users/ncui/Dropbox/JuJu/Base_projects/Udemy/Computer_Vision_A_Z/Module 3 - GANs')Files already downloaded and verifiedTraceback (most recent call last): File "<ipython-input-4-a3a7a503f14c>", line 1, in <module> runfile('C:/Users/ncui/Dropbox/JuJu/Base_projects/Udemy/Computer_Vision_A_Z/Module 3 - GANs/dcgan_commented.py', wdir='C:/Users/ncui/Dropbox/JuJu/Base_projects/Udemy/Computer_Vision_A_Z/Module 3 - GANs') File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 786, in runfile execfile(filename, namespace) File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile exec(compile(f.read(), filename, 'exec'), namespace) File "C:/Users/ncui/Dropbox/JuJu/Base_projects/Udemy/Computer_Vision_A_Z/Module 3 - GANs/dcgan_commented.py", line 104, in <module> for i, data in enumerate(dataloader, 0): # 我们迭代数据集的图像。 File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\site-packages\torch\utils\data\dataloader.py", line 819, in __iter__ return _DataLoaderIter(self) File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\site-packages\torch\utils\data\dataloader.py", line 560, in __init__ w.start() File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\multiprocessing\process.py", line 105, in start self._popen = self._Popen(self) File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\multiprocessing\context.py", line 223, in _Popen return _default_context.get_context().Process._Popen(process_obj) File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\multiprocessing\context.py", line 322, in _Popen return Popen(process_obj) File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__ reduction.dump(process_obj, to_child) File "C:\Users\ncui\AppData\Local\Continuum\anaconda3\envs\tensorflow\lib\multiprocessing\reduction.py", line 60, in dump ForkingPickler(file, protocol).dump(obj)BrokenPipeError: [Errno 32] Broken pipe
我尝试一步一步地做,但我无法在变量浏览器中看到dataloader
、i
和data
,我对此不太理解。
我使用的是Windows 7,Python 3.6,并使用Spyder作为Python IDE。该脚本中使用的数据可以在这里找到这里。
有谁能提供一些关于以下方面的建议
- 如何修复此错误?
- 为什么会发生此错误?
- 为什么我在变量浏览器中看不到
dataloader
、i
和data
- 如果可能的话,如何查看
dataloader
、i
和data
是什么 - 任何其他有用的信息。
非常感谢您。
回答:
添加
if __name__ == "__main__":
在第一个for循环之前。