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()來獲得模塊中的子模塊,然后將其轉成列表形式,然后就能夠根據想要的部分來進行處理了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM