Parser-Free Virtual Try-on via Distilling Appearance Flows代码解析

本文深入解析了基于深度学习的Parser-Free虚拟试穿技术,重点介绍了测试代码流程,包括test.sh脚本的参数设置、数据集处理方式以及CustomDatasetDataLoader中的数据封装。内容涉及AlignedDataset的get_param和get_transform方法,AFWM模块(外观流变形模块)的功能,以及FeatureEncoder、RefinePyramid和AFlowNet的细节。同时,还探讨了GM模块中的ResUnetGenerator在虚拟试穿中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从PF-AFN_test开始看,先看测试代码

1.test.sh  

python test.py --name demo --resize_or_crop None --batchSize 1 --gpu_ids 0

参数:name,resize_or_crop,gpu_ids  参数定义在options.base_options.py

定义:name demo 

          resize_or_crop None 不需要变换

          batchSize 1一次把网络中送入一个

2.test.py

opt = TestOptions().parse()#opt代表初始化的类对象
ctrl+鼠标左键点击Testoptions,找到opt对象的具体内容:
class TestOptions(BaseOptions):
    #TestOptions类的initialize函数系重写,但还是调用了BaseOptions.initialize(self)的,所以    
    #BaseOptions.initialize的数据也包含了的。
    #根据训练和测试所需要的数据不同,控制生成数据集和其他超参数
    def initialize(self):
    BaseOptions.initialize(self)
    ......
ctrl+鼠标左键点击Baseoptions
import argparse #argparse指定命令行参数
import torch

#配置文件options,专用于数据集目录信息。测试信息和超参数进行配置的文件
class BaseOptions():
    def __init__(self):...  #创建对象就默认执行init方法,
   
    def initialize(self):...

    def parse(self, save=True):
         '''
        指定GPU
        打印参数
        '''
        if not self.initialized:#self.initialized只要对象存在就执行init方法,init方法中self.initialized = False,if not False即为True
            self.initialize()#执行initialize()方法
        self.opt = self.parser.parse_args()#self.parser初始化的,.parse_args()获取参数的第一列'--name''--gpu_ids'
        #把parser中设置的所有"add_argument"给返回到opt子类实例当中, 那么parser中增加的属性内容都会在opts实例中,使用即可。
        self.opt.isTrain = self.isTrain   # train or test  在opt对象中添加参数,把self.isTrain 赋值给self.opt.isTrain,但没有self.isTrain这个参数???

        str_ids = self.opt.gpu_ids.split(',')#1,2,3在多GPU并行的时候,实际的batch size是单GPU设置的batch size的n倍
        self.opt.gpu_ids = []
        '''
        指定GPU
        '''
        for str_id in str_ids:
            id = int(str_id)
            if id >= 0:
                self.opt.gpu_ids.append(id)

        if len(self.opt.gpu_ids) > 0:
            torch.cuda.set_device(self.opt.gpu_ids[0])

        args = vars(self.opt)

        print('------------ Options -------------')#把参数打印一遍
        for k, v in sorted(args.items()):
            print('%s: %s' % (str(k), str(v)))
        print('-------------- End ----------------')

        return self.opt
   
  
          
opt = TestOptions().parse()#目的就是调用base_options中的方法,目的指定GPU,打印参数

数据集详细处理:

data_loader = CreateDataLoader(opt) #CreateDataLoader是封装数据迭代器的类 点进去
#pytorch怎么创建数据类:先把数据封装到一个dataset类里,该类的作用是把原来的图片和标签转换为tensor,dataset类再封装到dataloder类里,该类的作用把数据一批一批batch,3维转四4维
def CreateDataLoader(opt):
    from data.custom_dataset_data_loader_test import CustomDatasetDataLoader
    data_loader = CustomDatasetDataLoader()
    print(data_loader.name())
    data_loader.initialize(opt)
    return data_loader

具体内容在CustomDatasetDataLoader在,ctrl+左键点进去

class CustomDatasetDataLoader(BaseDataLoader):#继承了BaseDataLoader类
    def name(self):#返回类名
        return 'CustomDatasetDataLoader'

    def initialize(self, opt):
        BaseDataLoader.initialize(self, opt)
        #还封装了一层
        self.dataset = CreateDataset(opt)#第一步,创建dataset类
        self.dataloader = torch.utils.data.DataLoader(
            self.dataset,
            batch_size=opt.batchSize,
            shuffle = False,
            num_workers=int(opt.nThreads))

    def load_data(self):
        return self.dataloader

    def __len__(self):
        return min(len(self.dataset), self.opt.max_dataset_size)

发现还封装了一层,数据是:self.dataset = CreateDataset(opt)

#一般把图片加标签转成tensor数据
def CreateDataset(opt):
    dataset = None
    from aligned_dataset_test import AlignedDataset
    #又有封装函数
    dataset = AlignedDataset()

    print("dataset [%s] was created" % (dataset.name()))
    dataset.initialize(opt)#可以看出封装数据过程中动不动都在初始化
    return dataset
<