[RLlib] Trajectory view API - 03 Fast LSTM + prev actions/rewards (#9950)

This commit is contained in:
Sven Mika
2020-08-21 12:35:16 +02:00
committed by GitHub
parent 92664249e8
commit e968b52cb7
25 changed files with 1230 additions and 413 deletions
+48 -12
View File
@@ -59,19 +59,33 @@ class SampleBatch:
def __init__(self, *args, **kwargs):
"""Constructs a sample batch (same params as dict constructor)."""
self._initial_inputs = kwargs.pop("_initial_inputs", {})
# Possible seq_lens (TxB or BxT) setup.
self.time_major = kwargs.pop("_time_major", None)
self.seq_lens = kwargs.pop("_seq_lens", None)
self.max_seq_len = None
if self.seq_lens is not None and len(self.seq_lens) > 0:
self.max_seq_len = max(self.seq_lens)
# The actual data, accessible by column name (str).
self.data = dict(*args, **kwargs)
lengths = []
for k, v in self.data.copy().items():
assert isinstance(k, str), self
lengths.append(len(v))
self.data[k] = np.array(v, copy=False)
if isinstance(v, list):
self.data[k] = np.array(v)
if not lengths:
raise ValueError("Empty sample batch")
assert len(set(lengths)) == 1, ("data columns must be same length",
self.data, lengths)
self.count = lengths[0]
assert len(set(lengths)) == 1, \
"Data columns must be same length, but lens are {}".format(lengths)
if self.seq_lens is not None and len(self.seq_lens) > 0:
self.count = sum(self.seq_lens)
else:
self.count = len(self.data[k])
# Keeps track of new columns added after initial ones.
self.new_columns = []
@staticmethod
@PublicAPI
@@ -88,11 +102,21 @@ class SampleBatch:
"""
if isinstance(samples[0], MultiAgentBatch):
return MultiAgentBatch.concat_samples(samples)
seq_lens = []
concat_samples = []
for s in samples:
if s.count > 0:
concat_samples.append(s)
if s.seq_lens is not None:
seq_lens.extend(s.seq_lens)
out = {}
samples = [s for s in samples if s.count > 0]
for k in samples[0].keys():
out[k] = concat_aligned([s[k] for s in samples])
return SampleBatch(out)
for k in concat_samples[0].keys():
out[k] = concat_aligned(
[s[k] for s in concat_samples],
time_major=concat_samples[0].time_major)
return SampleBatch(
out, _seq_lens=seq_lens, _time_major=concat_samples[0].time_major)
@PublicAPI
def concat(self, other: "SampleBatch") -> "SampleBatch":
@@ -222,8 +246,18 @@ class SampleBatch:
SampleBatch: A new SampleBatch, which has a slice of this batch's
data.
"""
return SampleBatch({k: v[start:end] for k, v in self.data.items()})
if self.time_major is not None:
return SampleBatch(
{k: v[:, start:end]
for k, v in self.data.items()},
_seq_lens=self.seq_lens[start:end],
_time_major=self.time_major)
else:
return SampleBatch(
{k: v[start:end]
for k, v in self.data.items()},
_seq_lens=None,
_time_major=self.time_major)
@PublicAPI
def timeslices(self, k: int) -> List["SampleBatch"]:
@@ -290,7 +324,7 @@ class SampleBatch:
key (str): The key (column name) to return.
Returns:
TensorType]: The data under the given key.
TensorType: The data under the given key.
"""
return self.data[key]
@@ -302,6 +336,8 @@ class SampleBatch:
key (str): The column name to set a value for.
item (TensorType): The data to insert.
"""
if key not in self.data:
self.new_columns.append(key)
self.data[key] = item
@DeveloperAPI