TensorFlow中Seq2Seq模型投影层修改:无需重初始化权重更新单元数
调整NMT投影层单元数且保留原有权重的实现方案
嘿,我明白你想修改NMT模型的投影层单元数量,同时不想重新初始化所有权重——这确实是个很实用的需求,毕竟从头训练模型太耗费时间和资源了。结合你给出的解码器代码片段,我来给你一步步拆解具体的实现方法:
第一步:提取现有投影层的权重
首先你得先拿到当前已经训练过的投影层权重。假设你之前是用tf.layers.Dense定义的投影层,比如:projection_layer = tf.layers.Dense(target_vocab_size, use_bias=True)那你可以通过
projection_layer.kernel获取权重矩阵,projection_layer.bias获取偏置向量,这两个就是你已经训练好的参数。第二步:创建新投影层并迁移权重
根据你要调整的方向(扩大或缩小单元数),分两种情况处理:- 如果是扩大单元数量:把原有权重复制到新权重的对应部分,新增的单元权重可以用随机初始化或者其他策略补充
# 假设旧单元数是old_vocab_size,新单元数是new_vocab_size new_projection_layer = tf.layers.Dense(new_vocab_size, use_bias=True) # 手动迁移权重,需要注意变量作用域 with tf.variable_scope('', reuse=False): # 获取新投影层的权重变量 new_kernel = tf.get_variable('projection_layer/kernel', shape=(decoder_cell.output_size, new_vocab_size)) new_bias = tf.get_variable('projection_layer/bias', shape=(new_vocab_size,)) # 将旧权重赋值给新权重的前old_vocab_size列/元素 assign_kernel_op = tf.assign(new_kernel[:, :old_vocab_size], projection_layer.kernel) assign_bias_op = tf.assign(new_bias[:old_vocab_size], projection_layer.bias) # 在会话中执行赋值操作 with tf.Session() as sess: sess.run([assign_kernel_op, assign_bias_op]) - 如果是缩小单元数量:直接截取原有权重的对应部分即可
new_projection_layer = tf.layers.Dense(new_vocab_size, use_bias=True) with tf.variable_scope('', reuse=False): new_kernel = tf.get_variable('projection_layer/kernel', shape=(decoder_cell.output_size, new_vocab_size)) new_bias = tf.get_variable('projection_layer/bias', shape=(new_vocab_size,)) # 截取旧权重的前new_vocab_size列/元素赋值给新权重 assign_kernel_op = tf.assign(new_kernel, projection_layer.kernel[:, :new_vocab_size]) assign_bias_op = tf.assign(new_bias, projection_layer.bias[:new_vocab_size]) with tf.Session() as sess: sess.run([assign_kernel_op, assign_bias_op])
- 如果是扩大单元数量:把原有权重复制到新权重的对应部分,新增的单元权重可以用随机初始化或者其他策略补充
第三步:更新解码器的投影层配置
最后把你原来解码器里的投影层替换成新创建的new_projection_layer就行。比如在BasicDecoder的参数中指定output_layer:train_decoder = tf.contrib.seq2seq.BasicDecoder( decoder_cell, train_helper, decoder_initial_state, output_layer=new_projection_layer # 替换成新的投影层 )几个需要注意的点
- 一定要注意变量作用域的设置,避免出现变量名冲突的问题
- 如果你的投影层是自定义的变量(不是用
tf.layers.Dense封装的),直接找到对应的权重变量进行迁移操作就可以 - 权重迁移完成后,后续训练就可以基于新的投影层继续进行,不需要重新初始化所有参数
内容的提问来源于stack exchange,提问作者Noah
相关产品推荐
相关产品推荐

