<jupyter_start><jupyter_text>Binary segmentation with the Lovász Hinge Tensorflow version, see PyTorch version for more details & use in training<jupyter_code>%load_ext autoreload
%autoreload 2
from __future__ import division, print_function
import sys
import tensorflow as tf
import lovasz_losses_tf as L
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# add parent path to pythonpath to import demo_utils
import sys
sys.path.append('../demo_helpers')
from demo_utils import pil_grid, dummy_triangles
from demo_utils_tf import define_scope
# add pytorch folder to path for comparison
sys.path.append('../pytorch')
import lovasz_losses as L_pytorch<jupyter_output><empty_output><jupyter_text>Ground truth<jupyter_code>H = W = 200
IGNORE = 255
classes = [0, 255, 1]
C = len([c for c in classes if c != IGNORE])
B = 2
np.random.seed(18)
labels_ = [dummy_triangles(H, classes) for b in range(B)]
labels = np.stack(map(np.array, labels_)).astype(np.uint8)
pil_grid(labels_, 5, margin=1)<jupyter_output><empty_output><jupyter_text>Features<jupyter_code>np.random.seed(57)
feats = np.zeros(labels.shape)
feats[labels == 0] = np.random.normal(-1, 2.5, size=feats.shape)[labels == 0]
feats[labels == 1] = np.random.normal(1, 2.5, size=feats.shape)[labels == 1]
feats[labels == 255] = np.random.normal(0, 5, size=feats.shape)[labels == 255]
sess = tf.InteractiveSession()
labels_tf = tf.placeholder(np.int64, shape=(None, H, W), name='labels')
feats_tf = tf.placeholder(np.float32, shape=(None, H, W), name='features')
feed_dict = {labels_tf: labels, 
             feats_tf: feats}<jupyter_output><empty_output><jupyter_text>Model<jupyter_code>class Model:
    '''
    Simple linear model
    '''
    
    def __init__(self, feats):
        self.feats = feats
        self.scores
        self.predict

    @define_scope
    def scores(self):
        x = self.feats
        bias = tf.Variable(0., x.dtype, name="bias")
        return tf.add(x, bias, name="scores")
    
    @define_scope
    def probas(self):
        return tf.nn.sigmoid(self.scores)
    
    @define_scope
    def predict(self):
        return tf.greater_equal(self.scores, 0, name="predict")
m = Model(feats_tf)
sess.run(tf.global_variables_initializer())<jupyter_output><empty_output><jupyter_text>Lovász-Hinge value<jupyter_code>loss = L.lovasz_hinge(m.scores, labels_tf, ignore=IGNORE, per_image=True)
loss.eval(feed_dict)<jupyter_output><empty_output><jupyter_text>Gradient w.r.t. bias<jupyter_code>tf.gradients(loss, tf.trainable_variables()[0])[0].eval(feed_dict)<jupyter_output>WARNING: Logging before flag parsing goes to stderr.
W0226 18:10:16.500215 139827989141312 deprecation.py:323] From /esat/visicsdata/mberman/miniconda2/envs/lamlearn/lib/python3.6/site-packages/tensorflow/python/ops/array_grad.py:425: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.<jupyter_text>PyTorch reference should give the same results...<jupyter_code>import torch
from torch.autograd import Variable
import torch.nn.functional as F
from torch.optim import Adam
from torch import nn

class ModelPytorch(nn.Module):
    def __init__(self):
        super(ModelPytorch, self).__init__()
        self.bias = nn.Parameter(torch.Tensor([0]))
    
    def forward(self, x):
        return x + self.bias

m_torch = ModelPytorch()
out = m_torch(Variable(torch.from_numpy(feats.astype(np.float32))))
loss_torch = L_pytorch.lovasz_hinge(out, torch.from_numpy(labels), ignore=IGNORE, per_image=True)
loss_torch.data.numpy().item()<jupyter_output><empty_output><jupyter_text>Gradient w.r.t. bias<jupyter_code>loss_torch.backward()
m_torch.bias.grad.data.numpy().item()<jupyter_output><empty_output><jupyter_text>Lovász-Sigmoid value<jupyter_code>loss = L.lovasz_softmax(m.probas, labels_tf, classes=[1], ignore=IGNORE, per_image=True)
loss.eval(feed_dict)
tf.gradients(loss, tf.trainable_variables()[0])[0].eval(feed_dict)<jupyter_output><empty_output><jupyter_text>PyTorch reference<jupyter_code>sigmoid_out = torch.sigmoid(out)
loss_torch = L_pytorch.lovasz_softmax(sigmoid_out, torch.from_numpy(labels), classes=[1], ignore=IGNORE, per_image=True)
loss_torch
m_torch.bias.grad.data.fill_(0)
loss_torch.backward()
m_torch.bias.grad.data.numpy().item()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12609295904279796, 'fraction_numerical': 0.02208927749654855, 'mean_word_length': 5.656967840735069, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '485380', 'license': 'MIT', 'n_tokens_mistral': 1657, 'n_tokens_neox': 1607, 'n_words': 301, 'path': 'tensorflow/demo_binary_tf.ipynb', 'repo_name': 'dreadlord1984/LovaszSoftmax', 'size': '4346'}