পাইরঞ্চ মডেলটির পরামিতিগুলি কীভাবে পাতাগুলি নয় এবং গণনা গ্রাফে থাকতে পারে?


10

আমি নিউরাল নেট মডেলের প্যারামিটারগুলি আপডেট / পরিবর্তন করার চেষ্টা করছি এবং তারপরে আপডেট নিউরাল নেট এর ফরোয়ার্ড পাসটি গণনা গ্রাফে থাকুক (আমরা যতগুলি পরিবর্তন / আপডেট করি না কেন)।

আমি এই ধারণাটি চেষ্টা করেছিলাম কিন্তু যখনই এটি পাইটোর্চ আমার আপডেট হওয়া টেনসরগুলিকে (মডেলের অভ্যন্তরে) পাতাগুলি সেট করে, যা আমি গ্রেডিয়েন্টগুলি পেতে চাইলে নেটওয়ার্কগুলিতে গ্রেডিয়েন্টগুলির প্রবাহকে মেরে ফেলে। এটি গ্রেডিয়েন্টগুলির প্রবাহকে মেরে ফেলে কারণ লিফ নোডগুলি আমি যেভাবে চাই তা গণনা গ্রাফের অংশ নয় (যেহেতু তারা সত্যিকারের পাতা নয়)।

আমি একাধিক জিনিস চেষ্টা করেছি কিন্তু কিছুই কাজ করছে বলে মনে হচ্ছে না। আমি একটি ডামি কোড তৈরি করেছি যা স্বতঃ অন্তর্ভুক্ত যা নেটওয়ার্কগুলির গ্রেডিয়েন্টগুলি মুদ্রণ করতে চায় সেগুলি মুদ্রণ করে:

import torch
import torch.nn as nn

import copy

from collections import OrderedDict

# img = torch.randn([8,3,32,32])
# targets = torch.LongTensor([1, 2, 0, 6, 2, 9, 4, 9])
# img = torch.randn([1,3,32,32])
# targets = torch.LongTensor([1])
x = torch.randn(1)
target = 12.0*x**2

criterion = nn.CrossEntropyLoss()

#loss_net = nn.Sequential(OrderedDict([('conv0',nn.Conv2d(in_channels=3,out_channels=10,kernel_size=32))]))
loss_net = nn.Sequential(OrderedDict([('fc0', nn.Linear(in_features=1,out_features=1))]))

hidden = torch.randn(size=(1,1),requires_grad=True)
updater_net = nn.Sequential(OrderedDict([('fc0',nn.Linear(in_features=1,out_features=1))]))
print(f'updater_net.fc0.weight.is_leaf = {updater_net.fc0.weight.is_leaf}')
#
nb_updates = 2
for i in range(nb_updates):
    print(f'i = {i}')
    new_params = copy.deepcopy( loss_net.state_dict() )
    ## w^<t> := f(w^<t-1>,delta^<t-1>)
    for (name, w) in loss_net.named_parameters():
        print(f'name = {name}')
        print(w.size())
        hidden = updater_net(hidden).view(1)
        print(hidden.size())
        #delta = ((hidden**2)*w/2)
        delta = w + hidden
        wt = w + delta
        print(wt.size())
        new_params[name] = wt
        #del loss_net.fc0.weight
        #setattr(loss_net.fc0, 'weight', nn.Parameter( wt ))
        #setattr(loss_net.fc0, 'weight', wt)
        #loss_net.fc0.weight = wt
        #loss_net.fc0.weight = nn.Parameter( wt )
    ##
    loss_net.load_state_dict(new_params)
#
print()
print(f'updater_net.fc0.weight.is_leaf = {updater_net.fc0.weight.is_leaf}')
outputs = loss_net(x)
loss_val = 0.5*(target - outputs)**2
loss_val.backward()
print()
print(f'-- params that dont matter if they have gradients --')
print(f'loss_net.grad = {loss_net.fc0.weight.grad}')
print('-- params we want to have gradients --')
print(f'hidden.grad = {hidden.grad}')
print(f'updater_net.fc0.weight.grad = {updater_net.fc0.weight.grad}')
print(f'updater_net.fc0.bias.grad = {updater_net.fc0.bias.grad}')

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


দৃ related়ভাবে সম্পর্কিত পোস্ট:

ক্রস-পোস্ট


আপনি কি যুক্তি দিয়ে চেষ্টা করেছেন backward? যথা retain_graph=Trueএবং / অথবা create_graph=True?
সিজমন মাস্কে

উত্তর:


3

নামকরণের প্যারামিটার মডিউলগুলি মুছে ফেলা হবে না W


মনে হচ্ছে এটি কাজ করে:

import torch
import torch.nn as nn

from torchviz import make_dot

import copy

from collections import OrderedDict

# img = torch.randn([8,3,32,32])
# targets = torch.LongTensor([1, 2, 0, 6, 2, 9, 4, 9])
# img = torch.randn([1,3,32,32])
# targets = torch.LongTensor([1])
x = torch.randn(1)
target = 12.0*x**2

criterion = nn.CrossEntropyLoss()

#loss_net = nn.Sequential(OrderedDict([('conv0',nn.Conv2d(in_channels=3,out_channels=10,kernel_size=32))]))
loss_net = nn.Sequential(OrderedDict([('fc0', nn.Linear(in_features=1,out_features=1))]))

hidden = torch.randn(size=(1,1),requires_grad=True)
updater_net = nn.Sequential(OrderedDict([('fc0',nn.Linear(in_features=1,out_features=1))]))
print(f'updater_net.fc0.weight.is_leaf = {updater_net.fc0.weight.is_leaf}')
#
def del_attr(obj, names):
    if len(names) == 1:
        delattr(obj, names[0])
    else:
        del_attr(getattr(obj, names[0]), names[1:])
def set_attr(obj, names, val):
    if len(names) == 1:
        setattr(obj, names[0], val)
    else:
        set_attr(getattr(obj, names[0]), names[1:], val)

nb_updates = 2
for i in range(nb_updates):
    print(f'i = {i}')
    new_params = copy.deepcopy( loss_net.state_dict() )
    ## w^<t> := f(w^<t-1>,delta^<t-1>)
    for (name, w) in list(loss_net.named_parameters()):
        hidden = updater_net(hidden).view(1)
        #delta = ((hidden**2)*w/2)
        delta = w + hidden
        wt = w + delta
        del_attr(loss_net, name.split("."))
        set_attr(loss_net, name.split("."), wt)
    ##
#
print()
print(f'updater_net.fc0.weight.is_leaf = {updater_net.fc0.weight.is_leaf}')
print(f'loss_net.fc0.weight.is_leaf = {loss_net.fc0.weight.is_leaf}')
outputs = loss_net(x)
loss_val = 0.5*(target - outputs)**2
loss_val.backward()
print()
print(f'-- params that dont matter if they have gradients --')
print(f'loss_net.grad = {loss_net.fc0.weight.grad}')
print('-- params we want to have gradients --')
print(f'hidden.grad = {hidden.grad}') # None because this is not a leaf, it is overriden in the for loop above.
print(f'updater_net.fc0.weight.grad = {updater_net.fc0.weight.grad}')
print(f'updater_net.fc0.bias.grad = {updater_net.fc0.bias.grad}')
make_dot(loss_val)

আউটপুট:

updater_net.fc0.weight.is_leaf = True
i = 0
i = 1

updater_net.fc0.weight.is_leaf = True
loss_net.fc0.weight.is_leaf = False

-- params that dont matter if they have gradients --
loss_net.grad = None
-- params we want to have gradients --
hidden.grad = None
updater_net.fc0.weight.grad = tensor([[0.7152]])
updater_net.fc0.bias.grad = tensor([-7.4249])

স্বীকৃতি: পাইটরঞ্চ টিম থেকে শক্তিশালী আলবান্ড: https://discuss.pytorch.org/t/how-does-one-have-theparaparas-of-a-model-not-be-leafs/70076/9?u= Pinocchio


বন্ধুরা, এটি ভুল, এই কোডটি ব্যবহার করবেন না, এটি 1 টিরও বেশি পদক্ষেপের জন্য গ্রেডিয়েন্টগুলি প্রচার করতে দেয় না। : এই পরিবর্তে ব্যবহার করুন github.com/facebookresearch/higher
Pinocchio

এটি পিপিএল কাজ করে না!
পিনোচিও

উচ্চতর গ্রন্থাগারটি আমার পক্ষে এখনও কাজ করে না।
পিনোচিও

0

আপনার একই টেনারগুলি রাখার চেষ্টা করা উচিত, নতুন তৈরি না করে।

তাদের dataবৈশিষ্ট্যের জন্য যান এবং একটি নতুন মান সেট করুন।

for (name, w) in loss_net.named_parameters():
    ....
    w.data = wt.data

এটি এই প্রশ্নের জন্য আমার পক্ষে কাজ করেছে: ব্যাকপ্রসারণটি না ভেঙে কীভাবে পাইরঞ্চ ভেরিয়েবলকে নতুন মান নির্ধারণ করা যায়?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.