def add_pr_curve(self, tag, labels, predictions, global_step=None, num_thresholds=127, weights=None): """Adds precision recall curve. Args: tag (string): Data identifier labels (torch.Tensor, numpy.array, or string/blobname): Ground truth data. Binary label for each element. predictions (torch.Tensor, numpy.array, or string/blobname): The probability that an element be classified as true. Value should in [0, 1] global_step (int): Global step value to record num_thresholds (int): Number of thresholds used to draw the curve. """ labels, predictions = make_np(labels), make_np(predictions) raw_data = compute_curve(labels, predictions, num_thresholds, weights) # compute_curve returns np.stack((tp, fp, tn, fn, precision, recall)) # We want to access 'precision' and 'recall' precision, recall = raw_data[4, :], raw_data[5, :] self.vis.line( X=recall, Y=precision, name=tag, opts={ 'title': 'PR Curve for {}'.format(tag), 'xlabel': 'recall', 'ylabel': 'precision', }, )
def add_pr_curve(self, tag, labels, predictions, global_step=None, num_thresholds=127, weights=None): """Adds precision recall curve. Args: tag (string): Data identifier labels (torch.Tensor, numpy.array, or string/blobname): Ground truth data. Binary label for each element. predictions (torch.Tensor, numpy.array, or string/blobname): The probability that an element be classified as true. Value should in [0, 1] global_step (int): Global step value to record num_thresholds (int): Number of thresholds used to draw the curve. """ labels, predictions = make_np(labels), make_np(predictions) pr_dict = { tag: wandb.plots.precision_recall(y_true=labels, y_probas=predictions), 'epoch': global_step } wandb.log(pr_dict, commit=True)
def test_pytorch_histogram_raw(self): with SummaryWriter() as w: num = 50 floats = x2num.make_np(torch.rand((num,))) bins = [0.0, 0.25, 0.5, 0.75, 1.0] counts, limits = np.histogram(floats, bins) sum_sq = floats.dot(floats).item() w.add_histogram_raw('float histogram raw', min=floats.min().item(), max=floats.max().item(), num=num, sum=floats.sum().item(), sum_squares=sum_sq, bucket_limits=limits.tolist(), bucket_counts=counts.tolist()) ints = x2num.make_np(torch.randint(0, 100, (num,))) bins = [0, 25, 50, 75, 100] counts, limits = np.histogram(ints, bins) sum_sq = ints.dot(ints).item() w.add_histogram_raw('int histogram raw', min=ints.min().item(), max=ints.max().item(), num=num, sum=ints.sum().item(), sum_squares=sum_sq, bucket_limits=limits.tolist(), bucket_counts=counts.tolist())
def test_chainer_np(self): for tensor in tensors: # regular variable assert isinstance(x2num.make_np(tensor), np.ndarray) # python primitive type assert (isinstance(x2num.make_np(0), np.ndarray)) assert (isinstance(x2num.make_np(0.1), np.ndarray))
def test_chainer_np(): if not chainer_installed: return for tensor in tensors: # regular variable assert isinstance(x2num.make_np(tensor), np.ndarray) # python primitive type assert(isinstance(x2num.make_np(0), np.ndarray)) assert(isinstance(x2num.make_np(0.1), np.ndarray))
def test_scalar(): res = x2num.make_np(1.1) assert isinstance(res, np.ndarray) and res.shape == (1,) res = x2num.make_np(1000000000000000000000) assert isinstance(res, np.ndarray) and res.shape == (1,) res = x2num.make_np(np.float16(1.00000087)) assert isinstance(res, np.ndarray) and res.shape == (1,) res = x2num.make_np(np.float128(1.00008 + 9)) assert isinstance(res, np.ndarray) and res.shape == (1,) res = x2num.make_np(np.int64(100000000000)) assert isinstance(res, np.ndarray) and res.shape == (1,)
def add_heatmap(self, tag, values, global_step=None): """Add histogram to summary. Args: tag (string): Data identifier values (torch.Tensor, numpy.array, or string/blobname): Values to build histogram global_step (int): Global step value to record bins (string): one of {'tensorflow', 'auto', 'fd', ...}, this determines how the bins are made. You can find other options in: https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html """ values = make_np(values) self.vis.heatmap(make_np(values), opts={'title': tag})
def test_chainer_img(): if not chainer_installed: return shapes = [(77, 3, 13, 7), (77, 1, 13, 7), (3, 13, 7), (1, 13, 7), (13, 7)] for s in shapes: x = chainer.Variable(np.random.random_sample(s)) assert x2num.make_np(x, 'IMG').shape[2] == 3
def add_image(self, tag, img_tensor, global_step=None, caption=None, store_history=False): """Add image data to summary. Note that this requires the ``pillow`` package. Args: tag (string): Data identifier img_tensor (torch.Tensor, numpy.array, or string/blobname): Image data global_step (int): Global step value to record Shape: img_tensor: :math:`(C, H, W)`. Use ``torchvision.utils.make_grid()`` to prepare it is a good idea. C = colors (can be 1 - grayscale, 3 - RGB, 4 - RGBA) """ fn = self.vis.images if len(img_tensor.shape) > 3 else self.vis.image img_tensor = make_np(img_tensor) fn(img_tensor, win=tag, opts={ 'title': tag, 'caption': caption, 'store_history': store_history })
def make_session_start_summary( hparam_values, group_name: Optional[str] = None, start_time_secs: Optional[int] = None, ): """Assign values to the hyperparameters in the context of this session. Args: hparam_values: a dict of ``hp_name`` -> ``hp_value`` mappings group_name: optional group name for this session start_time_secs: optional starting time in seconds Returns: """ if start_time_secs is None: import time start_time_secs = int(time.time()) session_start_info = SessionStartInfo(group_name=group_name, start_time_secs=start_time_secs) for hp_name, hp_value in hparam_values.items(): # Logging a None would raise an exception when setting session_start_info.hparams[hp_name].number_value = None. # Logging a float.nan instead would work, but that run would not show at all in the tensorboard hparam plugin. # The best thing to do here is to skip that value, it will show as a blank cell in the table view of the # tensorboard plugin. However, that run would not be shown in the parallel coord or in the scatter plot view. if hp_value is None: loguru.warning( f"Hyper parameter {hp_name} is `None`: the tensorboard hp plugin " f"will show this run in table view, but not in parallel coordinates " f"view or in scatter plot matrix view") continue if isinstance(hp_value, string_types): session_start_info.hparams[hp_name].string_value = hp_value continue if isinstance(hp_value, bool): session_start_info.hparams[hp_name].bool_value = hp_value continue if not isinstance(hp_value, (int, float)): hp_value = make_np(hp_value)[0] session_start_info.hparams[hp_name].number_value = hp_value session_start_content = HParamsPluginData( session_start_info=session_start_info, version=PLUGIN_DATA_VERSION) session_start_summary_metadata = SummaryMetadata( plugin_data=SummaryMetadata.PluginData( plugin_name=PLUGIN_NAME, content=session_start_content.SerializeToString())) session_start_summary = Summary(value=[ Summary.Value(tag=SESSION_START_INFO_TAG, metadata=session_start_summary_metadata) ]) return session_start_summary
def add_scalar(self, tag, scalar_value, global_step=None): """Add scalar data to Visdom. Plots the values in a plot titled {main_tag}-{tag}. Args: tag (string): Data identifier scalar_value (float or string/blobname): Value to save global_step (int): Global step value to record """ assert '_' in tag, "tag needs to _, i.e. prefix_name" main_tag = tag.split('_')[0] if self.scalar_dict.get(main_tag) is None: self.scalar_dict[main_tag] = {} exists = self.scalar_dict[main_tag].get(tag) is not None self.scalar_dict[main_tag][tag] = self.scalar_dict[main_tag][tag] \ + [scalar_value] if exists else [scalar_value] # plot_name = '{}_{}'.format(main_tag, tag) plot_name = tag # If there is no global_step provided, follow sequential order x_val = len(self.scalar_dict[main_tag] [tag]) if not global_step else global_step if exists: # Update our existing Visdom window self.vis.line( X=make_np(x_val), Y=make_np(scalar_value), name=plot_name, update='append', win=self.windows[plot_name], ) else: # Save the window if we are creating this graph for the first time self.windows[plot_name] = self.vis.line( X=make_np(x_val), Y=make_np(scalar_value), name=plot_name, opts={ 'title': plot_name, 'xlabel': 'epoch', 'ylabel': tag.split('_')[-1], }, ) self.save()
def test_pytorch_np(self): tensors = [ torch.rand(3, 10, 10), torch.rand(1), torch.rand(1, 2, 3, 4, 5) ] for tensor in tensors: # regular tensor assert isinstance(x2num.make_np(tensor), np.ndarray) # CUDA tensor if torch.cuda.device_count() > 0: assert isinstance(x2num.make_np(tensor.cuda()), np.ndarray) # regular variable assert isinstance(x2num.make_np(torch.autograd.Variable(tensor)), np.ndarray) # CUDA variable if torch.cuda.device_count() > 0: assert isinstance( x2num.make_np(torch.autograd.Variable(tensor).cuda()), np.ndarray) # python primitive type assert (isinstance(x2num.make_np(0), np.ndarray)) assert (isinstance(x2num.make_np(0.1), np.ndarray))
def add_pr_curve_raw(self, tag, true_positive_counts, false_positive_counts, true_negative_counts, false_negative_counts, precision, recall, global_step=None, num_thresholds=127, weights=None): """Adds precision recall curve with raw data. Args: tag (string): Data identifier true_positive_counts (torch.Tensor, numpy.array, or string/blobname): true positive counts false_positive_counts (torch.Tensor, numpy.array, or string/blobname): false positive counts true_negative_counts (torch.Tensor, numpy.array, or string/blobname): true negative counts false_negative_counts (torch.Tensor, numpy.array, or string/blobname): false negative counts precision (torch.Tensor, numpy.array, or string/blobname): precision recall (torch.Tensor, numpy.array, or string/blobname): recall global_step (int): Global step value to record num_thresholds (int): Number of thresholds used to draw the curve. see: https://github.com/tensorflow/tensorboard/blob/master/tensorboard/plugins/pr_curve/README.md """ precision, recall = make_np(precision), make_np(recall) self.vis.line( X=recall, Y=precision, name=tag, opts={ 'title': 'PR Curve for {}'.format(tag), 'xlabel': 'recall', 'ylabel': 'precision', }, ) self.save()
def add_audio(self, tag, snd_tensor, global_step=None, sample_rate=44100): """Add audio data to summary. Args: tag (string): Data identifier snd_tensor (torch.Tensor, numpy.array, or string/blobname): Sound data global_step (int): Global step value to record sample_rate (int): sample rate in Hz Shape: snd_tensor: :math:`(1, L)`. The values should lie between [-1, 1]. """ snd_tensor = make_np(snd_tensor) self.vis.audio(tensor=snd_tensor, opts={'sample_frequency': sample_rate})
def test_pytorch_img(self): shapes = [(77, 3, 13, 7), (77, 1, 13, 7), (3, 13, 7), (1, 13, 7), (13, 7)] for s in shapes: x = torch.Tensor(np.random.random_sample(s)) assert x2num.make_np(x, 'IMG').shape[2] == 3
def test_pytorch_vid(self): shapes = [(16, 3, 30, 28, 28), (19, 3, 30, 28, 28), (19, 3, 29, 23, 19)] for s in shapes: x = torch.Tensor(np.random.random_sample(s)) assert x2num.make_np(x, 'VID').shape[3] == 3
def test_numpy_vid_uint8(self): x = np.random.random_integers(0, 255, (16, 3, 30, 28, 28)).astype(np.uint8) x2num.make_np(x, 'VID').shape[3] == 3
def test_numpy_vid(self): shapes = [(16, 3, 30, 28, 28), (19, 3, 30, 28, 28), (19, 3, 29, 23, 19)] for s in shapes: x = np.random.random_sample(s) assert x2num.make_np(x, 'VID').shape[3] == 3
def test_caffe2_np(self): workspace.FeedBlob("testBlob", np.random.randn(1, 3, 64, 64).astype(np.float32)) assert isinstance(x2num.make_np('testBlob'), np.ndarray)
def tensor2image(x): tensor = x2num.make_np(vutils.make_grid(x.data[:64], normalize=True)) xtensors = xutils.convert_to_HWC(tensor, 'CHW') plt.imshow(xtensors) plt.show()