Post-pre learning rule for ``LocalConnection2D`` subclass of ``AbstractConnection`` class.
(self, **kwargs)
| 285 | super().update() |
| 286 | |
| 287 | def _local_connection2d_update(self, **kwargs) -> None: |
| 288 | # language=rst |
| 289 | """ |
| 290 | Post-pre learning rule for ``LocalConnection2D`` subclass of |
| 291 | ``AbstractConnection`` class. |
| 292 | """ |
| 293 | # Get LC layer parameters. |
| 294 | stride = self.connection.stride |
| 295 | batch_size = self.source.batch_size |
| 296 | kernel_height = self.connection.kernel_size[0] |
| 297 | kernel_width = self.connection.kernel_size[1] |
| 298 | in_channels = self.connection.source.shape[0] |
| 299 | out_channels = self.connection.n_filters |
| 300 | height_out = self.connection.conv_size[0] |
| 301 | width_out = self.connection.conv_size[1] |
| 302 | |
| 303 | target_x = self.target.x.reshape( |
| 304 | batch_size, out_channels * height_out * width_out, 1 |
| 305 | ) |
| 306 | target_x = target_x * torch.eye(out_channels * height_out * width_out).to( |
| 307 | self.connection.w.device |
| 308 | ) |
| 309 | source_s = ( |
| 310 | self.source.s.type(torch.float) |
| 311 | .unfold(-2, kernel_height, stride[0]) |
| 312 | .unfold(-2, kernel_width, stride[1]) |
| 313 | .reshape( |
| 314 | batch_size, |
| 315 | height_out * width_out, |
| 316 | in_channels * kernel_height * kernel_width, |
| 317 | ) |
| 318 | .repeat(1, out_channels, 1) |
| 319 | .to(self.connection.w.device) |
| 320 | ) |
| 321 | |
| 322 | target_s = self.target.s.type(torch.float).reshape( |
| 323 | batch_size, out_channels * height_out * width_out, 1 |
| 324 | ) |
| 325 | target_s = target_s * torch.eye(out_channels * height_out * width_out).to( |
| 326 | self.connection.w.device |
| 327 | ) |
| 328 | source_x = ( |
| 329 | self.source.x.unfold(-2, kernel_height, stride[0]) |
| 330 | .unfold(-2, kernel_width, stride[1]) |
| 331 | .reshape( |
| 332 | batch_size, |
| 333 | height_out * width_out, |
| 334 | in_channels * kernel_height * kernel_width, |
| 335 | ) |
| 336 | .repeat(1, out_channels, 1) |
| 337 | .to(self.connection.w.device) |
| 338 | ) |
| 339 | |
| 340 | # Pre-synaptic update. |
| 341 | if self.nu[0].any(): |
| 342 | pre = self.reduction(torch.bmm(target_x, source_s), dim=0) |
| 343 | self.connection.w -= self.nu[0] * pre.view(self.connection.w.size()) |
| 344 | # Post-synaptic update. |