Дублирующее имя узла в графе: 'conv2d_0/kernel/Adam'
Я просто сохранил модель, с помощью этого кода:
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
И тогда я получаю несколько файлов:
MyModle__Stop_288.index
MyModle__Stop_288.meta
MyModle__Stop_288.data-00000-оф-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)
И будет возникать эта ошибка:
ValueError: Дубликат имени узла в графе: 'conv2d_0/kernel/Adam'
Как это можно исправить?
4 ответа
У меня была аналогичная ошибка:
ValueError: Duplicate node name in graph: 'packed/0'
Я думаю, что эта ошибка связана с другой версией Tensorfow, чем код, который был запрограммирован вами. Попробуйте понизить версию tf при импорте пакета:
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
это тривиальное решение смогло устранить проблему
Причина в том, что 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)
Примечание: неиспользуемые узлы не будут выполняться и, следовательно, не повлияют на время обучения.
Я также столкнулся с этой проблемой и решил ее, изменив код в моей виртуальной среде: venv\Lib\site-packages\tensorflow_core\python\framework\ops.py Там есть метод под названием "unique_name". Этот метод иногда допускает ошибки при создании имен. Особенно, когда он использует свой name_stack. Чтобы исправить это, я изменил метод и добавил небольшой метод splitAndSet, который решил проблему:
def splitAndSet(self, name, iInt):
#=================== Method splitAndSet =====================
nameList = re.split("/", name)
for nInt in range(len(nameList)):
nameList[nInt] = "%s_%d" % (nameList[nInt], iInt)
return "/".join(nameList)
#=============== END Method splitAndSet =====================
def unique_name(self, name, mark_as_used=True):
if self._name_stack:
name = self._name_stack + "/" + name
# For the sake of checking for names in use, we treat names as case
# insensitive (e.g. foo = Foo).
name = self.splitAndSet(name, 0)
name_key = self.splitAndSet(name.lower(), 0)
i = self._names_in_use.get(name_key, 0)
# Increment the number for "name_key".
if mark_as_used:
self._names_in_use[name_key] = i + 1
if i > 0:
base_name_key = name_key
# Make sure the composed name key is not already used.
while name_key in self._names_in_use:
#name_key = "%s_%d" % (base_name_key, i)
name_key = self.splitAndSet(base_name_key, i)
i += 1
# Mark the composed name_key as used in case someone wants
# to call unique_name("name_1").
if mark_as_used:
self._names_in_use[name_key] = 1
# Return the new name with the original capitalization of the given name.
#name = "%s_%d" % (name, i - 1)
name = self.splitAndSet(name, i - 1)
return name
Чтобы дать некоторый контекст того, как я получил эту ошибку, я пытался преобразовать веса даркнета в модель TensorFlow, следуя этому руководству. Я получил эту ошибку из-за следующего фрагмента кода:
flags.DEFINE_string('output', './checkpoints/yolov4-416', 'path to output')
Я указал неправильный путь в приведенном выше коде, мне потребовалось много времени, чтобы понять это после того, как я попробовал так много решений Stackoverflow. Это так тривиально, но я надеюсь, что это поможет кому-то застрять на этой ошибке.