From 3c615e305421f82a19f5526c74a51afe927435ef Mon Sep 17 00:00:00 2001 From: avelichk Date: Thu, 22 Oct 2020 01:01:23 +0100 Subject: [PATCH] Add metric strategies to submit by params Experiment page --- .../frontend/src/actions/hpCreateActions.js | 8 + .../frontend/src/actions/nasCreateActions.js | 8 + .../src/components/HP/Create/HPParameters.jsx | 68 ++--- .../components/HP/Create/Params/Algorithm.jsx | 4 - .../HP/Create/Params/CommonMeta.jsx | 2 - .../HP/Create/Params/CommonSpec.jsx | 2 - .../components/HP/Create/Params/Objective.jsx | 238 ++++++++++++------ .../HP/Create/Params/Parameters.jsx | 11 - .../components/NAS/Create/NASParameters.jsx | 65 ++--- .../NAS/Create/Params/Algorithm.jsx | 3 - .../NAS/Create/Params/CommonMeta.jsx | 2 - .../NAS/Create/Params/CommonSpec.jsx | 2 - .../NAS/Create/Params/NASConfig.jsx | 9 - .../NAS/Create/Params/Objective.jsx | 238 ++++++++++++------ .../v1beta1/frontend/src/reducers/hpCreate.js | 73 +++++- .../frontend/src/reducers/nasCreate.js | 69 ++++- 16 files changed, 501 insertions(+), 301 deletions(-) diff --git a/pkg/ui/v1beta1/frontend/src/actions/hpCreateActions.js b/pkg/ui/v1beta1/frontend/src/actions/hpCreateActions.js index bd1b1260323..1ba244a032d 100644 --- a/pkg/ui/v1beta1/frontend/src/actions/hpCreateActions.js +++ b/pkg/ui/v1beta1/frontend/src/actions/hpCreateActions.js @@ -49,6 +49,14 @@ export const editMetrics = (index, value) => ({ value, }); +export const CHANGE_METRIC_STRATEGY_HP = 'CHANGE_METRIC_STRATEGY_HP'; + +export const metricStrategyChange = (index, strategy) => ({ + type: CHANGE_METRIC_STRATEGY_HP, + index, + strategy, +}); + export const CHANGE_ALGORITHM_NAME_HP = 'CHANGE_ALGORITHM_NAME_HP'; export const changeAlgorithmName = algorithmName => ({ diff --git a/pkg/ui/v1beta1/frontend/src/actions/nasCreateActions.js b/pkg/ui/v1beta1/frontend/src/actions/nasCreateActions.js index 3ac2429645e..0030c698d05 100644 --- a/pkg/ui/v1beta1/frontend/src/actions/nasCreateActions.js +++ b/pkg/ui/v1beta1/frontend/src/actions/nasCreateActions.js @@ -50,6 +50,14 @@ export const editMetrics = (index, value) => ({ value, }); +export const CHANGE_METRIC_STRATEGY_NAS = 'CHANGE_METRIC_STRATEGY_NAS'; + +export const metricStrategyChange = (index, strategy) => ({ + type: CHANGE_METRIC_STRATEGY_NAS, + index, + strategy, +}); + export const CHANGE_ALGORITHM_NAME_NAS = 'CHANGE_ALGORITHM_NAME_NAS'; export const changeAlgorithmName = algorithmName => ({ diff --git a/pkg/ui/v1beta1/frontend/src/components/HP/Create/HPParameters.jsx b/pkg/ui/v1beta1/frontend/src/components/HP/Create/HPParameters.jsx index c4901fe32c7..a3566d0b410 100644 --- a/pkg/ui/v1beta1/frontend/src/components/HP/Create/HPParameters.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/HP/Create/HPParameters.jsx @@ -28,38 +28,13 @@ const styles = theme => ({ }, submit: { textAlign: 'center', - marginTop: 10, - }, - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%', - }, - help: { - padding: 4 / 2, - verticalAlign: 'middle', - }, - section: { - padding: 4, - }, - parameter: { - padding: 2, - }, - formControl: { - margin: 4, - width: '100%', - }, - selectEmpty: { - marginTop: 10, - }, - button: { - margin: 10, + margin: 20, }, }); -const SectionInTypography = (name, classes) => { +const SectionInTypography = name => { return ( -
+
{name} @@ -107,16 +82,31 @@ const addParameter = (source, destination) => { const HPParameters = props => { const submitJob = () => { let data = {}; + + // Add metadata. data.metadata = {}; deCapitalizeFirstLetterAndAppend(props.commonParametersMetadata, data.metadata); + + // Add common parameters. data.spec = {}; deCapitalizeFirstLetterAndAppend(props.commonParametersSpec, data.spec); + + // Add objective. data.spec.objective = {}; deCapitalizeFirstLetterAndAppend(props.objective, data.spec.objective); + + // Add additional metrics. data.spec.objective.additionalMetricNames = props.additionalMetricNames.map( (metrics, i) => metrics.value, ); + // Add metric strategies. + data.spec.objective.metricStrategies = props.metricStrategies.map(metric => ({ + name: metric.name, + value: metric.strategy, + })); + + // Add algorithm. data.spec.algorithm = {}; data.spec.algorithm.algorithmName = props.algorithmName; data.spec.algorithm.algorithmSettings = []; @@ -209,30 +199,25 @@ const HPParameters = props => { return (
{/* Common Metadata */} - {SectionInTypography('Metadata', classes)} + {SectionInTypography('Metadata')}
- {SectionInTypography('Common Parameters', classes)} + {SectionInTypography('Common Parameters')} - {SectionInTypography('Objective', classes)} + {SectionInTypography('Objective')} - {SectionInTypography('Algorithm', classes)} + {SectionInTypography('Algorithm')} - {SectionInTypography('Parameters', classes)} + {SectionInTypography('Parameters')} - {SectionInTypography('Metrics Collector Spec', classes)} + {SectionInTypography('Metrics Collector Spec')} - {SectionInTypography('Trial Template Spec', classes)} + {SectionInTypography('Trial Template Spec')}
-
@@ -261,6 +246,7 @@ const mapStateToProps = state => { commonParametersSpec: state[constants.HP_CREATE_MODULE].commonParametersSpec, objective: state[constants.HP_CREATE_MODULE].objective, additionalMetricNames: state[constants.HP_CREATE_MODULE].additionalMetricNames, + metricStrategies: state[constants.HP_CREATE_MODULE].metricStrategies, algorithmName: state[constants.HP_CREATE_MODULE].algorithmName, algorithmSettings: state[constants.HP_CREATE_MODULE].algorithmSettings, parameters: state[constants.HP_CREATE_MODULE].parameters, diff --git a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Algorithm.jsx b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Algorithm.jsx index d0425a029c1..f8c3ccd0582 100644 --- a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Algorithm.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Algorithm.jsx @@ -26,8 +26,6 @@ import { HP_CREATE_MODULE } from '../../../../constants/constants'; const useStyles = makeStyles({ textField: { - marginLeft: 4, - marginRight: 4, width: '80%', }, help: { @@ -45,7 +43,6 @@ const useStyles = makeStyles({ verticalAlign: 'middle !important', }, formControl: { - margin: 4, width: '100%', }, addButton: { @@ -98,7 +95,6 @@ const Algorithm = props => { value={props.algorithmName} onChange={onAlgorithmNameChange} label="Algorithm Name" - className={classes.select} > {props.allAlgorithms.map((algorithm, i) => { return ( diff --git a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/CommonMeta.jsx b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/CommonMeta.jsx index c0d5bc27d69..d92a9a1b8c8 100644 --- a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/CommonMeta.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/CommonMeta.jsx @@ -14,8 +14,6 @@ import { GENERAL_MODULE, HP_CREATE_MODULE } from '../../../../constants/constant const styles = () => ({ textField: { - marginLeft: 4, - marginRight: 4, width: '100%', }, help: { diff --git a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/CommonSpec.jsx b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/CommonSpec.jsx index 0de34d27154..a88882edf19 100644 --- a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/CommonSpec.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/CommonSpec.jsx @@ -14,8 +14,6 @@ import { HP_CREATE_MODULE } from '../../../../constants/constants'; const useStyles = makeStyles({ textField: { - marginLeft: 4, - marginRight: 4, width: '100%', }, help: { diff --git a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Objective.jsx b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Objective.jsx index c0b04fa609d..2e45e6ec234 100644 --- a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Objective.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Objective.jsx @@ -15,22 +15,26 @@ import FormControl from '@material-ui/core/FormControl'; import Select from '@material-ui/core/Select'; import InputLabel from '@material-ui/core/InputLabel'; import MenuItem from '@material-ui/core/MenuItem'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Checkbox from '@material-ui/core/Checkbox'; import { changeObjective, addMetrics, editMetrics, deleteMetrics, + metricStrategyChange, } from '../../../../actions/hpCreateActions'; import { HP_CREATE_MODULE } from '../../../../constants/constants'; const useStyles = makeStyles({ textField: { - marginLeft: 4, - marginRight: 4, width: '100%', }, + textFieldStrategy: { + width: '80%', + }, help: { padding: 4 / 2, verticalAlign: 'middle', @@ -48,6 +52,12 @@ const useStyles = makeStyles({ const Objective = props => { const classes = useStyles(); + const [checkedSetStrategies, setCheckedSetStrategies] = React.useState(false); + + const onCheckBoxChange = event => { + setCheckedSetStrategies(event.target.checked); + }; + const onObjectiveChange = name => event => { props.changeObjective(name, event.target.value); }; @@ -60,106 +70,165 @@ const Objective = props => { props.deleteMetrics(index); }; + const onMetricStrategyChange = index => event => { + props.metricStrategyChange(index, event.target.value); + }; + return (
{props.objective.map((param, i) => { return param.name === 'Type' ? ( -
- - - - - - - {param.name} - - - - - Objective Type - - - + + + + + + + {param.name} + -
- ) : ( -
- - - - - - - {param.name} - - - - + + Objective Type + + + + + ) : ( + + + + + + + {param.name} + -
+ + + + ); })} -
- - - - - - - AdditionalMetricNames - - - - {props.additionalMetricNames.map((metrics, mIndex) => { + + + + + + + AdditionalMetricNames + + + + {props.additionalMetricNames.map((metric, mIndex) => { + return ( + + + + + + + + + + + ); + })} + + + + + + + + + + + + + + MetricStrategies (optional) + + + + + } + label="Set" + /> + + {checkedSetStrategies && ( + + {props.metricStrategies.map((metric, mIndex) => { return ( - - + + - - - - + + + Strategy Type + + ); })} - - - - - - -
+ )} +
); }; @@ -169,6 +238,8 @@ const mapStateToProps = state => { allObjectiveTypes: state[HP_CREATE_MODULE].allObjectiveTypes, objective: state[HP_CREATE_MODULE].objective, additionalMetricNames: state[HP_CREATE_MODULE].additionalMetricNames, + metricStrategiesList: state[HP_CREATE_MODULE].metricStrategiesList, + metricStrategies: state[HP_CREATE_MODULE].metricStrategies, }; }; @@ -177,4 +248,5 @@ export default connect(mapStateToProps, { addMetrics, editMetrics, deleteMetrics, + metricStrategyChange, })(Objective); diff --git a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Parameters.jsx b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Parameters.jsx index b95087549cd..9fc1f4eedb3 100644 --- a/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Parameters.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/HP/Create/Params/Parameters.jsx @@ -31,21 +31,13 @@ import { HP_CREATE_MODULE } from '../../../../constants/constants'; const useStyles = makeStyles({ textField: { - marginLeft: 4, - marginRight: 4, width: '80%', }, - help: { - padding: 4 / 2, - verticalAlign: 'middle', - marginRight: 5, - }, parameter: { padding: 2, marginBottom: 10, }, formControl: { - margin: 4, width: '100%', }, selectEmpty: { @@ -55,9 +47,6 @@ const useStyles = makeStyles({ flexDirection: 'row', justifyContent: 'space-around', }, - divider: { - margin: 5, - }, addButton: { margin: 10, }, diff --git a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/NASParameters.jsx b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/NASParameters.jsx index e58be290063..5690c3838fb 100644 --- a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/NASParameters.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/NASParameters.jsx @@ -28,38 +28,13 @@ const styles = theme => ({ }, submit: { textAlign: 'center', - marginTop: 10, - }, - textField: { - marginLeft: 4, - marginRight: 4, - width: '100%', - }, - help: { - padding: 4 / 2, - verticalAlign: 'middle', - }, - section: { - padding: 4, - }, - parameter: { - padding: 2, - }, - formControl: { - margin: 4, - width: '100%', - }, - selectEmpty: { - marginTop: 10, - }, - addButton: { - margin: 10, + marginTop: 20, }, }); -const SectionInTypography = (name, classes) => { +const SectionInTypography = name => { return ( -
+
{name} @@ -113,18 +88,30 @@ const NASParameters = props => { const submitNASJob = () => { let data = {}; + // Add metadata. data.metadata = {}; deCapitalizeFirstLetterAndAppend(props.commonParametersMetadata, data.metadata); + // Add common parameters. data.spec = {}; deCapitalizeFirstLetterAndAppend(props.commonParametersSpec, data.spec); + // Add objective. data.spec.objective = {}; deCapitalizeFirstLetterAndAppend(props.objective, data.spec.objective); + + // Add additional metrics. data.spec.objective.additionalMetricNames = props.additionalMetricNames.map( (metrics, i) => metrics.value, ); + // Add metric strategies. + data.spec.objective.metricStrategies = props.metricStrategies.map(metric => ({ + name: metric.name, + value: metric.strategy, + })); + + // Add algorithm. data.spec.algorithm = {}; data.spec.algorithm.algorithmName = props.algorithmName; data.spec.algorithm.algorithmSettings = []; @@ -223,27 +210,22 @@ const NASParameters = props => { return (
{/* Common Metadata */} - {SectionInTypography('Metadata', classes)} + {SectionInTypography('Metadata')} - {SectionInTypography('Common Parameters', classes)} + {SectionInTypography('Common Parameters')} - {SectionInTypography('Objective', classes)} + {SectionInTypography('Objective')} - {SectionInTypography('Algorithm', classes)} + {SectionInTypography('Algorithm')} - {SectionInTypography('NAS Config', classes)} + {SectionInTypography('NAS Config')} - {SectionInTypography('Metrics Collector Spec', classes)} + {SectionInTypography('Metrics Collector Spec')} - {SectionInTypography('Trial Template Spec', classes)} + {SectionInTypography('Trial Template Spec')}
-
@@ -274,6 +256,7 @@ const mapStateToProps = state => { additionalMetricNames: state[constants.NAS_CREATE_MODULE].additionalMetricNames, algorithmName: state[constants.NAS_CREATE_MODULE].algorithmName, algorithmSettings: state[constants.NAS_CREATE_MODULE].algorithmSettings, + metricStrategies: state[constants.NAS_CREATE_MODULE].metricStrategies, numLayers: state[constants.NAS_CREATE_MODULE].numLayers, inputSize: state[constants.NAS_CREATE_MODULE].inputSize, outputSize: state[constants.NAS_CREATE_MODULE].outputSize, diff --git a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/Algorithm.jsx b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/Algorithm.jsx index cfac4629436..26de1cea3fe 100644 --- a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/Algorithm.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/Algorithm.jsx @@ -26,8 +26,6 @@ import { NAS_CREATE_MODULE } from '../../../../constants/constants'; const useStyles = makeStyles({ textField: { - marginLeft: 4, - marginRight: 4, width: '80%', }, help: { @@ -45,7 +43,6 @@ const useStyles = makeStyles({ verticalAlign: 'middle !important', }, formControl: { - margin: 4, width: '100%', }, addButton: { diff --git a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/CommonMeta.jsx b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/CommonMeta.jsx index bd5428106aa..2760b464fb5 100644 --- a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/CommonMeta.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/CommonMeta.jsx @@ -14,8 +14,6 @@ import { GENERAL_MODULE, NAS_CREATE_MODULE } from '../../../../constants/constan const styles = () => ({ textField: { - marginLeft: 4, - marginRight: 4, width: '100%', }, help: { diff --git a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/CommonSpec.jsx b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/CommonSpec.jsx index 63df6511b66..bb47ddec411 100644 --- a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/CommonSpec.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/CommonSpec.jsx @@ -14,8 +14,6 @@ import { NAS_CREATE_MODULE } from '../../../../constants/constants'; const useStyles = makeStyles({ textField: { - marginLeft: 4, - marginRight: 4, width: '100%', }, help: { diff --git a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/NASConfig.jsx b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/NASConfig.jsx index ad6ff632c54..cbe34b6468d 100644 --- a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/NASConfig.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/NASConfig.jsx @@ -41,8 +41,6 @@ import { NAS_CREATE_MODULE } from '../../../../constants/constants'; const useStyles = makeStyles({ textField: { - marginLeft: 4, - marginRight: 4, width: '80%', }, numLayers: { @@ -59,19 +57,12 @@ const useStyles = makeStyles({ marginBottom: 10, }, formControl: { - margin: 4, width: '100%', }, - selectEmpty: { - marginTop: 10, - }, group: { flexDirection: 'row', justifyContent: 'space-around', }, - divider: { - margin: 5, - }, addButton: { margin: 10, }, diff --git a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/Objective.jsx b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/Objective.jsx index 23a2ee96f02..f010c56610f 100644 --- a/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/Objective.jsx +++ b/pkg/ui/v1beta1/frontend/src/components/NAS/Create/Params/Objective.jsx @@ -15,22 +15,26 @@ import FormControl from '@material-ui/core/FormControl'; import Select from '@material-ui/core/Select'; import InputLabel from '@material-ui/core/InputLabel'; import MenuItem from '@material-ui/core/MenuItem'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Checkbox from '@material-ui/core/Checkbox'; import { changeObjective, addMetrics, editMetrics, deleteMetrics, + metricStrategyChange, } from '../../../../actions/nasCreateActions'; import { NAS_CREATE_MODULE } from '../../../../constants/constants'; const useStyles = makeStyles({ textField: { - marginLeft: 4, - marginRight: 4, width: '100%', }, + textFieldStrategy: { + width: '80%', + }, help: { padding: 4 / 2, verticalAlign: 'middle', @@ -48,6 +52,12 @@ const useStyles = makeStyles({ const Objective = props => { const classes = useStyles(); + const [checkedSetStrategies, setCheckedSetStrategies] = React.useState(false); + + const onCheckBoxChange = event => { + setCheckedSetStrategies(event.target.checked); + }; + const onObjectiveChange = name => event => { props.changeObjective(name, event.target.value); }; @@ -60,106 +70,165 @@ const Objective = props => { props.deleteMetrics(index); }; + const onMetricStrategyChange = index => event => { + props.metricStrategyChange(index, event.target.value); + }; + return (
{props.objective.map((param, i) => { return param.name === 'Type' ? ( -
- - - - - - - {param.name} - - - - - Objective Type - - - + + + + + + + {param.name} + -
- ) : ( -
- - - - - - - {param.name} - - - - + + Objective Type + + + + + ) : ( + + + + + + + {param.name} + -
+ + + + ); })} -
- - - - - - - AdditionalMetricNames - - - - {props.additionalMetricNames.map((metrics, mIndex) => { + + + + + + + AdditionalMetricNames + + + + {props.additionalMetricNames.map((metric, mIndex) => { + return ( + + + + + + + + + + + ); + })} + + + + + + + + + + + + + + MetricStrategies (optional) + + + + + } + label="Set" + /> + + {checkedSetStrategies && ( + + {props.metricStrategies.map((metric, mIndex) => { return ( - - + + - - - - + + + Strategy Type + + ); })} - - - - - - -
+ )} +
); }; @@ -169,6 +238,8 @@ const mapStateToProps = state => { allObjectiveTypes: state[NAS_CREATE_MODULE].allObjectiveTypes, objective: state[NAS_CREATE_MODULE].objective, additionalMetricNames: state[NAS_CREATE_MODULE].additionalMetricNames, + metricStrategiesList: state[NAS_CREATE_MODULE].metricStrategiesList, + metricStrategies: state[NAS_CREATE_MODULE].metricStrategies, }; }; @@ -177,4 +248,5 @@ export default connect(mapStateToProps, { addMetrics, editMetrics, deleteMetrics, + metricStrategyChange, })(Objective); diff --git a/pkg/ui/v1beta1/frontend/src/reducers/hpCreate.js b/pkg/ui/v1beta1/frontend/src/reducers/hpCreate.js index 6a3b287a1ea..ee35050a8ae 100644 --- a/pkg/ui/v1beta1/frontend/src/reducers/hpCreate.js +++ b/pkg/ui/v1beta1/frontend/src/reducers/hpCreate.js @@ -50,9 +50,16 @@ const initialState = { description: 'Name for the objective metric', }, ], - additionalMetricNames: [ + additionalMetricNames: ['Train-accuracy'], + metricStrategiesList: ['min', 'max', 'latest'], + metricStrategies: [ { - value: 'Train-accuracy', + name: 'Validation-accuracy', + strategy: 'max', + }, + { + name: 'Train-accuracy', + strategy: 'max', }, ], algorithmName: 'random', @@ -113,6 +120,38 @@ const filterValue = (obj, key) => { return obj.findIndex(p => p.name === key); }; +// setMetricStrategies sets metric strategies from objective and additional metrics +const setMetricStrategies = (objective, additionalMetricNames) => { + let metricStrategies = []; + // Objective metric - 2 index. + // Objective type can't be empty. + if (objective[2].value.trim() !== '') { + // Set strategy from objective type. + // Strategy == Objective Type by default. + let strategy; + if (objective[0].value === 'minimize') { + strategy = 'min'; + } else { + strategy = 'max'; + } + metricStrategies.push({ + name: objective[2].value, + strategy: strategy, + }); + + // Add not empty additional metrics. + additionalMetricNames.forEach(metric => { + if (metric.trim() !== '') { + metricStrategies.push({ + name: metric, + strategy: strategy, + }); + } + }); + } + return metricStrategies; +}; + const hpCreateReducer = (state = initialState, action) => { switch (action.type) { case actions.CHANGE_YAML_HP: @@ -137,18 +176,19 @@ const hpCreateReducer = (state = initialState, action) => { commonParametersSpec: spec, }; case actions.CHANGE_OBJECTIVE_HP: - let obj = state.objective.slice(); - index = filterValue(obj, action.name); - obj[index].value = action.value; + let newObjective = state.objective.slice(); + index = filterValue(newObjective, action.name); + newObjective[index].value = action.value; + // Set new metric strategies. + var newMetricStrategies = setMetricStrategies(newObjective, state.additionalMetricNames); return { ...state, - objective: obj, + objective: newObjective, + metricStrategies: newMetricStrategies, }; case actions.ADD_METRICS_HP: var additionalMetricNames = state.additionalMetricNames.slice(); - additionalMetricNames.push({ - value: '', - }); + additionalMetricNames.push(''); return { ...state, additionalMetricNames: additionalMetricNames, @@ -156,16 +196,29 @@ const hpCreateReducer = (state = initialState, action) => { case actions.DELETE_METRICS_HP: additionalMetricNames = state.additionalMetricNames.slice(); additionalMetricNames.splice(action.index, 1); + // Set new metric strategies. + newMetricStrategies = setMetricStrategies(state.objective, additionalMetricNames); return { ...state, additionalMetricNames: additionalMetricNames, + metricStrategies: newMetricStrategies, }; case actions.EDIT_METRICS_HP: additionalMetricNames = state.additionalMetricNames.slice(); - additionalMetricNames[action.index].value = action.value; + additionalMetricNames[action.index] = action.value; + // Set new metric strategies. + newMetricStrategies = setMetricStrategies(state.objective, additionalMetricNames); return { ...state, additionalMetricNames: additionalMetricNames, + metricStrategies: newMetricStrategies, + }; + case actions.CHANGE_METRIC_STRATEGY_HP: + newMetricStrategies = state.metricStrategies.slice(); + newMetricStrategies[action.index].strategy = action.strategy; + return { + ...state, + metricStrategies: newMetricStrategies, }; case actions.CHANGE_ALGORITHM_NAME_HP: return { diff --git a/pkg/ui/v1beta1/frontend/src/reducers/nasCreate.js b/pkg/ui/v1beta1/frontend/src/reducers/nasCreate.js index ef1f0db7658..61e857749f7 100644 --- a/pkg/ui/v1beta1/frontend/src/reducers/nasCreate.js +++ b/pkg/ui/v1beta1/frontend/src/reducers/nasCreate.js @@ -50,6 +50,13 @@ const initialState = { }, ], additionalMetricNames: [], + metricStrategiesList: ['min', 'max', 'latest'], + metricStrategies: [ + { + name: 'Validation-accuracy', + strategy: 'max', + }, + ], algorithmName: 'enas', allAlgorithms: ['enas'], algorithmSettings: [ @@ -353,6 +360,38 @@ const filterValue = (obj, key) => { return obj.findIndex(p => p.name === key); }; +// setMetricStrategies sets metric strategies from objective and additional metrics +const setMetricStrategies = (objective, additionalMetricNames) => { + let metricStrategies = []; + // Objective metric - 2 index. + // Objective type can't be empty. + if (objective[2].value.trim() !== '') { + // Set strategy from objective type. + // Strategy == Objective Type by default. + let strategy; + if (objective[0].value === 'minimize') { + strategy = 'min'; + } else { + strategy = 'max'; + } + metricStrategies.push({ + name: objective[2].value, + strategy: strategy, + }); + + // Add not empty additional metrics. + additionalMetricNames.forEach(metric => { + if (metric.trim() !== '') { + metricStrategies.push({ + name: metric, + strategy: strategy, + }); + } + }); + } + return metricStrategies; +}; + const nasCreateReducer = (state = initialState, action) => { switch (action.type) { case actions.CHANGE_YAML_NAS: @@ -377,18 +416,19 @@ const nasCreateReducer = (state = initialState, action) => { commonParametersSpec: spec, }; case actions.CHANGE_OBJECTIVE_NAS: - let obj = state.objective.slice(); - index = filterValue(obj, action.name); - obj[index].value = action.value; + let newObjective = state.objective.slice(); + index = filterValue(newObjective, action.name); + newObjective[index].value = action.value; + // Set new metric strategies. + var newMetricStrategies = setMetricStrategies(newObjective, state.additionalMetricNames); return { ...state, - objective: obj, + objective: newObjective, + metricStrategies: newMetricStrategies, }; case actions.ADD_METRICS_NAS: var additionalMetricNames = state.additionalMetricNames.slice(); - additionalMetricNames.push({ - value: '', - }); + additionalMetricNames.push(''); return { ...state, additionalMetricNames: additionalMetricNames, @@ -396,16 +436,29 @@ const nasCreateReducer = (state = initialState, action) => { case actions.DELETE_METRICS_NAS: additionalMetricNames = state.additionalMetricNames.slice(); additionalMetricNames.splice(action.index, 1); + // Set new metric strategies. + newMetricStrategies = setMetricStrategies(state.objective, additionalMetricNames); return { ...state, additionalMetricNames: additionalMetricNames, + metricStrategies: newMetricStrategies, }; case actions.EDIT_METRICS_NAS: additionalMetricNames = state.additionalMetricNames.slice(); - additionalMetricNames[action.index].value = action.value; + additionalMetricNames[action.index] = action.value; + // Set new metric strategies. + newMetricStrategies = setMetricStrategies(state.objective, additionalMetricNames); return { ...state, additionalMetricNames: additionalMetricNames, + metricStrategies: newMetricStrategies, + }; + case actions.CHANGE_METRIC_STRATEGY_NAS: + newMetricStrategies = state.metricStrategies.slice(); + newMetricStrategies[action.index].strategy = action.strategy; + return { + ...state, + metricStrategies: newMetricStrategies, }; case actions.CHANGE_ALGORITHM_NAME_NAS: return {