හයිපර්නෙට්වර්ක්ස්- හයිපර්එල්එස්එම්

අපි PyTorchභාවිතා විවරණ සමග, කඩදාසි HyperNetworksහඳුන්වා HyperlSTM ක්රියාත්මක කර ඇත. ඩේවිඩ් හාගේ මෙම බ්ලොග් සටහන හයිපර්නෙට්වර්ක්ස් පිළිබඳ හොඳ පැහැදිලි කිරීමක් ලබා දෙයි.

ෂේක්ස්පියර්දත්ත කට්ටලය පිළිබඳ පෙළ පුරෝකථනය කිරීම සඳහා හයිපර්එල්එස්ටීඑම් පුහුණු කරන අත්හදා බැලීමක් අපට තිබේ. මෙන්න කේතය සඳහා සබැඳිය: experiment.py

Open In Colab View Run

හයිපර්නෙට්වර්ක්ස්විශාල ජාලයක බර උත්පාදනය කිරීම සඳහා කුඩා ජාලයක් භාවිතා කරයි. ප්රභේද දෙකක් තිබේ: ස්ථිතික අධි-ජාල සහ ගතික අධි-ජාල. ස්ථිතික හයිපර්නෙට්වර්ක්ස් යනු සංවහන ජාලයක බර (කර්නල්) ජනනය කරන කුඩා ජාල ඇත. ඩයිනමික් හයිපර්නෙට්වර්ක්ස් එක් එක් පියවර සඳහා පුනරාවර්තන ස්නායුක ජාලයක පරාමිතීන් ජනනය කරයි. මෙය අවසාන වශයෙන් ක්රියාත්මක කිරීමයි.

ගතිකඅධි-ජාල

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 LSTMCell

හයිපර්එල්එස්ටීඑම්සෛලය

HyperLSTMසඳහා කුඩා ජාලය සහ විශාල ජාලය දෙකම 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 = ifgo

195        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_hat

හයිපර්එල්එස්ටීඑම්මොඩියුලය

203class 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)