需要启动两次训练以加载检查点(它有效,但为什么呢?)

Need to start the training twice to load checkpoint (It worked, but why?)

我正在修改 deeplab 网络。我在 mobilenet-v3 特征提取器的第一层添加了一个节点,它重用了现有的变量。由于不需要额外的参数,理论上我可以加载旧的检查点。

我看不懂的情况来了:

当我在一个新的空文件夹中开始训练时,像这样加载检查点:

python "${WORK_DIR}"/train.py \
  #--didn't change other parameters \
  --train_logdir="${EXP_DIR}/train" \
  --fine_tune_batch_norm=true \
  --tf_initial_checkpoint="init/deeplab/model.ckpt"

我得到一个错误:

ValueError: Total size of new array must be unchanged for MobilenetV3/Conv/BatchNorm/gamma lh_shape: [(16,)], rh_shape: [(480,)]

但是,如果我在一个新的空文件夹中开始训练,请不要加载任何检查点:

python "${WORK_DIR}"/train.py \
  #--didn't change other parameters \
  --train_logdir="${EXP_DIR}/train" \
  --fine_tune_batch_norm=false \
  #--tf_initial_checkpoint="init/deeplab/model.ckpt" #i.e. no checkpoint

可以顺利开始训练了

让我更困惑的是,如果在同一个文件夹中(这是 train_logdir 没有加载检查点),我尝试用检查点开始训练,我也可以无误地开始训练:

# same code as the first code block
python "${WORK_DIR}"/train.py \
  #--didn't change other parameters \
  --train_logdir="${EXP_DIR}/train" \
  --fine_tune_batch_norm=true \
  --tf_initial_checkpoint="init/deeplab/model.ckpt"

怎么会这样? --train_logdir 可以以某种方式存储上次训练的批量归一化参数的形状?

我在 train_utils.py 中找到了以下代码:(第 203 行)

    if tf.train.latest_checkpoint(train_logdir):
        tf.logging.info('Ignoring initialization; other checkpoint exists')
        return None

    tf.logging.info('Initializing model from path: %s', tf_initial_checkpoint)

它将尝试从 train_logdir 中的现有检查点加载,然后再尝试加载“tf_initial_checkpoint”标志中的给定检查点。

所以当我第二次开始训练时,网络加载了第一次训练的变量,这与我预训练的检查点无关。

我的实验还表明,像我这样开始两次训练并没有像我正确加载预训练检查点时那样得到好的结果。