图中的重复节点名称:'conv2d_0/kernel/Adam'

hei*_*hei 6 python tensorflow pre-trained-model

我刚刚通过该代码保存了一个模型:

def train():    
with tf.Session() as sess:
    saver = tf.train.Saver(max_to_keep = 2)
    Loss = myYoloLoss([Scale1,Scale2,Scale3],[Y1, Y2 ,Y3])
    opt = tf.train.AdamOptimizer(2e-4).minimize(Loss)
    init = tf.global_variables_initializer()
    sess.run(init)
    imageNum = 0
    Num = 0
    while(1):
        #get batchInput
        batchImg,batchScale1,batchScale2,batchScale3 = getBatchImage(batchSize = BATCHSIZE)
        for epoch in range(75):
            _ , epochloss = sess.run([opt,Loss],feed_dict={X:batchImg,Y1:batchScale1,Y2:batchScale2,Y3:batchScale3})
            if(epoch%15 == 0):
                print(epochloss)
        imageNum = imageNum + BATCHSIZE
        Num = Num + 1
        if(Num%4 == 0):
            saver.save(sess,MODELPATH + 'MyModle__' + str(imageNum))            
        if(os.path.exists(STOPFLAGPATH)):
            saver.save(sess,MODELPATH + 'MyModle__Stop_' + str(imageNum))   
            print('checked stopfile,stop')
            break
return 0
Run Code Online (Sandbox Code Playgroud)

然后我得到一些文件:

MyModle__Stop_288.index
MyModle__Stop_288.meta
MyModle__Stop_288.data-00000-of-00001
检查点

然后我继续训练这个模型:

def reTrain():
with tf.Session() as sess:
    loder = tf.train.import_meta_graph('E:/MyYoloModel/MyModle__Stop_288.meta')
    loder.restore(sess, tf.train.latest_checkpoint('E:/MyYoloModel/'))
    graph = tf.get_default_graph()
    X = graph.get_tensor_by_name("X:0")
    Y1 = graph.get_tensor_by_name("Y1:0")
    Y2 = graph.get_tensor_by_name("Y2:0")
    Y3 = graph.get_tensor_by_name("Y3:0")
    Scale1 = graph.get_tensor_by_name("Scale1:0")
    Scale2 = graph.get_tensor_by_name("Scale2:0")
    Scale3 = graph.get_tensor_by_name("Scale3:0")  
    Loss = myYoloLoss([Scale1,Scale2,Scale3],[Y1, Y2 ,Y3])
    #error code 
    opt = tf.train.AdamOptimizer(2e-4).minimize(Loss)
    init = tf.global_variables_initializer()
    sess.run(init)
    batchImg,batchScale1,batchScale2,batchScale3 = getBatchImage(batchSize = BATCHSIZE)
    for epoch in range(10):
        _ ,epochloss = sess.run([opt,Loss],feed_dict={X:batchImg,Y1:batchScale1,Y2:batchScale2,Y3:batchScale3})
        print(epochloss)
Run Code Online (Sandbox Code Playgroud)

并且会出现这个错误:ValueError: Duplicate node name in graph: 'conv2d_0/kernel/Adam'
How can fix it?

Kev*_*vin 0

原因是 AdamOptimizer 在您的图中创建了额外的变量和操作。当您存储模型时,这些操作将在您恢复模型时与图形一起存储和加载。如果你跑

tf.Graph.get_operations(图)

您可以看到随模型加载的操作列表。您将看到具有/Adam 或 train/Adam init 的操作。当您尝试查找调整或重用模型时,新的 AdamOptimizer 会尝试再次创建这些操作,因此会引发“重复节点名称”错误。解决此问题的一种方法是为新的 AdampOptimzer 命名。

opt = tf.train.AdamOptimizer(2e-4m name='MyNewAdam').minimize(损失)

然而,我们还没有完成。由于您想重用权重,因此无法初始化变量。但是,如果您在运行训练时遇到未初始化参数的错误,这是由于新的 AdamOptimizer 变量尚未初始化而引发的。为了解决这个问题,您需要通过以下方式初始化这些新变量:

uninitialized_vars = []
for var in tf.all_variables():
    try:
        sess.run(var)
    except tf.errors.FailedPreconditionError:
        uninitialized_vars.append(var)

tf.initialize_variables(uninitialized_vars)
Run Code Online (Sandbox Code Playgroud)

注意:未使用的节点将不会被执行,因此它们不会影响训练时间。