13import math
14
15import torch
16import torch.nn as nn
17
18from labml_nn.utils import clone_module_list
19from .feed_forward import FeedForward
20from .mha import MultiHeadAttention
21from .positional_encoding import get_positional_encoding
24class EmbeddingsWithPositionalEncoding(nn.Module):
31 def __init__(self, d_model: int, n_vocab: int, max_len: int = 5000):
32 super().__init__()
33 self.linear = nn.Embedding(n_vocab, d_model)
34 self.d_model = d_model
35 self.register_buffer('positional_encodings', get_positional_encoding(d_model, max_len))
37 def forward(self, x: torch.Tensor):
38 pe = self.positional_encodings[:x.shape[0]].requires_grad_(False)
39 return self.linear(x) * math.sqrt(self.d_model) + pe
42class EmbeddingsWithLearnedPositionalEncoding(nn.Module):
49 def __init__(self, d_model: int, n_vocab: int, max_len: int = 5000):
50 super().__init__()
51 self.linear = nn.Embedding(n_vocab, d_model)
52 self.d_model = d_model
53 self.positional_encodings = nn.Parameter(torch.zeros(max_len, 1, d_model), requires_grad=True)
55 def forward(self, x: torch.Tensor):
56 pe = self.positional_encodings[:x.shape[0]]
57 return self.linear(x) * math.sqrt(self.d_model) + pe
මෙයඑන්කෝඩර් තට්ටුවක් හෝ විකේතක තට්ටුවක් ලෙස ක්රියා කළ හැකිය.
🗒කඩදාසි ඇතුළු සමහර ක්රියාත්මක කිරීම්, ස්ථර-සාමාන්යකරණය සිදු කරන ස්ථානයේ වෙනස්කම් ඇති බව පෙනේ. මෙන්න අපි අවධානය සහ පෝෂක ඉදිරියට ජාල පෙර ස්ථරයක් සාමාන්යකරණය කරන්න, සහ මුල් අවශේෂ දෛශික එකතු කරන්න. විකල්පයක් වන්නේ අපද්රව්ය එකතු කිරීමෙන් පසු ස්ථර සාමාන්යකරණය කිරීමයි. නමුත් පුහුණුවීමේදී මෙය අඩු ස්ථාවර බව අපට පෙනී ගියේය. ට්රාන්ස්ෆෝමර් ගෘහ නිර්මාණ ශිල්පයේ ON Layer සාමාන්යකරණය පිළිබඳපත්රිකාවේ මේ පිළිබඳව සවිස්තරාත්මක සාකච්ඡාවක් අපට හමු විය.
60class TransformerLayer(nn.Module):
d_model
ටෝකනය කාවැද්දීමේ ප්රමාණයයි self_attn
ස්වයං අවධානය මොඩියුලය src_attn
යනු ප්රභව අවධානය යොමු කිරීමේ මොඩියුලය (මෙය විකේතකයක් තුළ භාවිතා කරන විට) feed_forward
යනු ආහාර ඉදිරි මොඩියුලයයි dropout_prob
ස්වයං අවධානයෙන් පසු ඉවත් වීමේ සම්භාවිතාව සහ FFN78 def __init__(self, *,
79 d_model: int,
80 self_attn: MultiHeadAttention,
81 src_attn: MultiHeadAttention = None,
82 feed_forward: FeedForward,
83 dropout_prob: float):
91 super().__init__()
92 self.size = d_model
93 self.self_attn = self_attn
94 self.src_attn = src_attn
95 self.feed_forward = feed_forward
96 self.dropout = nn.Dropout(dropout_prob)
97 self.norm_self_attn = nn.LayerNorm([d_model])
98 if self.src_attn is not None:
99 self.norm_src_attn = nn.LayerNorm([d_model])
100 self.norm_ff = nn.LayerNorm([d_model])
ආහාරඉදිරි ස්ථරයට ආදානය ඉතිරි කර ගත යුතුද යන්න
102 self.is_save_ff_input = False
104 def forward(self, *,
105 x: torch.Tensor,
106 mask: torch.Tensor,
107 src: torch.Tensor = None,
108 src_mask: torch.Tensor = None):
ස්වයංඅවධානය යොමු කිරීමට පෙර දෛශික සාමාන්යකරණය කරන්න
110 z = self.norm_self_attn(x)
ස්වයංඅවධානය හරහා ධාවනය කරන්න, i.e. යතුරු සහ වටිනාකම් ස්වයං සිට
112 self_attn = self.self_attn(query=z, key=z, value=z, mask=mask)
ස්වයංඅවධානය ප්රතිඵල එකතු
114 x = x + self.dropout(self_attn)
ප්රභවයක්ලබා දෙන්නේ නම්, ප්රභවයට අවධානය යොමු කිරීමෙන් ප්රති results ල ලබා ගන්න. එන්කෝඩර් ප්රතිදානයන් කෙරෙහි අවධානය යොමු කරන විකේතක තට්ටුවක් ඔබට ඇති විට මෙය
වේ119 if src is not None:
දෛශිකසාමාන්යකරණය කරන්න
121 z = self.norm_src_attn(x)
ප්රභවයටඅවධානය යොමු කරන්න. එනම් යතුරු සහ අගයන් ප්රභවයෙන් වේ
123 attn_src = self.src_attn(query=z, key=src, value=src, mask=src_mask)
මූලාශ්රඅවධානය යොමු ප්රතිඵල එක් කරන්න
125 x = x + self.dropout(attn_src)
පෝෂණයසඳහා සාමාන්යකරණය කරන්න
128 z = self.norm_ff(x)
නිශ්චිතවදක්වා ඇත්නම් ආදානය ආහාර ඉදිරි ස්ථරයට සුරකින්න
130 if self.is_save_ff_input:
131 self.ff_input = z.clone()
Feed-forwardජාලය හරහා ගමන් කරන්න
133 ff = self.feed_forward(z)
ප්රතිපෝෂණඉදිරි ප්රති results ල නැවත එක් කරන්න
135 x = x + self.dropout(ff)
136
137 return x
140class Encoder(nn.Module):
147 def __init__(self, layer: TransformerLayer, n_layers: int):
148 super().__init__()
ට්රාන්ස්ෆෝමර්ස්ථරයේ පිටපත් සාදන්න
150 self.layers = clone_module_list(layer, n_layers)
අවසානසාමාන්යකරණ ස්තරය
152 self.norm = nn.LayerNorm([layer.size])
154 def forward(self, x: torch.Tensor, mask: torch.Tensor):
එක්එක් ට්රාන්ස්ෆෝමර් ස්ථරය හරහා ධාවනය කරන්න
156 for layer in self.layers:
157 x = layer(x=x, mask=mask)
අවසානවශයෙන්, දෛශික සාමාන්යකරණය කරන්න
159 return self.norm(x)
162class Decoder(nn.Module):
169 def __init__(self, layer: TransformerLayer, n_layers: int):
170 super().__init__()
ට්රාන්ස්ෆෝමර්ස්ථරයේ පිටපත් සාදන්න
172 self.layers = clone_module_list(layer, n_layers)
අවසානසාමාන්යකරණ ස්තරය
174 self.norm = nn.LayerNorm([layer.size])
176 def forward(self, x: torch.Tensor, memory: torch.Tensor, src_mask: torch.Tensor, tgt_mask: torch.Tensor):
එක්එක් ට්රාන්ස්ෆෝමර් ස්ථරය හරහා ධාවනය කරන්න
178 for layer in self.layers:
179 x = layer(x=x, mask=tgt_mask, src=memory, src_mask=src_mask)
අවසානවශයෙන්, දෛශික සාමාන්යකරණය කරන්න
181 return self.norm(x)
මෙයටෝකන පුරෝකථනය කරන අතර එම අයගේ සොෆ්ට්මැක්ස් ලබා දෙයි. ඔබ භාවිතා කරන්නේ නම් ඔබට මෙය අවශ්ය නොවේ nn.CrossEntropyLoss
.
184class Generator(nn.Module):
194 def __init__(self, n_vocab: int, d_model: int):
195 super().__init__()
196 self.projection = nn.Linear(d_model, n_vocab)
198 def forward(self, x):
199 return self.projection(x)
202class EncoderDecoder(nn.Module):
209 def __init__(self, encoder: Encoder, decoder: Decoder, src_embed: nn.Module, tgt_embed: nn.Module, generator: nn.Module):
210 super().__init__()
211 self.encoder = encoder
212 self.decoder = decoder
213 self.src_embed = src_embed
214 self.tgt_embed = tgt_embed
215 self.generator = generator
මෙයඔවුන්ගේ කේතයෙන් වැදගත් විය. ග්ලෝරෝට්/fan_avg සමඟ පරාමිතීන් ආරම්භ කරන්න.
219 for p in self.parameters():
220 if p.dim() > 1:
221 nn.init.xavier_uniform_(p)
223 def forward(self, src: torch.Tensor, tgt: torch.Tensor, src_mask: torch.Tensor, tgt_mask: torch.Tensor):
එන්කෝඩරයහරහා ප්රභවය ධාවනය කරන්න
225 enc = self.encode(src, src_mask)
විකේතකයහරහා කේතීකරණ සහ ඉලක්ක ධාවනය කරන්න
227 return self.decode(enc, src_mask, tgt, tgt_mask)
229 def encode(self, src: torch.Tensor, src_mask: torch.Tensor):
230 return self.encoder(self.src_embed(src), src_mask)
232 def decode(self, memory: torch.Tensor, src_mask: torch.Tensor, tgt: torch.Tensor, tgt_mask: torch.Tensor):
233 return self.decoder(self.tgt_embed(tgt), memory, src_mask, tgt_mask)