天天看點

風格遷移1-06:Liquid Warping GAN(Impersonator)-源碼無死角解析(1)-訓練代碼總覽

以下連結是個人關于Liquid Warping GAN(Impersonator)-姿态遷移,所有見解,如有錯誤歡迎大家指出,我會第一時間糾正。有興趣的朋友可以加微信:17575010159 互相讨論技術。若是幫助到了你什麼,一定要記得點贊!因為這是對我最大的鼓勵。 文末附帶 \color{blue}{文末附帶} 文末附帶 公衆号 − \color{blue}{公衆号 -} 公衆号− 海量資源。 \color{blue}{ 海量資源}。 海量資源。

風格遷移1-00:Liquid Warping GAN(Impersonator)-目錄-史上最新無死角講解

訓練腳本參數

在訓練之前,我們先來看看訓練腳本,即scripts/train_iPER.sh,下面是簡單的一些注釋:

#! /bin/bash

# basic configs
#gpu_ids=0,1     # if using multi-gpus, increasing the batch_size
gpu_ids=0

# dataset configs
dataset_model=iPER  # use iPER dataset  指定使用資料集的格式
data_dir=../2.Dataset/ # need to be replaced!!!!! 指定資料集的根目錄
images_folder=images # 圖像的目錄
smpls_folder=smpls #樣本目錄,其主要儲存關鍵點和形狀的資訊
train_ids_file=train.txt # 參與訓練的ids
test_ids_file=val.txt # 用于測試的id

# saving configs,配置儲存模型的路徑和檔案名
checkpoints_dir=../2.Dataset/ckpts_models   # directory to save models, need to be replaced!!!!!
name=exp_iPER   # the directory is ${checkpoints_dir}/name, which is used to save the checkpoints.

# model configs,選擇訓練的模式,預設為模仿模式
model=impersonator_trainer
gen_name=impersonator
image_size=256

# training configs,論文中相關的參數
load_path="None"
batch_size=1
lambda_rec=10.0
lambda_tsf=10.0
lambda_face=5.0
lambda_style=0.0
lambda_mask=1.0
#lambda_mask=2.5
lambda_mask_smooth=1.0
# 在指定epoch範圍區間,學習率保持不變
nepochs_no_decay=5  # fixing learning rate when epoch ranges in [0, 5]
# 在指定epoch範圍區間,每個epoch學習率會衰減
nepochs_decay=25    # decreasing the learning rate when epoch ranges in [6, 25+5]




python train.py --gpu_ids ${gpu_ids}        \
    --data_dir  ${data_dir}                 \
    --images_folder    ${images_folder}     \
    --smpls_folder     ${smpls_folder}      \
    --checkpoints_dir  ${checkpoints_dir}   \
    --train_ids_file   ${train_ids_file}    \
    --test_ids_file    ${test_ids_file}     \
    --load_path        ${load_path}         \
    --model            ${model}             \
    --gen_name         ${gen_name}          \
    --name             ${name}              \
    --dataset_mode     ${dataset_model}     \
    --image_size       ${image_size}        \
    --batch_size       ${batch_size}        \
    --lambda_face      ${lambda_face}       \
    --lambda_tsf       ${lambda_tsf}        \
    --lambda_style     ${lambda_style}      \
    --lambda_rec       ${lambda_rec}         \
    --lambda_mask      ${lambda_mask}       \
    --lambda_mask_smooth  ${lambda_mask_smooth} \
    --nepochs_no_decay ${nepochs_no_decay}  --nepochs_decay ${nepochs_decay}  \
    --mask_bce     --use_vgg       --use_face

           

train.py代碼注釋

下面是訓練代碼的總體注釋,很多細節沒有給出,如可視化,以及列印的在終端的資訊,究竟是什麼資訊,不過沒有關系,後續在分析代碼的過程中,我們肯定能找到我們想要的答案,注釋如下:

import time
from options.train_options import TrainOptions
from data.custom_dataset_data_loader import CustomDatasetDataLoader
from models.models import ModelsFactory
from utils.tb_visualizer import TBVisualizer
from collections import OrderedDict


class Train(object):
    def __init__(self):
        # 對指令行參數進行解析
        self._opt = TrainOptions().parse()
        # 建立訓練,測試資料疊代對象
        data_loader_train = CustomDatasetDataLoader(self._opt, is_for_train=True)
        data_loader_test = CustomDatasetDataLoader(self._opt, is_for_train=False)

        # 加載訓練以及疊代資料
        self._dataset_train = data_loader_train.load_data()
        self._dataset_test = data_loader_test.load_data()

        # 擷取訓練以及疊代資料的長度,即每個epoch需要疊代多少次
        self._dataset_train_size = len(data_loader_train)
        self._dataset_test_size = len(data_loader_test)
        print('#train video clips = %d' % self._dataset_train_size)
        print('#test video clips = %d' % self._dataset_test_size)

        # 根據模式名字建立模型,預設使用impersonator模式進行訓練,self._opt.model= impersonator_trainer
        self._model = ModelsFactory.get_by_name(self._opt.model, self._opt)
        # tensorflow的可視化
        self._tb_visualizer = TBVisualizer(self._opt)

        # 進行訓練
        self._train()

    def _train(self):
        # 計算總的疊代步數
        self._total_steps = self._opt.load_epoch * self._dataset_train_size
        # 計算每個epoch疊代的次數
        self._iters_per_epoch = self._dataset_train_size / self._opt.batch_size

        self._last_display_time = None
        self._last_save_latest_time = None
        self._last_print_time = time.time()

        # 循環進行訓練
        for i_epoch in range(self._opt.load_epoch + 1, self._opt.nepochs_no_decay + self._opt.nepochs_decay + 1):
            epoch_start_time = time.time()
            # train epoch
            self._train_epoch(i_epoch)

            # save model,每個epoch訓練完,儲存一次模型
            print('saving the model at the end of epoch %d, iters %d' % (i_epoch, self._total_steps))
            self._model.save(i_epoch)

            # print epoch info,列印相關的資訊,如訓練了多少epoch,消耗了多少時間等等
            time_epoch = time.time() - epoch_start_time
            print('End of epoch %d / %d \t Time Taken: %d sec (%d min or %d h)' %
                  (i_epoch, self._opt.nepochs_no_decay + self._opt.nepochs_decay, time_epoch,
                   time_epoch / 60, time_epoch / 3600))

            # update learning rate,如果需要更新學習率,則更新學習率
            if i_epoch > self._opt.nepochs_no_decay:
                self._model.update_learning_rate()


    def _train_epoch(self, i_epoch):
        """
        訓練一個epoch的細節
        :param i_epoch:
        :return:
        """
        epoch_iter = 0
        # 模型設定為訓練模式
        self._model.set_train()
        for i_train_batch, train_batch in enumerate(self._dataset_train):
            # 記錄疊代的開始時間
            iter_start_time = time.time()

            # display flags
            do_visuals = self._last_display_time is None or time.time() - self._last_display_time > self._opt.display_freq_s
            do_print_terminal = time.time() - self._last_print_time > self._opt.print_freq_s or do_visuals

            # train model,設定模型輸入的
            self._model.set_input(train_batch)
            trainable = ((i_train_batch+1) % self._opt.train_G_every_n_iterations == 0) or do_visuals
            # 對參數進行進行優化,也就是反向傳播,do_visuals表示指定該次是否進行可視化
            self._model.optimize_parameters(keep_data_for_visuals=do_visuals, trainable=trainable)

            # update epoch info,更新步數
            self._total_steps += self._opt.batch_size
            epoch_iter += self._opt.batch_size

            # display terminal,終端列印訓練資訊
            if do_print_terminal:

                self._display_terminal(iter_start_time, i_epoch, i_train_batch, do_visuals)
                self._last_print_time = time.time()

            # display visualizer,可視化顯示
            if do_visuals:
                self._display_visualizer_train(self._total_steps)
                self._display_visualizer_val(i_epoch, self._total_steps)
                self._last_display_time = time.time()

            # save model
            if self._last_save_latest_time is None or time.time() - self._last_save_latest_time > self._opt.save_latest_freq_s:
                print('saving the latest model (epoch %d, total_steps %d)' % (i_epoch, self._total_steps))
                self._model.save(i_epoch)
                self._last_save_latest_time = time.time()

    def _display_terminal(self, iter_start_time, i_epoch, i_train_batch, visuals_flag):
        """
        終端列印訓練想過資訊,并且進行可視化
        """
        errors = self._model.get_current_errors()
        t = (time.time() - iter_start_time) / self._opt.batch_size
        self._tb_visualizer.print_current_train_errors(i_epoch, i_train_batch, self._iters_per_epoch, errors, t, visuals_flag)

    def _display_visualizer_train(self, total_steps):
        """
        訓練可視化
        """
        self._tb_visualizer.display_current_results(self._model.get_current_visuals(), total_steps, is_train=True)
        self._tb_visualizer.plot_scalars(self._model.get_current_errors(), total_steps, is_train=True)
        self._tb_visualizer.plot_scalars(self._model.get_current_scalars(), total_steps, is_train=True)

    def _display_visualizer_val(self, i_epoch, total_steps):
        """
        評估可視化
        """
        val_start_time = time.time()

        # set model to eval,設定模型為評估模式
        self._model.set_eval()

        # evaluate self._opt.num_iters_validate epochs
        val_errors = OrderedDict()

        # 疊代擷取資料,進行評估
        for i_val_batch, val_batch in enumerate(self._dataset_test):
            if i_val_batch == self._opt.num_iters_validate:
                break

            # evaluate model
            self._model.set_input(val_batch)
            self._model.forward(keep_data_for_visuals=(i_val_batch == 0))
            errors = self._model.get_current_errors()

            # store current batch errors
            for k, v in errors.items():
                if k in val_errors:
                    val_errors[k] += v
                else:
                    val_errors[k] = v

        # normalize errors
        for k in val_errors:
            val_errors[k] /= self._opt.num_iters_validate

        # visualize
        t = (time.time() - val_start_time)
        self._tb_visualizer.print_current_validate_errors(i_epoch, val_errors, t)
        self._tb_visualizer.plot_scalars(val_errors, total_steps, is_train=False)
        self._tb_visualizer.display_current_results(self._model.get_current_visuals(), total_steps, is_train=False)

        # set model back to train
        self._model.set_train()


if __name__ == "__main__":
    Train()

           

還是特别簡單,基本都是這個套路:

1.加載訓練測試資料集疊代器

2.建構網絡模型

3.疊代訓練

4.模型評估儲存

好了,總體的結構就簡單的介紹到這裡,下小結為大家開始講解代碼的每一個細節。

風格遷移1-06:Liquid Warping GAN(Impersonator)-源碼無死角解析(1)-訓練代碼總覽

繼續閱讀