Page MenuHomec4science

PCAnet.py
No OneTemporary

File Metadata

Created
Mon, Feb 24, 13:55

PCAnet.py

import numpy as np
from scipy.sparse import csr_matrix
import numpy
numpy.set_printoptions(threshold=numpy.nan)
def im2col_sliding(im, patch_dim, stride):
p_w, p_h = patch_dim
im_w, im_h = im.shape
s_w = s_h = stride
res = []
for j in range(0, im_w - p_w + 1, s_w):
for i in range(0, im_h - p_h + 1, s_h):
res.append(im[i:i+p_w,j:j+p_h].flatten('F'))
return np.array(res).T
def im2col_mean_removal(img, patch_dim, stepsize=1):
z = img.shape[2]
out = []
for i in range(z):
iim = im2col_sliding(img[:,:,i], (patch_dim, patch_dim), stepsize)
out.append(iim - iim.mean(0))
return np.array(out)
def im2col_gen(img, patch_dim, stepsize=1):
z = img.shape[2]
out = []
for i in range(z):
iim = im2col_sliding(img[:,:,i], (patch_dim, patch_dim), stepsize)
out.append(iim)
return np.array(out)
def pca_basis(patches, num_filter, patch_size, num_chls):
num_patches = patches.shape[1]
num_imgs = patches.shape[0]
Rx = np.zeros((num_chls * patch_size**2, num_chls * patch_size**2))
for i in range(num_imgs):
p = patches[i]
Rx += p.dot(p.T)
Rx /= num_patches * num_patches
evals, evecs = np.linalg.eigh(Rx)
idx = np.argsort(evals)[::-1]
evecs = evecs[:,idx]
evals = evals[idx]
evecs = evecs[:, :num_filter]
S = np.sign(evecs[0,:])
return evecs * S
def heaviside(X):
X[X > 0] = 1
X[X <= 0] = 0
return X
def histc(M, bins):
res = []
last = bins[-1]
bins = np.append(bins, last)
for i in range(M.shape[1]):
c = M[:,i]
h, e = np.histogram(c, bins)
res.append(h)
return np.array(res)
class PCAnet:
def __init__(self, max_samples=100000, rdm=np.random.RandomState(7), params=None):
self.max_samples = max_samples
self.rdm = rdm
self.params = params
def filter_bank(self, imgs, patch_dim, num_filters):
p = self.params
num_img = imgs.shape[0]
num_samples = min(self.max_samples, num_img)
rand_idx = self.rdm.permutation(num_img)
rand_idx = rand_idx[0:num_samples]
num_chls = np.shape(imgs[0])[2]
patches = np.vstack(im2col_mean_removal(imgs[i], patch_dim) for i in rand_idx)
return pca_basis(patches, num_filters, patch_dim, num_chls)
def filter_output(self, imgs, imgs_idx, patch_dim, num_filters, f_bank):
num_img, height, width, chls = imgs.shape
mag = int((patch_dim - 1) / 2)
out_imgs = []
for i in range(num_img):
imx, imy, chls = imgs[i].shape
img = np.zeros((imx + patch_dim - 1, imy + patch_dim - 1, chls))
img[mag:-mag, mag:-mag,:] = imgs[i]
im = im2col_mean_removal(img, patch_dim)
for j in range(num_filters):
out_imgs.append((f_bank[:,j].reshape(1, -1).dot(im)).reshape(imx,imy).T)
out_imgs_idx = np.kron(imgs_idx, np.ones((num_filters,1)))
out_imgs = np.array(out_imgs)
s = out_imgs.shape
out_imgs = out_imgs.reshape((s[0], s[1], s[2], 1))
return np.array(out_imgs), out_imgs_idx
def hashing_hist(self, imgs_idx, out_imgs):
p = self.params
num_img = int(max(imgs_idx)[0])
f = np.array([])
map_weights = 2 ** np.arange(p['num_filters'][-1])[::-1]
for idx in range(num_img + 1):
idx_span = np.where(imgs_idx == idx)[0]
num_0s = int(idx_span.size / p['num_filters'][-1])
bhist = np.array([])
for i in range(num_0s):
T = 0
img_size = out_imgs[idx_span[p['num_filters'][-1]*i + 1]]
for j in range(p['num_filters'][-1]):
T += map_weights[j] * heaviside(out_imgs[idx_span[p['num_filters'][-1]*i+j]])
T = T.T
s = T.shape
T = T.reshape((s[1], s[2], s[0]))
stride = np.round((1 - p['overlap_ratio'])*p['hist_size'])
h = histc(im2col_gen(T, p['hist_size'][0], int(stride[0]))[0], np.arange(2**p['num_filters'][-1]))
blkwise_features = h
blkwise_features = blkwise_features * \
(2**p['num_filters'][-1] / blkwise_features.sum(1).reshape((-1,1)))
bhist = np.vstack([bhist, blkwise_features]) if bhist.size else blkwise_features
#blk_idx = np.kron(np.ones((num_0s,1)),np.kron(np.arange(bhist[0].shape[1]).T, np.ones(bhist[0].shape[0],1)))
bhist = np.hstack(bhist.T)
f = np.vstack([f, bhist]) if f.size else bhist
return np.array(f)
def train(self, imgs):
p = self.params
num_imgs = imgs.shape[0]
imgs_idx = np.arange(num_imgs).reshape((1,-1)).T
V = []
for stage in range(p['num_stages']):
print('Computing PCA filter bank and its output at stage {0}'.format(stage))
V.append(self.filter_bank(imgs, p['patch_dim'][stage], p['num_filters'][stage]))
if (stage != p['num_stages'] -1):
imgs, imgs_idx = self.filter_output(imgs, imgs_idx, p['patch_dim'][stage], p['num_filters'][stage],
V[stage])
return np.array(V)
def extract(self, imgs, V):
num_imgs = imgs.shape[0]
imgs_idx = np.arange(num_imgs).reshape((1,-1)).T
out_imgs = imgs
params = self.params
for stage in range(params['num_stages']):
out_imgs, imgs_idx = self.filter_output(out_imgs, imgs_idx, params['patch_dim'][stage],
params['num_filters'][stage], V[stage])
return self.hashing_hist(imgs_idx, out_imgs)

Event Timeline