අපි PyTorchභාවිතා විවරණ සමග, කඩදාසි HyperNetworksහඳුන්වා HyperlSTM ක්රියාත්මක කර ඇත. ඩේවිඩ් හාගේ මෙම බ්ලොග් සටහන හයිපර්නෙට්වර්ක්ස් පිළිබඳ හොඳ පැහැදිලි කිරීමක් ලබා දෙයි.
ෂේක්ස්පියර්දත්ත කට්ටලය පිළිබඳ පෙළ පුරෝකථනය කිරීම සඳහා හයිපර්එල්එස්ටීඑම් පුහුණු කරන අත්හදා බැලීමක් අපට තිබේ. මෙන්න කේතය සඳහා සබැඳිය: experiment.py
හයිපර්නෙට්වර්ක්ස්විශාල ජාලයක බර උත්පාදනය කිරීම සඳහා කුඩා ජාලයක් භාවිතා කරයි. ප්රභේද දෙකක් තිබේ: ස්ථිතික අධි-ජාල සහ ගතික අධි-ජාල. ස්ථිතික හයිපර්නෙට්වර්ක්ස් යනු සංවහන ජාලයක බර (කර්නල්) ජනනය කරන කුඩා ජාල ඇත. ඩයිනමික් හයිපර්නෙට්වර්ක්ස් එක් එක් පියවර සඳහා පුනරාවර්තන ස්නායුක ජාලයක පරාමිතීන් ජනනය කරයි. මෙය අවසාන වශයෙන් ක්රියාත්මක කිරීමයි.
RNNහි එක් එක් පියවර සඳහා පරාමිතීන් නියතව පවතී. ගතික හයිපර්නෙට්වර්ක්ස් එක් එක් පියවර සඳහා විවිධ පරාමිතීන් ජනනය කරයි. හයිපර්එල්එස්ටීඑම් හි LSTM හි ව්යුහය ඇති නමුත් එක් එක් පියවරේ පරාමිතීන් කුඩා LSTM ජාලයකින් වෙනස් වේ.
මූලිකස්වරූපයෙන්, ඩයිනමික් හයිපර්නෙට්වර්ක් කුඩා පුනරාවර්තන ජාලයක් ඇති අතර එය විශාල පුනරාවර්තන ජාලයේ එක් එක් පරාමිති ටෙන්සරයට අනුරූප විශේෂාංග දෛශිකයක් ජනනය කරයි. විශාල ජාලයට යම් පරාමිතියක් ඇතැයි කියමු කුඩා ජාලය විශේෂාංග දෛශිකයක් ජනනය කරන අතර රේඛීය පරිවර්තනයක් ලෙස ගතිකව ගණනය කරමු . උදාහරණයක් ලෙස 3-d ටෙන්සර් පරාමිතියක් වන අතර එය ආතතිය-දෛශික ගුණ කිරීම වේ. සාමාන්යයෙන් කුඩා පුනරාවර්තන ජාලයේ නිමැවුමේ රේඛීය පරිවර්තනයකි.
විශාලපුනරාවර්තන ජාලයන් විශාල ගතිකව ගණනය කරන ලද පරාමිතීන් ඇත. මෙම ලක්ෂණය දෛශික රේඛීය පරිවර්තනය භාවිතා ගණනය කර ඇත. මෙම පරිවර්තනයට ඊටත් වඩා විශාල බර ආතතයක් අවශ්ය වේ. එනම්, හැඩය ඇති විට , වනු ඇත .
මෙයජය ගැනීම සඳහා, එකම ප්රමාණයේ අනුකෘතියක එක් එක් පේළිය ගතිකව පරිමාණය කිරීමෙන් පුනරාවර්තන ජාලයේ බර පරාමිතීන් ගණනය කරමු.
පරාමිති අනුකෘතියක් කොහෙද .
මූලද්රව්ය-wiseානවන්ත ගුණ කිරීම සඳහා අප ගණනය කරන විට අපට මෙය තවදුරටත් ප්රශස්තිකරණය කළ හැකිය.
73from typing import Optional, Tuple
74
75import torch
76from torch import nn
77
78from labml_helpers.module import Module
79from labml_nn.lstm import LSTMCellHyperLSTMසඳහා කුඩා ජාලය සහ විශාල ජාලය දෙකම LSTM ව්යුහය ඇත. මෙය කඩදාසි වල උපග්රන්ථය A.2.2 හි අර්ථ දක්වා ඇත.
82class HyperLSTMCell(Module): input_size
යනු ආදානයේ ප්රමාණය , hidden_size
LSTM හි ප්රමාණය hyper_size
වන අතර කුඩා LSTM හි බර වෙනස් කරන කුඩා LSTM වල ප්රමාණයයි විශාල පිටත LSTM. n_z
යනු LSTM බර වෙනස් කිරීම සඳහා භාවිතා කරන විශේෂාංග දෛශිකවල ප්රමාණයයි.
ගණනය කිරීම සඳහා අපි කුඩා LSTM හි ප්රතිදානය භාවිතා කරන අතර රේඛීය පරිවර්තනයන් භාවිතා කරමු. අපි නැවත රේඛීය පරිවර්තනයන් භාවිතා කරමින් , සහ මේවායින් ගණනය කරමු. මේවා ප්රධාන LSTM හි බර සහ පක්ෂග්රාහී ආතතීන් පේළි පරිමාණය කිරීමට භාවිතා කරයි.
📝වන ගණනය හා අනුක්රමික රේඛීය පරිවර්තනයන් දෙකක් මෙම තනි රේඛීය පරිවර්තනය බවට ඒකාබද්ධ කළ හැකි බැවින්. කෙසේ වෙතත් අපි මෙය වෙන වෙනම ක්රියාත්මක කර ඇති අතර එමඟින් එය කඩදාසි වල විස්තරය සමඟ ගැලපේ.
90 def __init__(self, input_size: int, hidden_size: int, hyper_size: int, n_z: int):108 super().__init__()හයිපර්එල්එස්ටීඑම්වෙත ආදානය යනු ආදානය කොතැනද යන්න සහ පෙර පියවරේදී පිටත LSTM හි ප්රතිදානය වේ. එබැවින් ආදාන ප්රමාණය වේ hidden_size + input_size
.
HyperlSTMහි ප්රතිදානය සහ .
121 self.hyper = LSTMCell(hidden_size + input_size, hyper_size, layer_norm=True)🤔 කඩදාසි තුළ එය ටයිපෝ බව මට හැඟෙන පරිදි නියම කර ඇත.
127 self.z_h = nn.Linear(hyper_size, 4 * n_z)129 self.z_x = nn.Linear(hyper_size, 4 * n_z)131 self.z_b = nn.Linear(hyper_size, 4 * n_z, bias=False)134 d_h = [nn.Linear(n_z, hidden_size, bias=False) for _ in range(4)]
135 self.d_h = nn.ModuleList(d_h)137 d_x = [nn.Linear(n_z, hidden_size, bias=False) for _ in range(4)]
138 self.d_x = nn.ModuleList(d_x)140 d_b = [nn.Linear(n_z, hidden_size) for _ in range(4)]
141 self.d_b = nn.ModuleList(d_b)බරමැට්ට්රිස්
144 self.w_h = nn.ParameterList([nn.Parameter(torch.zeros(hidden_size, hidden_size)) for _ in range(4)])බරමැට්ට්රිස්
146 self.w_x = nn.ParameterList([nn.Parameter(torch.zeros(hidden_size, input_size)) for _ in range(4)])ස්ථරයසාමාන්යකරණය
149 self.layer_norm = nn.ModuleList([nn.LayerNorm(hidden_size) for _ in range(4)])
150 self.layer_norm_c = nn.LayerNorm(hidden_size)152 def forward(self, x: torch.Tensor,
153 h: torch.Tensor, c: torch.Tensor,
154 h_hat: torch.Tensor, c_hat: torch.Tensor):161 x_hat = torch.cat((h, x), dim=-1)163 h_hat, c_hat = self.hyper(x_hat, h_hat, c_hat)166 z_h = self.z_h(h_hat).chunk(4, dim=-1)168 z_x = self.z_x(h_hat).chunk(4, dim=-1)170 z_b = self.z_b(h_hat).chunk(4, dim=-1)අපිගණනය කරමු , සහ ලූපයක් තුළ
173 ifgo = []
174 for i in range(4):176 d_h = self.d_h[i](z_h[i])178 d_x = self.d_x[i](z_x[i])185 y = d_h * torch.einsum('ij,bj->bi', self.w_h[i], h) + \
186 d_x * torch.einsum('ij,bj->bi', self.w_x[i], x) + \
187 self.d_b[i](z_b[i])
188
189 ifgo.append(self.layer_norm[i](y))192 i, f, g, o = ifgo195 c_next = torch.sigmoid(f) * c + torch.sigmoid(i) * torch.tanh(g)198 h_next = torch.sigmoid(o) * torch.tanh(self.layer_norm_c(c_next))
199
200 return h_next, c_next, h_hat, c_hat203class HyperLSTM(Module): HyperlSTMජාලයක් සාදන්න. n_layers
208 def __init__(self, input_size: int, hidden_size: int, hyper_size: int, n_z: int, n_layers: int):213 super().__init__()තත්වයආරම්භ කිරීම සඳහා ප්රමාණ ගබඩා කරන්න
216 self.n_layers = n_layers
217 self.hidden_size = hidden_size
218 self.hyper_size = hyper_sizeඑක්එක් ස්ථරය සඳහා සෛල සාදන්න. පළමු ස්ථරයට පමණක් ආදානය කෙලින්ම ලැබෙන බව සලකන්න. සෙසු ස්ථර පහත ස්ථරයෙන් ආදානය ලබා ගනී
222 self.cells = nn.ModuleList([HyperLSTMCell(input_size, hidden_size, hyper_size, n_z)] +
223 [HyperLSTMCell(hidden_size, hidden_size, hyper_size, n_z) for _ in
224 range(n_layers - 1)])x
හැඩය [n_steps, batch_size, input_size]
සහ state
ක tuple වේ . හැඩය [batch_size, hidden_size]
සහ හැඩය ඇති [batch_size, hyper_size]
. 226 def forward(self, x: torch.Tensor,
227 state: Optional[Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]] = None):234 n_steps, batch_size = x.shape[:2]නම්ශුන්ය සමඟ රාජ්යය ආරම්භ කරන්න None
237 if state is None:
238 h = [x.new_zeros(batch_size, self.hidden_size) for _ in range(self.n_layers)]
239 c = [x.new_zeros(batch_size, self.hidden_size) for _ in range(self.n_layers)]
240 h_hat = [x.new_zeros(batch_size, self.hyper_size) for _ in range(self.n_layers)]
241 c_hat = [x.new_zeros(batch_size, self.hyper_size) for _ in range(self.n_layers)]243 else:
244 (h, c, h_hat, c_hat) = stateඑක්එක් ස්ථරයේ තත්වයන් ලබා ගැනීම සඳහා ආතතීන් ආපසු හරවන්න
📝ඔබට ටෙන්සර් සමඟ වැඩ කළ හැකි නමුත් මෙය නිදොස් කිරීමට පහසුය
248 h, c = list(torch.unbind(h)), list(torch.unbind(c))
249 h_hat, c_hat = list(torch.unbind(h_hat)), list(torch.unbind(c_hat))එක්එක් පියවරේදී අවසාන ස්ථරයේ ප්රතිදානයන් එකතු කරන්න
252 out = []
253 for t in range(n_steps):පළමුස්ථරයට ආදානය යනු ආදානය ම වේ
255 inp = x[t]ස්ථරහරහා ලූප්
257 for layer in range(self.n_layers):ස්ථරයේතත්වය ලබා ගන්න
259 h[layer], c[layer], h_hat[layer], c_hat[layer] = \
260 self.cells[layer](inp, h[layer], c[layer], h_hat[layer], c_hat[layer])ඊළඟස්ථරයට ආදානය මෙම ස්ථරයේ තත්වයයි
262 inp = h[layer]අවසාන ස්ථරයේ ප්රතිදානය එකතු කරන්න
264 out.append(h[-1])ප්රතිදානයන්සහ ප්රාන්ත ගොඩගසන්න
267 out = torch.stack(out)
268 h = torch.stack(h)
269 c = torch.stack(c)
270 h_hat = torch.stack(h_hat)
271 c_hat = torch.stack(c_hat)274 return out, (h, c, h_hat, c_hat)