Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sc #5

Merged
merged 4 commits into from
Jun 26, 2011
Merged

Sc #5

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion scikits/learn/decomposition/dict_learning.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@


from .sparse_pca import dict_learning, sparse_pca, _update_V_parallel from .sparse_pca import dict_learning, sparse_pca, _update_V_parallel
from ..base import BaseEstimator, TransformerMixin from ..base import BaseEstimator, TransformerMixin
from ..linear_model import orthogonal_mp




class DictionaryLearning(BaseEstimator, TransformerMixin): class DictionaryLearning(BaseEstimator, TransformerMixin):
Expand All @@ -19,7 +20,7 @@ class DictionaryLearning(BaseEstimator, TransformerMixin):
Solves the optimization problem: Solves the optimization problem:
(U^*,V^*) = argmin 0.5 || Y - U V ||_2^2 + alpha * || U ||_1 (U^*,V^*) = argmin 0.5 || Y - U V ||_2^2 + alpha * || U ||_1
(U,V) (U,V)
with || V_k ||_2 = 1 for all 0<= k < n_atoms with || V_k ||_2 = 1 for all 0 <= k < n_atoms


Parameters Parameters
---------- ----------
Expand Down Expand Up @@ -130,6 +131,7 @@ def transform(self, X, y=None, method='omp', **kwargs):
X_new array, shape (n_samples, n_components) X_new array, shape (n_samples, n_components)
Transformed data Transformed data
""" """
# XXX : kwargs is not documented


# XXX: parameters should be made explicit so we can have defaults # XXX: parameters should be made explicit so we can have defaults
if method == 'omp': if method == 'omp':
Expand Down
45 changes: 23 additions & 22 deletions scikits/learn/feature_extraction/image.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
# Gael Varoquaux <gael.varoquaux@normalesup.org> # Gael Varoquaux <gael.varoquaux@normalesup.org>
# License: BSD # License: BSD



from itertools import product

import numpy as np import numpy as np
from scipy import sparse from scipy import sparse
from ..utils.fixes import in1d from ..utils.fixes import in1d
from ..utils import check_random_state from ..utils import check_random_state
from ..utils.fixes import product
from ..base import BaseEstimator from ..base import BaseEstimator




Expand Down Expand Up @@ -205,23 +203,18 @@ def extract_patches_2d(image, patch_size, max_patches=None, seed=None):
[ 4, 5, 6, 7], [ 4, 5, 6, 7],
[ 8, 9, 10, 11], [ 8, 9, 10, 11],
[12, 13, 14, 15]]) [12, 13, 14, 15]])

>>> patches = extract_patches_2d(one_image, (2, 2))
>>> patches = extract_patches_2d(one_image, (4, 4), (2, 2))
>>> patches.shape >>> patches.shape
(9, 2, 2) (9, 2, 2)

>>> patches[0] >>> patches[0]
array([[0, 1], array([[0, 1],
[4, 5]]) [4, 5]])

>>> patches[1] >>> patches[1]
array([[1, 2], array([[1, 2],
[5, 6]]) [5, 6]])

>>> patches[8] >>> patches[8]
array([[10, 11], array([[10, 11],
[14, 15]]) [14, 15]])

""" """
i_h, i_w = image.shape[:2] i_h, i_w = image.shape[:2]
p_h, p_w = patch_size p_h, p_w = patch_size
Expand All @@ -245,19 +238,16 @@ def extract_patches_2d(image, patch_size, max_patches=None, seed=None):
raise ValueError("Invalid value for max_patches!") raise ValueError("Invalid value for max_patches!")


rng = check_random_state(seed) rng = check_random_state(seed)
patches = np.zeros((n_patches, p_h, p_w, n_colors), dtype=image.dtype) patches = np.empty((n_patches, p_h, p_w, n_colors), dtype=image.dtype)
i_s = rng.randint(n_h, size=n_patches) i_s = rng.randint(n_h, size=n_patches)
j_s = rng.randint(n_w, size=n_patches) j_s = rng.randint(n_w, size=n_patches)
for offset, (i, j) in enumerate(zip(i_s, j_s)): for p, i, j in zip(patches, i_s, j_s):
patches[offset] = image[i:i + p_h, j:j + p_w, :] p[:] = image[i:i + p_h, j:j + p_w, :]
else: else:
n_patches = all_patches n_patches = all_patches
patches = np.zeros((n_patches, p_h, p_w, n_colors), dtype=image.dtype) patches = np.empty((n_patches, p_h, p_w, n_colors), dtype=image.dtype)
offset = 0 for p, (i, j) in zip(patches, product(xrange(n_h), xrange(n_w))):
for i in xrange(n_h): p[:] = image[i:i + p_h, j:j + p_w, :]
for j in xrange(n_w):
patches[offset] = image[i:i + p_h, j:j + p_w, :]
offset += 1


# remove the color dimension if useless # remove the color dimension if useless
if patches.shape[-1] == 1: if patches.shape[-1] == 1:
Expand All @@ -284,7 +274,7 @@ def reconstruct_from_patches_2d(patches, image_size):


Returns Returns
------- -------
image: array with shape image: array with shape




""" """
Expand All @@ -294,8 +284,9 @@ def reconstruct_from_patches_2d(patches, image_size):
# compute the dimensions of the patches array # compute the dimensions of the patches array
n_h = i_h - p_h + 1 n_h = i_h - p_h + 1
n_w = i_w - p_w + 1 n_w = i_w - p_w + 1
for offset, (i, j) in enumerate(product(xrange(n_h), xrange(n_w))): for p, (i, j) in zip(patches, product(xrange(n_h), xrange(n_w))):
img[i:i + p_h, j:j + p_w] += patches[offset] img[i:i + p_h, j:j + p_w] += p

for i in xrange(i_h): for i in xrange(i_h):
for j in xrange(i_w): for j in xrange(i_w):
# divide by the amount of overlap # divide by the amount of overlap
Expand All @@ -321,19 +312,29 @@ class PatchExtractor(BaseEstimator):
seed: int or RandomState seed: int or RandomState
Seed for the random number generator used in case max_patches is used. Seed for the random number generator used in case max_patches is used.
""" """

def __init__(self, patch_size, max_patches=None, seed=None): def __init__(self, patch_size, max_patches=None, seed=None):
self.patch_size = patch_size self.patch_size = patch_size
self.max_patches = max_patches self.max_patches = max_patches
self.seed = seed self.seed = seed


def fit(self, X, y=None): def fit(self, X, y=None):
"""

XXX : docstring is missing

"""
return self return self


def transform(self, X): def transform(self, X):
"""

XXX : docstring is missing

"""
patches = np.empty((0,) + self.patch_size) patches = np.empty((0,) + self.patch_size)
for image in X: for image in X:
partial_patches = extract_patches_2d(image, self.patch_size, partial_patches = extract_patches_2d(image, self.patch_size,
self.max_patches, self.seed) self.max_patches, self.seed)
# XXX : would be better to avoid a realloc for each image
patches = np.r_[patches, partial_patches] patches = np.r_[patches, partial_patches]
return patches return patches
2 changes: 2 additions & 0 deletions scikits/learn/feature_extraction/tests/test_image.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -128,12 +128,14 @@ def test_reconstruct_patches_perfect_color():
lena_reconstructed = reconstruct_from_patches_2d(patches, lena.shape) lena_reconstructed = reconstruct_from_patches_2d(patches, lena.shape)
np.testing.assert_array_equal(lena, lena_reconstructed) np.testing.assert_array_equal(lena, lena_reconstructed)



def test_patch_extractor_max_patches(): def test_patch_extractor_max_patches():
lenas = _make_images() lenas = _make_images()
extr = PatchExtractor(patch_size=(8, 8), max_patches=100, seed=0) extr = PatchExtractor(patch_size=(8, 8), max_patches=100, seed=0)
patches = extr.transform(lenas) patches = extr.transform(lenas)
assert patches.shape == (len(lenas) * 100, 8, 8) assert patches.shape == (len(lenas) * 100, 8, 8)



def test_patch_extractor_all_patches(): def test_patch_extractor_all_patches():
lenas = _make_images() lenas = _make_images()
i_h, i_w = lenas.shape[1:3] i_h, i_w = lenas.shape[1:3]
Expand Down