Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing form fields to new UI #1463

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AlgorithmsEnum,
AlgorithmSettingType,
EarlyStoppingAlgorithmsEnum,
} from '../enumerations/algorithms.enum';

export interface AlgorithmSetting {
Expand All @@ -15,7 +16,7 @@ export const GridSettings: AlgorithmSetting[] = [];
export const RandomSearchSettings: AlgorithmSetting[] = [
{
name: 'random_state',
value: 'None',
value: null,
type: AlgorithmSettingType.STRING,
},
];
Expand Down Expand Up @@ -46,7 +47,7 @@ export const BayesianOptimizationSettings: AlgorithmSetting[] = [
},
{
name: 'random_state',
value: 'None',
value: null,
type: AlgorithmSettingType.INTEGER,
},
];
Expand Down Expand Up @@ -216,6 +217,24 @@ export const DartsSettings: AlgorithmSetting[] = [
},
];

export const EarlyStoppingSettings: AlgorithmSetting[] = [
{
name: 'min_trials_required',
value: 3,
type: AlgorithmSettingType.INTEGER,
},
{
name: 'start_step',
value: 4,
type: AlgorithmSettingType.INTEGER,
},
];

export const EarlyStoppingSettingsMap: { [key: string]: AlgorithmSetting[] } = {
[EarlyStoppingAlgorithmsEnum.NONE]: [],
[EarlyStoppingAlgorithmsEnum.MEDIAN]: EarlyStoppingSettings,
};

export const AlgorithmSettingsMap: { [key: string]: AlgorithmSetting[] } = {
[AlgorithmsEnum.GRID]: GridSettings,
[AlgorithmsEnum.RANDOM]: RandomSearchSettings,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { AlgorithmsEnum } from '../enumerations/algorithms.enum';
import {
AlgorithmsEnum,
EarlyStoppingAlgorithmsEnum,
} from '../enumerations/algorithms.enum';

export const AlgorithmNames = {
[AlgorithmsEnum.GRID]: 'Grid',
Expand All @@ -13,3 +16,8 @@ export const NasAlgorithmNames = {
[AlgorithmsEnum.ENAS]: 'Efficient Neural Architecture Search',
[AlgorithmsEnum.DARTS]: 'Differentiable Architecture Search',
};

export const EarlyStoppingAlgorithmNames = {
[EarlyStoppingAlgorithmsEnum.NONE]: 'None',
[EarlyStoppingAlgorithmsEnum.MEDIAN]: 'Median Stopping Rule',
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ export enum AlgorithmsEnum {
DARTS = 'darts',
}

export enum EarlyStoppingAlgorithmsEnum {
NONE = 'none',
MEDIAN = 'medianstop',
}

export enum AlgorithmSettingType {
STRING = 'string',
INTEGER = 'integer',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ export interface ExperimentSpec {
parallelTrialCount?: number;
maxTrialCount?: number;
maxFailedTrialCount?: number;
resumePolicy?: ResumePolicyType;
objective?: ObjectiveSpec;
algorithm?: AlgorithmSpec;
earlyStopping?: AlgorithmSpec;
parameters?: ParameterSpec[];
metricsCollectorSpec?: MetricsCollectorSpec;
trialTemplate?: TrialTemplateSpec;
nasConfig?: NasConfig;
}

export type ResumePolicyType = 'Never' | 'LongRunning' | 'FromVolume';

export interface ObjectiveSpec {
type: ObjectiveType;
goal: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,10 @@
text="Algorithm settings"
>
<div class="flex-column">
<form
<app-algorithm-setting
*ngFor="let setting of algorithmSettings.controls; let i = index"
[formGroup]="setting"
>
<mat-form-field appearance="outline">
<mat-label>{{ setting.get('name').value }}</mat-label>

<ng-container *ngIf="!setting.get('values').value; else listParam">
<ng-container
*ngIf="setting.get('type').value !== 'integer'; else intParam"
>
<input [formControl]="setting.get('value')" matInput />
</ng-container>
</ng-container>

<!--input templates-->
<ng-template #intParam>
<input
[formControl]="setting.get('value')"
type="number"
step="1"
matInput
/>
</ng-template>

<ng-template #listParam>
<mat-select [formControl]="setting.get('value')">
<mat-option
*ngFor="let param_value of setting.get('values').value"
[value]="param_value"
>
{{ param_value }}
</mat-option>
</mat-select>
</ng-template>
</mat-form-field>
</form>
[setting]="setting"
></app-algorithm-setting>
</div>
</lib-advanced-options>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
export class FormAlgorithmComponent implements OnInit, OnDestroy {
algorithmSettings: FormArray;
algorithms: { [key: string]: string } = AlgorithmNames;
disableAddButton: boolean;
algorithmHasSettings = false;

private subscriptions: Subscription = new Subscription();
Expand All @@ -32,20 +31,12 @@ export class FormAlgorithmComponent implements OnInit, OnDestroy {
'algorithmSettings',
) as FormArray;

// set the list of algorithm settings once the form loads
this.setAlgorithmSettings(this.algorithmForm.value.algorithm);

this.subscriptions.add(
this.algorithmForm.get('algorithm').valueChanges.subscribe(algo => {
this.algorithmSettings.clear();
this.algorithmHasSettings = AlgorithmSettingsMap[algo].length !== 0;

// create the settings
for (const setting of AlgorithmSettingsMap[algo]) {
this.addSetting(
setting.name,
setting.value,
setting.type,
setting.values,
);
}
this.setAlgorithmSettings(algo);
}),
);

Expand All @@ -64,6 +55,21 @@ export class FormAlgorithmComponent implements OnInit, OnDestroy {
}

// form helpers
setAlgorithmSettings(algo: string) {
this.algorithmSettings.clear();
this.algorithmHasSettings = AlgorithmSettingsMap[algo].length !== 0;

// create the settings
for (const setting of AlgorithmSettingsMap[algo]) {
this.addSetting(
setting.name,
setting.value,
setting.type,
setting.values,
);
}
}

addSetting(
name: string,
value: any,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { FormModule } from 'kubeflow';

import { MatIconModule } from '@angular/material/icon';
import { MatRadioModule } from '@angular/material/radio';
import { FormAlgorithmSettingComponent } from './setting/setting.component';

@NgModule({
declarations: [FormAlgorithmComponent],
declarations: [FormAlgorithmComponent, FormAlgorithmSettingComponent],
imports: [CommonModule, FormModule, MatIconModule, MatRadioModule],
exports: [FormAlgorithmComponent],
exports: [FormAlgorithmComponent, FormAlgorithmSettingComponent],
})
export class FormAlgorithmModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div [formGroup]="setting">
<mat-form-field appearance="outline">
<mat-label>{{ setting.get('name').value }}</mat-label>

<ng-container *ngIf="!setting.get('values').value; else listParam">
<ng-container
*ngIf="setting.get('type').value !== 'integer'; else intParam"
>
<input [formControl]="setting.get('value')" matInput />
</ng-container>
</ng-container>

<!--input templates-->
<ng-template #intParam>
<input
[formControl]="setting.get('value')"
type="number"
step="1"
matInput
/>
</ng-template>

<ng-template #listParam>
<mat-select [formControl]="setting.get('value')">
<mat-option
*ngFor="let param_value of setting.get('values').value"
[value]="param_value"
>
{{ param_value }}
</mat-option>
</mat-select>
</ng-template>
</mat-form-field>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:host {
display: block;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { SettingComponent } from './setting.component';

describe('SettingComponent', () => {
let component: SettingComponent;
let fixture: ComponentFixture<SettingComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SettingComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(SettingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Component, OnInit, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';

@Component({
selector: 'app-algorithm-setting',
templateUrl: './setting.component.html',
styleUrls: ['./setting.component.scss'],
})
export class FormAlgorithmSettingComponent implements OnInit {
@Input() setting: FormGroup;

constructor() {}

ngOnInit() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<div class="lib-step-wrapper">
<form [formGroup]="formGroup" class="flex-column step-content">
<mat-form-field appearance="outline" class="wide">
<mat-label>Algorithm</mat-label>
<mat-select formControlName="algorithmName">
<mat-option
*ngFor="let algo of algorithms | keyvalue"
[value]="algo.key"
>
{{ algo.value }}
</mat-option>
</mat-select>
</mat-form-field>

<!--Algorithm configuration parameters-->
<lib-advanced-options
*ngIf="algorithmHasSettings"
text="Algorithm settings"
>
<div class="flex-column">
<app-algorithm-setting
*ngFor="let setting of algorithmSettings.controls; let i = index"
[setting]="setting"
></app-algorithm-setting>
</div>
</lib-advanced-options>
</form>

<!--step info-->
<div class="lib-step-info-wrapper">
<lib-step-info header="Early Stopping">
Early stopping allows you to avoid overfitting when you train your model
during Katib Experiments. You can read the
<a
href="https://www.kubeflow.org/docs/components/katib/early-stopping/"
target="_blank"
rel="noopener noreferrer"
>
official docs</a
>
for more information.
</lib-step-info>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { EarlyStoppingComponent } from './early-stopping.component';

describe('EarlyStoppingComponent', () => {
let component: EarlyStoppingComponent;
let fixture: ComponentFixture<EarlyStoppingComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EarlyStoppingComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(EarlyStoppingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading