পাইটর্চে প্রশিক্ষিত মডেলটি সংরক্ষণের সর্বোত্তম উপায়?


192

আমি পাইটর্চে প্রশিক্ষিত একটি মডেল সংরক্ষণের বিকল্প উপায়গুলি সন্ধান করছিলাম। এখন পর্যন্ত আমি দুটি বিকল্প খুঁজে পেয়েছি।

  1. torch.save () একটি মডেল এবং সংরক্ষণ করতে torch.load () একটি মডেল লোড করা হয়নি।
  2. মডেল.স্টেট_ডিক্ট () একটি প্রশিক্ষিত মডেল এবং মডেল লোড- স্টেট_ডিক্ট () সংরক্ষণ করুন load

আমি এই আলোচনায় এসে পৌঁছেছি যেখানে 1 পদ্ধতির উপরে 2 পদ্ধতির পরামর্শ দেওয়া হচ্ছে।

আমার প্রশ্ন, দ্বিতীয় পদ্ধতির পছন্দ কেন? এটি কি কেবলমাত্র টর্চ.এনএন মডিউলগুলির মধ্যে দুটি ফাংশন রয়েছে এবং আমরা সেগুলি ব্যবহার করতে উত্সাহিত করেছি?


2
আমি মনে করি এটি কারণ কারণ টর্চ.সেজ () সমস্ত মধ্যবর্তী ভেরিয়েবলগুলি সংরক্ষণ করে, যেমন পিছনের প্রচারের জন্য মধ্যবর্তী আউটপুটগুলি। তবে আপনাকে কেবলমাত্র মডেল প্যারামিটারগুলি যেমন ওজন / পক্ষপাত ইত্যাদি সংরক্ষণ করতে হবে কখনও কখনও পূর্ববর্তীটি পরবর্তীকালের চেয়ে অনেক বড় হতে পারে।
দাউই ইয়াং

2
আমি পরীক্ষা করেছি torch.save(model, f)এবং torch.save(model.state_dict(), f)। সংরক্ষিত ফাইলগুলির আকার একই থাকে। আমি এখন বিভ্রান্ত এছাড়াও, আমি মডেল.স্টেট_ডিক্ট () অত্যন্ত আস্তে সংরক্ষণ করতে আচার ব্যবহার করে দেখতে পেলাম। আমি মনে করি torch.save(model.state_dict(), f)যেহেতু আপনি মডেলটি তৈরির বিষয়টি পরিচালনা করেন এবং মশাল মডেল ওজনের বোঝা পরিচালনা করে তাই সর্বোত্তম উপায় হ'ল সম্ভাব্য সমস্যাগুলি দূর করে। তথ্যসূত্র: আলোচনা. pytorch.org/t/saving-torch-models/838/4
দাওয়ে ইয়াং

পাইটর্চের মতো মনে হচ্ছে এটি তাদের টিউটোরিয়াল বিভাগে আরও কিছুটা স্পষ্টভাবে সম্বোধন করেছে —এখানে প্রচুর ভাল তথ্য রয়েছে যা এখানে উত্তরগুলিতে তালিকাভুক্ত নয়, একসাথে একাধিক মডেল সংরক্ষণ এবং উষ্ণ প্রারম্ভিক মডেল সহ।
whlteXbread

ব্যবহারে ভুল কী pickle?
চার্লি পার্কার 18

1
@ চর্লিপার্কার টর্চ.স্যাভ আচারের উপর ভিত্তি করে। নীচে উপরে সংযুক্ত টিউটোরিয়ালটি থেকে নীচে: "[টর্চ.স্যাভ] পাইথনের আচার মডিউলটি ব্যবহার করে পুরো মডিউলটি সংরক্ষণ করবে this এই পদ্ধতির অসুবিধাটি হ'ল সিরিয়ালযুক্ত ডেটা নির্দিষ্ট ক্লাসগুলির সাথে আবদ্ধ এবং যখন মডেলটি ব্যবহৃত হয় তখন সঠিক ডিরেক্টরি কাঠামো ব্যবহৃত হয় সংরক্ষণ করা হয়েছে।এর কারণ হ'ল আচার মডেল শ্রেণিটি নিজেই সংরক্ষণ করে না। বরং এটি ক্লাসযুক্ত ফাইলের একটি পথ সংরক্ষণ করে, যা লোড সময় ব্যবহৃত হয় this এই কারণে আপনার কোডটি বিভিন্ন উপায়ে বিভক্ত হতে পারে যখন অন্যান্য প্রকল্পে বা রিফ্যাক্টরের পরে ব্যবহৃত হয়।
ডেভিড মিলার

উত্তর:


214

আমি এই পৃষ্ঠাটি তাদের গিথুব রেপোতে পেয়েছি , আমি কেবল এখানে লিখিত সামগ্রীটি পেস্ট করব।


একটি মডেল সংরক্ষণের জন্য প্রস্তাবিত পদ্ধতির

একটি মডেলকে সিরিয়ালাইজ এবং পুনরুদ্ধার করার জন্য দুটি প্রধান পন্থা রয়েছে।

প্রথম (প্রস্তাবিত) কেবলমাত্র মডেল প্যারামিটারগুলি সঞ্চয় করে এবং লোড করে:

torch.save(the_model.state_dict(), PATH)

তাহলে পরে:

the_model = TheModelClass(*args, **kwargs)
the_model.load_state_dict(torch.load(PATH))

দ্বিতীয়টি পুরো মডেলটিকে সংরক্ষণ এবং লোড করে:

torch.save(the_model, PATH)

তাহলে পরে:

the_model = torch.load(PATH)

তবে এই ক্ষেত্রে, সিরিয়ালযুক্ত ডেটা নির্দিষ্ট শ্রেণিবদ্ধ এবং ব্যবহৃত সঠিক ডিরেক্টরি কাঠামোর সাথে আবদ্ধ, যাতে এটি অন্যান্য প্রকল্পে ব্যবহার করার সময়, বা কিছু গুরুতর পুনরুদ্ধারের পরে বিভিন্ন উপায়ে ভেঙে যেতে পারে।


8
@Smth মতে discuss.pytorch.org/t/saving-and-loading-a-model-in-pytorch/... ডিফল্টরূপে মডেল প্রশিক্ষণের মডেল পুনরায় লোড করা। সুতরাং লোড করার পরে ম্যানুয়ালি কল করতে হবে_মডেল.এভাল () কে, যদি আপনি এটি অনুমানের জন্য লোড করে থাকেন, প্রশিক্ষণ পুনরায় শুরু না করে।
উইলজেড

দ্বিতীয় পদ্ধতিটি উইন্ডোজ ১০-এ স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / 3798৯৮০০৯/২ ত্রুটি দেয় এটি সমাধান করতে সক্ষম হয়নি
গুলজার

মডেল ক্লাসে অ্যাক্সেসের প্রয়োজন ছাড়া সংরক্ষণের কোনও বিকল্প আছে কি?
মাইকেল ডি

এই পদ্ধতির সাথে আপনি কীভাবে লোডের ক্ষেত্রে পাস করতে হবে * * আরগস এবং ** কাওয়ার্গগুলি ট্র্যাক করবেন?
মারিয়ানো কাম্প

ব্যবহারে ভুল কী pickle?
চার্লি পার্কার 18

144

এটি আপনি কী করতে চান তার উপর নির্ভর করে।

কেস # 1: মডেলটিকে অনুক্রমের জন্য নিজেকে ব্যবহার করার জন্য সংরক্ষণ করুন: আপনি মডেলটি সংরক্ষণ করেন, আপনি এটি পুনরুদ্ধার করেন এবং তারপরে আপনি মডেলটিকে মূল্যায়ন মোডে পরিবর্তন করেন। এটি করা হয় কারণ আপনার সাধারণত থাকে BatchNormএবং Dropoutস্তরগুলি যা ডিফল্টরূপে ট্রেন মোডে নির্মাণাধীন থাকে:

torch.save(model.state_dict(), filepath)

#Later to restore:
model.load_state_dict(torch.load(filepath))
model.eval()

কেস # 2: পরে প্রশিক্ষণ পুনরায় শুরু করতে মডেল সংরক্ষণ করুন : আপনি যে মডেলটি সংরক্ষণ করতে চলেছেন তা যদি প্রশিক্ষণ রাখতে হয় তবে আপনাকে কেবলমাত্র মডেলের চেয়ে বেশি সঞ্চয় করতে হবে। আপনাকে অপ্টিমাইজার, যুগ, স্কোর ইত্যাদির রাজ্যও সংরক্ষণ করতে হবে আপনি এটি এটি করতে চান:

state = {
    'epoch': epoch,
    'state_dict': model.state_dict(),
    'optimizer': optimizer.state_dict(),
    ...
}
torch.save(state, filepath)

প্রশিক্ষণ পুনরায় শুরু করতে আপনি কিছু করতে চাইবেন: state = torch.load(filepath)এবং তারপরে প্রতিটি পৃথক বস্তুর অবস্থা পুনরুদ্ধার করার জন্য, এরকম কিছু:

model.load_state_dict(state['state_dict'])
optimizer.load_state_dict(state['optimizer'])

আপনি প্রশিক্ষণ চালু করছে সাল থেকে, না কল model.eval()একবার আপনি রাজ্যের যখন লোডিং ফিরিয়ে আনুন।

কেস # 3: আপনার কোড অ্যাক্সেসবিহীন অন্য কারও দ্বারা ব্যবহৃত মডেল : টেনসরফ্লোতে আপনি একটি .pbফাইল তৈরি করতে পারেন যা মডেলটির আর্কিটেকচার এবং ওজন উভয়কে সংজ্ঞায়িত করে। এটি খুব সহজ, বিশেষত ব্যবহারের সময় Tensorflow serve। পাইটোর্কে এটি করার সমতুল উপায় হ'ল:

torch.save(model, filepath)

# Then later:
model = torch.load(filepath)

এই উপায়টি এখনও বুলেট প্রুফ নয় এবং যেহেতু পাইটর্চ এখনও অনেক পরিবর্তন চলছে, আমি এটির প্রস্তাব দেব না।


1
3 টি ক্ষেত্রে কি কোনও প্রস্তাবিত ফাইল শেষ হচ্ছে? নাকি সবসময়। Pth?
ভেরেনা হানস্মমিড

1
কেস # 3 এ torch.loadকেবল একটি অর্ডারডিক্ট প্রদান করে। পূর্বাভাস দেওয়ার জন্য আপনি কীভাবে মডেলটি পাবেন?
Alber8295

হাই, আমি কীভাবে উল্লিখিত "কেস # 2: পরে প্রশিক্ষণ পুনরায় শুরু করতে মডেল সংরক্ষণ করুন" কীভাবে করবেন তা জানতে পারি? আমি চেকপয়েন্টটি মডেলটিতে লোড করতে সক্ষম হয়েছি, তারপরে আমি "মডেল.টো (ডিভাইস) মডেল = ট্রেন-মডেল_পচ (মডেল, মানদণ্ড, অপ্টিমাইজার, শিডিউল,
ইপোকস

1
হাই, এক্ষেত্রে যা অনুমানের জন্য, অফিসিয়াল পাইটর্চ ডকটিতে বলে যে অনুমান বা প্রশিক্ষণ শেষ করার জন্য অবশ্যই অপ্টিমাইজার স্টেট_ডিক্টকে সংরক্ষণ করতে হবে। "সাধারণ চেকপয়েন্ট সংরক্ষণ করার সময়, অনুমান বা পুনরায় প্রশিক্ষণের জন্য ব্যবহার করার জন্য, আপনাকে কেবলমাত্র মডেলের রাজ্য_ডিক্টের চেয়ে বেশি সঞ্চয় করতে হবে the অপটিমাইজারের স্টেট_ডিক্ট সংরক্ষণ করাও গুরুত্বপূর্ণ, কারণ এতে বাফার এবং পরামিতি রয়েছে যা মডেল ট্রেন হিসাবে আপডেট করা হয় । "
মোহাম্মদ আউনি

1
# 3 ক্ষেত্রে মডেল ক্লাসটি কোথাও সংজ্ঞায়িত করা উচিত।
মাইকেল ডি

12

জরান serializing এবং একটি পাইথন বস্তুর ডি serializing জন্য পাইথন গ্রন্থাগার কার্যকরী বাইনারি প্রোটোকল।

যখন আপনি import torch(বা যখন আপনি পাইটর্চ ব্যবহার করবেন) এটি import pickleআপনার জন্য হবে এবং আপনাকে কল করার দরকার নেই pickle.dump()এবং pickle.load()সরাসরি, যা বস্তুটি সংরক্ষণ এবং লোড করার পদ্ধতি।

আসলে, torch.save()এবং torch.load()মোড়ানো pickle.dump()এবং আপনার pickle.load()জন্য হবে ।

state_dictউল্লিখিত অন্য একটি উত্তর আরও কয়েকটি নোটের দাবিদার।

state_dictপাইটর্কের ভিতরে আমাদের কী আছে? আসলে দুটি state_dictএস।

পাইটর্চ মডেলটিতে শেখার যোগ্য পরামিতি ( ডাব্লু এবং বি) পাওয়ার জন্য কল torch.nn.Moduleরয়েছে model.parameters()। একবারে এলোমেলোভাবে সেট করা এই শেখার যোগ্য প্যারামিটারগুলি আমাদের শেখার সাথে সাথে সময়ের সাথে সাথে আপডেট হবে। বোধগম্য পরামিতিগুলি প্রথম state_dict

দ্বিতীয়টি state_dictহ'ল অপটিমাইজার রাষ্ট্র আদেশ। আপনি মনে করতে পারেন যে আমাদের শেখার যোগ্য পরামিতিগুলি উন্নত করতে অপ্টিমাইজারটি ব্যবহৃত হয়। তবে অপটিমাইজার state_dictস্থির রয়েছে। সেখানে শেখার মতো কিছুই নেই।

যেহেতু state_dictবস্তুগুলি পাইথন অভিধান, সেগুলি সহজেই সংরক্ষণ করা যায়, আপডেট করা যায়, পরিবর্তন করা যায় এবং পুনরুদ্ধার করা যায়, পাইটর্চ মডেলগুলি এবং অপ্টিমাইজারগুলিতে প্রচুর পরিমাণে মডুলারিটি যুক্ত করে।

আসুন এটি ব্যাখ্যা করার জন্য একটি দুর্দান্ত সাধারণ মডেল তৈরি করুন:

import torch
import torch.optim as optim

model = torch.nn.Linear(5, 2)

# Initialize optimizer
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

print("Model's state_dict:")
for param_tensor in model.state_dict():
    print(param_tensor, "\t", model.state_dict()[param_tensor].size())

print("Model weight:")    
print(model.weight)

print("Model bias:")    
print(model.bias)

print("---")
print("Optimizer's state_dict:")
for var_name in optimizer.state_dict():
    print(var_name, "\t", optimizer.state_dict()[var_name])

এই কোডটি নিম্নলিখিতগুলি আউটপুট দেবে:

Model's state_dict:
weight   torch.Size([2, 5])
bias     torch.Size([2])
Model weight:
Parameter containing:
tensor([[ 0.1328,  0.1360,  0.1553, -0.1838, -0.0316],
        [ 0.0479,  0.1760,  0.1712,  0.2244,  0.1408]], requires_grad=True)
Model bias:
Parameter containing:
tensor([ 0.4112, -0.0733], requires_grad=True)
---
Optimizer's state_dict:
state    {}
param_groups     [{'lr': 0.001, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [140695321443856, 140695321443928]}]

নোট করুন এটি একটি ন্যূনতম মডেল। আপনি ক্রমিকের স্ট্যাক যুক্ত করার চেষ্টা করতে পারেন

model = torch.nn.Sequential(
          torch.nn.Linear(D_in, H),
          torch.nn.Conv2d(A, B, C)
          torch.nn.Linear(H, D_out),
        )

মনে রাখবেন যে কেবলমাত্র শিখার যোগ্য প্যারামিটারগুলি (কনভ্যুশনাল স্তরগুলি, লিনিয়ার স্তরগুলি ইত্যাদি) এবং নিবন্ধিত বাফারগুলি (ব্যাচনরম স্তরগুলি) মডেলটিতে প্রবেশ রয়েছে state_dict

অপ্রয়োজনীয় জিনিস state_dict, অপ্টিমাইজার অবজেক্টের অন্তর্ভুক্ত , এতে অপ্টিমাইজারের অবস্থা এবং সেই সাথে ব্যবহৃত হাইপারপ্যারামিটার সম্পর্কিত তথ্য রয়েছে।

গল্পের বাকি অংশগুলিও একই; অনুমানের পর্যায়ে (এটি একটি পর্যায় যখন আমরা প্রশিক্ষণের পরে মডেলটি ব্যবহার করি) ভবিষ্যদ্বাণী করার জন্য; আমরা যে পরামিতিগুলি শিখেছি তার উপর নির্ভর করে আমরা ভবিষ্যদ্বাণী করি। অনুমানের জন্য, আমাদের কেবল পরামিতিগুলি সংরক্ষণ করতে হবে model.state_dict()

torch.save(model.state_dict(), filepath)

এবং পরবর্তী মডেল.লোড_স্টেট_ডিক্ট (টর্চ.লোড (ফাইলপথ)) মডেল.ইভাল () ব্যবহার করতে

দ্রষ্টব্য: শেষ লাইনটি ভুলে যাবেন না model.eval()এটি মডেলটি লোড করার পরে গুরুত্বপূর্ণ।

এছাড়াও সংরক্ষণ করার চেষ্টা করবেন না torch.save(model.parameters(), filepath)। এটি model.parameters()হ'ল জেনারেটর অবজেক্ট।

অন্যদিকে, torch.save(model, filepath)মডেল অবজেক্টটি নিজেই সংরক্ষণ করে, তবে মনে রাখবেন মডেলটির অপটিমাইজারটি নেই state_dict। অপ্টিমাইজারের রাজ্য ডিকটি সংরক্ষণ করতে @ জাদিল ডি আরমাসের অন্যান্য দুর্দান্ত উত্তরটি দেখুন।


যদিও এটি সরল সমাধান নয়, সমস্যার মর্ম গভীরভাবে বিশ্লেষণ করা হয়েছে! ভোট দিন।
জেসন ইয়ং

7

একটি সাধারণ পাইটর্চ কনভেনশন হ'ল .pt বা .pth ফাইল এক্সটেনশন ব্যবহার করে মডেলগুলি সংরক্ষণ করা।

সমস্ত মডেল সংরক্ষণ করুন / লোড করুন:

path = "username/directory/lstmmodelgpu.pth"
torch.save(trainer, path)

ভার:

মডেল ক্লাস কোথাও সংজ্ঞায়িত করা আবশ্যক

model = torch.load(PATH)
model.eval()

4

আপনি যদি মডেলটি সংরক্ষণ করতে চান এবং পরে প্রশিক্ষণটি আবার শুরু করতে চান:

একক জিপিইউ: সংরক্ষণ করুন:

state = {
        'epoch': epoch,
        'state_dict': model.state_dict(),
        'optimizer': optimizer.state_dict(),
}
savepath='checkpoint.t7'
torch.save(state,savepath)

ভার:

checkpoint = torch.load('checkpoint.t7')
model.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
epoch = checkpoint['epoch']

একাধিক জিপিইউ: সংরক্ষণ করুন

state = {
        'epoch': epoch,
        'state_dict': model.module.state_dict(),
        'optimizer': optimizer.state_dict(),
}
savepath='checkpoint.t7'
torch.save(state,savepath)

ভার:

checkpoint = torch.load('checkpoint.t7')
model.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
epoch = checkpoint['epoch']

#Don't call DataParallel before loading the model otherwise you will get an error

model = nn.DataParallel(model) #ignore the line if you want to load on Single GPU
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.