()
| 2302 | } |
| 2303 | |
| 2304 | buildSelectionDetail() { |
| 2305 | if (!this.selectedNeuron) return null; |
| 2306 | const { layerIndex, neuronIndex } = this.selectedNeuron; |
| 2307 | const data = this.selectionConnectionData || this.collectSelectionConnectionData(); |
| 2308 | const layerActivations = this.lastNetworkActivations?.[layerIndex] ?? null; |
| 2309 | const activationValue = |
| 2310 | Array.isArray(layerActivations) || layerActivations instanceof Float32Array |
| 2311 | ? layerActivations[neuronIndex] ?? null |
| 2312 | : null; |
| 2313 | const previousActivations = |
| 2314 | layerIndex > 0 ? this.lastNetworkActivations?.[layerIndex - 1] ?? null : null; |
| 2315 | const nextActivations = |
| 2316 | layerIndex < this.lastNetworkActivations.length - 1 |
| 2317 | ? this.lastNetworkActivations?.[layerIndex + 1] ?? null |
| 2318 | : null; |
| 2319 | let sumContributions = 0; |
| 2320 | |
| 2321 | const incoming = data.incoming.map((connection) => { |
| 2322 | const sourceActivation = |
| 2323 | previousActivations && (previousActivations instanceof Float32Array || Array.isArray(previousActivations)) |
| 2324 | ? previousActivations[connection.sourceIndex] ?? 0 |
| 2325 | : 0; |
| 2326 | const contribution = sourceActivation * connection.weight; |
| 2327 | sumContributions += contribution; |
| 2328 | return { |
| 2329 | sourceIndex: connection.sourceIndex, |
| 2330 | weight: connection.weight, |
| 2331 | sourceActivation, |
| 2332 | contribution, |
| 2333 | }; |
| 2334 | }); |
| 2335 | |
| 2336 | const bias = data.bias ?? (layerIndex > 0 ? 0 : null); |
| 2337 | const preActivationFromModel = |
| 2338 | layerIndex > 0 |
| 2339 | ? this.lastPreActivations?.[layerIndex - 1]?.[neuronIndex] ?? null |
| 2340 | : activationValue ?? null; |
| 2341 | const inferredPreActivation = |
| 2342 | bias !== null && bias !== undefined ? sumContributions + bias : sumContributions; |
| 2343 | const preActivation = |
| 2344 | preActivationFromModel !== null && preActivationFromModel !== undefined |
| 2345 | ? preActivationFromModel |
| 2346 | : inferredPreActivation; |
| 2347 | |
| 2348 | const outgoingContributionBase = Number.isFinite(activationValue) ? activationValue : 0; |
| 2349 | const outgoing = data.outgoing.map((connection) => { |
| 2350 | const targetActivation = |
| 2351 | nextActivations && (nextActivations instanceof Float32Array || Array.isArray(nextActivations)) |
| 2352 | ? nextActivations[connection.targetIndex] ?? 0 |
| 2353 | : 0; |
| 2354 | return { |
| 2355 | targetIndex: connection.targetIndex, |
| 2356 | weight: connection.weight, |
| 2357 | targetActivation, |
| 2358 | contribution: outgoingContributionBase * connection.weight, |
| 2359 | }; |
| 2360 | }); |
| 2361 |
no test coverage detected