def generate_batch(X: np.ndarray, y: np.ndarray, start: int = 0, batch_size: int = 10) -> Batch: assert (X.dim() == 2) and (y.dim() == 2), \ "X and Y must be 2 dimensional" if start + batch_size > X.shape[0]: batch_size = X.shape[0] - start X_batch, y_batch = X[start:start + batch_size], y[start:start + batch_size] return X_batch, y_batch
def numpy2tens(x: np.ndarray, dtype='f') -> torch.Tensor: """Converts a numpy array into torch.Tensor Parameters ---------- x: np.ndarray Array to be converted dtype: str Target data type of the tensor. Can be f - float and l - long Returns ------- result: torch.Tensor """ x = x.squeeze() x = torch.from_numpy(x) if x.dim() == 2: # CxHxW format x = x.unsqueeze(0) if dtype == 'f': return x.float() elif dtype == 'l': return x.long() else: raise NotImplementedError
def _index_select(self, index: np.ndarray, axis=0) -> 'Table': assert axis < len(self._prefix) if isinstance(index, np.ndarray): assert issubclass(index.dtype.type, Integral) assert index.dim() == 1 else: assert issubclass(type(index), Integral),\ "Table.index_select: unsupported index type" + type(index).__name__ return self._map(lambda t: np.take(t, index, axis=axis))
def forward(self, state: np.ndarray, must): state = torch.Tensor(state) # Add batch dimension if not present if state.dim() == 2: state = state.unsqueeze(dim=0) state = state.to(_device) if isinstance(must, bool): must = [must] # Remember if it was a must self.musts += must elif not isinstance(must, list): raise ValueError( f"'must' should be either a bool or a list! ({type(must)})") must = torch.Tensor(must).unsqueeze(dim=1).to(_device) # state -> (batch_size, in_channels, num_cards) # must -> (batch_size, 1) out222 = F.relu( self.conv222(state)) # -> (batch_size, out_channels, 3) out211 = F.relu( self.conv211(state)) # -> (batch_size, out_channels, 7) out213 = F.relu( self.conv213(state)) # -> (batch_size, out_channels, 5) out = torch.cat((out222, out211, out213), dim=2) # -> (batch_size, out_channels, 15) out = out.view(out.size(0), -1) # flatten -> (batch_size, 4 * 15 = 60) out = torch.cat( (out, must), dim=1) # concatenate with must info -> (batch_size, 60 + 1 = 61) probs = F.softmax(self.classify(out), dim=1) if must[0]: mask = torch.ones(4 + 1).to(_device) mask[4] = 0 probs = probs * mask # Get action distribution = Categorical(probs) action_idx = distribution.sample() log_action_probability = distribution.log_prob(action_idx) # Remember the log-probability self.log_action_probabilities.append(log_action_probability) return action_idx.item(), log_action_probability
def tf2pt( name_tf: str, array_tf: np.ndarray, name_mapping_function: Callable, ) -> Tuple[str, np.ndarray]: name_pt = name_mapping_function(name_tf) num_dimensions = array_tf.dim() if num_dimensions == 1: array_pt = array_tf elif num_dimensions == 5: array_pt = array_tf.permute(4, 3, 0, 1, 2) else: raise NotImplementedError return name_pt, array_pt
def run(self, src: np.ndarray, mode: str = "time") -> th.Tensor: """ Args: src (ndarray): (C) x S """ expected_length = src.shape[-1] src = th.from_numpy(src).to(self.device) if self.stitcher is None: return self.nnet.infer(src, mode=mode) else: if mode != "time": raise RuntimeError("Now only supports time inference mode") chunks = [] beg = self.lctx # for beg in range(0, expected_length, self.chunk_hop): while True: if (beg - self.lctx) % (logger_interval * self.chunk_hop) == 0: progress = beg * 100 / expected_length logger.info( f"--- Processing chunks, done {progress:.2f}% ...") pad = expected_length - beg - self.chunk_len if pad < 0: # last chunk, need padding if src.dim() == 1: zero = th.zeros(-pad, device=self.device) else: zero = th.zeros(src.shape[0], -pad, device=self.device) mix_chunk = th.cat([src[..., beg - self.lctx:], zero], 0) else: mix_chunk = src[..., beg - self.lctx:beg + self.chunk_len] sep_chunk = self.nnet.infer(mix_chunk, mode=mode) if isinstance(sep_chunk, th.Tensor): sep_chunk = sep_chunk.cpu() else: sep_chunk = [s.cpu() for s in sep_chunk] chunks.append(sep_chunk) beg += self.chunk_hop if pad < 0: break logger.info("--- Stitch & Reorder ...") return self.stitcher.stitch(chunks, expected_length)
def __call__(self, data: np.ndarray): assert data.dim() == 2 return self.pca.fit_transform(data)
def forward(self, state: np.ndarray, bidder, trump, legalCards): ''' In order to export an onnx model the inputs AND outputs of this function have to be TENSORS See also here: https://discuss.pytorch.org/t/torch-onnx-export-fails/72418/2 ''' # datatype: <class 'numpy.ndarray'>, <enum 'Suit'>, <class 'int'>, <class 'list'> # if datatype is tensor transform it: if torch.is_tensor(bidder): bidder = bidder.tolist() if torch.is_tensor(trump): trump = trump.tolist() # State state = torch.Tensor(state) # state.shape : torch.Size([4, 3, 32]) # state.dim : 3 if state.dim() == 3: state = state.unsqueeze(dim=0) # no effect on cpu state = state.to(_device) # Bidder if isinstance(bidder, int): bidder = [bidder] elif not isinstance(bidder, list): raise ValueError( f"'bidder' should be either an int or a list! ({type(must)})") bidder_tensors = list() for bidderIndex in bidder: t = torch.zeros(len(belot.PlayerRole)) t[bidderIndex] = 1 bidder_tensors.append(t) bidder = torch.stack(bidder_tensors, dim=0).to(_device) # Trump if isinstance(trump, int): trump = [trump] elif not isinstance(bidder, list): raise ValueError( f"'trump' should be either an int or a list! ({type(must)})") trump_tensors = list() for trumpIndex in trump: t = torch.zeros(len(belot.Suit)) t[trumpIndex] = 1 trump_tensors.append(t) trump = torch.stack(trump_tensors, dim=0).to(_device) # Legal mask if not torch.is_tensor(legalCards): mask = torch.zeros(1, len(belot.cards)) for legalCard in legalCards: idx = belot.cards.index(legalCard) mask[:, idx] = 1 mask = mask.to(_device) else: mask = legalCards #print(state.shape) # torch.Size([1, 4, 3, 32]) # state -> 4 (players), 3 (card states), 32 (cards) out418 = F.relu( self.conv418(state)) # -> (batch_size, out_channels, ?, ?) out881 = F.relu( self.conv881(state)) # -> (batch_size, out_channels, ?, ?) # print("out418", out418.shape) out418 torch.Size([1, 8, 1, 8]) # print("out881", out881.shape) out881 torch.Size([1, 8, 1, 4]) # print("bidder", bidder.shape) bidder torch.Size([1, 4]) # print("trump", trump.shape) trump torch.Size([1, 4]) out = torch.cat( ( out418.view(out418.size(0), -1), # convert from 1,8,1,8 to 1,64 out881.view(out881.size(0), -1), bidder.view(bidder.size(0), -1), trump.view(trump.size(0), -1)), dim=1) # -> (batch_size, ?) # print(out418) # tensor([[[[0.0000, ..(8Values). ]], 8 lines]]]] # print(out418.shape) # torch.Size([1, 8, 1, 8]) # print(out418.size(0)) # 1 # print(out418.view(out418.size(0), -1).shape) # torch.Size([1, 64]) # print(out418.view(out418.size(0), -1)) # print(out.shape) # torch.Size([1, 104]) probs = F.softmax(self.classify(out), dim=1) # mask e.g.: 0. 0., 0., 0., 1., 0., 0., 1.,.... # mask. shape: 1x32, probs.shape: 1x32 probs = probs * mask # probs.shape = 1x32 #print(probs)# e.g. tensor([[0.000, 0.0266, 0.0000,...]], grad_fn=<MulBackward0>) # Get action distribution = Categorical( probs ) # print(distribution) Categorical(probs: torch.Size([1, 32])) print(probs) print(distribution) print(distribution.sample()) action_idx = distribution.sample() # print(action_idx) # tensor([22]) # In case it throws this error: # Categorical(probs).sample() generates RuntimeError: invalid argument 2: invalid multinomial distribution # the softmax had turned into a vector of lovely NaNs. then categorical fails with above error. # The model itself is generating the nan because of the exploding gradients due to the learning rate. log_action_probability = distribution.log_prob( action_idx ) # print(log_action_probability) # tensor([-1.9493], grad_fn=<SqueezeBackward1>) # Remember the log-probability self.log_action_probabilities.append(log_action_probability) returned_tensor = torch.zeros(1, 2) returned_tensor[:, 0] = action_idx.item() returned_tensor[:, 1] = log_action_probability return returned_tensor