Pytorch - mass classification - pytorch

I trained a model to classify picture into 2 classes.
I wanna use it to order my iPhone images, I have got a lot. So I moved the trained model on my MacBook and started some tests.
Everything works as expected as long a the image folder contains not more than 223 pictures.
It seems to have something to do with the size of the dataset, I can reproduce the issue with the following code.
I tried to split the pictures into batches but I could not figure out how. What is the common fix to that issue? Is it possible to use a Dataloader?
test_dataset = ImageFolderWithPaths('/Users/daniel/Gimp/test-ds/test/', test_trans)
# check images
for img, label, data in test_dataset:
print(img.shape, label, data)
data_path = '/Users/daniel/Gimp/test-ds/test/'
data_path = '/Users/daniel/Pictures/Photos1/'
data_file = data.split('/')[-1]
data_file_new = 'class0_' + data.split('/')[-1]
print(data_path + data_file_new)
Output
torch.Size([3, 64, 64]) 0 /Users/daniel/Gimp/test-ds/test/3/020B1786-E77D-47E8-B0F1-DD72313546B7.jpeg
/Users/daniel/Pictures/Photos1/class0_020B1786-E77D-47E8-B0F1-DD72313546B7.jpeg
torch.Size([3, 64, 64]) 0 /Users/daniel/Gimp/test-ds/test/3/020BC6D0-2AC0-4BF3-A540-6630BA7200ED.jpeg
/Users/daniel/Pictures/Photos1/class0_020BC6D0-2AC0-4BF3-A540-6630BA7200ED.jpeg
torch.Size([3, 64, 64]) 0 /Users/daniel/Gimp/test-ds/test/3/021453CC-CAC1-4546-8188-20739F3C778F.jpeg
/Users/daniel/Pictures/Photos1/class0_021453CC-CAC1-4546-8188-20739F3C778F.jpeg
torch.Size([3, 64, 64]) 0 /Users/daniel/Gimp/test-ds/test/3/0235EEF0-2831-46D3-8889-8E57CDF42205.jpeg
/Users/daniel/Pictures/Photos1/class0_0235EEF0-2831-46D3-8889-8E57CDF42205.jpeg
torch.Size([3, 64, 64]) 0 /Users/daniel/Gimp/test-ds/test/3/02398B72-6F73-49D6-843B-25E2A2593DA9.jpeg
/Users/daniel/Pictures/Photos1/class0_02398B72-6F73-49D6-843B-25E2A2593DA9.jpeg
Prediction Method
class pred01():
def __init__(self, imgpath, model):
cc = 0
cc1 = 0
cc0 = 0
cc2 = 0
"""Predict image class"""
self.ds = ImageFolderWithPaths(imgpath, transform=test_trans)
for img, label, data in self.ds:
self.xb = to_device(img.unsqueeze(0), device)
self.yb = model(self.xb)
_, self.preds = torch.max(self.yb, dim=1)
self.preds1 = torch.softmax(self.yb, dim=1).max()
cc += 1
if dataset.classes[self.preds[0].item()] == '0' and self.preds1.item() > 0.80 or self.preds1.item() == 1.00:
#print('normal pic')
cc0 += 1
# pass
elif dataset.classes[self.preds[0].item()] == '1' and self.preds1.item() > 0.80 or self.preds1.item() == 1.00:
#print('class pic, new name: ' 'class1_' + data.split('/')[-1])
#os.rename(data, '/Users/daniel/Pictures/Photos1/1/' + 'duolingo_' + data.split('/')[-1])
cc1 += 1
else:
pass
#print('not sure')
cc2 += 1
print(cc)
print(f'cc0: {cc0}')
print(f'cc1: {cc1}')
print(f'cc2: {cc2}')
Results after 3 runs
365
cc0: 152
cc1: 195
cc2: 18
365
cc0: 154
cc1: 186
cc2: 25
365
cc0: 136
cc1: 206
cc2: 23

Related

'Evaluator' object has no attribute 'loss_value'

I'm trying to make a simple style copy net, combining two images. I'm a newbie and doing it from the example to get some experience in programming. The main idea is to copy style on the target image. Here's the code I wrote:
def preprocess(image_path):
img = load_img(image_path, target_size = (img_height, img_width))
img = img_to_array(img)
img = np.expand_dims(img, axis = 0)
img = vgg19.preprocess_input(img)
return img
def deprocess(x):
x[:, :, 0] += 103.939
x[:, :, 1] += 116.779
x[:, :, 2] += 123.68
x = x[:, :, ::-1]
x = np.clip(x, 0, 255).astype('unit8')
return x
target_image = backend.variable(preprocess(target_image_path))
sr_image = backend.variable(preprocess(sr_image_path))
if backend.image_data_format() == 'channels_first':
combination_image = backend.placeholder((1,3,img_height, img_width))
else:
combination_image = backend.placeholder((1,img_height, img_width,3))
input_tensor = backend.concatenate([target_image, sr_image, combination_image], axis = 0)
model = vgg19.VGG19(input_tensor = input_tensor, weights = 'imagenet', include_top = False)
print('Model loaded successfully')
def content_loss(base, combination):
return backend.sum(backend.square(combination - base))
def gram_matrix(x):
features = backend.batch_flatten(backend.permute_dimensions(x, (2, 0, 1)))
gram = backend.dot(features, backend.transpose(features))
return gram
def style_loss(style, combination):
S = gram_matrix(style)
C = gram_matrix(combination)
channels = 3
size = img_height * img_width
return backend.sum(backend.square(S - C)) / (4.0 * (channels ** 2) * (size ** 2))
def total_variation_loss(x):
a = backend.square(
x[:, :img_height - 1, :img_width - 1, :] -
x[:, 1:, :img_width - 1, :])
b = backend.square(
x[:, :img_height - 1, :img_width - 1, :] -
x[:, :img_height - 1, 1:, :])
return backend.sum(backend.pow(a + b, 1.25))
outputs_dict = dict([(layer.name, layer.output) for layer in model.layers])
content_layer = 'block5_conv2'
style_layers = ['block1_conv1',
'block2_conv1',
'block3_conv1',
'block4_conv1',
'block5_conv1']
total_variation_weight = 1e-4
style_weight = 1.
content_weight = 0.025
loss = backend.variable(0.0)
layer_features = outputs_dict[content_layer]
target_image_features = layer_features[0, :, :, :]
combination_features = layer_features[2, :, :, :]
loss = loss + content_weight * content_loss(target_image_features, combination_features)
for layer_name in style_layers:
layer_features = outputs_dict[layer_name]
style_reference_features = layer_features[1, :, :, :]
combination_features = layer_features[2, :, :, :]
sl = style_loss(style_reference_features, combination_features)
loss = loss + (style_weight / len(style_layers)) * sl
loss += total_variation_weight * total_variation_loss(combination_image)
grads = backend.gradients(loss, combination_image)
outputs = [loss]
if isinstance(grads, (list,tuple)):
outputs += grads
else:
outputs.append(grads)
f_outputs = backend.function([combination_image], outputs)
def eval_loss_and_grads(x):
if backend.image_data_format() == 'channels_first':
x = x.reshape((1, 3, img_height, img_width))
else:
x = x.reshape((1, img_height, img_width, 3))
outs = f_outputs([x])
loss_value = outs[0]
if len(outs[1:]) == 1:
grad_values = outs[1].flatten().astype('float64')
else:
grad_values = np.array(outs[1:]).flatten().astype('float64')
return loss_value, grad_values
class Evaluator(object):
def _unit_(self):
self.loss_value = None
self.grads_values = None
def loss(self, x):
assert self.loss_value is None
loss_value, grad_values = eval_loss_and_grads(x)
self.loss_value = loss_value
self.grads_values = grad_values
return self.loss_value
def grads(self, x):
assert self.loss_value is not None
grad_values = np.copy(self.grad_values)
self.loss_value = None
self.grad_values = None
return grad_values
evaluator = Evaluator()
result_prefix = 'result'
iterations = 20
x = preprocess(target_image_path)
x = x.flatten()
for i in range(iterations):
print('Start of iterations', i)
start_time = time.time()
x, min_val, info = fmin_l_bfgs_b(evaluator.loss, x,
fprime = evaluator.grads, maxfun = 20)
print('Current loss value:', min_val)
img = x.copy().reshape((img_height, img_width, 3))
img = deprocess(img)
fname = result_prefix + '_at_iteration_%d.png' % i
save_img('D:\study\Stylecopy\fmane', img)
print('image saved as:', fname)
end_time = time.time()
print(' Iteration %d completed in %ds' % (i , end_time - start_time))
Here's the error I got:
AttributeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_12264/556996678.py in <module>
7 print('Start of iterations', i)
8 start_time = time.time()
----> 9 x, min_val, info = fmin_l_bfgs_b(evaluator.loss, x,
10 fprime = evaluator.grads, maxfun = 20)
11 print('Current loss value:', min_val)
~\anaconda3\envs\CNN_base\lib\site-packages\scipy\optimize\lbfgsb.py in fmin_l_bfgs_b(func, x0, fprime, args, approx_grad, bounds, m, factr, pgtol, epsilon, iprint, maxfun, maxiter, disp, callback, maxls)
195 'maxls': maxls}
196
--> 197 res = _minimize_lbfgsb(fun, x0, args=args, jac=jac, bounds=bounds,
198 **opts)
199 d = {'grad': res['jac'],
~\anaconda3\envs\CNN_base\lib\site-packages\scipy\optimize\lbfgsb.py in _minimize_lbfgsb(fun, x0, args, jac, bounds, disp, maxcor, ftol, gtol, eps, maxfun, maxiter, iprint, callback, maxls, finite_diff_rel_step, **unknown_options)
304 iprint = disp
305
--> 306 sf = _prepare_scalar_function(fun, x0, jac=jac, args=args, epsilon=eps,
307 bounds=new_bounds,
308 finite_diff_rel_step=finite_diff_rel_step)
~\anaconda3\envs\CNN_base\lib\site-packages\scipy\optimize\optimize.py in _prepare_scalar_function(fun, x0, jac, args, bounds, epsilon, finite_diff_rel_step, hess)
259 # ScalarFunction caches. Reuse of fun(x) during grad
260 # calculation reduces overall function evaluations.
--> 261 sf = ScalarFunction(fun, x0, args, grad, hess,
262 finite_diff_rel_step, bounds, epsilon=epsilon)
263
~\anaconda3\envs\CNN_base\lib\site-packages\scipy\optimize\_differentiable_functions.py in __init__(self, fun, x0, args, grad, hess, finite_diff_rel_step, finite_diff_bounds, epsilon)
138
139 self._update_fun_impl = update_fun
--> 140 self._update_fun()
141
142 # Gradient evaluation
~\anaconda3\envs\CNN_base\lib\site-packages\scipy\optimize\_differentiable_functions.py in _update_fun(self)
231 def _update_fun(self):
232 if not self.f_updated:
--> 233 self._update_fun_impl()
234 self.f_updated = True
235
~\anaconda3\envs\CNN_base\lib\site-packages\scipy\optimize\_differentiable_functions.py in update_fun()
135
136 def update_fun():
--> 137 self.f = fun_wrapped(self.x)
138
139 self._update_fun_impl = update_fun
~\anaconda3\envs\CNN_base\lib\site-packages\scipy\optimize\_differentiable_functions.py in fun_wrapped(x)
132 # Overwriting results in undefined behaviour because
133 # fun(self.x) will change self.x, with the two no longer linked.
--> 134 return fun(np.copy(x), *args)
135
136 def update_fun():
~\AppData\Local\Temp/ipykernel_12264/3220866978.py in loss(self, x)
29
30 def loss(self, x):
---> 31 assert self.loss_value is None
32 loss_value, grad_values = eval_loss_and_grads(x)
33 self.loss_value = loss_value
AttributeError: 'Evaluator' object has no attribute 'loss_value'
I'm dealing with this problem and don't know how to solve it. I've double checked the code with the example (https://www.kaggle.com/code/gabrieltangzy/p2p-gan-newver-slice-cezanne), but haven't found any mistakes. I suppose it may occur because of difference in python versions. I use 3.9.7

RuntimeError: min(): Expected reduction dim to be specified for input.numel() == 0. Specify the reduction dim with the 'dim' argument [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 9 months ago.
Improve this question
RuntimeError Traceback (most recent call last)
/tmp/ipykernel_33/2056227650.py in <module>
----> 1 learn.fit_one_cycle(n, max_learning_rate)
2 learn.recorder.plot_losses()
/opt/conda/lib/python3.7/site-packages/fastai/train.py in fit_one_cycle(learn, cyc_len, max_lr, moms, div_factor, pct_start, final_div, wd, callbacks, tot_epochs, start_epoch)
21 callbacks.append(OneCycleScheduler(learn, max_lr, moms=moms, div_factor=div_factor, pct_start=pct_start,
22 final_div=final_div, tot_epochs=tot_epochs, start_epoch=start_epoch))
---> 23 learn.fit(cyc_len, max_lr, wd=wd, callbacks=callbacks)
24
25 def fit_fc(learn:Learner, tot_epochs:int=1, lr:float=defaults.lr, moms:Tuple[float,float]=(0.95,0.85), start_pct:float=0.72,
/opt/conda/lib/python3.7/site-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)
--> 200 fit(epochs, self, metrics=self.metrics, callbacks=self.callbacks+callbacks)
201
202 def create_opt(self, lr:Floats, wd:Floats=0.)->None:
/opt/conda/lib/python3.7/site-packages/fastai/basic_train.py in fit(epochs, learn, callbacks, metrics)
104 if not cb_handler.skip_validate and not learn.data.empty_val:
105 val_loss = validate(learn.model, learn.data.valid_dl, loss_func=learn.loss_func,
--> 106 cb_handler=cb_handler, pbar=pbar)
107 else: val_loss=None
108 if cb_handler.on_epoch_end(val_loss): break
/opt/conda/lib/python3.7/site-packages/fastai/basic_train.py in validate(model, dl, loss_func, cb_handler, pbar, average, n_batch)
61 if not is_listy(yb): yb = [yb]
62 nums.append(first_el(yb).shape[0])
---> 63 if cb_handler and cb_handler.on_batch_end(val_losses[-1]): break
64 if n_batch and (len(nums)>=n_batch): break
65 nums = np.array(nums, dtype=np.float32)
/opt/conda/lib/python3.7/site-packages/fastai/callback.py in on_batch_end(self, loss)
306 "Handle end of processing one batch with `loss`."
307 self.state_dict['last_loss'] = loss
--> 308 self('batch_end', call_mets = not self.state_dict['train'])
309 if self.state_dict['train']:
310 self.state_dict['iteration'] += 1
/opt/conda/lib/python3.7/site-packages/fastai/callback.py in __call__(self, cb_name, call_mets, **kwargs)
248 "Call through to all of the `CallbakHandler` functions."
249 if call_mets:
--> 250 for met in self.metrics: self._call_and_update(met, cb_name, **kwargs)
251 for cb in self.callbacks: self._call_and_update(cb, cb_name, **kwargs)
252
/opt/conda/lib/python3.7/site-packages/fastai/callback.py in _call_and_update(self, cb, cb_name, **kwargs)
239 def _call_and_update(self, cb, cb_name, **kwargs)->None:
240 "Call `cb_name` on `cb` and update the inner state."
--> 241 new = ifnone(getattr(cb, f'on_{cb_name}')(**self.state_dict, **kwargs), dict())
242 for k,v in new.items():
243 if k not in self.state_dict:
/opt/conda/lib/python3.7/site-packages/object_detection_fastai/callbacks/callbacks.py in on_batch_end(self, last_output, last_target, **kwargs)
125 scores = scores[:total_nms_examples]
126 preds = preds[:total_nms_examples]
--> 127 to_keep = nms(bbox_pred, scores, self.nms_thresh)
128 bbox_pred, preds, scores = bbox_pred[to_keep].cpu(), preds[to_keep].cpu(), scores[to_keep].cpu()
129
/opt/conda/lib/python3.7/site-packages/object_detection_fastai/helper/object_detection_helper.py in nms(boxes, scores, thresh)
156 mask_keep = iou_vals <= thresh
157 if len(mask_keep.nonzero()) == 0: break
--> 158 idx_first = mask_keep.nonzero().min().item()
159 boxes, scores, indexes = boxes[mask_keep], scores[mask_keep], indexes[mask_keep]
160 return LongTensor(to_keep)
RuntimeError: min(): Expected reduction dim to be specified for input.numel() == 0. Specify the reduction dim with the 'dim' argument.
# %% [code] {"id":"asY9Gl86zcYl","outputId":"71cad981-691c-489e-f203-66ee5df9e25a","execution":{"iopub.status.busy":"2022-05-02T07:47:26.313181Z","iopub.execute_input":"2022-05-02T07:47:26.313767Z","iopub.status.idle":"2022-05-02T07:47:36.173129Z","shell.execute_reply.started":"2022-05-02T07:47:26.313727Z","shell.execute_reply":"2022-05-02T07:47:36.172282Z"}}
%reload_ext autoreload
%autoreload 2
%matplotlib inline
!pip install -U plotly
import json
from pathlib import Path
import plotly
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
from tqdm import tqdm
import pandas as pd
import random
import cv2
# %% [code] {"id":"NvOPXHfk2PzM","outputId":"4849c9ec-32d2-4aeb-b8f6-5a881423392e","execution":{"iopub.status.busy":"2022-05-02T07:47:36.175278Z","iopub.execute_input":"2022-05-02T07:47:36.175539Z","iopub.status.idle":"2022-05-02T07:47:36.278379Z","shell.execute_reply.started":"2022-05-02T07:47:36.175505Z","shell.execute_reply":"2022-05-02T07:47:36.277469Z"}}
folder = "midog-challenge"
midog_folder = Path("../input") / Path(folder)
print(list(midog_folder.glob("*.*")))
# %% [code] {"id":"3hzo-Io-zsRk","outputId":"5a4b2a8b-e79a-4371-dd41-c819c44026a9","execution":{"iopub.status.busy":"2022-05-02T07:47:36.280155Z","iopub.execute_input":"2022-05-02T07:47:36.280431Z","iopub.status.idle":"2022-05-02T07:47:45.692203Z","shell.execute_reply.started":"2022-05-02T07:47:36.280394Z","shell.execute_reply":"2022-05-02T07:47:45.691328Z"}}
!pip install -U object-detection-fastai
from object_detection_fastai.helper.wsi_loader import *
from object_detection_fastai.loss.RetinaNetFocalLoss import RetinaNetFocalLoss
from object_detection_fastai.models.RetinaNet import RetinaNet
from object_detection_fastai.callbacks.callbacks import BBMetrics, PascalVOCMetricByDistance, PascalVOCMetric, PascalVOCMetricByDistance
# %% [code] {"id":"jiZJLWqD5Rpr","execution":{"iopub.status.busy":"2022-05-02T07:47:45.694445Z","iopub.execute_input":"2022-05-02T07:47:45.694685Z","iopub.status.idle":"2022-05-02T07:47:45.801985Z","shell.execute_reply.started":"2022-05-02T07:47:45.694652Z","shell.execute_reply":"2022-05-02T07:47:45.800941Z"}}
image_folder = midog_folder / "images"
hamamatsu_rx_ids = list(range(0, 51))
hamamatsu_360_ids = list(range(51, 101))
aperio_ids = list(range(101, 151))
leica_ids = list(range(151, 201))
# %% [code] {"id":"tNwJXJufaVt-","outputId":"0e710552-9a03-4825-f1a3-97444a2be238","execution":{"iopub.status.busy":"2022-05-02T07:47:45.803635Z","iopub.execute_input":"2022-05-02T07:47:45.804129Z","iopub.status.idle":"2022-05-02T07:47:46.032320Z","shell.execute_reply.started":"2022-05-02T07:47:45.804090Z","shell.execute_reply":"2022-05-02T07:47:46.031354Z"}}
annotation_file = midog_folder / "MIDOG.json"
print(annotation_file," ",image_folder)
rows = []
with open(annotation_file) as f:
data = json.load(f)
categories = {1: 'mitotic figure', 2: 'hard negative'}
for row in data["images"]:
file_name = row["file_name"]
image_id = row["id"]
width = row["width"]
height = row["height"]
scanner = "Hamamatsu XR"
if image_id in hamamatsu_360_ids:
scanner = "Hamamatsu S360"
if image_id in aperio_ids:
scanner = "Aperio CS"
if image_id in leica_ids:
scanner = "Leica GT450"
for annotation in [anno for anno in data['annotations'] if anno["image_id"] == image_id]:
box = annotation["bbox"]
cat = categories[annotation["category_id"]]
rows.append([file_name, image_id, width, height, box, cat, scanner])
df = pd.DataFrame(rows, columns=["file_name", "image_id", "width", "height", "box", "cat", "scanner"])
df.head()
# %% [markdown] {"id":"r2Tm_N5PqbMJ"}
# ### Visual Examples
# %% [code] {"id":"KIALOeDIuCKo","execution":{"iopub.status.busy":"2022-05-02T07:47:53.807583Z","iopub.execute_input":"2022-05-02T07:47:53.807862Z","iopub.status.idle":"2022-05-02T07:47:53.904670Z","shell.execute_reply.started":"2022-05-02T07:47:53.807827Z","shell.execute_reply":"2022-05-02T07:47:53.903659Z"}}
def sample_function(y, classes, size, level_dimensions, level):
width, height = level_dimensions[level]
if len(y[0]) == 0:
return randint(0, width - size[0]), randint(0, height -size[1])
else:
#if randint(0, 5) < 2:
if True:
class_id = np.random.choice(classes, 1)[0] # select a random class
ids = np.array(y[1]) == class_id # filter the annotations according to the selected class
xmin, ymin, _, _ = np.array(y[0])[ids][randint(0, np.count_nonzero(ids) - 1)] # randomly select one of the filtered annotatons as seed for the training patch
# To have the selected annotation not in the center of the patch and an random offset.
xmin += random.randint(-size[0]/2, size[0]/2)
ymin += random.randint(-size[1]/2, size[1]/2)
xmin, ymin = max(0, int(xmin - size[0] / 2)), max(0, int(ymin -size[1] / 2))
xmin, ymin = min(xmin, width - size[0]), min(ymin, height - size[1])
return xmin, ymin
else:
return randint(0, width - size[0]), randint(0, height -size[1])
# %% [code] {"id":"HH_0sG8w4TfA","outputId":"d9de5667-10c5-46b1-c0e0-28a99e7f95d7","execution":{"iopub.status.busy":"2022-05-02T07:47:58.157246Z","iopub.execute_input":"2022-05-02T07:47:58.157508Z","iopub.status.idle":"2022-05-02T07:48:00.797900Z","shell.execute_reply.started":"2022-05-02T07:47:58.157480Z","shell.execute_reply":"2022-05-02T07:48:00.797151Z"}}
def create_wsi_container(annotations_df: pd.DataFrame):
container = []
for image_name in tqdm(annotations_df["file_name"].unique()):
image_annos = annotations_df[annotations_df["file_name"] == image_name]
bboxes = [box for box in image_annos["box"]]
labels = [label for label in image_annos["cat"]]
container.append(SlideContainer(image_folder/image_name, y=[bboxes, labels], level=res_level,width=patch_size, height=patch_size, sample_func=sample_function))
return container
train_scanner = "Aperio CS" #["Hamamatsu XR", "Hamamatsu S360", "Aperio CS"]
val_scanner = "Hamamatsu XR" #["Hamamatsu XR", "Hamamatsu S360", "Aperio CS"]
patch_size = 256
res_level = 0
train_annos = df[df["scanner"].isin(train_scanner.split(","))]
train_container = create_wsi_container(train_annos)
val_annos = df[df["scanner"].isin(val_scanner.split(","))]
valid_container = create_wsi_container(val_annos)
f"Created: {len(train_container)} training WSI container and {len(valid_container)} validation WSI container"
# %% [code] {"cellView":"form","id":"Mei_iD1sxJCA","outputId":"2c87f1b1-e9fd-4de1-bd16-6fdc5224d05a","execution":{"iopub.status.busy":"2022-05-02T07:48:18.070337Z","iopub.execute_input":"2022-05-02T07:48:18.070756Z","iopub.status.idle":"2022-05-02T07:48:18.213409Z","shell.execute_reply.started":"2022-05-02T07:48:18.070722Z","shell.execute_reply":"2022-05-02T07:48:18.212544Z"}}
import numpy as np
train_samples_per_scanner = 1500
val_samples_per_scanner = 500
train_images = list(np.random.choice(train_container, train_samples_per_scanner))
print('training_images =',len(train_images))
valid_images = list(np.random.choice(valid_container, val_samples_per_scanner))
print('validation_images =',len(valid_images))
# %% [code] {"id":"UZKoHWjR1mUG","outputId":"5cd9552e-8a9a-4aeb-f898-614e30e17eca","execution":{"iopub.status.busy":"2022-05-02T07:48:20.127048Z","iopub.execute_input":"2022-05-02T07:48:20.129167Z","iopub.status.idle":"2022-05-02T07:48:48.039604Z","shell.execute_reply.started":"2022-05-02T07:48:20.129128Z","shell.execute_reply":"2022-05-02T07:48:48.038869Z"}}
batch_size = 64
do_flip = True
flip_vert = True
max_rotate = 90
max_zoom = 1.1
max_lighting = 0.2
max_warp = 0.2
p_affine = 0.75
p_lighting = 0.75
tfms = get_transforms(do_flip=do_flip,
flip_vert=flip_vert,
max_rotate=max_rotate,
max_zoom=max_zoom,
max_lighting=max_lighting,
max_warp=max_warp,
p_affine=p_affine,
p_lighting=p_lighting)
train, valid = ObjectItemListSlide(train_images), ObjectItemListSlide(valid_images)
item_list = ItemLists(".", train, valid)
lls = item_list.label_from_func(lambda x: x.y, label_cls=SlideObjectCategoryList)
lls = lls.transform(tfms, tfm_y=True, size=patch_size)
data = lls.databunch(bs=batch_size, collate_fn=bb_pad_collate,num_workers=0).normalize()
# %% [code] {"id":"g5PZ9e-c2k1S","outputId":"317422c4-b572-4898-dd82-84c054f98735","execution":{"iopub.status.busy":"2022-05-02T07:48:54.016278Z","iopub.execute_input":"2022-05-02T07:48:54.016534Z","iopub.status.idle":"2022-05-02T07:48:54.455317Z","shell.execute_reply.started":"2022-05-02T07:48:54.016506Z","shell.execute_reply":"2022-05-02T07:48:54.454672Z"}}
scales = [2]
ratios=[1]
#The feature map sizes. [(64,64), (32,32) , (16,16), (8,8), (4,4)]
sizes=[(32,32)]
anchors = create_anchors(sizes=sizes, ratios=ratios, scales=scales)
fig,ax = plt.subplots(figsize=(15,15))
ax.imshow(image2np(data.valid_ds[0][0].data))
for i, bbox in enumerate(anchors[:len(scales)*len(ratios)*len(sizes)]):
bb = bbox.numpy()
x = (bb[0] + 1) * patch_size / 2
y = (bb[1] + 1) * patch_size / 2
w = bb[2] * patch_size / 2
h = bb[3] * patch_size / 2
rect = [x,y,w,h]
draw_rect(ax,rect)
# %% [code] {"id":"Mfrl8VJ94edJ","outputId":"3793f0b0-fa4c-4c87-a4ed-14840d18b4c2","execution":{"iopub.status.busy":"2022-05-02T07:49:03.926600Z","iopub.execute_input":"2022-05-02T07:49:03.926887Z","iopub.status.idle":"2022-05-02T07:49:39.263251Z","shell.execute_reply.started":"2022-05-02T07:49:03.926856Z","shell.execute_reply":"2022-05-02T07:49:39.262482Z"}}
all_boxes, all_labels = show_anchors_on_images(data, anchors, figsize=(12, 12))
# %% [code] {"id":"J-qEw_bN41cG","outputId":"eaf1c350-1c1f-4d50-a919-311ee538e612","execution":{"iopub.status.busy":"2022-05-02T07:49:39.264920Z","iopub.execute_input":"2022-05-02T07:49:39.265265Z","iopub.status.idle":"2022-05-02T07:49:39.546091Z","shell.execute_reply.started":"2022-05-02T07:49:39.265226Z","shell.execute_reply":"2022-05-02T07:49:39.545301Z"}}
from fastai.utils.collect_env import show_install
show_install()
# %% [code] {"id":"te6ci-Z35_5I","outputId":"67f2f18b-041b-44fd-fdc6-1a53121c445a","execution":{"iopub.status.busy":"2022-05-02T07:49:39.548856Z","iopub.execute_input":"2022-05-02T07:49:39.549088Z","iopub.status.idle":"2022-05-02T07:49:47.657381Z","shell.execute_reply.started":"2022-05-02T07:49:39.549058Z","shell.execute_reply":"2022-05-02T07:49:47.656648Z"}}
backbone = "ResNet101" #["ResNet18", "ResNet34", "ResNet50", "ResNet101", "ResNet150"]
backbone_model = models.resnet18
if backbone == "ResNet34":
backbone_model = models.resnet34
if backbone == "ResNet50":
backbone_model = models.resnet50
if backbone == "ResNet101":
backbone_model = models.resnet101
if backbone == "ResNet150":
backbone_model = models.resnet150
pre_trained_on_imagenet = True
encoder = create_body(models.resnet101, pre_trained_on_imagenet, -2)
loss_function = "FocalLoss"
if loss_function == "FocalLoss":
crit = RetinaNetFocalLoss(anchors)
channels = 128
final_bias = -4
n_conv = 3
model = RetinaNet(encoder, n_classes=data.train_ds.c,
n_anchors=len(scales) * len(ratios),
sizes=[size[0] for size in sizes],
chs=channels, # number of hidden layers for the classification head
final_bias=final_bias,
n_conv=n_conv # Number of hidden layers
)
# %% [code] {"id":"waS3UZNaNz4p","outputId":"9b49bd00-7b21-4cad-8588-a46248953370","execution":{"iopub.status.busy":"2022-05-02T07:49:47.659276Z","iopub.execute_input":"2022-05-02T07:49:47.659604Z","iopub.status.idle":"2022-05-02T07:49:47.758263Z","shell.execute_reply.started":"2022-05-02T07:49:47.659566Z","shell.execute_reply":"2022-05-02T07:49:47.757182Z"}}
voc = PascalVOCMetric(anchors, patch_size, [str(i) for i in data.train_ds.y.classes[1:]])
voc
# %% [code] {"id":"nwgGmvsPZ3bN","execution":{"iopub.status.busy":"2022-05-02T07:49:47.759735Z","iopub.execute_input":"2022-05-02T07:49:47.760020Z","iopub.status.idle":"2022-05-02T07:49:47.973584Z","shell.execute_reply.started":"2022-05-02T07:49:47.759982Z","shell.execute_reply":"2022-05-02T07:49:47.972749Z"}}
learn = Learner(data, model, loss_func=crit,
callback_fns=[BBMetrics, ShowGraph],
metrics=[voc]
)
learn.split([model.encoder[6], model.c5top5])
learn.freeze_to(-2)
# %% [code] {"id":"NWwQRvzw6vnr","outputId":"e9c8b89b-0a90-468b-de6d-351fd09bf467","execution":{"iopub.status.busy":"2022-05-02T07:47:46.267766Z","iopub.status.idle":"2022-05-02T07:47:46.268297Z","shell.execute_reply.started":"2022-05-02T07:47:46.268040Z","shell.execute_reply":"2022-05-02T07:47:46.268066Z"}}
learn.lr_find()
learn.recorder.plot(suggestion=True)
# %% [code] {"id":"gK1s61jSJtie","outputId":"aa0f9d65-3d19-42d6-b17e-7a29fe5fca8f","execution":{"iopub.status.busy":"2022-05-01T17:20:57.239658Z","iopub.execute_input":"2022-05-01T17:20:57.239975Z","iopub.status.idle":"2022-05-01T19:08:05.944655Z","shell.execute_reply.started":"2022-05-01T17:20:57.239931Z","shell.execute_reply":"2022-05-01T19:08:05.939947Z"}}
max_learning_rate = 1e-3
n=250
learn.fit_one_cycle(n, max_learning_rate)
learn.recorder.plot_sched()
learn.recorder.plot_losses()
This issue arises when the tensor on which you take max/min becomes empty.

PyTorch random_split() is returning wrong sized loader

I have a custom dataset loader for my dataset. I want to split the dataset into 70% train data, 20% validation data, and 10% test data. I have 16,488 data. So, my train data is supposed to be 11,542. But it's becoming 770 train data, 220 validation data, and 110 test data. I've tried but couldn't figure out the problem.
class Dataset(Dataset):
def __init__(self, directory, transform, preload=False, device: torch.device = torch.device('cpu'), **kwargs):
self.device = device
self.directory = directory
self.transform = transform
self.labels = []
self.images = []
self.preload = preload
for i, file in enumerate(os.listdir(self.directory)):
file_labels = parse('{}_{}_{age}_{gender}.jpg', file)
if file_labels is None:
continue
if self.preload:
image = Image.open(os.path.join(self.directory, file)).convert('RGB')
if self.transform is not None:
image = self.transform(image).to(self.device)
else:
image = os.path.join(self.directory, file)
self.images.append(image)
gender_to_class_id = {
'm': 0,
'f': 1
}
gender = gender_to_class_id[file_labels['gender']]
age = int(file_labels['age'])
self.labels.append({
'age': age,
'gender': gender
})
pass
def __len__(self):
return len(self.labels)
def __getitem__(self, idx):
if torch.is_tensor(idx):
idx = idx.tolist()
image = self.images[idx]
if not self.preload:
image = Image.open(image).convert('RGB')
if self.transform is not None:
image = self.transform(image).to(self.device)
labels = {
'age': self.labels[idx]['age'],
'gender': self.labels[idx]['gender'],
}
return image.to(self.device), labels
def get_loaders(self, transform, train_size=0.7, validate_size=0.2, test_size=0.1, batch_size=15, **kwargs):
if round(train_size + validate_size + test_size, 1) > 1.0:
sys.exit("Sum of the percentages should be less than 1. it's " + str(
train_size + validate_size + test_size) + " now!")
train_len = int(len(self) * train_size)
validate_len = int(len(self) * validate_size)
test_len = int(len(self) * test_size)
others_len = len(self) - train_len - validate_len - test_len
self.trainDataset, self.validateDataset, self.testDataset, _ = torch.utils.data.random_split(
self, [train_len, validate_len, test_len, others_len]
)
train_loader = DataLoader(self.trainDataset, batch_size=batch_size)
validate_loader = DataLoader(self.validateDataset, batch_size=batch_size)
test_loader = DataLoader(self.testDataset, batch_size=batch_size)
return train_loader, validate_loader, test_loader
It seems that you are giving
batch_size=15
As a dataloader is iterable, it maybe simply giving you the len() of the 1st batch.
It also explains why you are getting train data = 770, where it is supposed to be 11,542. Because,
16488 / 15 * 0.7 = 769.44 ≈ 770
Assigning batch_size = 1 should do the trick.
16488 / 1 * 0.7 = 11541.6 ≈ 11542

Encounter the error one of the variables needed for gradient computation has been modified by an inplace operation

I have encountered the following error. This is a different rnn structure. I have implemented to use in graph convolution. The problem is that the hidden is updated in-place operation. However, I have to update its value in each forward call. How can I do that? Thanks in advance.
RuntimeError Traceback (most recent call last)
<ipython-input-110-b4425651d544> in <module>()
8 out = model(x[i])
9 loss = mael(out, x[i+1])
---> 10 loss.backward(retain_graph=True)
11 optimizer.step()
12 print(loss.item())
1 frames
/usr/local/lib/python3.6/dist-packages/torch/autograd/__init__.py in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables)
130 Variable._execution_engine.run_backward(
131 tensors, grad_tensors_, retain_graph, create_graph,
--> 132 allow_unreachable=True) # allow_unreachable flag
133
134
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [1, 100]], which is output 0 of SelectBackward, is at version 1; expected version 0 instead. Hint: the backtrace further above shows the operation that failed to compute its gradient. The variable in question was changed in there or anywhere later. Good luck!
This is a different rnn structure. I have implemented to use in graph convolution. The problem is that the hidden is updated in-place operation. However, I have to update its value in each forward call. How can I do that? Thanks in advance.
class RNN(nn.Module):
def __init__(self, input_dim, hidden_dim):
super(RNN,self).__init__()
self.input_dim = input_dim
self.hidden_dim = hidden_dim
self.weight = Parameter(torch.rand(10,input_dim,hidden_dim, requires_grad=True))
self.weight_h = Parameter(torch.rand(10,input_dim,hidden_dim, requires_grad=True))
self.bias = Parameter(torch.rand(10,input_dim,hidden_dim, requires_grad=True))
self.hidden = torch.rand(10,input_dim, hidden_dim)
self.weight_2 = Parameter(torch.rand(10,input_dim,hidden_dim,requires_grad=True))
self.weight_h_2 = Parameter(torch.rand(10,hidden_dim,hidden_dim, requires_grad=True))
self.bias_2 = Parameter(torch.rand(10,input_dim,hidden_dim, requires_grad=True))
self.tanh = Tanh()
self.iteration = 0
self.next_layer = False
self.hidden_init = torch.rand(1,1)
def set_hidden(self,x):
y = self.tanh(mm(x, self.weight[self.iteration]) + mm(self.hidden_init, self.weight_h[self.iteration]) + self.bias[self.iteration])
return y
def set_hidden_state_layer_2(self, x, hidden):
y = self.tanh(mm(x, self.weight_2[self.iteration]) + mm(hidden, self.weight_h_2[self.iteration]) + self.bias_2[self.iteration])
return y
def forward(self, x):
try:
dim_1, dim_2, dim_3 = x.shape
except:
x = torch.unsqueeze(x,0)
if self.iteration == 10:
self.next_layer = True
self.iteration = 0
if self.next_layer:
self.hidden[self.iteration] = self.set_hidden_state_layer_2(x, self.hidden[self.iteration].clone())
self.iteration = self.iteration + 1
return self.hidden[self.iteration - 1]
else:
hidden_init = torch.rand(1,1)
self.hidden[self.iteration] = self.tanh(mm(x, self.weight[self.iteration]) + mm(self.hidden_init, self.weight_h[self.iteration]) + self.bias[self.iteration])
self.iteration = self.iteration + 1
return self.hidden[self.iteration - 1]
model = RNN(1,100)
mael = nn.L1Loss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
x = torch.rand(11,1)
x_2 = torch.rand(11,1)
for i in range(10):
optimizer.zero_grad()
out = model(x[i])
loss = mael(out, x[i+1])
loss.backward(retain_graph=True)
optimizer.step()
print(loss.item())

How to create layer0 input for input images with 3 channels

Hi I am following the http://deeplearning.net/tutorial/code/convolutional_mlp.py code to implement a conv neural net. I have input images where the channel is important and hence I want to have 3 channel feature map as layer 0 input.
So I need something like this
layer0_input = x.reshape((batch_size, 3, 240, 135)) # width 240, height 135, 3 channels
instead of
layer0_input = x.reshape((batch_size, 1, 28, 28)) # 28*28 normalized MNIST gray scale images
which will be used here
layer0 = LeNetConvPoolLayer(
rng,
input=layer0_input,
image_shape=(batch_size, 3, 240, 135),
filter_shape=(nkerns[0], 1, 5, 5),
poolsize=(2, 2)
)
where that x is provided to theano as
train_model = theano.function(
[index],
cost,
updates=updates,
givens={
x: train_set_x[index * batch_size: (index + 1) * batch_size],
y: train_set_y[index * batch_size: (index + 1) * batch_size]
}
)
So - my question is - how should I create (shape) that train_set_x ?
With (gray scale intensity - i.e single channel) train_set_x is created as
shared_x = theano.shared(numpy.asarray(data_x,
dtype=theano.config.floatX),
where data_x is a flattened numpy array of length 784 (for 28*28 pixels)
Thanks a lot for advice
I was able to get it working. I am pasting some code here which might help some one. Not very elegant - but works.
def shuffle_in_unison(a, b):
#courtsey http://stackoverflow.com/users/190280/josh-bleecher-snyder
assert len(a) == len(b)
shuffled_a = np.empty(a.shape, dtype=a.dtype)
shuffled_b = np.empty(b.shape, dtype=b.dtype)
permutation = np.random.permutation(len(a))
for old_index, new_index in enumerate(permutation):
shuffled_a[new_index] = a[old_index]
shuffled_b[new_index] = b[old_index]
return shuffled_a, shuffled_b
def createDataSet(imagefolder):
os.chdir(imagefolder)
# total number of files
number_of_files = len([item for item in os.listdir('.') if os.path.isfile(os.path.join('.', item))])
# get a shuffled list : I needed this because my image names were of the format n_x_<some details>.jpg
# where n was my target and x was a number from 0 to m-1 where m was the number of samples
# of the target value n. So I needed so shuffle and iterate while putting images in train
# test and validate arrays
image_index_array = range(0,number_of_files)
random.seed(12)
random.shuffle(image_index_array)
# split 80/10/10 - train/test/val
trainsize = int(number_of_files*.8)
testsize = int(number_of_files*.1)
valsize = number_of_files - trainsize - testsize
# create the random value arrays of train/test/val by slicing the total image index array
train_index_array = image_index_array[0:trainsize]
test_index_array = image_index_array[trainsize:trainsize+testsize]
validate_index_array = image_index_array[trainsize+testsize:]
# initialize the data structures
dataset = {'train':[[],[]],'test':[[],[]],'validate':[[],[]]}
i_counter = 0
train_X = []
train_y = []
test_X = []
test_y = []
val_X = []
val_y = []
for item in os.listdir('.'):
if not os.path.isfile(os.path.join('.', item)):
continue
if item.endswith('.pkl'):
continue
print 'Processing item ' + item
item_y = item.split('_')[0]
item_x = cv2.imread(item)
height, width = item_x.shape[:2]
# this was my requirement - skip it if you do not need it
if(height != 135 or width != 240):
continue
# get 3 channels
b,g,r = cv2.split(item_x)
item_x = [b,g,r]
item_x = np.array(item_x)
item_x = item_x.reshape(3,135*240)
if i_counter in test_index_array:
test_X.append(item_x)
test_y.append(item_y)
elif i_counter in validate_index_array:
val_X.append(item_x)
val_y.append(item_y)
else:
train_X.append(item_x)
train_y.append(item_y)
i_counter = i_counter + 1
# fix the dimensions. Flatten out the channel and intensity dimensions
train_X = np.array(train_X)
train_X = train_X.reshape(train_X.shape[0],train_X.shape[1]*train_X.shape[2])
test_X = np.array(test_X)
test_X = test_X.reshape(test_X.shape[0],test_X.shape[1]*test_X.shape[2])
val_X = np.array(val_X)
val_X = val_X.reshape(val_X.shape[0],val_X.shape[1]*val_X.shape[2])
train_y = np.array(train_y)
test_y = np.array(test_y)
val_y = np.array(val_y)
# shuffle the train and test arrays in unison
train_X,train_y = shuffle_in_unison(train_X,train_y)
test_X,test_y = shuffle_in_unison(test_X,test_y)
# pickle them
dataset['train'] = [train_X,train_y]
dataset['test'] = [test_X,test_y]
dataset['validate'] = [val_X,val_y]
output = open('pcount.pkl', 'wb')
cPickle.dump(dataset, output)
output.close`
Once you have this pickle file
You can use it in convolutional_mlp.py like this.
layer0_input = x.reshape((batch_size, 3, 135, 240))
# Construct the first convolutional pooling layer:
# filtering reduces the image size to (135-8+1 , 240-5+1) = (128, 236)
# maxpooling reduces this further to (128/2, 236/2) = (64, 118)
# 4D output tensor is thus of shape (batch_size, nkerns[0], 64, 118)
layer0 = LeNetConvPoolLayer(
rng,
input=layer0_input,
image_shape=(batch_size, 3, 135, 240),
filter_shape=(nkerns[0], 3, 8, 5),
poolsize=(2, 2)
)
The load_data function in logistic_sgd.py will need a small change as below
f = open(dataset, 'rb')
dump = cPickle.load(f)
train_set = dump['train']
valid_set = dump['validate']
test_set = dump['test']
f.close()
Hope this helps

Resources