Keras ResNet50 model for Melanoma prediction - python

Below is my professor's code to implement Keras ResNet50.
model = ResNet50(weights='imagenet', include_top=False, input_shape=(150, 150,3))
Y_train = []
X_train = []
label = 0
# 2 for loop, 1 for classes and 1 for images in the class
for i in os.listdir(train_path): #for class
img_path = train_path + "/" + i + "/"
img_num = 0
for file in os.listdir(img_path): # for images
img_path1 = img_path+"/"+file
img=cv2.imread(img_path1)
img=cv2.resize(img,(150,150))
img = image.img_to_array(img)
img = resnet50.preprocess_input(np.expand_dims(img.copy(), axis=0))
img = model.predict(img)
X_train.append(img.flatten())
Y_train.append(label)
label = label+1
Y_test = []
X_test = []
label = 0
for i in os.listdir(test_path):
path = test_path + "/" + i + "/"
img_num = 0
for file in os.listdir(img_path):
img_path1 = img_path+"/"+file
img=cv2.imread(img_path1)
img=cv2.resize(img,(150,150))
img = image.img_to_array(img)
img = resnet50.preprocess_input(np.expand_dims(img.copy(), axis=0))
img = model.predict(img)
X_test.append(img.flatten()/255)
Y_test.append(label)
label = label+1
model = linear_model.LogisticRegression().fit(X_train,Y_train)
pred = model.predict(X_test)
cm = confusion_matrix(Y_test,pred)
print((cm[0,0]+cm[1,1])/(sum(sum(cm))))
I asked my professor about why there are "double prediction", as in the line img = model.predict(img) and LogReg is implemented after that. He explained that img = model.predict(img) is to embed the image, not provide prediction. However when I looked up to online material they all said model.predict is to predict the image output.
So how should I understand the line model.predict(img) in this case?

Related

MarkRCNN output images (prediction)

I'm following this object detection tutorial in Pytorch for Mask RCNN: https://pytorch.org/tutorials/intermediate/torchvision_tutorial.html and at the end there are some verification image.
How can I get this prediction image? I'm working with object deteciton.
Is there some way to output images from trained model that I can see is my network is learn something?
This is my code:
import os
import numpy as np
import torch
from PIL import Image
import torchvision
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.models.detection.mask_rcnn import MaskRCNNPredictor
#from engine import train_one_epoch, evaluate
from vision.references.detection.engine import train_one_epoch, evaluate
import utils
import transforms as T
import matplotlib.pyplot as plt
class Moj_Dataset_ArT(object):
def __init__(self, root, transforms):
self.root = root
self.transforms = transforms
# load all image files, sorting them to
# ensure that they are aligned
self.imgs = list(sorted(os.listdir(os.path.join(root, "NEW_train"))))
self.masks = list(sorted(os.listdir(os.path.join(root, "train_masks"))))
def __getitem__(self, idx):
# load images and masks
img_path = os.path.join(self.root, "NEW_train", self.imgs[idx])
mask_path = os.path.join(self.root, "train_masks", self.masks[idx])
img = Image.open(img_path).convert("RGB")
# note that we haven't converted the mask to RGB,
# because each color corresponds to a different instance
# with 0 being background
mask = Image.open(mask_path)
mask = np.array(mask)
# instances are encoded as different colors
obj_ids = np.unique(mask)
# first id is the background, so remove it
obj_ids = obj_ids[1:]
# split the color-encoded mask into a set
# of binary masks
masks = mask == obj_ids[:, None, None]
# get bounding box coordinates for each mask
num_objs = len(obj_ids)
boxes = []
for i in range(num_objs):
pos = np.where(masks[i])
xmin = np.min(pos[1])
xmax = np.max(pos[1])
ymin = np.min(pos[0])
ymax = np.max(pos[0])
boxes.append([xmin, ymin, xmax, ymax])
boxes = torch.as_tensor(boxes, dtype=torch.float32)
# there is only one class
labels = torch.ones((num_objs,), dtype=torch.int64)
masks = torch.as_tensor(masks, dtype=torch.uint8)
image_id = torch.tensor([idx])
area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
# suppose all instances are not crowd
iscrowd = torch.zeros((num_objs,), dtype=torch.int64)
target = {}
target["boxes"] = boxes
target["labels"] = labels
target["masks"] = masks
target["image_id"] = image_id
target["area"] = area
target["iscrowd"] = iscrowd
if self.transforms is not None:
img, target = self.transforms(img, target)
return img, target
def __len__(self):
return len(self.imgs)
def get_model_instance_segmentation(num_classes):
# load an instance segmentation model pre-trained pre-trained on COCO
model = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=False) #bilo na True
# get number of input features for the classifier
in_features = model.roi_heads.box_predictor.cls_score.in_features
# replace the pre-trained head with a new one
model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
# now get the number of input features for the mask classifier
in_features_mask = model.roi_heads.mask_predictor.conv5_mask.in_channels
hidden_layer = 256
# and replace the mask predictor with a new one
model.roi_heads.mask_predictor = MaskRCNNPredictor(in_features_mask,
hidden_layer,
num_classes)
return model
def get_transform(train):
transforms = []
transforms.append(T.ToTensor())
#if train:
#transforms.append(T.RandomHorizontalFlip(0.5))
return T.Compose(transforms)
def draw_loss(ml):
plt.figure(figsize=(10,5))
plt.title("Training Loss")
#plt.plot(val_losses,label="val")
plt.plot(ml,label="train")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()
plt.xlim([0,80])
plt.ylim([0, 1.2])
plt.show()
def main():
# train on the GPU or on the CPU, if a GPU is not available
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
# our dataset has two classes only - background and person
num_classes = 2
# use our dataset and defined transformations
dataset = Moj_Dataset_ArT('Train/ArT', get_transform(train=True))
dataset_test = Moj_Dataset_ArT('Train/ArT', get_transform(train=False))
# split the dataset in train and test set
indices = torch.randperm(len(dataset)).tolist()
dataset = torch.utils.data.Subset(dataset, indices[:-500])
dataset_test = torch.utils.data.Subset(dataset_test, indices[-500:])
# define training and validation data loaders
data_loader = torch.utils.data.DataLoader(
dataset, batch_size=4, shuffle=True, num_workers=4,
collate_fn=utils.collate_fn)
data_loader_test = torch.utils.data.DataLoader(
dataset_test, batch_size=1, shuffle=False, num_workers=4,
collate_fn=utils.collate_fn)
# get the model using our helper function
model = get_model_instance_segmentation(num_classes)
# move model to the right device
model.to(device)
# construct an optimizer
params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.SGD(params, lr=0.0005,
momentum=0.9, weight_decay=0.0005)
# and a learning rate scheduler
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
step_size=30,
gamma=0.1) # gamma bila na 0.5
# let's train it for 10 epochs
num_epochs = 200
PATH = 'home//Train/ArT/models/'
ml =[]
for epoch in range(num_epochs):
# train for one epoch, printing every 10 iterations
loss_value = train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq=10)
ml.append(loss_value)
# update the learning rate
lr_scheduler.step()
torch.save(model, PATH)
# evaluate on the test dataset
#evaluate(model, data_loader_test, device=device)
print(ml)
draw_loss(ml)
if __name__ == "__main__":
main()
Something like this
When I run this after evalueate():
img, _ = dataset_test[20]
with torch.no_grad():
prediction = model([img.to(device)])
imag = Image.fromarray(img.mul(255).permute(1, 2, 0).byte().numpy())
imaag = Image.fromarray(prediction[0]['masks'][0, 0].mul(255).byte().cpu().numpy())
imag.show()
imaag.show()
I get this (not good image):
I also tried with Detectron2
but then I need to make cfg file and train on the other way, but I'm using this Pytorch tutorial

Show image mask tensor model

I am working on a tensor model.
I have trained it and now testing and evaluating it.
Img_score with the prediction is working correctly.
I want also to print the seg_mask image (seg_out in the code), but plt.imshow does not work, even if I permute it.
Moreover if I print the values of the seg_out image they are all negatives which I don't understand how to handle them in images.
Here is what I am using.
INPUT_WIDTH = 232
INPUT_HEIGHT = 640
INPUT_CHANNELS = 3
device = "cpu"
model = SegDecNet(device, INPUT_WIDTH, INPUT_HEIGHT, INPUT_CHANNELS)
model.set_gradient_multipliers(0)
model_path = "/final_state_dict.pth"
model.load_state_dict(torch.load(model_path, map_location=device))
# %%
img_path = '/20118.png'
img = cv2.imread(img_path) if INPUT_CHANNELS == 3 else cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (INPUT_WIDTH, INPUT_HEIGHT))
print(img.shape)
img = np.transpose(img, (2, 0, 1)) if INPUT_CHANNELS == 3 else img[np.newaxis]
img_t = torch.from_numpy(img)[np.newaxis].float() / 445400 # must be [BATCH_SIZE x CHANNELS x HEIGHT x WIDTH]
dec_out, seg_out = model(img_t)
img_score = torch.sigmoid(dec_out)
print(img_score)
print(seg_out[0][0].shape)
print(seg_out[0][0].permute(0, 1))
#plt.imshow(seg_out[0].permute(2, 0, 1))
thanks

Concatenation in path Deep learning with Unet

The path is not written as I want. In my TRAIN_PATH, I have files 1, 2, 3, 4 inside each one I have two files, images (contain image tiff) and masks (contain mask png).
I don't know how to get access to each image or mask
I would be grateful for your help community
TRAIN_PATH = '/content/drive/MyDrive/PFE_MOHTICH/dataset/train'
TEST_PATH = '/content/drive/MyDrive/PFE_MOHTICH/dataset/test'
train_ids = next(os.walk(TRAIN_PATH))[1]
test_ids = next(os.walk(TEST_PATH))[1]
X_train = np.zeros((len(train_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)
Y_train = np.zeros((len(train_ids), IMG_HEIGHT, IMG_WIDTH, 1), dtype=np.bool)
print('Resizing training images and masks')
for n, i in tqdm(enumerate(train_ids), total=len(train_ids)):
path = TRAIN_PATH + i
img = imread(path + '/images/' + i + '.tiff')[:,:,:IMG_CHANNELS]
img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)
X_train[n] = img #Fill empty X_train with values from img
mask = np.zeros((IMG_HEIGHT, IMG_WIDTH, 1), dtype=np.bool)
for mask_file in next(os.walk(path + '/masks/'))[2]:
mask_ = imread(path + '/masks/' + mask_file)
mask_ = np.expand_dims(resize(mask_, (IMG_HEIGHT, IMG_WIDTH), mode='constant',
preserve_range=True), axis=-1)
mask = np.maximum(mask, mask_)
Y_train[n] = mask
***************************ERROR**********************
0%| | 0/4 [00:00<?, ?it/s]Resizing training images and masks
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
<ipython-input-12-2ea116d05bcb> in <module>()
11 for n, i in tqdm(enumerate(train_ids), total=len(train_ids)):
12 path = TRAIN_PATH + i
---> 13 img = imread(path + '/images/' + i + '.tiff')[:,:,:IMG_CHANNELS]
14 img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)
15 X_train[n] = img #Fill empty X_train with values from img
5 frames
/usr/local/lib/python3.7/dist-packages/tifffile/tifffile.py in open(self)
9457 self._file = os.path.realpath(self._file)
9458 self._dir, self._name = os.path.split(self._file)
-> 9459 self._fh = open(self._file, self._mode)
9460 self._close = True
9461 if self._offset is None:
FileNotFoundError: [Errno 2] No such file or directory: '/content/drive/MyDrive/PFE_MOHTICH/dataset/train1/images/1.tiff'
If your image path is something like '.../dataset/train/1/images/1.tiff', try changing the path var to:
# for ...
path = TRAIN_PATH + '/' + i
#...
If instead the image path is something like '.../dataset/train/images/1.tiff', try changing the path var to:
# for ...
path = TRAIN_PATH
#...

how can i train kears model for different volumes

****i working in a project to segmenting liver from CT image volumes , the CT volumes have different number of slice so the shape of each volumes is different ex:(512,512,183) and (512,512,64) and (512,512,335) and so on**
i tried to use None and Global MaxPooling3D() as i seen in another post
but have same error which is :-
**
Traceback (most recent call last):
File "E:\Liver_Seg_Project\LiveSegtraining.py", line 123, in train
H = model.fit_generator(aug.flow(data, label, batch_size=100),
File "C:\python3.6.1\Python\lib\site-packages\keras_preprocessing\image\image_data_generator.py", line 430, in flow subset=subset
File "C:\python3.6.1\Python\lib\site-packages\keras_preprocessing\image\numpy_array_iterator.py", line 72, in init
(len(x), len(xx)))
ValueError: All of the arrays in x should have the same length. Found a pair with: len(x[0]) = 183, len(x[?]) = 64
Here is my model:
class ModelNw2:
#staticmethod
def build(depth,height, width):
input_size = (None,None,None,1)
x = Input(input_size)
# layer 1
x1=Conv3D(32, 7, padding="same",data_format="channels_last")(x)
x1=Activation("relu")(x1)
x1=MaxPooling3D(pool_size=(2, 2,2), strides=(2, 2,2))(x1)
# layer 2
x2=Conv3D(64, 5, padding="same")(x1)
x2=Activation("relu")(x2)
x2=MaxPooling3D(pool_size=(2, 2,2), strides=(2, 2,2))(x2)
# layer 3
x3=Conv3D(128, 5, padding="same")(x2)
x3=Activation("relu")(x3)
# layer 4
x4=Conv3D(128, 3, padding="same")(x3)
x4=Activation("relu")(x4)
# concat layer 3 and 4
concat34 = concatenate([x3,x4], axis = -1)
Here is part of training code
# initialize the data and labels
print("[INFO] loading images...")
data=[]
label=[]
for i in range(10):
if i>5:
j=i+10
filename ='TrainingF/image/liver-orig0' + str(j+1) + '.mhd'
else:
j=i
filename ='TrainingF/image/liver-orig00' + str(j+1) + '.mhd'
image = sitk.ReadImage(filename)
image = sitk.GetArrayFromImage(image)
image=Norma(image)
image = img_to_array(image)
data.append(image)
print("inssss=" + str(len(data)))
print("[INFO] loading maskss...")
for i in range(10):
if i>5:
j=i+10
# print("label "+ str(j+1))
filename ='TrainingF/label/liver-seg0' + str(j+1) + '.mhd'
else:
j=i
filename ='TrainingF/label/liver-seg00' + str(j+1) + '.mhd'
image = sitk.ReadImage(filename)
mask = sitk.GetArrayFromImage(image)
mask = img_to_array(mask)
label.append(mask)
Finally i Fit the data and mask numpy array to the model :
aug = ImageDataGenerator(rotation_range=45, width_shift_range=0.1,
height_shift_range=0.1, shear_range=0.2, zoom_range=0.2,
horizontal_flip=True, fill_mode="nearest")
# initialize the model
print("[INFO] compiling model...")
model = ModelNw2.build(depth=183,width=512, height=512)
# train the network
print("[INFO] training network...")
weight_saver = ModelCheckpoint('weights1.h1', monitor='val_dice_coef', save_best_only=True, save_weights_only=True)
annealer = LearningRateScheduler(lambda x: 1e-3 * 0.8 ** x)
stop_here = EarlyStopping(patience=5)
start = timeit.default_timer()
H = model.fit_generator(aug.flow(data, label, batch_size=100),
validation_data=(testX, testY), steps_per_epoch=50,
epochs=EPOCHS, verbose=2, callbacks = [weight_saver, annealer])
end = timeit.default_timer()

Keras - how to pass a array of images to ImageDataGenerator.flow

I'm learning about image classification in keras. I've downloaded sample dataset of donuts and waffles, but they differ in size. To standardise their size I'm loading images from their directories, resize them and store them in numpy arrays:
test_data_dir = 'v_data/train/donuts_and_waffles/'
validation_data_dir = 'v_data/test/donuts_and_waffles/'
loaded_test_donuts = list()
for filename in listdir(test_data_dir + 'donuts/'):
image1 = Image.open(test_data_dir + 'donuts/' + filename)
img_resized = image1.resize((224,224))
img_data = asarray(img_resized)
loaded_test_donuts.append(img_data)
loaded_test_waffles = list()
for filename in listdir(test_data_dir + 'waffles/'):
image1 = Image.open(test_data_dir + 'waffles/' + filename)
img_resized = image1.resize((224,224))
img_data = asarray(img_resized)
loaded_test_waffles.append(img_data)
loaded_validation_donuts = list()
for filename in listdir(validation_data_dir + 'donuts/'):
image1 = Image.open(validation_data_dir + 'donuts/' + filename)
img_resized = image1.resize((224,224))
img_data = asarray(img_resized)
loaded_validation_donuts.append(img_data)
loaded_validation_waffles = list()
for filename in listdir(validation_data_dir + 'waffles/'):
image1 = Image.open(validation_data_dir + 'waffles/' + filename)
img_resized = image1.resize((224,224))
img_data = asarray(img_resized)
loaded_validation_waffles.append(img_data)
test_data = list()
validation_data = list()
test_data.append(np.array(loaded_test_donuts))
test_data.append(np.array(loaded_test_waffles))
validation_data.append(np.array(loaded_validation_donuts))
validation_data.append(np.array(loaded_validation_waffles))
test_data = np.array(test_data)
validation_data = np.array(validation_data)
Then I want to create an ImageDataGenerator for my data:
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow(
#how can I pass here test_data to make it work (along with which parameters)
)
validation_generator = test_datagen.flow(
#how can I pass here validation_data to make it work (along with which parameters)
)
How to achieve that?
I have tried like this:
train_generator = train_datagen.flow(
test_data, #does not work
batch_size=batch_size)
validation_generator = test_datagen.flow(
validation_data, #does not work
batch_size=batch_size)
but then I get this error:
Traceback (most recent call last):
...
ValueError: ('Input data in `NumpyArrayIterator` should have rank 4. You passed an array with shape', (2, 770, 224, 224, 3))
It's hard to say what does not work without error message, but I assume the problem is that you pass lists to your ImageDataGenerators. You can fix this easily by converting your lists to numpy-arrays:
test_data = list()
validation_data = list()
test_data.append(np.array(loaded_test_donuts))
test_data.append(np.array(loaded_test_waffles))
validation_data.append(np.array(loaded_validation_donuts))
validation_data.append(np.array(loaded_validation_waffles))
test_data = np.array(test_data)
validation_data = np.array(validation_data)
Edit: A better way, stacking instead of appending to lists and converting
test_data = np.vstack((np.array(loaded_test_donuts),np.array(loaded_test_waffles)))
validation_data = np.vstack((np.array(loaded_validation_donuts),np.array(loaded_validation_waffles)))
What I would recommend is that you create a folder where you have n folders representing your classes such as "dog", "cat" and do the preprocessing step first and then save the produced images like this:
from PIL import Image
import glob
from keras.preprocessing import image
W=500
H=825
for folder in glob.glob("*"): #goes through every folder
ims = glob.glob(folder+ "\\*.png") #reads image names from folder assuming images are png
for im in ims:
img = Image.open(im)
print(im)
if (img.size != (W, H)):
imgr = process(img, W, H) # where "process" is reszing in your case
imgr.save(im)
then spilt your data into train and validation folders and do:
traingen = image.ImageDataGenerator(rescale=1./255)
validationgen = image.ImageDataGenerator(rescale=1./255)
train = traingen.flow_from_directory("train",target_size=(H,W), batch_size=s,shuffle=True)
val = validationgen.flow_from_directory("validation",target_size=(500, 825), batch_size=32, shuffle=False)
You test_data does not have the correct shape, you have to convert into an array of shape 4 for example (770, 224, 224, 3), 770 refers the number of the images, 224x224 refers to the size of the images (pixels) and the 3 refers the color of the images.

Categories