neuron-viewer/src/types.ts (57 lines of code) (raw):

import { scaleLinear } from "d3-scale" import { min, max, flatten } from "lodash" export type Neuron = { layer: number; neuron: number; } export type TokenAndActivation = { token: string, activation: number normalized_activation?: number } export type TokenSequence = TokenAndActivation[] export const normalizeTokenActs = (...sequences: TokenSequence[][]) => { // console.log('sequences', sequences) let flattened: TokenAndActivation[] = flatten(flatten(sequences)) // Replace all activations less than 0 in data.tokens with 0. This matches the format in the // top + random activation records displayed in the main grid. flattened = flattened.map(({token, activation}) => { return { token, activation: Math.max(activation, 0) } }) const maxActivation = max(flattened.map((ta) => ta.activation)) || 0; const neuronScale = scaleLinear() // Even though we're only displaying positive activations, we still need to scale in a way that // accounts for the existence of negative activations, since our color scale includes them. .domain([0, maxActivation]) .range([0, 1]) return sequences.map((seq) => seq.map((tas) => tas.map(({ token, activation }) => ({ token, activation, normalized_activation: neuronScale(activation), })))) } export type Color = {r: number, g: number, b: number}; export function interpolateColor(color_l: Color, color_r: Color, value: number) { const color = { r: Math.round(color_l.r + (color_r.r - color_l.r) * value), g: Math.round(color_l.g + (color_r.g - color_l.g) * value), b: Math.round(color_l.b + (color_r.b - color_l.b) * value), } return color } export function getInterpolatedColor(colors: Color[], boundaries: number[], value: number) { const index = boundaries.findIndex((boundary) => boundary >= value) const colorIndex = Math.max(0, index - 1) const color_left = colors[colorIndex] const color_right = colors[colorIndex + 1] const boundary_left = boundaries[colorIndex] const boundary_right = boundaries[colorIndex + 1] const ratio = (value - boundary_left) / (boundary_right - boundary_left) const color = interpolateColor(color_left, color_right, ratio) return color } export const DEFAULT_COLORS = [ // { r: 255, g: 0, b: 105 }, { r: 255, g: 255, b: 255 }, { r: 0, g: 255, b: 0 }, ] export const DEFAULT_BOUNDARIES = [ // 0, 0.5, 1 0, 1 ]