以下連結是個人關于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.模型評估儲存
好了,總體的結構就簡單的介紹到這裡,下小結為大家開始講解代碼的每一個細節。