Pytorch: محسن load_state_dict () مشكلة؟

تم إنشاؤها على ٢٢ سبتمبر ٢٠١٧  ·  23تعليقات  ·  مصدر: pytorch/pytorch

مرحبًا ، لقد واجهت هذا الخطأ:

    optimizer.step()
    exp_avg.mul_(beta1).add_(1 - beta1, grad)

TypeError: add_ received an invalid combination of arguments - got (float, torch.cuda.FloatTensor), but expected one of:
 * (float value)
 * (torch.FloatTensor other)
 * (torch.SparseFloatTensor other)
 * (float value, torch.FloatTensor other)
      didn't match because some of the arguments have invalid types: (float, torch.cuda.FloatTensor)
 * (float value, torch.SparseFloatTensor other)
      didn't match because some of the arguments have invalid types: (float, torch.cuda.FloatTensor)

الهيكل العظمي للشفرة هو مثل:

model = Model()
model.load_state_dict(checkpoint['model'])
model.cuda()

optimizer = optim.Adam()
optimizer.load_state_dict(checkpoint['optimizer'])

...
#  In train loop
for epoch in range(...):
  ...
  optimizer.step()
     -> BUG <-

يبدو أن param_groups تم تحميله هو torch.cuda.FloatTensor ، ولقد حاولت إيجاد حل بديل
انقل optmizer.param_groups إلى cpu ، لكن لا يزال به نفس الخطأ.

awaiting response (this tag is deprecated) needs reproduction

التعليق الأكثر فائدة

apaszke آه ، يا سيئة. لقد نسيت تحديث السطر حيث يتم إعادة إنشاء المُحسِّن. لكن بخلاف ذلك ، يجب أن يقوم ما يلي بالمهمة ، أليس كذلك؟

model = Model()
model.load_state_dict(checkpoint['model'])
model.cuda()
optimizer = optim.Adam(model.parameters())
optimizer.load_state_dict(checkpoint['optimizer'])
for state in optimizer.state.values():
    for k, v in state.items():
        if isinstance(v, torch.Tensor):
            state[k] = v.cuda()

ال 23 كومينتر

هل يمكنك توفير نص كامل لإعادة إظهار المشكلة؟

ربما يمكنك أن تجرب مثل هذا ،
optimizer.step ()
exp_avg.mul_ (beta1) .add_ (1 - beta1، grad.cpu ())

آسف ، فاتني الرد على البريد الإلكتروني.

أخشى أنني غير قادر على توفير الناسخ الآن. إنه عمل أقوم به لمشروع OpenNMT-py : https : //github.com/OpenNMT/OpenNMT-py ، محاولًا استخدام lr_scheduler لإجراء تحديث lr. وقمت بتشكيل هذه المشكلة عند اختبار حالة resume a suspended training . لذلك قمت بإخراج الهيكل العظمي للشفرة في الاعتبار حول هذه المشكلة أعلاه.

لقد جربت عدة طرق ، بما في ذلك الحيل مثل ما يقترحهhefeicyp ، لكنه لا يزال يحدث.

وفقًا لتحليلي ، فذلك لأن التدريب السابق تم إجراؤه على وحدة معالجة الرسومات ، لذلك عند حفظ optimizer.state_dict ، تكون الحالات المخزنة (الموترات) من إصدار cuda . أثناء الاستئناف ، عندما نقوم بتحميل المُحسِّن المحفوظ ، يقوم load_state_dict() بتحميل إصدار cuda إلى وحدة المعالجة المركزية (يمكن نقل النموذج ( nn.Module ) إلى وحدة معالجة الرسومات بسهولة ، ولكن torch.optimizer يبدو يفتقر إلى هذه القدرة؟) ، لذلك تظهر هذه المشكلة.

حاول نقل حالة المحسن إلى ذاكرة وحدة معالجة الرسومات يدويًا بعد تحميلها من نقطة التفتيش.

optimizer = optim.Adam()
optimizer.load_state_dict(checkpoint['optimizer'])
for state in optimizer.state.values():
    for k, v in state.items():
        if isinstance(v, torch.Tensor):
            state[k] = v.cuda()

أوافق على أن وجود طريقة optimizer.cuda() لهذه العملية سيكون أمرًا رائعًا.

dogancan ، شكرا. تم تعليق عملي بسبب مشاكل أخرى ، عند استئنافه ، سأحاول طريقتك.

أخشى أن حل dogancan لن ينجح. سيؤدي ذلك إلى إزالة الخطأ ، لكن المحسن الخاص بك لن يقوم بتدريب النموذج بعد الآن. يجب إعادة إنشاء أدوات تحسين بعد إرسال الوحدات النمطية إلى نوع أو جهاز مختلف ، ويمكنك استخدام load_state_dict لاستعادة الحالة من نسخة سابقة. هذا لا يعمل حاليًا ، ولكن يجب علينا إصلاحه (عن طريق النسخ من البيانات من الحالة ، بدلاً من استخدام الموترات مباشرةً - وهذا يسمح بالتحديثات عبر الأجهزة أو عبر النوع).

apaszke ، نعم ، طريقتك هي ما أستخدمه حاليًا ، وهي تعمل. لكنني سأنتظر حتى المنبع لإصلاح هذه المشكلة بالرغم من ذلك. شكرا لأعمالك العظيمة!

apaszke آه ، يا سيئة. لقد نسيت تحديث السطر حيث يتم إعادة إنشاء المُحسِّن. لكن بخلاف ذلك ، يجب أن يقوم ما يلي بالمهمة ، أليس كذلك؟

model = Model()
model.load_state_dict(checkpoint['model'])
model.cuda()
optimizer = optim.Adam(model.parameters())
optimizer.load_state_dict(checkpoint['optimizer'])
for state in optimizer.state.values():
    for k, v in state.items():
        if isinstance(v, torch.Tensor):
            state[k] = v.cuda()

اه صحيح. يجب أن يعمل 😊

باستثناء أنه يجب عليك استخدام torch.is_tensor(v) بدلاً من isinstance(v, torch.Tensor)

لدي مشكلة مماثلة. عندما أقوم بحفظ حالة المُحسِّن من وحدة معالجة الرسومات بخلاف GPU 0 ثم تحميل الحالة ، لا يزال يتم تحميل كل شيء إلى GPU 0. تحديد map_location في torch.load() لم ينجح أيضًا. لكن حل المشكلة .

مرحبًا يا شباب ، لدي مشكلة مشابهة جدًا لتلك الموجودة في هذا الموضوع ، إليك الكود الخاص بي:

model = inceptionresnetv2(num_classes=config['tr_classes'])
model = torch.nn.DataParallel(model).cuda()
model.load_state_dict(checkpoint['md_state_dict'])
optimizer = torch.optim.Adam(model.parameters(), lr=config['tr_lr'], weight_decay=config['tr_weightdecay'])
optimizer.load_state_dict(checkpoint['md_optimizer'])
for state in optimizer.state.values():
    for k, v in state.items():
        if torch.is_tensor(v):
            state[k] = v.cuda()

وبعد ذلك بمجرد الاستئناف ، حصلت على KeyErrors في أداة التحسين الخاصة بي:

---> 40         optimizer.step()
     41 
     42         config['am_batch_time'].update(time.time() - end)
~/.conda/envs/env_pytorch/lib/python3.5/site-packages/torch/optim/adam.py in step(self, closure)
     44                     continue
     45                 grad = p.grad.data
---> 46                 state = self.state[p]
     47 
     48                 # State initialization
KeyError: Parameter containing:
(0 ,0 ,.,.) = 
 -1.6336e-01 -5.6482e-01 -4.2228e-02
...
[torch.cuda.FloatTensor of size 32x3x3x3 (GPU 0)]

هل تعرفون يا رفاق كيفية إصلاح هذه المشكلة؟ راجع للشغل ، لدي 8 وحدات معالجة رسومات مستخدمة ، وأظن ما إذا كانت هذه المشكلة بسبب ذلك؟

@ CodArs-van هل تمكنت من حل مشكلتك باستخدام وحدات معالجة رسومات متعددة؟

rafaelvalle شكرا على السؤال. نعم ، أنا قادر على ذلك ، تبين أن المشكلة هي لأنني استخدمت إصدارًا مبكرًا من PyTorch ، بعد أن قمت بتحديث الإصدار ، يعمل مثل السحر!

مجرد تعليق ، سبب هذه المشكلة

    def load_state_dict(self, state_dict):
        ...
        # deepcopy, to be consistent with module API
        state_dict = deepcopy(state_dict)
       ...  

deepcopy يجعل كل موتر الحالة يتم نقله إلى GPU0 ,
لذلك من خلال نقل حالة مُحسِّن إلى وحدة معالجة رسومات محددة ، سيؤدي ذلك إلى حل هذه المشكلة.

مرحبًا lzcn ، كيف تعرف موقع GPU المحدد

هل ستكون الميزة التي تستخدم فيها جميع مكالمات torch.save () دائمًا إصدار وحدة المعالجة المركزية التي يتم إنشاؤها تلقائيًا أمرًا ممكنًا؟
وبعد ذلك ، عند الاستئناف ، ستستفيد torch.load () من الجهاز "الحالي" المستخدم (أو أي استراتيجية أفضل).
في الوقت الحالي ، يبدو أننا بحاجة إلى الكثير من كود boilerplater لضمان أن الحفظ والتحميل عبارة عن اتساق عبر الأجهزة للطرازات / المُحسِّن / المجدول / إلخ.

لقد واجهت مشكلة مماثلة ، أعدت إنشاء محسن Adam بدون optimizer.cuda () بعد إعادة تحميل النموذج ، model.cuda () و DataParallel (النموذج) وفقًا لحلdogancan .

شكرا ، انها تعمل!

apaszke آه ، يا سيئة. لقد نسيت تحديث السطر حيث يتم إعادة إنشاء المُحسِّن. لكن بخلاف ذلك ، يجب أن يقوم ما يلي بالمهمة ، أليس كذلك؟

model = Model()
model.load_state_dict(checkpoint['model'])
model.cuda()
optimizer = optim.Adam(model.parameters())
optimizer.load_state_dict(checkpoint['optimizer'])
for state in optimizer.state.values():
    for k, v in state.items():
        if isinstance(v, torch.Tensor):
            state[k] = v.cuda()

تضمين التغريدة
مرحبًا ، كما تقول: في كل مرة ننقل فيها نموذجًا إلى جهاز آخر ، يجب أن نبني مُحسِّنًا ، ولكن إذا نقلنا النموذج إلى جهاز آخر ورجعنا إلى الوراء ، فهل يجب أن نبني المُحسِّن مرة أخرى؟
هنا رمز مثال:

model = Model()
model.cuda()
optimizer = optim.Adam(model.parameters())

for d, gt in trn_dataloader:
    # train
    ... 
    optimizer.step()
    model.cpu() # move to cpu
    # eval or do other things
    ...
    model.cuda()  # but finnally, move back

هل يعمل المحسن بالشكل المتوقع؟

أيضًا ، إذا كنت تقوم بـ model.to(model.device) ، فهل يجب علينا إعادة إنشاء المحسن؟

apaszke آه ، يا سيئة. لقد نسيت تحديث السطر حيث يتم إعادة إنشاء المُحسِّن. لكن بخلاف ذلك ، يجب أن يقوم ما يلي بالمهمة ، أليس كذلك؟

model = Model()
model.load_state_dict(checkpoint['model'])
model.cuda()
optimizer = optim.Adam(model.parameters())
optimizer.load_state_dict(checkpoint['optimizer'])
for state in optimizer.state.values():
    for k, v in state.items():
        if isinstance(v, torch.Tensor):
            state[k] = v.cuda()

apaszke هل توجد مشكلة إذا قمت بتبديل الترتيب إلى شيء مثل هذا؟

"" الثعبان
النموذج = النموذج ()
model.to ('cuda')
محسن = optim.Adam (model.parameters ())
optimizer.load_state_dict (نقطة تفتيش ['محسن'])
للحالة في optimizer.state.values ​​():
لـ k ، v في state.items ():
if isinstance (v، torch.Tensor):
الدولة [k] = v.cuda ()
model.load_state_dict (نقطة تفتيش ['model'])

بمعنى نقل النموذج إلى "cuda" ولكن فقط تحميل إملاء الحالة الخاص به من نقطة التفتيش بعد تحميل إملاء حالة المحسن أولاً؟

يمكن استنتاج المشكلة أن حالة المحسن سيتم تحميلها على الجهاز مثل النموذج. يجب عليك تحميل النموذج إلى GPU في البداية ، ثم تحميل حالة المحسن. بحيث يتم تحميل كل من النموذج وحالة المحسن في وحدة معالجة الرسومات.

بدلاً من نقل المحسن إلى cuda بعد تحميله في وحدة المعالجة المركزية ، يمكنك تحميل نقطة التفتيش مباشرة في cuda:

model.to(device)

ckpt = torch.load(<model_path>, map_location=device)

model.load_state_dict(ckpt['state_dict'])
optimizer.load_state_dict(ckpt['optimizer'])
scheduler.load_state_dict(ckpt['scheduler'])

del ckpt
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات