docs/si/transformers/feedback/index.html
[View code on Github](https://github.com/labmlai/annotated_deep_learning_paper_implementations/tree/master/labml_nn/transformers/feedback/ init.py)
මෙය PyTorch ක්රියාත්මක කිරීම කඩදාසි ප්රතිපෝෂණ මතකය සමඟ අනුක්රමික ට්රාන්ස්ෆෝමර්වල ඉහළ මට්ටමේ නිරූපණයන් වෙත ප්රවේශ වීම .
සාමාන්යට්රාන්ස්ෆෝමර් සමාන්තරව ටෝකන සකසනවා. සෑම ට්රාන්ස්ෆෝමර් ස්ථරයක්ම පෙර ස්ථරයේ ප්රතිදානයන් කෙරෙහි අවධානය යොමු කරයි. ප්රතිපෝෂණ ට්රාන්ස්ෆෝමරය පෙර පියවරයන්හි සියලුම ස්ථරවල ප්රතිදානය කෙරෙහි අවධානය යොමු කරයි. එබැවින් මෙය පුනරාවර්තනය එකතු කරන අතර, අපි ටෝකන්-විසින්-ටෝකන් සැකසිය යුතුය. මෙය පුහුණුව සැලකිය යුතු ලෙස මන්දගාමී වේ (අනුක්රමයේ දිග අනුව 5X - 10X පමණ). කෙසේ වෙතත්, ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් පුරෝකථනය කිරීමේදී වේගවත් වන්නේ ඔබ මතක දෛශික හැඹිලි කළහොත් ඊළඟ ටෝකනය පුරෝකථනය කළ හැකි බැවිනි.
පුහුණුවවේගවත් කිරීම සඳහා, කඩදාසි සාකච්ඡා කරන්නේ කෙටි අනුක්රමික දිගකින් ආරම්භ කර එය ක්රමයෙන් වැඩි කිරීමයි. ආරම්භක ස්ථානය ලෙස පෙර පුහුණු සමාන්තර ට්රාන්ස්ෆෝමරයක් භාවිතා කිරීම ද ඔවුහු සාකච්ඡා කරති.
මුල්ප්රතිපෝෂණ ට්රාන්ස්ෆෝමරය සියලු ස්ථරවල ප්රතිදානයන් තබා නොගනී. ඒ වෙනුවට එය සියලු ස්ථරවල නිමැවුමේ බර තැබූ එකතුව තබා ගනී. මෙය අනාවැකිය තුළ හැඹිලි සඳහා භාවිතා කරන මතකය අඩු කරයි. මෙම ගොනුවේ පළමු භාගය මෙය ක්රියාත්මක කරයි.
යාවත්කාලීනකරන ලද ප්රතිපෝෂණ ට්රාන්ස්ෆෝමරය බර බෙදා ගන්නා Wkl අතර ස්ථර අතර යතුරු සහ අගයන් ගණනය කිරීමට Wvl භාවිතා කරයි. ඉන්පසු අපි එක් එක් පියවර සඳහා යතුරු සහ අගයන් එක් වරක් පමණක් ගණනය කර ඒවා හැඹිලි කර තබමු. මෙම ගොනුවේ දෙවන භාගය මෙය ක්රියාත්මක කරයි. කාර්ය සාධනය වැඩි දියුණු කිරීම සඳහා අපි අභිරුචි PyTorch ශ්රිතයක් ක්රියාත්මක කළෙමු.
කුඩාෂේක්ස්පියර් දත්ත කට්ටලය පිළිබඳ ප්රතිපෝෂණ ට්රාන්ස්ෆෝමරයක් පුහුණු කිරීම සඳහා පුහුණු කේතය සහ සටහන් පොතක් මෙන්න.
43importmath44fromtypingimportOptional4546importtorch47fromtorchimportnn4849fromlabml\_helpers.moduleimportModule50fromlabml\_nn.transformers.feed\_forwardimportFeedForward51fromlabml\_nn.transformers.mhaimportPrepareForMultiHeadAttention52fromlabml\_nn.utilsimportclone\_module\_list
මෙමමොඩියුලය මුල් ට්රාන්ස්ෆෝමර් කඩදාසි වලින් අවධානයට සමාන පුනරාවර්තන අවධානයක් ගණනය කරයි.
Attention(Q,K,V)=seqsoftmax(dkQ⊤K)V
55classFeedbackAttention(Module):
d_model ට්රාන්ස්ෆෝමරයේ ඇති ලක්ෂණ ගණනdropout_prob අවධානය යොමු කිරීමේ සම්භාවිතාවis_kv_precomputed යතුරද යන්න, අගය ආතතීන් දැනටමත් ගණනය කර ඇත66def\_\_init\_\_(self,heads:int,d\_model:int,dropout\_prob:float=0.1,\*,67is\_kv\_precomputed:bool=False):
75super().\_\_init\_\_()
හිසකටවිශේෂාංග ගණන
78self.d\_k=d\_model//heads
80self.heads=heads
මේවා query බහු-ශීර්ෂ අවධානය පරිවර්තනය කරයි.
83self.query=PrepareForMultiHeadAttention(d\_model,heads,self.d\_k,bias=False)
මේවාබහු ශීර්ෂ අවධානය value සඳහා පරිවර්තනය කරයි. key
85ifnotis\_kv\_precomputed:86self.key=PrepareForMultiHeadAttention(d\_model,heads,self.d\_k,bias=False)87self.value=PrepareForMultiHeadAttention(d\_model,heads,self.d\_k,bias=True)
යතුරුසහ අගයන් දැනටමත් ගණනය කර ඇත
89else:90self.key=None91self.value=None
ප්රතිදානස්ථරය
94self.output=nn.Linear(d\_model,d\_model)
හැලීම
96self.dropout=nn.Dropout(dropout\_prob)
සොෆ්ට්මැක්ස්වලට පෙර පරිමාණ සාධකය
98self.scale=1/math.sqrt(self.d\_k)
කාලමානය ඔස්සේ අවධානය යොමු කිරීම සඳහා සොෆ්ට්මැක්ස් key
101self.softmax=nn.Softmax(dim=0)
සාපේක්ෂතනතුරු ගණන
104self.P=2\*\*12
විමසුමටසාපේක්ෂව යතුර සඳහා සාපේක්ෂ ස්ථානීය කාවැද්දීම්.
107self.key\_pos\_embeddings=nn.Parameter(torch.zeros((self.P,heads,self.d\_k)),requires\_grad=True)
විමසුමටසාපේක්ෂව යතුර සඳහා සාපේක්ෂ ස්ථානීය කාවැද්දීමේ නැඹුරුව.
109self.key\_pos\_bias=nn.Parameter(torch.zeros((self.P,heads)),requires\_grad=True)
විමසුමසඳහා ස්ථානීය කාවැද්දීම් විමසුමේ පිහිටුමෙන් ස්වාධීන වේ
111self.query\_pos\_bias=nn.Parameter(torch.zeros((heads,self.d\_k)),requires\_grad=True)
අවශ්යනම් ලොග් වීම හෝ වෙනත් ගණනය කිරීම් සඳහා භාවිතා කළ හැකි වන පරිදි අපි අවධානය ගබඩා කරමු
114self.attn=None
අපිඅවධානය සඳහා සාපේක්ෂ ස්ථානීය කේතීකරණ භාවිතා කරමු, සාපේක්ෂ බහු-හිස අවධානය ආකෘති ට්රාන්ස්ෆෝමර්-එක්ස්එල් කඩදාසිවලට සමානය.
පියවරප්රධාන වත්මන් පියවර ගේ විමසුම සිට අවධානය j (වත්මන් පියවර සාපේක්ෂව) වේ,
Aj=Q⊤Kj=linq(Xq+Pq)⊤link(Xjk+Pj)=(Q+UQ)⊤(Kj+UjK)=AQ⊤Kj+BQ⊤UjK+CUQ⊤Kj+DUQ⊤UjK
මුල්කාවැද්දීම්වල රේඛීය පරිවර්තනයන් UQ,UjK වන Xq,Xjk අතර ස්ථානීය කේතීකරණයේ රේඛීය පරිවර්තනයන් වේ Q,Kj Pq,Pj.
අපිපදය D වෙනුවට ආදේශ කරමු Sj.
116defget\_scores(self,query:torch.Tensor,key:torch.Tensor):
UjK
144key\_pos\_emb=self.key\_pos\_embeddings[-key.shape[0]:]
UQ
146query\_pos\_bias=self.query\_pos\_bias[None,:,:]
Sj
148key\_pos\_bias=self.key\_pos\_bias[-key.shape[0]:]
AQ⊤Kj+CUQ⊤Kj
151ac=torch.einsum('bhd,jbhd-\>jbh',query+query\_pos\_bias,key)
BQ⊤UjK+DSj
153bd=torch.einsum('bhd,jhd-\>jbh',query,key\_pos\_emb)+key\_pos\_bias[:,None,:]
Aj
156returnac+bd
query හැඩය ඇත [batch_size, d_model]key සහ හැඩය value ඇත [seq_len, batch_size, d_model]158defforward(self,\*,159query:torch.Tensor,160key:torch.Tensor,161value:torch.Tensor):
සූදානම්වන්න query , key සහ අවධානය ගණනය කිරීම value සඳහා key සහ පසුව හැඩය value ඇත [seq_len, batch_size, heads, d_k] සහ හැඩය query ඇත [batch_size, heads, d_k]
170query=self.query(query)171ifself.key:172key=self.key(key)173ifself.value:174value=self.value(value)
අවධානයලකුණු ගණනය කරන්න. හැඩයේ ආතතියෙන් ප්රති Results ල [seq_len, batch_size, heads]
178scores=self.get\_scores(query,key)
පරිමාණලකුණු dk1
181scores\*=self.scale
සොෆ්ට්මැක්ස්
184attn=self.softmax(scores)
අතහැරදැමීම යොදන්න
187attn=self.dropout(attn)
අගයන්අනුව ගුණ කරන්න
190x=torch.einsum("jbh,jbhd-\>bhd",attn,value)
බහුහිස් සංයුක්ත කරන්න
193x=x.reshape(x.shape[0],-1)
ප්රතිදානස්ථරය
196returnself.output(x)
මෙයප්රතිපෝෂණ ට්රාන්ස්ෆෝමරයේ තනි ට්රාන්ස්ෆෝමර් තට්ටුවක් ක්රියාත්මක කරයි.
199classFeedbackTransformerLayer(Module):
d_model ට්රාන්ස්ෆෝමරයේ ඇති ලක්ෂණ ගණනattn යනු ප්රතිපෝෂණ අවධානය මොඩියුලයයිfeed_forward ස්ථාන-wise ානවන්ත ආහාර ඉදිරි ස්ථරයයිdropout_prob යනු අවධානය සහ පෝෂණය කිරීමෙන් පසු ස්ථර අතහැර දැමීමේ සම්භාවිතාවයයි206def\_\_init\_\_(self,\*,207d\_model:int,208attn:FeedbackAttention,209feed\_forward:FeedForward,210dropout\_prob:float):
217super().\_\_init\_\_()
ට්රාන්ස්ෆෝමර්ප්රමාණය dmodel
219self.size=d\_model
221self.attn=attn222self.feed\_forward=feed\_forward223self.dropout=nn.Dropout(dropout\_prob)
සාමාන්යකරණයස්ථර
226self.norm\_self\_attn=nn.LayerNorm([d\_model])227self.norm\_ff=nn.LayerNorm([d\_model])
229defforward(self,\*,230x:torch.Tensor,231key:Optional[torch.Tensor],232value:Optional[torch.Tensor]):
මතකයක්තිබේ නම්
234ifkeyisnotNone:
ස්වයංඅවධානය යොමු කිරීමට පෙර දෛශික සාමාන්යකරණය කරන්න
236z=self.norm\_self\_attn(x)
ස්වයංඅවධානය හරහා ධාවනය කරන්න, i.e. යතුරු සහ වටිනාකම් ස්වයං සිට
238self\_attn=self.attn(query=z,key=key,value=value)
ස්වයංඅවධානය ප්රතිඵල එකතු
240x=x+self.dropout(self\_attn)
පෝෂණයසඳහා සාමාන්යකරණය කරන්න
243z=self.norm\_ff(x)
Feed-forwardජාලය හරහා ගමන් කරන්න
245ff=self.feed\_forward(z)
ප්රතිපෝෂණඉදිරි ප්රති results ල නැවත එක් කරන්න
247x=x+self.dropout(ff)
250returnx
253classFeedbackTransformer(Module):
layer අපි එක් එක් ස්ථරයක් සඳහා පරිගණක ක්රිඩාවට සමාන වන ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් ස්ථරය, වේn_layers ට්රාන්ස්ෆෝමරයේ ස්ථර ගණන258def\_\_init\_\_(self,layer:FeedbackTransformerLayer,n\_layers:int):
264super().\_\_init\_\_()
ට්රාන්ස්ෆෝමර්ස්ථරයේ පිටපත් සාදන්න
266self.layers=clone\_module\_list(layer,n\_layers)
අවසානසාමාන්යකරණ ස්තරය
268self.norm=nn.LayerNorm([layer.size])
මතකදෛශික ගණනය කරනු ලබන්නේ එක් එක් ස්ථරයේ නිරූපණවල බර කිරන ලද එකතුවකි. ඒ සඳහා බර පරාමිතිය මෙයයි.
271self.weights=nn.Parameter(torch.ones(n\_layers+1),requires\_grad=True)
බරතැබූ මුදල ගැනීමට පෙර බර සඳහා සොෆ්ට්මැක්ස්
273self.softmax=nn.Softmax(0)
x_seq හැඩය සහිත ආදානය වේ [seq_len, batch_size, d_model]275defforward(self,x\_seq:torch.Tensor):
අනුක්රමිකඅක්ෂය දිගේ ලැයිස්තුවකට ආදානය බෙදන්න
281x\_seq=torch.unbind(x\_seq,dim=0)
ප්රතිදානයන්ගබඩා කිරීම සඳහා ලැයිස්තුව
283res=[]
මතකදෛශික ගබඩා කිරීමට ලැයිස්තුව
285mem=[]
එක්එක් ආදාන පියවර සඳහා
287forxinx\_seq:
ස්ථරප්රතිදානයන් ගබඩා කිරීම සඳහා ලැයිස්තුව
289layer\_outputs=[x]
මතකයක්තිබේ නම්, ඒවා දෛශිකයකට ගොඩගසන්න
292mem\_tensor=torch.stack(mem)ifmemelseNone
එක්එක් ස්ථරය හරහා ධාවනය කරන්න
295forlayerinself.layers:
ස්ථරප්රතිදානය ලබා ගන්න
297x=layer(x=x,key=mem\_tensor,value=mem\_tensor)
ස්ථරප්රතිදානයන් ලැයිස්තුවට ඒවා එකතු කරන්න
299layer\_outputs.append(x)
ස්ථරයේප්රතිදානයන් ටෙන්සරයකට ගොඩගසන්න
302layer\_outputs=torch.stack(layer\_outputs)
ස්ථරප්රතිදානවල බර තැබූ එකතුවක් ලෙස මතක දෛශිකය ගණනය කරන්න
304mem.append(torch.einsum('lbd,l-\>bd',layer\_outputs,self.softmax(self.weights)))
ප්රති. ල සඳහා ප්රතිදානය එක් කරන්න
306res.append(x)
නිමැවුම්ආතතීන් ගොඩගසන්න
309res=torch.stack(res)
ප්රතිදානයසාමාන්යකරණය කරන්න
311returnself.norm(res)
අපිpython ලැයිස්තුවකට appending හා පසුව කරන්නේ වෙනුවට අභිරුචි ශ්රිතයක් ක්රියාත්මක torch.stack . මෙම බොහෝ සෙයින් අනුක්රමය ඔස්සේ එක් එක් පියවර torch.stack දී ඉල්ලා පුරා කාර්ය සාධනය වැඩි දියුණු කරන ලදි. සෑම විටම කැඳවනු torch.stack ලැබේ, එය නව ආතතියක් නිර්මාණය කරයි, මෙම ක්රමය සහ ඒ සමඟ ඇති පන්ති Stack කොටස් මතකය එක් එක් පියවර සඳහා.
318classStackFunction(torch.autograd.Function):
ctx යනු ශ්රිතයේ සන්දර්භය (එය අපට හැඹිලි දේවල් වලට ඉඩ දෙයි)memory යනු හවුල් මතක ටෙන්සරය වන අතර එහිදී අපි එක් එක් පියවරේ අගයන් ගබඩා කර ගබඩා කරමු (යතුරු සහ අගයන්)memory_grad යනු එක් එක් පියවරේ අනුක්රමික ගබඩා කිරීම හා රැස් කිරීම සඳහා හවුල් මතක ආතතියකිlast අවසාන අගය ගොඩගැසී ඇතn පියවර ගණන (එනම් අඩුක්කුව ප්රමාණය)මෙයපියවර සඳහා ගොඩගැසී ඇති ටෙන්සරය නැවත ලබා දෙයි n .
330@staticmethod331defforward(ctx,memory,memory\_grad,last,n):
හැඹිලිසමුච්චිත අනුක්රමික
343ctx.\_mem\_grad=memory\_grad
තොගයේප්රමාණය හැඹිලිය
345ctx.\_n=n
තොගයආපසු දෙන්න
347returnmemory[:n+1]
grad_output``forward ශ්රිතයේ ප්රතිදානය සම්බන්ධයෙන් ශ්රේණිය වේමෙයහවුල් මතක ටෙන්සරයේ ඇති අනුක්රමික සමුච්චය වන අතර තොගයේ last ප්රති result ලය සම්බන්ධයෙන් අනුක්රමික ආපසු ලබා දෙන්න.
349@staticmethod350defbackward(ctx,grad\_output):
තොගයේවත්මන් ප්රමාණය ලබා ගන්න
358n=ctx.\_n
සමුච්චිතඅනුක්රමික ලබා ගන්න
360memory\_grad=ctx.\_mem\_grad
අනුක්රමිකඑකතු කරන්න
362memory\_grad[:n+1]+=grad\_output
W.r.tඅනුක්රමික තොගයේ අවසාන අගය වෙත ආපසු ලබා දෙන්න
364returnNone,None,memory\_grad[n],None
මෙයඉහත අර්ථ දක්වා ඇති සිරස් ශ්රිතය භාවිතා කරන අතර අවශ්ය ආරම්භකකරණයන් සිදු කරයි.
367classStack:
max_len අඩුක්කුව උපරිම ප්රමාණය374def\_\_init\_\_(self,max\_len:int):
378self.max\_len=max\_len379self.memory=None380self.memory\_grad=None381self.last=None382self.n=-1383self.last\_get\_n=-1
n අඩුක්කුව ප්රමාණය වේvalue අඩුක්කුව එකතු කළ යුතු බව tensor වේ385defappend(self,n:int,value:torch.Tensor):
අගයක්එකතු කිරීමෙන් පසු ඔබට අඩුක්කුව ලබා ගත යුතුය (භාවිතා කරන්න). එසේ නොමැතිනම් මෙම ක්රියාත්මක කිරීම අසමත් වේ
393assertn==0orself.last\_get\_n==n-1,f"{n}, {self.last\_get\_n}"
අනුක්රමිකනොමැතිව මෙය කරන්න
396withtorch.no\_grad():
තොගයතබා ගැනීම සඳහා හවුල් මතක ටෙන්සරය ආරම්භ කරන්න
398ifself.memoryisNoneorself.memory.shape[1:]!=value.shape:
මෙයසිදුවිය යුත්තේ තොගය හිස් වූ විට පමණි
400assertn==0
අඩුක්කුවසඳහා ටෙන්සරයක් සාදන්න
402self.memory=value.new\_zeros(self.max\_len,\*value.shape,requires\_grad=False)
අනුක්රමිකසමුච්චය කිරීමට tensor සාදන්න
404self.memory\_grad=value.new\_zeros(self.memory.shape,requires\_grad=False)
මතකයදැනටමත් ආරම්භ කර ඇති නමුත් අපි තොගය නැවත සකසමින් සිටිමු.
මෙයතවත් කාර්යයක් විය හැකිය reset , නමුත් මෙය භාවිතා කිරීම පහසු බව අපට පෙනී ගියේය.
409elifn==0:
සමුච්චිතඅනුක්රමික නැවත සකසන්න
411self.memory\_grad.fill\_(0.)
තොගයේනිවැරදි ස්ථානයේ වටිනාකම සකසන්න
414self.memory.data[n]=value.detach()
(නිදොස්කරණය සඳහා) අඩුක්කුව පිළිබඳ වාර්තාවක් තබා ගන්න
416self.n=n
තොගයටඑකතු කරන ලද අවසාන අගය පිළිබඳ වාර්තාවක් තබා ගන්න. ආපස්සට ප්රචාරය කිරීම සඳහා අපට මෙය සම්මත කර ගත යුතුය. StackFunction
421self.last=value
තොගයආපසු ලබා දෙයි
423defget(self):
එයභාවිතා කරන විට අඩුක්කුව ප්රමාණය පිළිබඳ වාර්තාවක් තබා ගන්න. මෙය සනීපාරක්ෂක පරීක්ෂණයක් සඳහා භාවිතා වේ append .
430self.last\_get\_n=self.n
පසුපසටප්රචාරණය කිරීමේදී PyTorch විසින් කැඳවනු ලබන StackFunction ඒ StackFunction.backwards සියල්ල හරහා ගන්න.
433returnStackFunction.apply(self.memory,self.memory\_grad,self.last,self.n)
මතකයමුදා හැරීමට
435deffree(self):
440self.memory=None441self.memory\_grad=None442self.last=None
යතුරුසහ අගයන් හැඹිලි කරන යාවත්කාලීන කරන ලද ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් මොඩියුලය මෙයයි.
445classFeedbackTransformerKV(Module):
layer අපි එක් එක් ස්ථරයක් සඳහා පරිගණක ක්රිඩාවට සමාන වන ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් ස්ථරය, වේn_layers ට්රාන්ස්ෆෝමරයේ ස්ථර ගණනd_model ට්රාන්ස්ෆෝමරයේ ඇති ලක්ෂණ ගණන452def\_\_init\_\_(self,layer:FeedbackTransformerLayer,n\_layers:int,d\_model:int,heads:int):
460super().\_\_init\_\_()
ට්රාන්ස්ෆෝමර්ස්ථරයේ පිටපත් සාදන්න
462self.layers=clone\_module\_list(layer,n\_layers)
අවසානසාමාන්යකරණ ස්තරය
464self.norm=nn.LayerNorm([layer.size])
මතකදෛශික ගණනය කරනු ලබන්නේ එක් එක් ස්ථරයේ නිරූපණවල බර කිරන ලද එකතුවකි. ඒ සඳහා බර පරාමිතිය මෙයයි.
467self.weights=nn.Parameter(torch.ones(n\_layers+1),requires\_grad=True)
බරතැබූ මුදල ගැනීමට පෙර බර සඳහා සොෆ්ට්මැක්ස්
469self.softmax=nn.Softmax(0)
හිසෙහිවිශේෂාංග ගණන
472d\_k=d\_model//heads
යතුරුලබා ගැනීම සඳහා කාවැද්දීම් (මතකය) පරිවර්තනය කිරීමේ මොඩියුලය
474self.key=PrepareForMultiHeadAttention(d\_model,heads,d\_k,bias=False)
යතුරුලබා ගැනීම සඳහා කාවැද්දීම් (මතකය) පරිවර්තනය කිරීමේ මොඩියුලය
476self.value=PrepareForMultiHeadAttention(d\_model,heads,d\_k,bias=False)
සිරස්වඇති යතුරු සඳහා මතකය
479self.mem\_key=Stack(512)
සිරස්වඇති අගයන් සඳහා මතකය
481self.mem\_value=Stack(512)
x_seq හැඩය සහිත ආදානය වේ [seq_len, batch_size, d_model]483defforward(self,x\_seq:torch.Tensor):
අනුක්රමිකඅක්ෂය දිගේ ලැයිස්තුවකට ආදානය බෙදන්න
489x\_seq=torch.unbind(x\_seq,dim=0)
ප්රතිදානයන්ගබඩා කිරීම සඳහා ලැයිස්තුව
491res=[]
එක්එක් ආදාන පියවර සඳහා
493forstep,xinenumerate(x\_seq):
ස්ථරප්රතිදානයන් ගබඩා කිරීම සඳහා ලැයිස්තුව
495layer\_outputs=[x]
යතුරුසහ වටිනාකම් තොගයක්
498key\_tensor=None499value\_tensor=None
අපිආරම්භක පියවර ඔබ්බට නම් යතුරු සහ අගයන් tensors ලබා ගන්න
501ifstep\>0:502key\_tensor=self.mem\_key.get()503value\_tensor=self.mem\_value.get()
එක්එක් ස්ථරය හරහා ධාවනය කරන්න
506forlayerinself.layers:
ස්ථරප්රතිදානය ලබා ගන්න
508x=layer(x=x,key=key\_tensor,value=value\_tensor)
ස්ථරප්රතිදානයන් ලැයිස්තුවට ඒවා එකතු කරන්න
510layer\_outputs.append(x)
ස්ථරයේප්රතිදානයන් ටෙන්සරයකට ගොඩගසන්න
513layer\_outputs=torch.stack(layer\_outputs)
ස්ථරප්රතිදානවල බර තැබූ එකතුවක් ලෙස මතක දෛශිකය ගණනය කරන්න
515mem=torch.einsum('lbd,l-\>bd',layer\_outputs,self.softmax(self.weights))
මතකයෙන්යතුරු ගණනය කර එය තොගයට එක් කරන්න
517self.mem\_key.append(step,self.key(mem))
මතකයෙන්අගයන් ගණනය කර එය තොගයට එක් කරන්න
519self.mem\_value.append(step,self.value(mem))
ප්රති. ල සඳහා ප්රතිදානය එක් කරන්න
521res.append(x)
නිමැවුම්ආතතීන් ගොඩගසන්න
524res=torch.stack(res)
ප්රතිදානයසාමාන්යකරණය කරන්න
526returnself.norm(res)
528deffree(self):529self.mem\_key.free()530self.mem\_value.free()