Module ainshamsflow.utils.utils
Utils module for miscellaneous helper functions.
Expand source code
"""Utils module for miscellaneous helper functions."""
import numpy as np
from ainshamsflow.data import Dataset
def pred_one_hot(y_pred):
n_c = y_pred.shape[-1]
return np.squeeze(np.eye(n_c)[np.argmax(y_pred, axis=-1)])
def true_one_hot(y_true, n_c):
m = y_true.shape[0]
return np.squeeze(np.eye(n_c)[y_true]).reshape((m, -1))
def confution_matrix(y_pred_1h, y_true_1h):
y_pred = y_pred_1h.argmax(axis=1)
y_true = y_true_1h.argmax(axis=1)
m, n_c = y_pred_1h.shape
cm = np.zeros((n_c, n_c))
for i in range(m):
cm[y_true[i]][y_pred[i]] += 1
return cm
def get_dataset_from_xy(x, y):
if x is None:
raise RunningWithoutDataError
elif isinstance(x, Dataset):
if x.data is None:
raise RunningWithoutDataError
elif x.target is None:
if y is None:
raise RunningWithoutDataError
elif isinstance(y, Dataset):
return x.add_targets(y.target)
else: # isinstance(y, np.array)
return x.add_targets(y)
else: # x.target is not None
return x
else: # isinstance(x, np.array)
if y is None:
raise RunningWithoutDataError
elif isinstance(y, Dataset):
return y.add_data(x)
else: # isinstance(y, np.array)
return Dataset(x, y)
def get_indices(X_shape, HF, WF, stride, pad):
"""
Returns index matrices in order to transform our input image into a matrix.
Parameters:
-X_shape: Input image shape.
-HF: filter height.
-WF: filter width.
-stride: stride value.
-pad: padding value.
Returns:
-i: matrix of index i.
-j: matrix of index j.
-d: matrix of index d.
(Use to mark delimitation for each channel
during multi-dimensional arrays indexing).
"""
# get input size
m, n_H, n_W, n_C = X_shape
p_h, p_w = pad
s_h, s_w = stride
# get output size
out_h = int((n_H + 2 * p_h - HF) / s_h) + 1
out_w = int((n_W + 2 * p_w - WF) / s_w) + 1
# ----Compute matrix of index i----
# Level 1 vector.
level1 = np.repeat(np.arange(HF), WF)
# Duplicate for the other channels.
level1 = np.tile(level1, n_C)
# Create a vector with an increase by 1 at each level.
everyLevels = s_h * np.repeat(np.arange(out_h), out_w)
# Create matrix of index i at every levels for each channel.
i = level1.reshape(-1, 1) + everyLevels.reshape(1, -1)
# ----Compute matrix of index j----
# Slide 1 vector.
slide1 = np.tile(np.arange(WF), HF)
# Duplicate for the other channels.
slide1 = np.tile(slide1, n_C)
# Create a vector with an increase by 1 at each slide.
everySlides = s_h * np.tile(np.arange(out_w), out_h)
# Create matrix of index j at every slides for each channel.
j = slide1.reshape(-1, 1) + everySlides.reshape(1, -1)
# ----Compute matrix of index d----
# This is to mark delimitation for each channel
# during multi-dimensional arrays indexing.
d = np.repeat(np.arange(n_C), HF * WF).reshape(-1, 1)
return i, j, d
def im2col(X, idx, pad):
"""
Transforms our input image into a matrix.
Parameters:
- X: input image.
- HF: filter height.
- WF: filter width.
- stride: stride value.
- pad: padding value.
Returns:
-cols: output matrix.
"""
p_h, p_w = pad
# Padding
X_padded = np.pad(X, ((0, 0), (0, 0), (p_h, p_h), (p_w, p_w)), mode='constant')
i, j, d = idx
# Multi-dimensional arrays indexing.
cols = X_padded[:, d, i, j]
cols = np.concatenate(cols, axis=-1)
return cols
def col2im(dX_col, X_shape,idx, pad):
"""
Transform our matrix back to the input image.
Parameters:
- dX_col: matrix with error.
- X_shape: input image shape.
- HF: filter height.
- WF: filter width.
- stride: stride value.
- pad: padding value.
Returns:
-x_padded: input image with error.
"""
# Get input size
N, D, H, W = X_shape
p_h, p_w = pad
# Add padding if needed.
H_padded, W_padded = H + 2 * p_h, W + 2 * p_w
X_padded = np.zeros((N, D, H_padded, W_padded))
# Index matrices, necessary to transform our input image into a matrix.
i, j, d = idx
# Retrieve batch dimension by spliting dX_col N times: (X, Y) => (N, X, Y)
dX_col_reshaped = np.array(np.hsplit(dX_col, N))
# Reshape our matrix back to image.
# slice(None) is used to produce the [::] effect which means "for every elements".
np.add.at(X_padded, (slice(None), d, i, j), dX_col_reshaped)
# Remove padding from new image if needed.
if all((p_h == 0, p_w == 0)):
return X_padded
else:
return X_padded[p_h:-p_h, p_w:-p_w, :, :]
def time_elapsed(t):
if t > 60:
return '{:.3f} mins'.format(t/60)
elif t > 0:
return '{:.3f} s'.format(t)
elif t > 1e-3:
return '{:.3f} ms'.format(t*1e3)
else:
return '{} us'.format(t*1e6)
Functions
def col2im(dX_col, X_shape, idx, pad)-
Transform our matrix back to the input image. Parameters: - dX_col: matrix with error. - X_shape: input image shape. - HF: filter height. - WF: filter width. - stride: stride value. - pad: padding value. Returns: -x_padded: input image with error.
Expand source code
def col2im(dX_col, X_shape,idx, pad): """ Transform our matrix back to the input image. Parameters: - dX_col: matrix with error. - X_shape: input image shape. - HF: filter height. - WF: filter width. - stride: stride value. - pad: padding value. Returns: -x_padded: input image with error. """ # Get input size N, D, H, W = X_shape p_h, p_w = pad # Add padding if needed. H_padded, W_padded = H + 2 * p_h, W + 2 * p_w X_padded = np.zeros((N, D, H_padded, W_padded)) # Index matrices, necessary to transform our input image into a matrix. i, j, d = idx # Retrieve batch dimension by spliting dX_col N times: (X, Y) => (N, X, Y) dX_col_reshaped = np.array(np.hsplit(dX_col, N)) # Reshape our matrix back to image. # slice(None) is used to produce the [::] effect which means "for every elements". np.add.at(X_padded, (slice(None), d, i, j), dX_col_reshaped) # Remove padding from new image if needed. if all((p_h == 0, p_w == 0)): return X_padded else: return X_padded[p_h:-p_h, p_w:-p_w, :, :] def confution_matrix(y_pred_1h, y_true_1h)-
Expand source code
def confution_matrix(y_pred_1h, y_true_1h): y_pred = y_pred_1h.argmax(axis=1) y_true = y_true_1h.argmax(axis=1) m, n_c = y_pred_1h.shape cm = np.zeros((n_c, n_c)) for i in range(m): cm[y_true[i]][y_pred[i]] += 1 return cm def get_dataset_from_xy(x, y)-
Expand source code
def get_dataset_from_xy(x, y): if x is None: raise RunningWithoutDataError elif isinstance(x, Dataset): if x.data is None: raise RunningWithoutDataError elif x.target is None: if y is None: raise RunningWithoutDataError elif isinstance(y, Dataset): return x.add_targets(y.target) else: # isinstance(y, np.array) return x.add_targets(y) else: # x.target is not None return x else: # isinstance(x, np.array) if y is None: raise RunningWithoutDataError elif isinstance(y, Dataset): return y.add_data(x) else: # isinstance(y, np.array) return Dataset(x, y) def get_indices(X_shape, HF, WF, stride, pad)-
Returns index matrices in order to transform our input image into a matrix. Parameters: -X_shape: Input image shape. -HF: filter height. -WF: filter width. -stride: stride value. -pad: padding value. Returns: -i: matrix of index i. -j: matrix of index j. -d: matrix of index d. (Use to mark delimitation for each channel during multi-dimensional arrays indexing).
Expand source code
def get_indices(X_shape, HF, WF, stride, pad): """ Returns index matrices in order to transform our input image into a matrix. Parameters: -X_shape: Input image shape. -HF: filter height. -WF: filter width. -stride: stride value. -pad: padding value. Returns: -i: matrix of index i. -j: matrix of index j. -d: matrix of index d. (Use to mark delimitation for each channel during multi-dimensional arrays indexing). """ # get input size m, n_H, n_W, n_C = X_shape p_h, p_w = pad s_h, s_w = stride # get output size out_h = int((n_H + 2 * p_h - HF) / s_h) + 1 out_w = int((n_W + 2 * p_w - WF) / s_w) + 1 # ----Compute matrix of index i---- # Level 1 vector. level1 = np.repeat(np.arange(HF), WF) # Duplicate for the other channels. level1 = np.tile(level1, n_C) # Create a vector with an increase by 1 at each level. everyLevels = s_h * np.repeat(np.arange(out_h), out_w) # Create matrix of index i at every levels for each channel. i = level1.reshape(-1, 1) + everyLevels.reshape(1, -1) # ----Compute matrix of index j---- # Slide 1 vector. slide1 = np.tile(np.arange(WF), HF) # Duplicate for the other channels. slide1 = np.tile(slide1, n_C) # Create a vector with an increase by 1 at each slide. everySlides = s_h * np.tile(np.arange(out_w), out_h) # Create matrix of index j at every slides for each channel. j = slide1.reshape(-1, 1) + everySlides.reshape(1, -1) # ----Compute matrix of index d---- # This is to mark delimitation for each channel # during multi-dimensional arrays indexing. d = np.repeat(np.arange(n_C), HF * WF).reshape(-1, 1) return i, j, d def im2col(X, idx, pad)-
Transforms our input image into a matrix. Parameters: - X: input image. - HF: filter height. - WF: filter width. - stride: stride value. - pad: padding value. Returns: -cols: output matrix.
Expand source code
def im2col(X, idx, pad): """ Transforms our input image into a matrix. Parameters: - X: input image. - HF: filter height. - WF: filter width. - stride: stride value. - pad: padding value. Returns: -cols: output matrix. """ p_h, p_w = pad # Padding X_padded = np.pad(X, ((0, 0), (0, 0), (p_h, p_h), (p_w, p_w)), mode='constant') i, j, d = idx # Multi-dimensional arrays indexing. cols = X_padded[:, d, i, j] cols = np.concatenate(cols, axis=-1) return cols def pred_one_hot(y_pred)-
Expand source code
def pred_one_hot(y_pred): n_c = y_pred.shape[-1] return np.squeeze(np.eye(n_c)[np.argmax(y_pred, axis=-1)]) def time_elapsed(t)-
Expand source code
def time_elapsed(t): if t > 60: return '{:.3f} mins'.format(t/60) elif t > 0: return '{:.3f} s'.format(t) elif t > 1e-3: return '{:.3f} ms'.format(t*1e3) else: return '{} us'.format(t*1e6) def true_one_hot(y_true, n_c)-
Expand source code
def true_one_hot(y_true, n_c): m = y_true.shape[0] return np.squeeze(np.eye(n_c)[y_true]).reshape((m, -1))