参考:https://zhuanlan.zhihu.com/p/53814653
问题描述:网上搜到的csdn tensorflow的finetune的文章都不太容易令人理解,看了好几篇都无法在tensorflow下实现finetune;后来在bing上搜到了引用这篇参考网站的github上tensorflow finetune实现,非常的简洁易懂。
该篇文章在tensorflow下实现finetune的主要就几个步骤,准备数据,在原来的图(Graph)上修改构建自己的图(比如说改最后一层分类层,只训练某些层),然后将保存模型的所需要的张量(tensor)的值恢复到我自己构建的图中。主要是将保存的分割模型UNet由六分类改成二分类。
代码块1
segment_a4c_a2c_a3c_plax_psax.py中的部分代码(这个不用细看,这里只不过是为了在代码块2中finetune时引用此代码块中的Unet类来构造神经网络UNet,在第二个代码块中直接使用model0=Unet(24,1e-12,1e-4,2,maxout=False).unet(x_train,24,keep_prob = 0.5, reuse = True)就能直接创建一个和保存模型一样构造的UNet。)
(创建Unet类的好处是可以直接创建新的Unet,各层名字与之前保存的Unet模型是一致的,这样修改或添加层,或冻结层比较方便,直接按照Unet类里的名字就可以了)
#Unet类中的self.opt = tf.train.AdamOptimizer(self.learning_rate).minimize(self.loss)被注释了;如果不注释,新创建的Unet对象的优化器就不会改变,优化器不改变就没法使用tf.train.AdamOptimizer(1e-4).minimize(loss,var_list=output_vars)实现冻结层效果
class Unet(object):
def __init__(self, mean, weight_decay, learning_rate, label_dim, maxout = False):
self.x_train = tf.placeholder(tf.float32, [None, 384, 384, 1])
self.y_train = tf.placeholder(tf.float32, [None, 384, 384, label_dim])
self.x_test = tf.placeholder(tf.float32, [None, 384, 384, 1])
self.y_test = tf.placeholder(tf.float32, [None, 384, 384, label_dim])
self.label_dim = label_dim
self.weight_decay = weight_decay
self.learning_rate = learning_rate
self.maxout = maxout
self.output = self.unet(self.x_train, mean)
self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = self.output, labels = self.y_train))
# self.opt = tf.train.AdamOptimizer(self.learning_rate).minimize(self.loss)
self.pred = self.unet(self.x_test, mean, keep_prob = 1.0, reuse = True)
self.loss_summary = t