colour_channel_weights = np.array([-0.0148366, -0.01253134, -0.01040762], dtype='float32')
Many thanks
def compute_PCA(image_array):
# Transpose and reshape the original image_array from N x channels x height x width to N x height x width x channels
imT = image_array.transpose(0,2,3,1)
reshaped_array = imT.reshape(imT.shape[0]*imT.shape[1]*imT.shape[2],3)
# Get covariance matrix, the eigenvectors and eigenvalues
cov = np.dot(reshaped_array.T, reshaped_array) / reshaped_array.shape[0]
U,S,V = np.linalg.svd(cov)
eigenvalues = np.sqrt(S) # because cov is symmetric and psd
return eigenvalues,U
def add_color_noise(image_array,eigenvalues,U,mu=0,sigma=0.1):
for idx in xrange(image_array.shape[0]):
# Generate the \alpha samples
samples = np.random.normal(mu, sigma, 3)
augmentation = samples * eigenvalues
noise = np.dot(U, augmentation.T)
# Add the noise
z = image_array[idx].transpose(1,2,0) + noise / eigenvalues # Scale here with the corresponding eigenvalue ?
image_array[idx] = z.transpose(2,0,1)
I am really struggling to implement this fancy PCA augmentation method, here is what I believe I must do (correct me if I am wrong):1) Create a Matrix where the first column contains all the red pixel data, the 2n column all the green pixel data and the 3rd all the blue pixel data from all the images in the dataset.
2) Calculate the mean of every column and subtract it from every respective column.
3) Normalise the data between 0 and 1? (is this necessary? since all values are already between 0 and 255)
4) Apply PCA, i.e. create covariance matrix and compute the 3 eigenvectors and eigenvalues.
5) Then add eigenVec1 * a1 * eigenVal1 + eigenVec2 * a2 * eigenVal2 + eigenVec3 * a3 * eigenVal3 to each rgb channel in every image; Where 'a' is sampled from a gaussian with 0 mean and 0.1 std (or 0.5).
Hey, is it normal to get values slightly larger than 1.0 and slightly less than 0.0? I am getting this.
Hey, is it normal to get values slightly larger than 1.0 and slightly less than 0.0? I am getting this.
Good point, you may want to clip this back to the usual input range. It's surely possible -- you're sampling multiplication factors from a Gaussian. But note that I haven't checked back whether Alex used the square root of Eigenvalues or the Eigenvalues themselves -- if the latter, the result depends on what scale the input data was in (still in 0--255, or already in 0--1).
--
You received this message because you are subscribed to a topic in the Google Groups "lasagne-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lasagne-users/meCDNeA9Ud4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lasagne-users+unsubscribe@googlegroups.com.
To post to this group, send email to lasagn...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lasagne-users/6fdbd224-8ebd-4687-b0bb-ceb05aabcabf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Also, I am unclear as to why we are taking the square root of the eigenvalues.
the paper which introduced the "fancy PCA" color jitter idea never touches on taking the square root of the eigenvalues. Any insight on this?
here's the code:
def PCA(data, dims_rescaled_data):
imgvector = data.reshape(-1, 3)
# print imgvector
# calculate the covariance matrix
R = np.cov(imgvector.T)
# calculate eigenvectors & eigenvalues of the covariance matrix
# use 'eigh' rather than 'eig' since R is symmetric,
# the performance gain is substantial
evals, evecs = LA.eigh(R)
# sort eigenvalue in decreasing order
idx = np.argsort(evals)[::-1]
evecs = evecs[:, idx]
# sort eigenvectors according to same index
evals = evals[idx]
# select the first n eigenvectors (n is desired dimension
# of rescaled data array, or dims_rescaled_data)
evecs = evecs[:, :dims_rescaled_data]
# carry out the transformation on the data using eigenvectors
# and return the re-scaled data, eigenvalues, and eigenvectors
return evals, evecs
def perturbation_eigen( img):
eVal, eVec = PCA(img, 1)
pca = np.sqrt(eVal) * eVec
perturb = (pca * np.random.randn(3) * .1).sum(axis = 1)
print perturb
imgvector = img.reshape(-1, 3)
print '\n'
print imgvector
new_imgvector = np.add(imgvector, perturb) # error
unshaped_img = new_imgvector.reshape(220, 220, -1 )
return unshaped_img
Any idea what's wrong, I think it's how I am adding the noise to the image, but other than that I'm not really sure
imgvector = img.reshape(-1, 3)
#imgvector = img.reshape(-1, 3) #Comment this reshape step out, then add the following code
# Compute centered rgb values matrix
(rows,cols,colors) = image.shape
rgb_mat = np.zeros((rows*cols,3))
for i in range(colors):
rgb_mat[:,i] = image[:,:,i].flatten()
rgb_mat -= np.mean(rgb_mat, axis=0)
I hope it helps!!
--
You received this message because you are subscribed to a topic in the Google Groups "lasagne-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lasagne-users/meCDNeA9Ud4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lasagne-users+unsubscribe@googlegroups.com.
To post to this group, send email to lasagn...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lasagne-users/340a3d7b-5660-45d5-82c0-1e55d1b314a9%40googlegroups.com.
# sort eigenvalue in decreasing order
idx = np.argsort(evals)[::-1]
evecs = evecs[:, idx]
# sort eigenvectors according to same index
evals = evals[idx]
# select the first n eigenvectors (n is desired dimension
# of rescaled data array, or dims_rescaled_data)
evecs = evecs[:, :dims_rescaled_data]
# carry out the transformation on the data using eigenvectors
# and return the re-scaled data, eigenvalues, and eigenvectors
return evals, evecs
def perturbation_eigen( img):
eVal, eVec = PCA(img, 1)
pca = np.sqrt(eVal) * eVec
perturb = (pca * np.random.randn(3) * .1).sum(axis = 1)
print perturb
imgvector = img.reshape(-1, 3)
print '\n'
print imgvector
new_imgvector = np.add(imgvector, perturb) # error
unshaped_img = new_imgvector.reshape(220, 220, -1 )
Any idea what's wrong, I think it's how I am adding the noise to the image, but other than that I'm not really sure
--
You received this message because you are subscribed to a topic in the Google Groups "lasagne-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lasagne-users/meCDNeA9Ud4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lasagne-users+unsubscribe@googlegroups.com.
To post to this group, send email to lasagn...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lasagne-users/50a149cb-fb4d-4963-821a-fb85b8d97176%40googlegroups.com.
To unsubscribe from this group and all its topics, send an email to lasagne-user...@googlegroups.com.
Thank you, I made the changes, couple of questions though. Do I mean center the data before normalizing it, but after reshaping it? what does this do to the result?
Also I found something weird when I print the image vectors when I'm done, the values look correct but when I display those rgb values, through opencv, as pixels the image is usually a white screen with some pixelated outlines. Any thoughts on why that might be?
If you use np.cov(), there's no need to reshape it.
Thank you, you were right about the data type, I assume leaving it in floating point would allow for more variation than unsigned int right? Or will the network round those values when i'm training it?
def com_PCA(image_array):
imgvector = image_array.reshape(-1, 3)
R = np.cov(imgvector.T)
U,S,V = np.linalg.svd(R)
print (U,S,V)
eigenvalues = np.sqrt(S) # because cov is symmetric and psd
return eigenvalues,U
def add_color_noise(image_array,eigenvalues,U,mean,batch_size,mu=0,sigma=0.1):
# image_array = (image_array - np.stack([mean]*batch_size))
distorted_images_array = np.zeros((image_array.shape[0],3,224,224))
dx=dy=224
for idx in range(distorted_images_array.shape[0]):
scale_factor = random.uniform( 0.9 , 1.1)
# image_array[idx] = ndimage.zoom(image_array[idx], (1,scale_factor, scale_factor))
distorted_image = ndimage.zoom(image_array[idx], (1,scale_factor, scale_factor))
w, h = distorted_image.shape[1:]
x = random.randint(0, w - dx - 1)
y = random.randint(0, h - dy - 1)
distorted_image = distorted_image[:,x:x+dx,y:y+dy]
scipy.misc.imsave('before_outfile.jpg', distorted_image.transpose(2, 1, 0))
# Generate the \alpha samples
samples = np.random.normal(mu, sigma, 3)
augmentation = samples * eigenvalues
noise = np.dot(U, augmentation.T)
# Add the noise
z = distorted_image.transpose(2,1,0) + noise
scipy.misc.imsave('after_outfile.jpg', z)
distorted_images_array[idx]= z.transpose(2,1,0)
return distorted_images_arrayand these are my output
here's is my code, is it correct?
4) Apply PCA, i.e. create covariance matrix and compute the 3 eigenvectors and eigenvalues.cov = np.cov(yourdata.T) # this already includes mean removal. note the transpose.eigvals, eigvects = np.linalg.eigh(cov)5) Then add eigenVec1 * a1 * eigenVal1 + eigenVec2 * a2 * eigenVal2 + eigenVec3 * a3 * eigenVal3 to each rgb channel in every image; Where 'a' is sampled from a gaussian with 0 mean and 0.1 std (or 0.5).I think you want the square root of the eigen values:pca = np.sqrt(eigvals) * eigvects