@webwriter/neural-network
Version:
Deep learning visualization for feed-forward networks with custom datasets, training and prediction.
111 lines (98 loc) • 3.98 kB
text/typescript
import { LitElementWw } from '@webwriter/lit'
import { CSSResult, TemplateResult, html } from 'lit'
import { customElement, property, query } from 'lit/decorators.js'
import { consume } from '@lit/context'
import { globalStyles } from '@/global_styles'
import { editableContext } from '@/contexts/editable_context'
import type { Settings } from '@/types/settings'
import { settingsContext } from '@/contexts/settings_context'
import type { CLayer } from '@/components/network/c_layer'
import type { Activation } from '@/types/activation'
import { NetworkUtils } from '@/utils/network_utils'
import type { ModelConf } from '@/types/model_conf'
import { modelConfContext } from '@/contexts/model_conf_context'
import type { SlChangeEvent } from '@shoelace-style/shoelace'
import { CCard } from '../reusables/c-card'
import SlSelect from '@shoelace-style/shoelace/dist/components/select/select.component.js'
import SlOption from '@shoelace-style/shoelace/dist/components/option/option.component.js'
import { msg } from '@lit/localize'
export class LayerActivationCard extends LitElementWw {
static scopedElements = {
'c-card': CCard,
'sl-select': SlSelect,
'sl-option': SlOption,
}
({ context: editableContext, subscribe: true })
accessor editable: boolean
({ context: settingsContext, subscribe: true })
accessor settings: Settings
({ context: modelConfContext, subscribe: true })
accessor modelConf: ModelConf
({ attribute: false })
accessor layer: CLayer
('sl-select')
accessor _selectActivationFormElm: SlSelect
// METHODS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
handleChangeActivation(): void {
const activationName = this._selectActivationFormElm.value
const activation: Activation = NetworkUtils.getActivation(
activationName as any,
)
this.layer.setActivation(activation)
this.dispatchEvent(
new Event('update-layer-confs', {
bubbles: true,
composed: true,
}),
)
// we need to request an update, so that when we select another layer with
// the same activation function as this layers activation function before
// the update/rerender, lit can detect the changes and rerender
this.requestUpdate()
}
// STYLES - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static styles: CSSResult = globalStyles
// RENDER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
render(): TemplateResult<1> {
const activation = NetworkUtils.getActivation(
this.layer.conf.activation.name as any,
)
return html`
<c-card>
<div slot="title">${msg('Activation function')}</div>
<div slot="content">
<sl-select
value=${this.layer.conf.activation.name}
?disabled=${this.modelConf.model ||
(!this.editable && !this.settings.mayChangeActivationFunction)}
help-text=${msg(
'The selected activation applies to all neurons in this layer.',
)}
@sl-change=${(_e: SlChangeEvent) => {
this.handleChangeActivation()
}}
>
${NetworkUtils.activationOptions.map(
(activation) =>
html`<sl-option value="${activation.name}"
>${activation.name}</sl-option
>`,
)}
</sl-select>
${Object.hasOwn(this.layer.conf.activation, 'img')
? html`<img src=${activation.img} />`
: html``}
<p>
${msg(
"After calculating a neuron's value by adding up its weighted input values and its bias:",
)}${' '}${this.layer.conf.activation.description}
</p>
<p>
${msg('Range of possible output values:')}${' '}${this.layer.conf
.activation.range}
</p>
</div>
</c-card>
`
}
}