From a81b5cfd505d6579b2dd8fa9630a1f5a1d79b50b Mon Sep 17 00:00:00 2001 From: Neil Lawrence Date: Wed, 27 Nov 2013 10:07:08 +0000 Subject: [PATCH 01/14] Fixed test in kern.py to request correct output dim for multioutput covariances. --- GPy/kern/kern.py | 4 ++-- GPy/testing/bcgplvm_tests.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/GPy/kern/kern.py b/GPy/kern/kern.py index 46bb01c8..bf8ba612 100644 --- a/GPy/kern/kern.py +++ b/GPy/kern/kern.py @@ -861,13 +861,13 @@ def kern_test(kern, X=None, X2=None, output_ind=None, verbose=False, X_positive= if X_positive: X = abs(X) if output_ind is not None: - X[:, output_ind] = np.random.randint(kern.parts[0].output_dim, X.shape[0]) + X[:, output_ind] = np.random.randint(low=0,high=kern.parts[0].output_dim, size=X.shape[0]) if X2==None: X2 = np.random.randn(20, kern.input_dim) if X_positive: X2 = abs(X2) if output_ind is not None: - X2[:, output_ind] = np.random.randint(kern.parts[0].output_dim, X2.shape[0]) + X2[:, output_ind] = np.random.randint(low=0, high=kern.parts[0].output_dim, size=X2.shape[0]) if verbose: print("Checking covariance function is positive definite.") diff --git a/GPy/testing/bcgplvm_tests.py b/GPy/testing/bcgplvm_tests.py index 94282a0b..a5bec821 100644 --- a/GPy/testing/bcgplvm_tests.py +++ b/GPy/testing/bcgplvm_tests.py @@ -15,7 +15,7 @@ class BCGPLVMTests(unittest.TestCase): k = GPy.kern.mlp(input_dim) + GPy.kern.bias(input_dim) bk = GPy.kern.rbf(output_dim) mapping = GPy.mappings.Kernel(output_dim=input_dim, X=Y, kernel=bk) - m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) + m = GPy._models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() self.assertTrue(m.checkgrad()) @@ -28,7 +28,7 @@ class BCGPLVMTests(unittest.TestCase): k = GPy.kern.mlp(input_dim) + GPy.kern.bias(input_dim) bk = GPy.kern.rbf(output_dim) mapping = GPy.mappings.Linear(output_dim=input_dim, input_dim=output_dim) - m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) + m = GPy._models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() self.assertTrue(m.checkgrad()) @@ -41,7 +41,7 @@ class BCGPLVMTests(unittest.TestCase): k = GPy.kern.mlp(input_dim) + GPy.kern.bias(input_dim) bk = GPy.kern.rbf(output_dim) mapping = GPy.mappings.MLP(output_dim=input_dim, input_dim=output_dim, hidden_dim=[5, 4, 7]) - m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) + m = GPy._models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() self.assertTrue(m.checkgrad()) From 6da3fc5a89b60d1f01f885f4c558e7f42ed7fe30 Mon Sep 17 00:00:00 2001 From: Neil Lawrence Date: Wed, 27 Nov 2013 11:17:33 +0000 Subject: [PATCH 02/14] Added gradient of sympy kernel, seems to pass tests, but know it's not numerically stable. Checking in before making numerically stable. --- GPy/kern/parts/sympy_helpers.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/GPy/kern/parts/sympy_helpers.cpp b/GPy/kern/parts/sympy_helpers.cpp index 9f30eea9..9b0d5885 100644 --- a/GPy/kern/parts/sympy_helpers.cpp +++ b/GPy/kern/parts/sympy_helpers.cpp @@ -170,9 +170,25 @@ double dh_dl(double t, double tprime, double d_i, double d_j, double l){ } double dh_dt(double t, double tprime, double d_i, double d_j, double l){ - return 0.0; + // compute gradient of h function with respect to t. + double diff_t = t - tprime; + double half_l_di = 0.5*l*d_i; + double arg_1 = half_l_di + tprime/l; + double arg_2 = half_l_di - diff_t/l; + double ln_part_1 = ln_diff_erf(arg_1, arg_2); + arg_2 = half_l_di - t/l; + double ln_part_2 = ln_diff_erf(half_l_di, arg_2); + + return (d_i*(erf(d_i*l/2) - erf(d_i*l/2 - t/l))*exp(-d_i*t - d_j*tprime) - d_i*(erf(d_i*l/2 + tprime/l) - erf(d_i*l/2 - (t - tprime)/l))*exp(-d_i*(t - tprime)) + 2*exp(-d_i*(t - tprime) - pow(d_i*l/2 - (t - tprime)/l, 2))/(sqrt(M_PI)*l) - 2*exp(-d_i*t - d_j*tprime - pow(d_i*l/2 - t/l,2))/(sqrt(M_PI)*l))*exp(d_i*l/2*d_i*l/2)/(d_i + d_j); } double dh_dtprime(double t, double tprime, double d_i, double d_j, double l){ - return 0.0; + // compute gradient of h function with respect to tprime. + double diff_t = t - tprime; + double half_l_di = 0.5*l*d_i; + double arg_1 = half_l_di + tprime/l; + double arg_2 = half_l_di - diff_t/l; + double ln_part_1 = ln_diff_erf(arg_1, arg_2); + + return (d_i*(erf(d_i*l/2 + tprime/l) - erf(d_i*l/2 - (t - tprime)/l))*exp(-d_i*(t - tprime)) + d_j*(erf(d_i*l/2) - erf(d_i*l/2 - t/l))*exp(-d_i*t - d_j*tprime) + (-2*exp(-pow(d_i*l/2 - (t - tprime)/l,2)) + 2*exp(-pow(d_i*l/2 + tprime/l,2)))*exp(-d_i*(t - tprime))/(sqrt(M_PI)*l))*exp(d_i*l/2*d_i*l/2)/(d_i + d_j); } From 557d296d4c2d77b06c078d9bcd02a3f40d2b3080 Mon Sep 17 00:00:00 2001 From: Neil Lawrence Date: Wed, 27 Nov 2013 11:21:08 +0000 Subject: [PATCH 03/14] Modified to improve part of stability, gradient checks still passing. --- GPy/kern/parts/sympy_helpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPy/kern/parts/sympy_helpers.cpp b/GPy/kern/parts/sympy_helpers.cpp index 9b0d5885..d5e0205a 100644 --- a/GPy/kern/parts/sympy_helpers.cpp +++ b/GPy/kern/parts/sympy_helpers.cpp @@ -179,7 +179,7 @@ double dh_dt(double t, double tprime, double d_i, double d_j, double l){ arg_2 = half_l_di - t/l; double ln_part_2 = ln_diff_erf(half_l_di, arg_2); - return (d_i*(erf(d_i*l/2) - erf(d_i*l/2 - t/l))*exp(-d_i*t - d_j*tprime) - d_i*(erf(d_i*l/2 + tprime/l) - erf(d_i*l/2 - (t - tprime)/l))*exp(-d_i*(t - tprime)) + 2*exp(-d_i*(t - tprime) - pow(d_i*l/2 - (t - tprime)/l, 2))/(sqrt(M_PI)*l) - 2*exp(-d_i*t - d_j*tprime - pow(d_i*l/2 - t/l,2))/(sqrt(M_PI)*l))*exp(d_i*l/2*d_i*l/2)/(d_i + d_j); + return (d_i*exp(ln_part_2-d_i*t - d_j*tprime) - d_i*(erf(half_l_di + tprime/l) - erf(half_l_di - diff_t/l))*exp(-d_i*diff_t) + 2*exp(-d_i*diff_t - pow(half_l_di - diff_t/l, 2))/(sqrt(M_PI)*l) - 2*exp(-d_i*t - d_j*tprime - pow(half_l_di - t/l,2))/(sqrt(M_PI)*l))*exp(half_l_di*half_l_di)/(d_i + d_j); } double dh_dtprime(double t, double tprime, double d_i, double d_j, double l){ @@ -190,5 +190,5 @@ double dh_dtprime(double t, double tprime, double d_i, double d_j, double l){ double arg_2 = half_l_di - diff_t/l; double ln_part_1 = ln_diff_erf(arg_1, arg_2); - return (d_i*(erf(d_i*l/2 + tprime/l) - erf(d_i*l/2 - (t - tprime)/l))*exp(-d_i*(t - tprime)) + d_j*(erf(d_i*l/2) - erf(d_i*l/2 - t/l))*exp(-d_i*t - d_j*tprime) + (-2*exp(-pow(d_i*l/2 - (t - tprime)/l,2)) + 2*exp(-pow(d_i*l/2 + tprime/l,2)))*exp(-d_i*(t - tprime))/(sqrt(M_PI)*l))*exp(d_i*l/2*d_i*l/2)/(d_i + d_j); + return (d_i*(erf(half_l_di + tprime/l) - erf(half_l_di - diff_t/l))*exp(-d_i*diff_t) + d_j*(erf(half_l_di) - erf(half_l_di - t/l))*exp(-d_i*t - d_j*tprime) + (-2*exp(-pow(half_l_di - diff_t/l,2)) + 2*exp(-pow(half_l_di + tprime/l,2)))*exp(-d_i*diff_t)/(sqrt(M_PI)*l))*exp(half_l_di*half_l_di)/(d_i + d_j); } From ea05ba54bf5926392e2aa4f04cdd0c712f7e1b01 Mon Sep 17 00:00:00 2001 From: Neil Lawrence Date: Wed, 27 Nov 2013 11:25:42 +0000 Subject: [PATCH 04/14] sympykern kern_tests now passing, code is inefficient but should be numerically stable. --- GPy/kern/parts/sympy_helpers.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/GPy/kern/parts/sympy_helpers.cpp b/GPy/kern/parts/sympy_helpers.cpp index d5e0205a..56aa6f21 100644 --- a/GPy/kern/parts/sympy_helpers.cpp +++ b/GPy/kern/parts/sympy_helpers.cpp @@ -80,7 +80,7 @@ double ln_diff_erf(double x0, double x1){ else //x0 and x1 non-positive return log(erfcx(-x0)-erfcx(-x1)*exp(x0*x0 - x1*x1))-x0*x0; } - +// TODO: For all these computations of h things are very efficient at the moment. Need to recode sympykern to allow the precomputations to take place and all the gradients to be computed in one function. Not sure of best way forward for that yet. Neil double h(double t, double tprime, double d_i, double d_j, double l){ // Compute the h function for the sim covariance. double half_l_di = 0.5*l*d_i; @@ -179,7 +179,7 @@ double dh_dt(double t, double tprime, double d_i, double d_j, double l){ arg_2 = half_l_di - t/l; double ln_part_2 = ln_diff_erf(half_l_di, arg_2); - return (d_i*exp(ln_part_2-d_i*t - d_j*tprime) - d_i*(erf(half_l_di + tprime/l) - erf(half_l_di - diff_t/l))*exp(-d_i*diff_t) + 2*exp(-d_i*diff_t - pow(half_l_di - diff_t/l, 2))/(sqrt(M_PI)*l) - 2*exp(-d_i*t - d_j*tprime - pow(half_l_di - t/l,2))/(sqrt(M_PI)*l))*exp(half_l_di*half_l_di)/(d_i + d_j); + return (d_i*exp(ln_part_2-d_i*t - d_j*tprime) - d_i*exp(ln_part_1-d_i*diff_t) + 2*exp(-d_i*diff_t - pow(half_l_di - diff_t/l, 2))/(sqrt(M_PI)*l) - 2*exp(-d_i*t - d_j*tprime - pow(half_l_di - t/l,2))/(sqrt(M_PI)*l))*exp(half_l_di*half_l_di)/(d_i + d_j); } double dh_dtprime(double t, double tprime, double d_i, double d_j, double l){ @@ -189,6 +189,8 @@ double dh_dtprime(double t, double tprime, double d_i, double d_j, double l){ double arg_1 = half_l_di + tprime/l; double arg_2 = half_l_di - diff_t/l; double ln_part_1 = ln_diff_erf(arg_1, arg_2); + arg_2 = half_l_di - t/l; + double ln_part_2 = ln_diff_erf(half_l_di, arg_2); - return (d_i*(erf(half_l_di + tprime/l) - erf(half_l_di - diff_t/l))*exp(-d_i*diff_t) + d_j*(erf(half_l_di) - erf(half_l_di - t/l))*exp(-d_i*t - d_j*tprime) + (-2*exp(-pow(half_l_di - diff_t/l,2)) + 2*exp(-pow(half_l_di + tprime/l,2)))*exp(-d_i*diff_t)/(sqrt(M_PI)*l))*exp(half_l_di*half_l_di)/(d_i + d_j); + return (d_i*exp(ln_part_1-d_i*diff_t) + d_j*exp(ln_part_2-d_i*t - d_j*tprime) + (-2*exp(-pow(half_l_di - diff_t/l,2)) + 2*exp(-pow(half_l_di + tprime/l,2)))*exp(-d_i*diff_t)/(sqrt(M_PI)*l))*exp(half_l_di*half_l_di)/(d_i + d_j); } From f9fa378aa08edb97c95d5775358d39325d235a4e Mon Sep 17 00:00:00 2001 From: James Hensman Date: Wed, 27 Nov 2013 12:30:19 +0000 Subject: [PATCH 05/14] added some tips to the readme --- GPy/kern/kern.py | 1 + README.md | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/GPy/kern/kern.py b/GPy/kern/kern.py index bf8ba612..ed045534 100644 --- a/GPy/kern/kern.py +++ b/GPy/kern/kern.py @@ -862,6 +862,7 @@ def kern_test(kern, X=None, X2=None, output_ind=None, verbose=False, X_positive= X = abs(X) if output_ind is not None: X[:, output_ind] = np.random.randint(low=0,high=kern.parts[0].output_dim, size=X.shape[0]) + import ipdb; ipdb.set_trace() if X2==None: X2 = np.random.randn(20, kern.input_dim) if X_positive: diff --git a/README.md b/README.md index 0ff3d890..10ca8a83 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,31 @@ A Gaussian processes framework in Python. Continuous integration status: ![CI status](https://travis-ci.org/SheffieldML/GPy.png) +Getting started +=============== +Installing with pip +------------------- +The simplest way to install GPy is using pip. +pip install gpy + +Ubuntu +------ +For the most part, the developers are using ubuntu. To install the required packages: +sudo apt-get install python-numpy python-scipy python-matplotlib + +clone this git repository and add it to your path: + git clone git@github.com:SheffieldML/GPy.git \ + echo "PYTHONPATH=$PYTHONPATH:\ > ~/.bashrc + +Windows +------- +On windows, we recommend the ![anaconda python distribution](http://continuum.io/downloads). We've also had luck with ![enthought](http://www.enthought.com). git clone or unzip the source to a suitable directory, and add a PYTHONPATH environement variable. + +OSX +--- +everything appears to work out-of-the box using ![enthought](http://www.enthought.com) on osx Mavericks. + + Compiling documentation: ======================== From f8bc7a827fb67a50457d0b090573a252f180ff59 Mon Sep 17 00:00:00 2001 From: Neil Lawrence Date: Wed, 27 Nov 2013 12:31:01 +0000 Subject: [PATCH 06/14] Push minor fix to eq_sympy kernel test. --- GPy/kern/kern.py | 2 ++ GPy/testing/kernel_tests.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/GPy/kern/kern.py b/GPy/kern/kern.py index bf8ba612..37a18f04 100644 --- a/GPy/kern/kern.py +++ b/GPy/kern/kern.py @@ -861,12 +861,14 @@ def kern_test(kern, X=None, X2=None, output_ind=None, verbose=False, X_positive= if X_positive: X = abs(X) if output_ind is not None: + assert(output_ind Date: Wed, 27 Nov 2013 12:38:12 +0000 Subject: [PATCH 07/14] fixed import errors in tests --- GPy/testing/bcgplvm_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GPy/testing/bcgplvm_tests.py b/GPy/testing/bcgplvm_tests.py index a5bec821..94282a0b 100644 --- a/GPy/testing/bcgplvm_tests.py +++ b/GPy/testing/bcgplvm_tests.py @@ -15,7 +15,7 @@ class BCGPLVMTests(unittest.TestCase): k = GPy.kern.mlp(input_dim) + GPy.kern.bias(input_dim) bk = GPy.kern.rbf(output_dim) mapping = GPy.mappings.Kernel(output_dim=input_dim, X=Y, kernel=bk) - m = GPy._models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) + m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() self.assertTrue(m.checkgrad()) @@ -28,7 +28,7 @@ class BCGPLVMTests(unittest.TestCase): k = GPy.kern.mlp(input_dim) + GPy.kern.bias(input_dim) bk = GPy.kern.rbf(output_dim) mapping = GPy.mappings.Linear(output_dim=input_dim, input_dim=output_dim) - m = GPy._models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) + m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() self.assertTrue(m.checkgrad()) @@ -41,7 +41,7 @@ class BCGPLVMTests(unittest.TestCase): k = GPy.kern.mlp(input_dim) + GPy.kern.bias(input_dim) bk = GPy.kern.rbf(output_dim) mapping = GPy.mappings.MLP(output_dim=input_dim, input_dim=output_dim, hidden_dim=[5, 4, 7]) - m = GPy._models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) + m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() self.assertTrue(m.checkgrad()) From 6fb7fe2352960f3d5b5ad1ccb18569ae3ebe9978 Mon Sep 17 00:00:00 2001 From: James Hensman Date: Wed, 27 Nov 2013 12:41:47 +0000 Subject: [PATCH 08/14] minor edits to the README --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 10ca8a83..a3d98466 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,13 @@ For the most part, the developers are using ubuntu. To install the required pack sudo apt-get install python-numpy python-scipy python-matplotlib clone this git repository and add it to your path: - git clone git@github.com:SheffieldML/GPy.git \ - echo "PYTHONPATH=$PYTHONPATH:\ > ~/.bashrc + + git clone git@github.com:SheffieldML/GPy.git ~/gpy + echo "PYTHONPATH=$PYTHONPATH:~/gpy > ~/.bashrc Windows ------- -On windows, we recommend the ![anaconda python distribution](http://continuum.io/downloads). We've also had luck with ![enthought](http://www.enthought.com). git clone or unzip the source to a suitable directory, and add a PYTHONPATH environement variable. +On windows, we recommend the ![anaconda python distribution](http://continuum.io/downloads). We've also had luck with ![enthought](http://www.enthought.com). git clone or unzip the source to a suitable directory, and add a PYTHONPATH environment variable. OSX --- From 9231cf4bfc668e0f1aec337de913d776ef1d6373 Mon Sep 17 00:00:00 2001 From: James Hensman Date: Wed, 27 Nov 2013 13:02:24 +0000 Subject: [PATCH 09/14] more readme edits --- README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a3d98466..5bf6e44a 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,12 @@ Getting started =============== Installing with pip ------------------- -The simplest way to install GPy is using pip. -pip install gpy +The simplest way to install GPy is using pip. ubuntu users can do: + + sudo apt-get install python-pip + pip install gpy + +If you'd like to install from source, or want to contribute to the project (e.g. by sending pull requests via github), read on. Ubuntu ------ @@ -23,8 +27,9 @@ sudo apt-get install python-numpy python-scipy python-matplotlib clone this git repository and add it to your path: - git clone git@github.com:SheffieldML/GPy.git ~/gpy - echo "PYTHONPATH=$PYTHONPATH:~/gpy > ~/.bashrc + git clone git@github.com:SheffieldML/GPy.git ~/SheffieldML + echo 'PYTHONPATH=$PYTHONPATH:~/SheffieldML' >> ~/.bashrc + Windows ------- @@ -32,8 +37,10 @@ On windows, we recommend the ![anaconda python distribution](http://continuum.io OSX --- -everything appears to work out-of-the box using ![enthought](http://www.enthought.com) on osx Mavericks. +Everything appears to work out-of-the box using ![enthought](http://www.enthought.com) on osx Mavericks. Download/clone GPy, and then add GPy to your PYTHONPATH + git clone git@github.com:SheffieldML/GPy.git ~/SheffieldML + echo 'PYTHONPATH=$PYTHONPATH:~/SheffieldML' >> ~/.profile Compiling documentation: From 36cc17cf2407604c7eb62fc001bb2fa57fa9308f Mon Sep 17 00:00:00 2001 From: James Hensman Date: Wed, 27 Nov 2013 13:09:27 +0000 Subject: [PATCH 10/14] more readme stuff --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5bf6e44a..2aada317 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,8 @@ If you'd like to install from source, or want to contribute to the project (e.g. Ubuntu ------ For the most part, the developers are using ubuntu. To install the required packages: -sudo apt-get install python-numpy python-scipy python-matplotlib + + sudo apt-get install python-numpy python-scipy python-matplotlib clone this git repository and add it to your path: @@ -33,7 +34,11 @@ clone this git repository and add it to your path: Windows ------- -On windows, we recommend the ![anaconda python distribution](http://continuum.io/downloads). We've also had luck with ![enthought](http://www.enthought.com). git clone or unzip the source to a suitable directory, and add a PYTHONPATH environment variable. +On windows, we recommend the ![anaconda python distribution](http://continuum.io/downloads). We've also had luck with ![enthought](http://www.enthought.com). git clone or unzip the source to a suitable directory, and add an approptiate PYTHONPATH environment variable. + +On windows 7 (and possibly earlier versions) there's a bug in scipy version 0.13 which tries to write very long filenmnames. Reverting to scipy 0.12 seems to do the trick: + + conda install scipy=0.12 OSX --- From 6673a8ae0218d81e5e972f025253ad073dcf8e82 Mon Sep 17 00:00:00 2001 From: James Hensman Date: Wed, 27 Nov 2013 13:10:15 +0000 Subject: [PATCH 11/14] more readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2aada317..27af0b0d 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Windows ------- On windows, we recommend the ![anaconda python distribution](http://continuum.io/downloads). We've also had luck with ![enthought](http://www.enthought.com). git clone or unzip the source to a suitable directory, and add an approptiate PYTHONPATH environment variable. -On windows 7 (and possibly earlier versions) there's a bug in scipy version 0.13 which tries to write very long filenmnames. Reverting to scipy 0.12 seems to do the trick: +On windows 7 (and possibly earlier versions) there's a bug in scipy version 0.13 which tries to write very long filenames. Reverting to scipy 0.12 seems to do the trick: conda install scipy=0.12 From 77a0d61bf685e3d002e60be65d294ee86de86304 Mon Sep 17 00:00:00 2001 From: Max Zwiessele Date: Wed, 27 Nov 2013 13:12:05 +0000 Subject: [PATCH 12/14] gradientchecker added as a model --- GPy/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/GPy/models.py b/GPy/models.py index 9a847ea0..a56fb305 100644 --- a/GPy/models.py +++ b/GPy/models.py @@ -20,3 +20,4 @@ from _models.mrd import MRD#; _mrd = mrd; del mrd from _models.gradient_checker import GradientChecker#; _gradient_checker = gradient_checker ; del gradient_checker from _models.gp_multioutput_regression import GPMultioutputRegression#; _gp_multioutput_regression = gp_multioutput_regression ; del gp_multioutput_regression from _models.sparse_gp_multioutput_regression import SparseGPMultioutputRegression#; _sparse_gp_multioutput_regression = sparse_gp_multioutput_regression ; del sparse_gp_multioutput_regression +from _models.gradient_checker import GradientChecker \ No newline at end of file From 4be3f4482dbb64df59c38bbb039be3fd67f96910 Mon Sep 17 00:00:00 2001 From: Max Zwiessele Date: Wed, 27 Nov 2013 13:16:00 +0000 Subject: [PATCH 13/14] gradient checker comments and import updates --- GPy/_models/gradient_checker.py | 41 ++++++++++++++++----------------- GPy/kern/kern.py | 9 ++++---- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/GPy/_models/gradient_checker.py b/GPy/_models/gradient_checker.py index 64b8b2fb..dfd0640f 100644 --- a/GPy/_models/gradient_checker.py +++ b/GPy/_models/gradient_checker.py @@ -28,38 +28,37 @@ class GradientChecker(Model): :param df: Gradient of function to check :param x0: Initial guess for inputs x (if it has a shape (a,b) this will be reflected in the parameter names). - Can be a list of arrays, if takes a list of arrays. This list will be passed + Can be a list of arrays, if f takes a list of arrays. This list will be passed to f and df in the same order as given here. - If only one argument, make sure not to pass a list!!! - + If f takes only one argument, make sure not to pass a list for x0!!! :type x0: [array-like] | array-like | float | int - :param names: + :param list names: Names to print, when performing gradcheck. If a list was passed to x0 a list of names with the same length is expected. - :param args: Arguments passed as f(x, *args, **kwargs) and df(x, *args, **kwargs) + :param args kwargs: Arguments passed as f(x, *args, **kwargs) and df(x, *args, **kwargs) Examples: --------- - from GPy.models import GradientChecker - N, M, Q = 10, 5, 3 + from GPy.models import GradientChecker + N, M, Q = 10, 5, 3 - Sinusoid: + Sinusoid: - X = numpy.random.rand(N, Q) - grad = GradientChecker(numpy.sin,numpy.cos,X,'x') - grad.checkgrad(verbose=1) + X = numpy.random.rand(N, Q) + grad = GradientChecker(numpy.sin,numpy.cos,X,'sin_in') + grad.checkgrad(verbose=1) - Using GPy: + Using GPy: - X, Z = numpy.random.randn(N,Q), numpy.random.randn(M,Q) - kern = GPy.kern.linear(Q, ARD=True) + GPy.kern.rbf(Q, ARD=True) - grad = GradientChecker(kern.K, - lambda x: 2*kern.dK_dX(numpy.ones((1,1)), x), - x0 = X.copy(), - names='X') - grad.checkgrad(verbose=1) - grad.randomize() - grad.checkgrad(verbose=1) + X, Z = numpy.random.randn(N,Q), numpy.random.randn(M,Q) + kern = GPy.kern.linear(Q, ARD=True) + GPy.kern.rbf(Q, ARD=True) + grad = GradientChecker(kern.K, + lambda x: kern.dK_dX(numpy.ones((1,1)), x), + x0 = X.copy(), + names=['X_input']) + grad.checkgrad(verbose=1) + grad.randomize() + grad.checkgrad(verbose=1) """ Model.__init__(self) if isinstance(x0, (list, tuple)) and names is None: diff --git a/GPy/kern/kern.py b/GPy/kern/kern.py index f51c3c13..2c56f47a 100644 --- a/GPy/kern/kern.py +++ b/GPy/kern/kern.py @@ -737,15 +737,16 @@ class kern(Parameterized): else: raise NotImplementedError, "Cannot plot a kernel with more than two input dimensions" -from GPy.core.model import Model - +from ..core.model import Model class Kern_check_model(Model): """This is a dummy model class used as a base class for checking that the gradients of a given kernel are implemented correctly. It enables checkgradient() to be called independently on a kernel.""" def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): num_samples = 20 num_samples2 = 10 if kernel==None: + import GPy kernel = GPy.kern.rbf(1) + del GPy if X==None: X = np.random.normal(size=(num_samples, kernel.input_dim)) if dL_dK==None: @@ -760,7 +761,7 @@ class Kern_check_model(Model): self.dL_dK = dL_dK #self.constrained_indices=[] #self.constraints=[] - Model.__init__(self) + super(Kern_check_model, self).__init__() def is_positive_definite(self): v = np.linalg.eig(self.kernel.K(self.X))[0] @@ -863,7 +864,6 @@ def kern_test(kern, X=None, X2=None, output_ind=None, verbose=False, X_positive= if output_ind is not None: assert(output_ind Date: Wed, 27 Nov 2013 13:16:18 +0000 Subject: [PATCH 14/14] removed ipdb statement from kern, cleaned up some nasty whitespace --- GPy/kern/kern.py | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/GPy/kern/kern.py b/GPy/kern/kern.py index f51c3c13..df1e3f47 100644 --- a/GPy/kern/kern.py +++ b/GPy/kern/kern.py @@ -487,12 +487,11 @@ class kern(Parameterized): p1.psi1(Z, mu, S, psi11) Mu, Sigma = p1._crossterm_mu_S(Z, mu, S) Mu, Sigma = Mu.reshape(NM,self.input_dim), Sigma.reshape(NM,self.input_dim) - + p2.psi1(Z, Mu, Sigma, psi12) eK2 = psi12.reshape(N, M, M) crossterms = eK2 * (psi11[:, :, None] + psi11[:, None, :]) target += crossterms - #import ipdb;ipdb.set_trace() else: raise NotImplementedError, "psi2 cannot be computed for this kernel" return target @@ -540,15 +539,15 @@ class kern(Parameterized): # turn around to have rbf in front p1, p2 = self.parts[i2], self.parts[i1] ps1, ps2 = self.param_slices[i2], self.param_slices[i1] - + N, M = mu.shape[0], Z.shape[0]; NM=N*M psi11 = np.zeros((N, M)) p1.psi1(Z, mu, S, psi11) - + Mu, Sigma = p1._crossterm_mu_S(Z, mu, S) Mu, Sigma = Mu.reshape(NM,self.input_dim), Sigma.reshape(NM,self.input_dim) - + tmp1 = np.zeros_like(target[ps1]) tmp2 = np.zeros_like(target[ps2]) # for n in range(N): @@ -559,7 +558,7 @@ class kern(Parameterized): # Mu, Sigma= Mu.reshape(N,M,self.input_dim), Sigma.reshape(N,M,self.input_dim) # p2.dpsi1_dtheta((dL_dpsi2[n:n+1,m:m+1,m_prime:m_prime+1]*(psi11[n:n+1,m_prime:m_prime+1]))[0], Z[m:m+1], Mu[n:n+1,m], Sigma[n:n+1,m], target[ps2]) # p2.dpsi1_dtheta((dL_dpsi2[n:n+1,m:m+1,m_prime:m_prime+1]*(psi11[n:n+1,m:m+1]))[0], Z[m_prime:m_prime+1], Mu[n:n+1, m_prime], Sigma[n:n+1, m_prime], target[ps2])#Z[m_prime:m_prime+1], Mu[n+m:(n+m)+1], Sigma[n+m:(n+m)+1], target[ps2]) - + if isinstance(p1, RBF) and isinstance(p2, RBF): psi12 = np.zeros((N, M)) p2.psi1(Z, mu, S, psi12) @@ -571,11 +570,11 @@ class kern(Parameterized): if isinstance(p1, RBF) and isinstance(p2, Linear): #import ipdb;ipdb.set_trace() pass - + p2.dpsi1_dtheta((dL_dpsi2*(psi11[:,:,None] + psi11[:,None,:])).reshape(NM,M), Z, Mu, Sigma, tmp2) - + target[ps1] += tmp1 - target[ps2] += tmp2 + target[ps2] += tmp2 else: raise NotImplementedError, "psi2 cannot be computed for this kernel" @@ -615,17 +614,17 @@ class kern(Parameterized): psi11 = np.zeros((N, M)) psi12 = np.zeros((NM, M)) #psi12_t = np.zeros((N,M)) - + p1.psi1(Z, mu, S, psi11) Mu, Sigma = p1._crossterm_mu_S(Z, mu, S) Mu, Sigma = Mu.reshape(NM,self.input_dim), Sigma.reshape(NM,self.input_dim) - + p2.psi1(Z, Mu, Sigma, psi12) tmp1 = np.zeros_like(target) p1.dpsi1_dZ((dL_dpsi2*psi12.reshape(N,M,M)).sum(1), Z, mu, S, tmp1) p1.dpsi1_dZ((dL_dpsi2*psi12.reshape(N,M,M)).sum(2), Z, mu, S, tmp1) target += tmp1 - + #p2.dpsi1_dtheta((dL_dpsi2*(psi11[:,:,None] + psi11[:,None,:])).reshape(NM,M), Z, Mu, Sigma, target) p2.dpsi1_dZ((dL_dpsi2*(psi11[:,:,None] + psi11[:,None,:])).reshape(NM,M), Z, Mu, Sigma, target) else: @@ -666,21 +665,21 @@ class kern(Parameterized): psi11 = np.zeros((N, M)) psi12 = np.zeros((NM, M)) #psi12_t = np.zeros((N,M)) - + p1.psi1(Z, mu, S, psi11) Mu, Sigma = p1._crossterm_mu_S(Z, mu, S) Mu, Sigma = Mu.reshape(NM,self.input_dim), Sigma.reshape(NM,self.input_dim) - + p2.psi1(Z, Mu, Sigma, psi12) p1.dpsi1_dmuS((dL_dpsi2*psi12.reshape(N,M,M)).sum(1), Z, mu, S, target_mu, target_S) p1.dpsi1_dmuS((dL_dpsi2*psi12.reshape(N,M,M)).sum(2), Z, mu, S, target_mu, target_S) - + #p2.dpsi1_dtheta((dL_dpsi2*(psi11[:,:,None] + psi11[:,None,:])).reshape(NM,M), Z, Mu, Sigma, target) p2.dpsi1_dmuS((dL_dpsi2*(psi11[:,:,None])).sum(1)*2, Z, Mu.reshape(N,M,self.input_dim).sum(1), Sigma.reshape(N,M,self.input_dim).sum(1), target_mu, target_S) else: raise NotImplementedError, "psi2 cannot be computed for this kernel" return target_mu, target_S - + def plot(self, x=None, plot_limits=None, which_parts='all', resolution=None, *args, **kwargs): if which_parts == 'all': which_parts = [True] * self.num_parts @@ -753,7 +752,7 @@ class Kern_check_model(Model): dL_dK = np.ones((X.shape[0], X.shape[0])) else: dL_dK = np.ones((X.shape[0], X2.shape[0])) - + self.kernel=kernel self.X = X self.X2 = X2 @@ -768,7 +767,7 @@ class Kern_check_model(Model): return False else: return True - + def _get_params(self): return self.kernel._get_params() @@ -783,7 +782,7 @@ class Kern_check_model(Model): def _log_likelihood_gradients(self): raise NotImplementedError, "This needs to be implemented to use the kern_check_model class." - + class Kern_check_dK_dtheta(Kern_check_model): """This class allows gradient checks for the gradient of a kernel with respect to parameters. """ def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): @@ -798,7 +797,7 @@ class Kern_check_dKdiag_dtheta(Kern_check_model): Kern_check_model.__init__(self,kernel=kernel,dL_dK=dL_dK, X=X, X2=None) if dL_dK==None: self.dL_dK = np.ones((self.X.shape[0])) - + def log_likelihood(self): return (self.dL_dK*self.kernel.Kdiag(self.X)).sum() @@ -815,7 +814,7 @@ class Kern_check_dK_dX(Kern_check_model): def _get_param_names(self): return ['X_' +str(i) + ','+str(j) for j in range(self.X.shape[1]) for i in range(self.X.shape[0])] - + def _get_params(self): return self.X.flatten() @@ -837,7 +836,7 @@ class Kern_check_dKdiag_dX(Kern_check_model): def _get_param_names(self): return ['X_' +str(i) + ','+str(j) for j in range(self.X.shape[1]) for i in range(self.X.shape[0])] - + def _get_params(self): return self.X.flatten() @@ -863,7 +862,6 @@ def kern_test(kern, X=None, X2=None, output_ind=None, verbose=False, X_positive= if output_ind is not None: assert(output_ind