পাইটর্কের কোনও নেটওয়ার্কে ওজন এবং বায়াসগুলি (উদাহরণস্বরূপ, তিনি বা জাভিয়ার সূচনা সহ) কীভাবে প্রাথমিককরণ করবেন?
পাইটর্কের কোনও নেটওয়ার্কে ওজন এবং বায়াসগুলি (উদাহরণস্বরূপ, তিনি বা জাভিয়ার সূচনা সহ) কীভাবে প্রাথমিককরণ করবেন?
উত্তর:
একটি একক স্তরের ওজন সূচনা করতে, থেকে একটি ফাংশন ব্যবহার করুন torch.nn.init
। এই ক্ষেত্রে:
conv1 = torch.nn.Conv2d(...)
torch.nn.init.xavier_uniform(conv1.weight)
বিকল্পভাবে, আপনি conv1.weight.data
(যা এটি torch.Tensor
) তে লিখে প্যারামিটারগুলি সংশোধন করতে পারেন । উদাহরণ:
conv1.weight.data.fill_(0.01)
একই পক্ষপাতিত্বের জন্য প্রযোজ্য:
conv1.bias.data.fill_(0.01)
nn.Sequential
বা কাস্টম nn.Module
একটি সূচনা ফাংশন পাস করুন torch.nn.Module.apply
। এটি সম্পূর্ণ nn.Module
পুনরাবৃত্তির সাথে ওজনকে সূচনা করবে ।
আবেদন ( FN ): প্রয়োগ
fn
প্রত্যেক submodule করতে যাও recursively (যেমন দ্বারা ফিরে.children()
স্ব হিসাবে) হিসাবে ভাল। সাধারণ ব্যবহারের মধ্যে একটি মডেলের প্যারামিটারগুলি আরম্ভ করা অন্তর্ভুক্ত থাকে (টর্চ-এনএন-থিমও দেখুন)
উদাহরণ:
def init_weights(m):
if type(m) == nn.Linear:
torch.nn.init.xavier_uniform(m.weight)
m.bias.data.fill_(0.01)
net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
net.apply(init_weights)
আপনি যদি ওসামের রেজারের নীতিটি অনুসরণ করেন তবে আপনি মনে করতে পারেন যে সমস্ত ওজন 0 বা 1 এ সেট করা সবচেয়ে ভাল সমাধান হবে। এই ক্ষেত্রে না হয়.
প্রতি ওজন সমান হওয়ায় প্রতিটি স্তরের সমস্ত নিউরন একই আউটপুট উত্পাদন করে। এটি কোন ওজনগুলি সমন্বয় করতে পারে তা সিদ্ধান্ত নেওয়া শক্ত করে তোলে।
# initialize two NN's with 0 and 1 constant weights
model_0 = Net(constant_weight=0)
model_1 = Net(constant_weight=1)
Validation Accuracy
9.625% -- All Zeros
10.050% -- All Ones
Training Loss
2.304 -- All Zeros
1552.281 -- All Ones
একটি অভিন্ন বন্টন সংখ্যার একটি সেট থেকে কোন সংখ্যা অবচয় সমান সম্ভাবনা রয়েছে।
দেখি কত ভাল স্নায়ুর নেটওয়ার্ক একটি অভিন্ন ওজন আরম্ভের, যেখানে ব্যবহার ট্রেন যাক low=0.0
এবং high=1.0
।
নীচে, আমরা নেটওয়ার্কের ওজন শুরুর জন্য আরেকটি উপায় (নেট ক্লাস কোড ছাড়াও) দেখতে পাব। মডেল সংজ্ঞার বাইরে ওজন নির্ধারণ করতে, আমরা এটি করতে পারি:
- একটি ফাংশন নির্ধারণ নেটওয়ার্ক লেয়ার ধরণ দ্বারা নির্ধারণ ওজন তারপর
- এই ওজনগুলি একটি প্রাথমিক মডেল ব্যবহার করে
model.apply(fn)
প্রয়োগ করুন, যা প্রতিটি মডেল স্তরের একটি ফাংশন প্রয়োগ করে।
# takes in a module and applies the specified weight initialization
def weights_init_uniform(m):
classname = m.__class__.__name__
# for every Linear layer in a model..
if classname.find('Linear') != -1:
# apply a uniform distribution to the weights and a bias=0
m.weight.data.uniform_(0.0, 1.0)
m.bias.data.fill_(0)
model_uniform = Net()
model_uniform.apply(weights_init_uniform)
Validation Accuracy
36.667% -- Uniform Weights
Training Loss
3.208 -- Uniform Weights
নিউরাল নেটওয়ার্কে ওজন নির্ধারণের সাধারণ নিয়ম হ'ল এগুলি খুব ছোট না হয়ে শূন্যের কাছাকাছি রাখা।
ভাল অনুশীলন হ'ল [-y, y] এর সীমার মধ্যে আপনার ওজন শুরু করা যেখানে
y=1/sqrt(n)
(এন প্রদত্ত নিউরনের ইনপুটগুলির সংখ্যা)।
# takes in a module and applies the specified weight initialization
def weights_init_uniform_rule(m):
classname = m.__class__.__name__
# for every Linear layer in a model..
if classname.find('Linear') != -1:
# get the number of the inputs
n = m.in_features
y = 1.0/np.sqrt(n)
m.weight.data.uniform_(-y, y)
m.bias.data.fill_(0)
# create a new model with these weights
model_rule = Net()
model_rule.apply(weights_init_uniform_rule)
নীচে আমরা এনএন এর পারফরম্যান্স তুলনা করি, ইউনিট বিতরণ [-0.5,0.5) এর সাথে ওজন সূচনা করে যার ওজন সাধারণ নিয়ম ব্যবহার করে আরম্ভ করা হয়
Validation Accuracy
75.817% -- Centered Weights [-0.5, 0.5)
85.208% -- General Rule [-y, y)
Training Loss
0.705 -- Centered Weights [-0.5, 0.5)
0.469 -- General Rule [-y, y)
সাধারণ বিতরণটির গড় গড় 0 এবং একটি স্ট্যান্ডার্ড বিচ্যুতি হওয়া উচিত
y=1/sqrt(n)
, যেখানে এন এন-এ ইনপুটগুলির সংখ্যা
## takes in a module and applies the specified weight initialization
def weights_init_normal(m):
'''Takes in a module and initializes all linear layers with weight
values taken from a normal distribution.'''
classname = m.__class__.__name__
# for every Linear layer in a model
if classname.find('Linear') != -1:
y = m.in_features
# m.weight.data shoud be taken from a normal distribution
m.weight.data.normal_(0.0,1/np.sqrt(y))
# m.bias.data should be 0
m.bias.data.fill_(0)
নীচে আমরা দুটি এনএন এর কর্মক্ষমতা প্রদর্শন করি যার মধ্যে একটি ইউনিফর্ম-বিতরণ এবং অন্যটি সাধারণ-বিতরণ ব্যবহার করে শুরু করা হয়েছিল
Validation Accuracy
85.775% -- Uniform Rule [-y, y)
84.717% -- Normal Distribution
Training Loss
0.329 -- Uniform Rule [-y, y)
0.443 -- Normal Distribution
পাইটর্চ এটি আপনার জন্য করবে। যদি আপনি এটি সম্পর্কে ভাবেন, এটি অনেক জ্ঞান আছে। আমাদের স্তরগুলি কেন শুরু করা উচিত, যখন পাইটর্চ এটি করতে পারে সর্বশেষ প্রবণতাগুলি অনুসরণ করে।
উদাহরণস্বরূপ লিনিয়ার স্তরটি পরীক্ষা করুন ।
__init__
পদ্ধতিতে এটি কাইমিং হি ইন ফাংশনটিকে কল করবে ।
def reset_parameters(self):
init.kaiming_uniform_(self.weight, a=math.sqrt(3))
if self.bias is not None:
fan_in, _ = init._calculate_fan_in_and_fan_out(self.weight)
bound = 1 / math.sqrt(fan_in)
init.uniform_(self.bias, -bound, bound)
অনুরূপ অন্যান্য স্তর ধরণের জন্য। জন্য conv2d
উদাহরণস্বরূপ পরীক্ষা এখানে ।
দ্রষ্টব্য: সঠিক আরম্ভের লাভটি দ্রুত প্রশিক্ষণের গতি। যদি আপনার সমস্যাটি বিশেষ সূচনার দাবি রাখে তবে আপনি এটি আফটারওয়ার্ড করতে পারেন।
xavier_uniform
ডিফল্ট আরম্ভকরণের পরিবর্তে ওজনগুলির জন্য (বায়াসগুলি প্রাথমিকভাবে 0-এ শুরু করা হয়েছে) পরিবর্তনের পরিবর্তে 30 এর পরে আমার বৈধতার যথার্থতা রয়েছে আরএমএসপ্রপের পর্বগুলি 82% থেকে 86% এ বৃদ্ধি পেয়েছে। পাইটর্চের অন্তর্নির্মিত ভিজিজি 16 মডেলটি (প্রাক প্রশিক্ষণপ্রাপ্ত নয়) ব্যবহার করার সময় আমি 86% বৈধতার যথার্থতা পেয়েছি, তাই আমি মনে করি আমি এটি সঠিকভাবে প্রয়োগ করেছি। (আমি 0.00001 এর শিক্ষার হার ব্যবহার করেছি))
import torch.nn as nn
# a simple network
rand_net = nn.Sequential(nn.Linear(in_features, h_size),
nn.BatchNorm1d(h_size),
nn.ReLU(),
nn.Linear(h_size, h_size),
nn.BatchNorm1d(h_size),
nn.ReLU(),
nn.Linear(h_size, 1),
nn.ReLU())
# initialization function, first checks the module type,
# then applies the desired changes to the weights
def init_normal(m):
if type(m) == nn.Linear:
nn.init.uniform_(m.weight)
# use the modules apply function to recursively apply the initialization
rand_net.apply(init_normal)
এত দেরিতে থাকার জন্য দুঃখিত, আমি আশা করি আমার উত্তরটি সাহায্য করবে।
normal distribution
ব্যবহারের সাথে ওজন সূচনা করতে:
torch.nn.init.normal_(tensor, mean=0, std=1)
অথবা একটি constant distribution
লিখন ব্যবহার করতে:
torch.nn.init.constant_(tensor, value)
বা এটি ব্যবহার করতে uniform distribution
:
torch.nn.init.uniform_(tensor, a=0, b=1) # a: lower_bound, b: upper_bound
আপনি এখানে টেনারগুলি আরম্ভ করার জন্য অন্যান্য পদ্ধতিগুলি পরীক্ষা করতে পারেন
আপনি যদি কিছু অতিরিক্ত নমনীয়তা চান, আপনি নিজেও ওজন সেট করতে পারেন ।
বলুন আপনার কাছে সকলের ইনপুট রয়েছে:
import torch
import torch.nn as nn
input = torch.ones((8, 8))
print(input)
tensor([[1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1.]])
এবং আপনি কোনও পক্ষপাতহীন একটি ঘন স্তর তৈরি করতে চান (যাতে আমরা কল্পনা করতে পারি):
d = nn.Linear(8, 8, bias=False)
সমস্ত ওজন 0.5 এ সেট করুন (বা অন্য কিছু):
d.weight.data = torch.full((8, 8), 0.5)
print(d.weight.data)
ওজন:
Out[14]:
tensor([[0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000],
[0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000],
[0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000],
[0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000],
[0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000],
[0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000],
[0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000],
[0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000]])
আপনার সমস্ত ওজন এখন 0.5। এর মাধ্যমে ডেটা পাস করুন:
d(input)
Out[13]:
tensor([[4., 4., 4., 4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4., 4., 4., 4.]], grad_fn=<MmBackward>)
মনে রাখবেন যে প্রতিটি নিউরন 8 টি ইনপুট গ্রহণ করে, যার সবকটির ওজন 0.5 এবং 1 এর মান (এবং কোনও পক্ষপাত নেই), তাই এটির জন্য এটি প্রতিটি জন্য 4 এর সমষ্টি।
যদি apply
মডেলটি Sequential
সরাসরি প্রয়োগ না করে আপনি উদাহরণস্বরূপ ব্যবহার করতে পারবেন না :
# see UNet at https://github.com/milesial/Pytorch-UNet/tree/master/unet
def init_all(model, init_func, *params, **kwargs):
for p in model.parameters():
init_func(p, *params, **kwargs)
model = UNet(3, 10)
init_all(model, torch.nn.init.normal_, mean=0., std=1)
# or
init_all(model, torch.nn.init.constant_, 1.)
def init_all(model, init_funcs):
for p in model.parameters():
init_func = init_funcs.get(len(p.shape), init_funcs["default"])
init_func(p)
model = UNet(3, 10)
init_funcs = {
1: lambda x: torch.nn.init.normal_(x, mean=0., std=1.), # can be bias
2: lambda x: torch.nn.init.xavier_normal_(x, gain=1.), # can be weight
3: lambda x: torch.nn.init.xavier_uniform_(x, gain=1.), # can be conv1D filter
4: lambda x: torch.nn.init.xavier_uniform_(x, gain=1.), # can be conv2D filter
"default": lambda x: torch.nn.init.constant(x, 1.), # everything else
}
init_all(model, init_funcs)
torch.nn.init.constant_(x, len(x.shape))
সেগুলি যথাযথভাবে শুরু করা হয়েছে কিনা তা পরীক্ষা করে দেখতে পারেন :
init_funcs = {
"default": lambda x: torch.nn.init.constant_(x, len(x.shape))
}
যদি আপনি অবমূল্যায়নের সতর্কতা (@ ফ্যাবিও পেরেজ) দেখেন ...
def init_weights(m):
if type(m) == nn.Linear:
torch.nn.init.xavier_uniform_(m.weight)
m.bias.data.fill_(0.01)
net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
net.apply(init_weights)
কুউজ আমি এখনও পর্যন্ত যথেষ্ট খ্যাতি পাই নি, আমি এর অধীনে কোনও মন্তব্য যুক্ত করতে পারি না
উত্তর পোস্ট করেছে prosti থেকে এ 13:16 এ জুন 26 '19 ।
def reset_parameters(self):
init.kaiming_uniform_(self.weight, a=math.sqrt(3))
if self.bias is not None:
fan_in, _ = init._calculate_fan_in_and_fan_out(self.weight)
bound = 1 / math.sqrt(fan_in)
init.uniform_(self.bias, -bound, bound)
তবে আমি এটি উল্লেখ করতে চাই যে কাইমিং হি , ডিলিভ ডিপ ইন রেকটিফায়ারস: ইমেজনেট শ্রেণিবিন্যাসে মানব-স্তরের পারফরম্যান্সকে ছাড়িয়ে যাওয়া, এমন কিছু কাগজপত্রের মধ্যে আমরা আসলে কিছু ধারণা অনুধাবন করি না, যদিও এটি ইচ্ছাকৃতভাবে নকশাকৃত প্রাথমিককরণ পদ্ধতি অনুশীলনকে কার্যকর করে তোলে বলে মনে হয় ।
উদাহরণস্বরূপ, পশ্চাদপদ প্রচার মামলার উপধারাটির মধ্যে , তারা ধরে নেয় যে $ w_l $ এবং $ \ ডেল্টা y_l each একে অপরের থেকে স্বতন্ত্র। তবে যেমনটি আমরা সকলেই জানি, স্কোর মানচিত্রটিকে $ \ ডেল্টা ওয়াই ^ এল_আই take উদাহরণ হিসাবে ধরুন, এটি প্রায়শই $ y_i-softmax (y ^ L_i) = y_i-softmax (w ^ L_ix ^ L_i) $ যদি আমরা একটি সাধারণ ব্যবহার করি ক্রস এনট্রপি ক্ষতি ফাংশন উদ্দেশ্য।
সুতরাং আমি মনে করি যে কেন তিনি ইনিশিয়ালাইজেশন ভালভাবে কাজ করেন তার প্রকৃত অন্তর্নিহিত কারণটি অবমুক্ত করা যায়। কিউজ প্রত্যেকে গভীর শিক্ষার প্রশিক্ষণ বৃদ্ধিতে এর শক্তি প্রত্যক্ষ করেছে।
reset_parameters
অনেকগুলি মডিউলগুলির উত্স কোডে একটি পদ্ধতি পেয়েছি । ওজন প্রারম্ভিককরণের জন্য আমার কি পদ্ধতিটি ওভাররাইড করা উচিত?