title: Mask values in segmentation task are either 0 or 255. How do I resolve this?
body: <p>I must be getting something terribly wrong with the fast-ai library, since I seem to be the only one having this problem. Everytime I try the learning rate finder or training the network, it gives me an error. It took me a week to produce this specific error message, which made me check the mask values. It turns out they are either 0 for background pixels and 255 for foreground ones. This is a problem as I only have two classes. How can I change the 255 values to 1 within my Databunch Object? Is there a way to divide each mask value by 255 or do I need to do it beforehand somehow? I am kinda lost within the process.</p>
  
  <p>Here's the error message i'm getting:</p>
  
  <pre><code>LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
  
  ---------------------------------------------------------------------------
  </code></pre>
  
  <pre class="lang-py prettyprint-override"><code>    RuntimeError                              Traceback (most recent call last)
  
      &lt;ipython-input-20-c7a9c29f9dd1&gt; in &lt;module&gt;()
      ----&gt; 1 learn.lr_find()
            2 learn.recorder.plot()
  
      8 frames
  
      /usr/local/lib/python3.6/dist-packages/fastai/train.py in lr_find(learn, start_lr, end_lr, num_it, stop_div, wd)
           39     cb = LRFinder(learn, start_lr, end_lr, num_it, stop_div)
           40     epochs = int(np.ceil(num_it/len(learn.data.train_dl)))
      ---&gt; 41     learn.fit(epochs, start_lr, callbacks=[cb], wd=wd)
           42 
           43 def to_fp16(learn:Learner, loss_scale:float=None, max_noskip:int=1000, dynamic:bool=True, clip:float=None,
  
      /usr/local/lib/python3.6/dist-packages/fastai/basic_train.py in fit(self, epochs, lr, wd, callbacks)
          198         else: self.opt.lr,self.opt.wd = lr,wd
          199         callbacks = [cb(self) for cb in self.callback_fns + listify(defaults.extra_callback_fns)] + listify(callbacks)
      --&gt; 200         fit(epochs, self, metrics=self.metrics, callbacks=self.callbacks+callbacks)
          201 
          202     def create_opt(self, lr:Floats, wd:Floats=0.)-&gt;None:
  
      /usr/local/lib/python3.6/dist-packages/fastai/basic_train.py in fit(epochs, learn, callbacks, metrics)
           99             for xb,yb in progress_bar(learn.data.train_dl, parent=pbar):
          100                 xb, yb = cb_handler.on_batch_begin(xb, yb)
      --&gt; 101                 loss = loss_batch(learn.model, xb, yb, learn.loss_func, learn.opt, cb_handler)
          102                 if cb_handler.on_batch_end(loss): break
          103 
  
      /usr/local/lib/python3.6/dist-packages/fastai/basic_train.py in loss_batch(model, xb, yb, loss_func, opt, cb_handler)
           28 
           29     if not loss_func: return to_detach(out), to_detach(yb[0])
      ---&gt; 30     loss = loss_func(out, *yb)
           31 
           32     if opt is not None:
  
      /usr/local/lib/python3.6/dist-packages/fastai/layers.py in __call__(self, input, target, **kwargs)
          241         if self.floatify: target = target.float()
          242         input = input.view(-1,input.shape[-1]) if self.is_2d else input.view(-1)
      --&gt; 243         return self.func.__call__(input, target.view(-1), **kwargs)
          244 
          245 def CrossEntropyFlat(*args, axis:int=-1, **kwargs):
  
      /usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
          539             result = self._slow_forward(*input, **kwargs)
          540         else:
      --&gt; 541             result = self.forward(*input, **kwargs)
          542         for hook in self._forward_hooks.values():
          543             hook_result = hook(self, input, result)
  
      /usr/local/lib/python3.6/dist-packages/torch/nn/modules/loss.py in forward(self, input, target)
          914     def forward(self, input, target):
          915         return F.cross_entropy(input, target, weight=self.weight,
      --&gt; 916                                ignore_index=self.ignore_index, reduction=self.reduction)
          917 
          918 
  
      /usr/local/lib/python3.6/dist-packages/torch/nn/functional.py in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction)
         2007     if size_average is not None or reduce is not None:
         2008         reduction = _Reduction.legacy_get_string(size_average, reduce)
      -&gt; 2009     return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
         2010 
         2011 
  
      /usr/local/lib/python3.6/dist-packages/torch/nn/functional.py in nll_loss(input, target, weight, size_average, ignore_index, reduce, reduction)
         1836                          .format(input.size(0), target.size(0)))
         1837     if dim == 2:
      -&gt; 1838         ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
         1839     elif dim == 4:
         1840         ret = torch._C._nn.nll_loss2d(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
  
      RuntimeError: Assertion `cur_target &gt;= 0 &amp;&amp; cur_target &lt; n_classes' failed.  at /pytorch/aten/src/THNN/generic/ClassNLLCriterion.c:97
  </code></pre>
  
  <p>Also this is how I set up my data:</p>
  
  <pre class="lang-py prettyprint-override"><code>    data = (SegmentationItemList.from_df(img_df,IMAGE_PATH)
            # import from df in greyscale ('L')
            .split_by_rand_pct(valid_pct=0.15)
            # 1/15 train/validation split
            .label_from_func(get_mask, classes = array(['background','cell']))
            # segmentation mask and classes
            .transform(tfms, tfm_y=True, size=TILE_SHAPE)
            # apply data augmentation
            .databunch(bs=BATCH_SIZE)
            # set batchsize
            .normalize()
      )
  </code></pre>
  
  <p>Please tell me if you need any more information. I already tried adding an 'after_open' function, which should have divided all by 255 to the 'label_from_func' part. I also know there is a div attribute within the 'open_image' function of fast-ai, which is supposed to normalize RGB values between 0 and 1, but I couldn't find one for 'label_from_func'.</p>
  
  <p>Edit:</p>
  
  <p>I found <a href="https://forums.fast.ai/t/unet-binary-segmentation/29833/25" rel="noreferrer">this post</a> in the fastai community. However even with these answers i was not able to solve my problem. I tried adding this snippet to pass div=True into the open_mask function, but it did not work:</p>
  
  <pre class="lang-py prettyprint-override"><code>    src.train.y.create_func = partial(open_mask, div=True)
      src.valid.y.create_func = partial(open_mask, div=True)
  </code></pre>
  
  <p>I also tried <code>.set_attr(mask_opener=partial(open_mask, div=True))</code> after <code>.label_from_func()</code>, but then it throws this attribute error: <code>AttributeError: setattr</code></p>
  
  <p>Still need help</p>