I don’t understand your question. you have a 7 channel image? Maybe if you post an example it would be clear what you are trying to do and I could help out.
I have 7 channels as input to CNN.The dataset is similar to one used in dstl competition.For One Output mask there are 7 channels as input.It is basically a segmentation problem
@bfarzin Basically I have a (7 * size * size) as my Input and I want to pass it To UNET to get (n_classes * sz * sz) as output masks.How do I pass this to Fastai.While using Standard Pytorch I implemented Basic Transformations like horizontal flip and 90 degree rotations using numpy.Will the transforms of fastai work for 7 channel input i not how can i pass my own transforms to fastai.
This is outside the scope of my experience, really. I would suggest breaking out as a new topic in the forums and see if there is broader help. I suspect you can do all the transforms in fastai, but I have not spent a ton of time working on that part of the library.
I think you are discussing these two lines:
#channel 4 is all 255, drop it
label = cv2.resize(img[:,:,:3],(int(img.shape[1]/8),int(img.shape[0]/8)),interpolation = cv2.INTER_CUBIC)*64
Is that correct? Here I am just saving space since the images are only three channel (RGB.) I don’t see why you couldn’t have it be N channel but have never tried that. Did you just try to allow all channels? Does something break?
I think transforms are only defined for a channel<=3 so this isnt working.I have my own dataset with transforms available.All I need to know is How I can pass it to fastai.I guess I just need the one fit cycle on a custom model and a custom dataset.Could you help me with that
@bfarzin
Here is the function that is performing transforms
def applytransform(x,y,mode):
if mode=="val":
return x,y
if random.random()>=0.5:
return x,y
else:
if random.random()>=0.5:
for i in range(len(x)):x[i]=np.fliplr(x[i])
y=np.fliplr(y)
if random.random()>=0.5:
for i in range(len(x)):x[i]=np.flipud(x[i])
y=np.flipud(y)
if random.random()>=0.5:
k=random.randint(0,3)
for i in range(len(x)):x[i]=np.rot90(x[i],k)
y=np.rot90(y,k)
return x,y
I am going through each channel and applying transformation to both image and mask
Here is one idea. You could extend the TensorDataset
with your own __getitem__
that can pull your own transforms (from your own data) rather than having the data be static. From there, it should all flow, but I have not tried this myself. Let me know if that works for you.
@bfarzin Okay I will try that.But using Tensor Dataset Does it mean I must have all the tensors in memory first?I already have created something that returns me the Final Tensors after transformation.
class GetTransformedSet(Dataset):
def __init__(self,root,img_list,mask_list,transforms=None,mode="train"):
self.root=root
self.img_list=img_list
self.mask_list=mask_list
self.transformation=transforms
self.mode=mode
def __len__(self):
return len(self.img_list)
def __getitem__(self,i):
mask_path=os.path.join(os.getcwd(),self.root+path+self.mask_list[i])
img,mask=open_multiple_channel_img(input_files[i],mask_path,self.mode)
img = img.type('torch.FloatTensor')
return img,mask
def open_multiple_channel_img(file_name,mask_path,mode):
file_name=file_name.split("_")
file_name=file_name[0]+"_"+file_name[1]+"_"+file_name[2]+"_"+file_name[3]
path=f'{im_input}/'+file_name
images=[]
mask=Image.open(mask_path)
mask=np.array(mask)
for i in range(1,8):
im=Image.open(path+"_"+str(i)+".tif")
im_array=np.array(im)/255
im_array=im_array-mean_norm[i-1]
#im_array=im_array/std_norm[i-1]
images.append(im_array)
images,masks=applytransform(np.stack(images, axis=0),mask,mode)
return torch.from_numpy(images.copy()),torch.from_numpy(masks.copy())
Hello @at98
Does this address your question?
Classifier with multiple images as input and multiple labels as output.
I am trying to use multichannels as inputs to a pre-trained resnet model so I cam across your post and this other one above.
CC: @bfarzin
Thank you!
Hi guys,
I want to create my own data generator from a csv
file for the segmentation task. The file contains two columns: 1st column contains the location of the image and the 2nd one contains the location of the mask. I have written the following code:
df = pd.read_csv('/path/to/csv/data.csv')
X = list(df['input_img'])
y = list(df['mask_img'])
X_train, X_valid, y_train, y_valid = train_test_split(
X, y, test_size=0.33, random_state=42)
class ToTensor(object):
"""Convert ndarrays in sample to Tensors."""
def __call__(self, img):
img = img.transpose((2, 0, 1))
# return {'image': torch.from_numpy(img),
# }
return torch.from_numpy(img)
class NumbersDataset(Dataset):
def __init__(self, inputs, labels, transform=None):
classes = [0,1]
self.X = inputs
self.y = labels
self.transform = transform
self.c = 2
def __len__(self):
return len(self.X)
def __getitem__(self, idx):
img_train = cv2.imread(self.X[idx])
img_mask = cv2.imread(self.y[idx])
img_train = cv2.resize(img_train, (427,240), interpolation = cv2.INTER_LANCZOS4)
img_mask = cv2.resize(img_mask, (427,240), interpolation = cv2.INTER_LANCZOS4)
img_mask = cv2.cvtColor(img_mask, cv2.COLOR_BGR2GRAY)
bin_mask = np.zeros_like(img_mask)
bin_mask[(img_mask)>0]=1
bin_mask = bin_mask.reshape(240, 427, 1)
if self.transform:
img_train = self.transform(img_train)
bin_mask = self.transform(bin_mask)
return img_train, bin_mask
if __name__ == '__main__':
dataset_train = NumbersDataset(X_train, y_train, transforms.Compose([ToTensor()]))
# dataset_train = NumbersDataset(X_train, y_train)
dataloader_train = DataLoader(dataset_train, batch_size=4, shuffle=True)
# dataset_valid = NumbersDataset(X_valid, y_valid)
dataset_valid = NumbersDataset(X_valid, y_valid, transforms.Compose([ToTensor()]))
dataloader_valid = DataLoader(dataset_valid, batch_size=4, shuffle=True)
datas = DataBunch(train_dl = dataloader_train, valid_dl = dataloader_valid)
# datas.show_batch()
datas.c = 1
learner = unet_learner(datas, models.resnet34)
I get the following error:
Traceback (most recent call last):
File "dataset_test.py", line 104, in <module>
learner = unet_learner(datas, models.resnet34)
File "/home/sarvagya/miniconda3/envs/gr/lib/python3.6/site-packages/fastai/vision/learner.py", line 121, in unet_learner
bottle=bottle), data.device)
File "/home/sarvagya/miniconda3/envs/gr/lib/python3.6/site-packages/fastai/core.py", line 66, in _init
old_init(self, *args,**kwargs)
File "/home/sarvagya/miniconda3/envs/gr/lib/python3.6/site-packages/fastai/vision/models/unet.py", line 43, in __init__
sfs_szs = model_sizes(encoder, size=imsize)
File "/home/sarvagya/miniconda3/envs/gr/lib/python3.6/site-packages/fastai/callbacks/hooks.py", line 113, in model_sizes
x = dummy_eval(m, size)
File "/home/sarvagya/miniconda3/envs/gr/lib/python3.6/site-packages/fastai/callbacks/hooks.py", line 108, in dummy_eval
return m.eval()(dummy_batch(m, size))
File "/home/sarvagya/miniconda3/envs/gr/lib/python3.6/site-packages/fastai/callbacks/hooks.py", line 104, in dummy_batch
return one_param(m).new(1, ch_in, *size).requires_grad_(False).uniform_(-1.,1.)
TypeError: new() argument after * must be an iterable, not builtin_function_or_method
What should I do?
Hi, Bobak,
Thanks for sharing your work! I’ve been tying to create my custom training pipeline with the fastai library, and I find your notebook very useful. However, under the current version of fastai v1.0.60, your code doesn’t work anymore. The thing is, now we should import DataBunch
from fastai.basic_data
, and import Learner
from fastai.basic_train
. My problem is, after I’ve done these import right, and pass a custom model, a DataBunch
, a loss function and an optimzor into Learner
, when I called learn.lr_find()
, it returns AttributeError: 'Learner' object has no attribute 'lr_find'
.
I’ve googled a lot and can’t find the solution. Can you help me?
I have not yet caught up on the latest version of the library. I don’t think that finding the lr_find()
is related to the custom pipeline. But I am just not sure.
If you do find a solution, please post a link here so others can find in the future. Good luck!
I didn’t find the solutoin. I create my custom lr_find
with pytorch’s torch.optim.lr_scheduler.LambdaLR
. Normally creating a fastai leaner class with Learner
will have lr_find
and fit_one_cycle
attributes automatically, as the fastai doc says. However, even when I pass lr_find
callbacks explicitly into callback_fns
when creating my learn
object using learn = Learner(data, model, opt_func=optim.SGD, loss_func=loss_func, callback_fns=[lr_finder])
, lr_find
does not appear in my learn
's attributes list.