zoukankan      html  css  js  c++  java
  • pytorch怎么使用定义好的模型的一部分

    Encoder代码为:

    class Encoder(nn.Module):  #输入图片的大小isize、噪声的维度nz=100、输入图片的通道nc=3、ndf=64、
        def __init__(self,isize,nz,nc,ndf,ngpu,n_exter_layers=0,add_final_conv=True):
            super(Encoder,self).__init__()
            self.ngpu=ngpu
            # 必须为16倍数
            assert isize % 16==0,"isize has to be a multiple of 16"
    
            main=nn.Sequential()
            # 图片的高宽缩小一倍
            main.add_module('initial-conv-{0}-{1}'.format(nc,ndf),nn.Conv2d(nc,ndf,4,2,1,bias=False))
            main.add_module('initial-relu-{0}'.format(ndf),nn.LeakyReLU(0.2,inplace=True))
            csize,cndf=isize/2,ndf
    
            for t in range(n_exter_layers): #在这里面特征宽高不变,通道数也不变
                main.add_module('extra-layers-{0}-{1}-conv'.format(t,cndf),nn.Conv2d(cndf,cndf,3,1,1,bias=False))
                main.add_module('extra-layers-{0}-{1}-batchnorm'.format(t,cndf),nn.BatchNorm2d(cndf))
                main.add_module('extra-layers-{0}-{1}-relu'.format(t,cndf),nn.LeakyReLU(0.2,inplace=True))
    
            # 在特征高宽仍大于4时,就添加缩小一倍高宽,通道增加一倍的卷积块
            while csize>4:
                in_feat = cndf
    
                out_feat = cndf * 2
    
                main.add_module('pyramid-{0}-{1}-conv'.format(in_feat, out_feat),nn.Conv2d(in_feat, out_feat, 4, 2, 1, bias=False))
    
                main.add_module('pyramid-{0}-batchnorm'.format(out_feat),nn.BatchNorm2d(out_feat))
    
                main.add_module('pyramid-{0}-relu'.format(out_feat),nn.LeakyReLU(0.2, inplace=True))
    
                cndf = cndf * 2
    
                csize = csize / 2
    
            # 最后一层卷积,将4*4变为1*1,得到nz = 100的噪声
            if add_final_conv:
    
                main.add_module('final-{0}-{1}-conv'.format(cndf, 1),nn.Conv2d(cndf, nz, 4, 1, 0, bias=False))
                self.main=main
        
        def forward(self,input):
            if self.ngpu>1:
                 output=nn.parallel.data_parallel(self.main,input,range(self.ngpu)) #在多个gpu上运行模型,并行计算
            else:
                output=self.main(input)
            
            return output  #如果输入的大小是3×32×32,最后的输出是100×1×1.

    判别器为:

     #定义判别器D (编码器)     
    class NetD(nn.Module):
        def __init__(self, opt):
            super(NetD, self).__init__()
            
            # 第二个参数是1 因为判别器最后输出一个数
            # 不过编码器在生成器里的时候 
            # 这个参数是100 因为它要把图片下采样成100×1×1的向量
            model = Encoder(opt.isize, 1, opt.nc, opt.ndf, opt.ngpu, opt.extralayers)  
    
            layers = list(model.main.children())
    
            '''layers的输出如下:
            [
            Conv2d(3, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False),
    
            LeakyReLU(negative_slope=0.2, inplace),
    
            Conv2d(64, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False),
    
            BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True),
    
            LeakyReLU(negative_slope=0.2, inplace),
    
            Conv2d(128, 256, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False),
    
            BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True),
    
            LeakyReLU(negative_slope=0.2, inplace),
    
            Conv2d(256, 1, kernel_size=(4, 4), stride=(1, 1), bias=False)] 因为132行定义的nz参数是1,所以经过这层之后输出的大小是1×1×1
            '''
    
            self.features = nn.Sequential(*layers[:-1])
            # self.features的内容为除了最后一层的前8层
    # nn.Sequential函数里面的参数一定是Module的子类,而list不是一个模块子类,
    所以不能当做参数 # 当然model.children()也一样不是一个模块子类,只有他们里面的值才是
    # 这里的*就起了作用,将list或者children的内容迭代地一个一个的传进去。 #生成一个分类器模块 self.classifier = nn.Sequential(layers[-1]) #self.classifier的内容为Conv2d(256, 1, kernel_size=(4, 4), stride=(1, 1), bias=False)最后一层 #并在后面添加子模块sigmoid self.classifier.add_module('Sigmoid', nn.Sigmoid()) def forward(self, x): features = self.features(x) #图片通过前8层之后的结果256×4×4,前提是输入的图片的大小是32 features = features classifier = self.classifier(features)#此时的结果是1×1×1,值在[01],因为经过了sigmoid classifier = classifier.view(-1, 1).squeeze(1) #a=torch.ones([1,1,1]) 即a=tensor([[[ 1.]]]) 再a.view(-1,1) 变成tensor([[ 1.]]) 再加一个squeeze就是 # a.view(-1,1).squeeze(1) 结果是tensor([ 1.]),squeeze里的值是0是1随意,只要去掉一个维度上的就可以 # 因此返回得到一个判别值classifier 和一个大小为256×4×4的特征值 return classifier, features

    重点在:

    • layers = list(model.main.children())
    • self.features = nn.Sequential(*layers[:-1]) :使用除了最后一层的前面所有层
    • self.classifier = nn.Sequential(layers[-1]):仅使用最后一层

    这里可见同样的模型结构我们在Encoder.py中已经定义过一遍了,在判别其中实在不想再定义一遍,那我们就能够使用model.main.children()来获得模块中的子模块,然后将其转成列表形式,然后就能够根据想要的部分来进行处理了

  • 相关阅读:
    Android studio导入开源项目
    使用Kindeditor上传图片
    IOS实现自动循环滚动广告--ScrollView的优化和封装
    Android开发之Drag&Drop框架实现拖放手势
    IOS中的手势详解
    Android实现图片轮显效果——自定义ViewPager控件
    IOS欢迎界面Launch Screen动态加载广告
    tomcat 启动参数 Xms, Xmx, XX:MaxNewSize, XX:PermSize, -XX:MaxPermSize, Djava.awt.headless
    PHP提升echo, printf, print, file_put_contents等输出方法的效率
    WIN7下强制分第四个主分区的方法
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/11278211.html
Copyright © 2011-2022 走看看