 SOLVED

# Machine Teaching dataset for MOAB example

I am trying to train a brain based on an AML-Dataset.

The training should be reward based with the rewards and termina state defined in columns in the dataset as state.reward and state.terminal.

It's included in the Dataset interface details: and I've added the corresponding reward and terminal functions.

``````function GetReward(s: DatasetState): number { return (s.reward)}
function GetTerminal(s: DatasetState): number { return (s.terminal)}``````

Unfortunately, I get an error: ``````inkling "2.0"
# Define a type that represents the per-iteration state
# returned by the dataset.
type DatasetState {
# Ball X,Y position
ball_x: number<-MaxDistancePerStep - RadiusOfPlate .. RadiusOfPlate + MaxDistancePerStep>,
ball_y: number<-MaxDistancePerStep - RadiusOfPlate .. RadiusOfPlate + MaxDistancePerStep>,

# Ball X,Y velocity
ball_vel_x: number<-MaxVelocity .. MaxVelocity>,
ball_vel_y: number<-MaxVelocity .. MaxVelocity>,
}
using Math
using Goal
const RadiusOfPlate = 0.1125
const MaxVelocity = 6.0
const MaxInitialVelocity = 1.0
const CloseEnough = 0.02
const DefaultTimeDelta = 0.045
const MaxDistancePerStep = DefaultTimeDelta * MaxVelocity
# Define a type that represents the per-iteration action
# accepted by the dataset.
#type DatasetAction {
#    input_roll: number,
#    input_pitch: number,
#}

type DatasetAction {
# Range -1 to 1 is a scaled value that represents
# the full plate rotation range supported by the hardware.
input_pitch: number<-1 .. 1>, # rotate about x-axis
input_roll: number<-1 .. 1>, # rotate about y-axis
}
# Per-episode configuration that can be sent to the dataset.
# All iterations within an episode will use the same configuration.
type DatasetConfig {

# Model initial ball conditions
initial_x: number<-RadiusOfPlate .. RadiusOfPlate>, # in (m)

# Model initial ball velocity conditions
initial_vel_x: number<-MaxInitialVelocity .. MaxInitialVelocity>, # in (m/s)
initial_vel_y: number<-MaxInitialVelocity .. MaxInitialVelocity>,

# Range -1 to 1 is a scaled value that represents
# the full plate rotation range supported by the hardware.
initial_pitch: number<-1 .. 1>,
initial_roll: number<-1 .. 1>,
}

data Dataset(action: DatasetAction, config: DatasetConfig): DatasetState {
# Uses this dataset for training
dataset "moab-test"
}

simulator Simulator(Action: number): DatasetState {
}

# Define a concept graph
graph (input: DatasetState): DatasetAction {
concept MoveToCenter(input): DatasetAction {
curriculum {
# The source of training for this concept is a dataset
# that takes an action as an input and outputs a state.
source Dataset
reward GetReward

lesson `Randomize Start` {
scenario {
initial_x: number<-RadiusOfPlate * 0.5 .. RadiusOfPlate * 0.5>,
initial_y: number<-RadiusOfPlate * 0.5 .. RadiusOfPlate * 0.5>,

initial_vel_x: number<-MaxInitialVelocity * 0.02 .. MaxInitialVelocity * 0.02>,
initial_vel_y: number<-MaxInitialVelocity * 0.02 .. MaxInitialVelocity * 0.02>,

initial_pitch: number<-0.2 .. 0.2>,
initial_roll: number<-0.2 .. 0.2>,
}
}

# Add goals here describing what you want to teach the brain
# See the Inkling documentation for goals syntax
# https://docs.microsoft.com/bonsai/inkling/keywords/goal
}
}
}
#function GetReward(s: DatasetState): number {
#    return 0.01
#}

function GetReward(s: DatasetState): number {
return s.reward
}

function GetTerminal(s: DatasetState): number {
return (s.terminal)
}<div> <div> </div></div>``````

best response confirmed by cristiandatum (Occasional Contributor)
Solution

# Re: Machine Teaching dataset for MOAB example

It looks like your dataset contains fields that are not available to the brain at inference time. That means you need to define a different state type that describes your dataset. It is common for such a type to be a superset of the "observable state" type (i.e. the type that is available to the brain at inference time).

You can use the "extends" keyword to extend an existing type and add additional fields to it.

Here's an updated inkling document that demonstrates this. I've also taken the liberty of moving the "data", "reward" and "terminal" statements inline. I find this is easier to read, at least for a brain with just one concept.

``````inkling "2.0"

const RadiusOfPlate = 0.1125
const MaxVelocity = 6.0
const MaxInitialVelocity = 1.0
const DefaultTimeDelta = 0.045
const MaxDistancePerStep = DefaultTimeDelta * MaxVelocity

type ObservableState {
ball_x: number<-MaxDistancePerStep - RadiusOfPlate .. RadiusOfPlate + MaxDistancePerStep>,
ball_y: number<-MaxDistancePerStep - RadiusOfPlate .. RadiusOfPlate + MaxDistancePerStep>,
ball_vel_x: number<-MaxVelocity .. MaxVelocity>,
ball_vel_y: number<-MaxVelocity .. MaxVelocity>,
}

type DatasetState extends ObservableState {
terminal: number,
reward: number,
}

type DatasetAction {
input_pitch: number<-1 .. 1>,
input_roll: number<-1 .. 1>,
}

type DatasetConfig {
initial_vel_x: number<-MaxInitialVelocity .. MaxInitialVelocity>,
initial_vel_y: number<-MaxInitialVelocity .. MaxInitialVelocity>,
initial_pitch: number<-1 .. 1>,
initial_roll: number<-1 .. 1>,
}

graph (input: ObservableState): DatasetAction {
concept MoveToCenter(input): DatasetAction {
curriculum {
source data (action: DatasetAction, config: DatasetConfig): DatasetState {
dataset "moab-test"
}

reward function (s: DatasetState): number {
return s.reward
}

terminal function GetTerminal(s: DatasetState): number {
return (s.terminal)
}

lesson `Randomize Start` {
scenario {
initial_x: number<-RadiusOfPlate * 0.5 .. RadiusOfPlate * 0.5>,
initial_y: number<-RadiusOfPlate * 0.5 .. RadiusOfPlate * 0.5>,

initial_vel_x: number<-MaxInitialVelocity * 0.02 .. MaxInitialVelocity * 0.02>,
initial_vel_y: number<-MaxInitialVelocity * 0.02 .. MaxInitialVelocity * 0.02>,

initial_pitch: number<-0.2 .. 0.2>,
initial_roll: number<-0.2 .. 0.2>,
}
}
}
}
}
`````` 