diff --git a/CHANGELOG.md b/CHANGELOG.md index 35cf9368..8407105b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Marcelle changelog +## 0.4.4 + +- Various minor bugfixes + ## 0.4.3 - Fixed svelte component compilation (reverted to svelte v3.39) diff --git a/package.json b/package.json index 395c3660..094e3d18 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@marcellejs/core", "description": "Marcelle Core API", - "version": "0.4.3", + "version": "0.4.4", "repository": { "type": "git", "url": "https://github.com/marcellejs/marcelle" diff --git a/src/components/dataset-browser/dataset-browser.view.svelte b/src/components/dataset-browser/dataset-browser.view.svelte index a11b7c3e..3ac2d002 100644 --- a/src/components/dataset-browser/dataset-browser.view.svelte +++ b/src/components/dataset-browser/dataset-browser.view.svelte @@ -171,7 +171,6 @@ } }); }); - @@ -250,11 +249,10 @@ .browser-class-body img { width: 60px; box-sizing: content-box; - @apply border-2 border-transparent rounded-md; + @apply border-solid border-2 border-transparent rounded-md; } .browser-class-body img.selected { - @apply border-teal-700; + @apply border-gray-600; } - diff --git a/src/components/mlp-classifier/mlp-classifier.component.ts b/src/components/mlp-classifier/mlp-classifier.component.ts index 59cee498..6f844ae4 100644 --- a/src/components/mlp-classifier/mlp-classifier.component.ts +++ b/src/components/mlp-classifier/mlp-classifier.component.ts @@ -20,6 +20,7 @@ import { import type { ServiceIterable } from '../../core/data-store/service-iterable'; import { Dataset, isDataset } from '../../core/dataset'; import { Catch, TrainingError } from '../../utils/error-handling'; +import { throwError } from '../../utils/error-handling'; interface TrainingData { training_x: Tensor2D; @@ -130,6 +131,13 @@ export class MLPClassifier extends TFJSBaseModel : (this.labels = Array.from(new Set(await dataset.map(({ y }) => y).toArray()))); const ds = isDataset(dataset) ? dataset.items() : dataset; this.$training.set({ status: 'start', epochs: this.parameters.epochs.value }); + if (this.labels.length === 0) { + throwError(new TrainingError('This dataset is empty or is missing labels')); + this.$training.set({ + status: 'error', + }); + return; + } setTimeout(async () => { const data = await dataSplit(ds, 0.75, this.labels); this.buildModel(data.training_x.shape[1], data.training_y.shape[1]); diff --git a/src/components/training-history/training-history.component.ts b/src/components/training-history/training-history.component.ts index 55c95f0b..82346c06 100644 --- a/src/components/training-history/training-history.component.ts +++ b/src/components/training-history/training-history.component.ts @@ -1,6 +1,7 @@ import { Paginated, Service } from '@feathersjs/feathers'; import { logger, Model, Component, Stream, TrainingRun, TrainingStatus } from '../../core'; import { DataStore } from '../../core/data-store'; +import { preventConcurrentCalls } from '../../utils/asynchronicity'; import { noop } from '../../utils/misc'; import View from './training-history.view.svelte'; @@ -38,9 +39,12 @@ export class TrainingHistory extends Component { protected modelName: string; protected nextIndex: number; + private lock = Promise.resolve(); + constructor(public dataStore: DataStore, options: TrainingHistoryOptions = {}) { super(); this.options = { ...defaultOptions, ...options }; + this.lock = this.lock.then(noop); this.start(); this.ready = this.ready .then(() => this.dataStore.connect()) @@ -71,7 +75,7 @@ export class TrainingHistory extends Component { }) .then(({ data: foundRuns }) => { if (foundRuns.length > 0) { - return parseInt(foundRuns[0].name.split(`${name}-`)[1]) + 1; + return parseInt(foundRuns[0].name.split(`${basename}-`)[1]) + 1; } return 1; }) @@ -85,6 +89,7 @@ export class TrainingHistory extends Component { return this; } + @preventConcurrentCalls('lock') protected async trackTrainingStream(x: TrainingStatus): Promise { if (x.status === 'start') { this.crtRun = await this.runService.create({ @@ -119,6 +124,10 @@ export class TrainingHistory extends Component { }, ]), }); + } else if (x.status === 'error') { + this.runService.patch(this.crtRun.id, { + status: x.status, + }); } } diff --git a/src/components/training-history/training-history.view.svelte b/src/components/training-history/training-history.view.svelte index 690672e9..bae701e4 100644 --- a/src/components/training-history/training-history.view.svelte +++ b/src/components/training-history/training-history.view.svelte @@ -47,6 +47,10 @@ }, }); + provider.data.subscribe(() => { + selection.set([]); + }); + const columns: Column[] = [ { name: 'name', sortable: true }, { name: 'start', sortable: true, type: 'date' }, @@ -82,7 +86,7 @@ {provider} actions={[ ...actions.map((name) => (typeof name === 'string' ? { name } : name)), - { name: 'remove', confirm: true }, + { name: 'delete', confirm: true }, ]} bind:selection={$selection} bind:this={mainTable} diff --git a/src/ui/components/Select.svelte b/src/ui/components/Select.svelte index a32de3e7..27a0537a 100644 --- a/src/ui/components/Select.svelte +++ b/src/ui/components/Select.svelte @@ -17,7 +17,7 @@ on:change={(e) => dispatch('change', e.target.value)} > {#if placeholder} - + {/if} {#each options as option} diff --git a/src/ui/components/Table.svelte b/src/ui/components/Table.svelte index 19908a70..0a1be66a 100644 --- a/src/ui/components/Table.svelte +++ b/src/ui/components/Table.svelte @@ -1,5 +1,5 @@