pytorch-tutorial之DCGANs学习

又看了一次DCGANs,比上次看的清楚了些,代码也大致看明白了。这次总结也是结合代码记录一下遇到的问题。

  1. 数据处理部分。数据处理包括数据预处理和数据格式转换。数据预处理使用的是torchvision.datasets, torchvision.transforms, 在datasets模块下面有一个datasets.ImageFolder,可以获取文件夹下面的图片。
torchvision.datasets.ImageFolder(root, transform=None, target_transform=None, loader=<function default_loader>, is_valid_file=None)
[source]
    A generic data loader where the images are arranged in this way:
    root/dog/xxx.png
    root/cat/123.png

对于ImageFolder里面有一个参数是路径,这里一个细节是我们写的路径下面还要有一个子目录,把数据放在子目录里面才可以正常被读取.
torchvision.transforms() 的常见操作是transforms.Compose([ ]), transforms.Resize(), transforms.Crop(),transforms.ToTensor(), transforms.Normalize(mean=(a,b,c), std=(a,b,c)),这里面,Resize()和Crop()操作的对象是PIL格式的图片,也就是说,ToTensor()的操作要在这些操作之后才可以,如果顺序颠倒,就会报错.

  1. 接下来的就是torch.utils.data.DataLoader()操作,
class
torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, sampler=None, batch_sampler=None, num_workers=0, collate_fn=None, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None, multiprocessing_context=None)
[source]
    Data loader. Combines a dataset and a sampler, and provides an iterable over the given dataset.
    The DataLoader supports both map-style and iterable-style datasets with single- or multi-process loading, customizing loading order and optional automatic batching (collation) and memory pinning.

之前我就很奇怪,数据预处理完了为什么还要进行这一步操作,感觉好麻烦,这次算是明白了一点原因。 我的理解是,DataLoader最大的作用就是将上面的数据集变成了一个可迭代的对象,我们通过设置batch_size的大小来决定一次内存处理数据的多少;同时通过num_workers来设置多进程处理。使用了dataLoader()之后,我们就可以使用iter()+next()来迭代数据,亦可使用 enumerate(DataLoader)来遍历数据。

for i, data in enumerate(dataloader, 0):
        ############################
        # (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))
        ###########################
        netD.zero_grad()
        real_cpu = data[0].to(device)
        b_size = real_cpu.size(0)
        label = torch.full((b_size,), real_label, device=device)

对于这几行代码我进行了debug,来看看他们的数据类型。
在这里插入图片描述
data是列表类型,但是它里面存的两个Tensor, 这种类型嵌套我最近才搞明白。再来看一下data[0]的维度,这也是一个细节。最后一个细节是data[1]代表的label,还记得我们之前的ImageFolder吗,对于同一目录下的文件,全都赋予同样的标签。

d

  1. matplotlib画图
    plt 画图要求数据格式为PIL而不是tensor,这里就会涉及到一个维度的转变,在Tensor中,图片的存储方式为(C,H,W),而PI的维度要求为(H,W,C),因此,我们需要np.transpose(Tensor,(1,2,0))进行调整。

  2. class torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True, dilation=1, padding_mode='zeros')
    有仔细看了一下输入输出维度变化的计算公式,这里记录一下,顺便和nn.Conv2d()比较一下。
    ConvTranspose2d: W o u t = ( W i n − 1 ) ∗ s t r i d e − 2 ∗ p a d d i n g + k e r n e l s i z e W_{out} = (W_{in}-1)*stride - 2*padding + kernel_size Wout=(Win1)stride2padding+kernelsize

    Conv2d: W o u t = ( W i n − k e r n e l s i z e ) + 2 ∗ p a d d i n g 2 ∗ s t r i d e + 1 W_{out} = \frac{(W_{in}-kernel_size) + 2*padding}{2*stride} + 1 Wout=2stride(Winkernelsize)+2padding+1
    这里就显示了Conv2d和ConvTranspose2其实就是两个相反的操作~

  3. torch.full(size, fill_value, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor .在上面代码最后一行,第一个参数代表张量大小,第二个代表要填充的值,最后返回的就是是一个张量。这里一个细节是label之前并没有定义哦

  4. 最后一个问题就是关于loss的。对BCELoss()算是有了个初步的了解了。先放公式
    torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')

  5. l ( x , y ) = L = { l 1 , . . . , l N } T l(x,y)=L=\{ l_1,...,l_N\}^T l(x,y)=L={l1,...,lN}T ,   l n = − [ y n l o g x n + ( 1 − y ) l o g ( 1 − x n ) ] l_n=-[y_nlogx_n + (1-y)log(1-x_n)] ln=[ynlogxn+(1y)log(1xn)]
    首先来看鉴别器D,D的loss两部分都有,一方面它要尽可能的把真图识别为1;另一方面它要尽可能的把假图识别为0,所以当真正测试的时候,使用criterion(output, label),就要用两次,一次label=0,一次label=1.
    接下来是生成器G,G的loss也是基于D,但是他只需要一项,那么问题来了,使用哪一项呢? 一方面我们可以使用label=1,那么G的目的就是使 l o g x n logx_n logxn尽可能趋于0,也就是D(G(z))尽可能趋近于1(根本目的还是要 降低loss)记住,此时 x n = D ( G ( z ) ) x_n=D(G(z)) xn=D(G(z));另一方面,我们还可以使用label=0,此时就是要使 l o g ( 1 − x n ) log(1-x_n) log1xn尽可能趋于0,也就是1-D(G(z))尽可能趋近于0。
    这两个方法,作者选择了第一个,说是这样好训练,我等也就这样吧。一开始以为会写很多,结果发现其实就这些内容,不过还是要记录下来,记性太差了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值