### Adapters
Adapters unify problems into a standard form so any agent in the elsciRL library can be used.
In short, it transforms the state to a new form, optionally adding more context and then outputting a tensor.
- *inputs*: state, legal moves, action history for episode
- *outputs*: tensor for the encoded form of the adapted state
To be imported into the elsciRL GUI tool, the class name must be *'Adapter'*.
```python
# numeric adapter (numeric.py)
class Adapter(setup_info):
def __init__():
# Determine discrete environment size: e.g. "4x4" => 16 positions
# Initialize a StateEncoder for these positions
# Optionally define an observation space (e.g., Discrete) needed for Gym agents
def adapter(state, legal_moves=[], episode_action_history=[], encode=True, indexed=False):
# If encode=True, convert the numeric state to a tensor (StateEncoder)
# If indexed=True, map states to integer IDs
return tensor(state_encoded)
```
#### Language Adapters
```python
# Import language transformer from elsciRL
from elsciRL.encoders.language_transformers.MiniLM_L6v2 import LanguageEncoder
# numeric adapter (numeric.py)
class Adapter(setup_info):
def __init__():
# Initialize the language transformer
self.encoder = LanguageEncoder()
# Get variables from encoder
# - Observation space is used for compatibility with other RL agent libraries
# - Output dim is required to used for the input of neural agents
self.observation_space = self.encoder.observation_space
self.output_dim = self.encoder.output_dim
# Specify the language adapter, e.g.:
# - directly map state_id or x_y to text
self.stateID_language = {
'0':'You are in a hallway, next to you is a door',
'1':'...',
}
self.x_y_language = {
'0_1':'You are in a hallway, next to you is a door',
'0_2':'...',
}
def adapter(state, legal_moves=[], episode_action_history=[], encode=True, indexed=False):
# 1. Transform observed data to language
# - Map state
state = self.obs_mapping[state]
# - Add legal moves or action history information, e.g. last action taken
if len(episode_action_history)>0:
state = state + ' '+ episode_action_history[-1] + '.'
# 2. Encode text using language transformer
# - If encode=True, convert the numeric state to a tensor (StateEncoder)
# - else, return raw state text (used by instruction following approaches)
if encode:
state_output = self.encoder(state=state)
else:
state_output = state
# - likewise indexed state if indexed=True, map states to integer IDs
if (indexed):
state_indexed = list()
for sent in state:
if (sent not in Adapter._cached_state_idx):
Adapter._cached_state_idx[sent] = len(Adapter._cached_state_idx)
state_indexed.append(Adapter._cached_state_idx[sent])
self.state_indexed = torch.tensor(state_indexed)
return state_output
```