source: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceNeuralNetwork.cs @ 10489

Last change on this file since 10489 was 10489, checked in by gkronber, 6 years ago

#2125 fixed the bug that covariance functions returned the full gradient vector even when parameters are partially fixed.
changed the calculation of NN covariance and gradient to direct calculation (instead of AutoDiff)

File size: 6.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Linq.Expressions;
26using AutoDiff;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Algorithms.DataAnalysis {
34  [StorableClass]
35  [Item(Name = "CovarianceNeuralNetwork",
36    Description = "Neural network covariance function for Gaussian processes.")]
37  public sealed class CovarianceNeuralNetwork : ParameterizedNamedItem, ICovarianceFunction {
38    public IValueParameter<DoubleValue> ScaleParameter {
39      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
40    }
41
42    public IValueParameter<DoubleValue> LengthParameter {
43      get { return (IValueParameter<DoubleValue>)Parameters["Length"]; }
44    }
45    private bool HasFixedScaleParameter {
46      get { return ScaleParameter.Value != null; }
47    }
48    private bool HasFixedLengthParameter {
49      get { return LengthParameter.Value != null; }
50    }
51
52    [StorableConstructor]
53    private CovarianceNeuralNetwork(bool deserializing)
54      : base(deserializing) {
55    }
56
57    private CovarianceNeuralNetwork(CovarianceNeuralNetwork original, Cloner cloner)
58      : base(original, cloner) {
59    }
60
61    public CovarianceNeuralNetwork()
62      : base() {
63      Name = ItemName;
64      Description = ItemDescription;
65
66      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter."));
67      Parameters.Add(new OptionalValueParameter<DoubleValue>("Length", "The length parameter."));
68    }
69
70    public override IDeepCloneable Clone(Cloner cloner) {
71      return new CovarianceNeuralNetwork(this, cloner);
72    }
73
74    public int GetNumberOfParameters(int numberOfVariables) {
75      return
76        (HasFixedScaleParameter ? 0 : 1) +
77        (HasFixedLengthParameter ? 0 : 1);
78    }
79
80    public void SetParameter(double[] p) {
81      double scale, length;
82      GetParameterValues(p, out scale, out length);
83      ScaleParameter.Value = new DoubleValue(scale);
84      LengthParameter.Value = new DoubleValue(length);
85    }
86
87
88    private void GetParameterValues(double[] p, out double scale, out double length) {
89      // gather parameter values
90      int c = 0;
91      if (HasFixedLengthParameter) {
92        length = LengthParameter.Value.Value;
93      } else {
94        length = Math.Exp(2 * p[c]);
95        c++;
96      }
97
98      if (HasFixedScaleParameter) {
99        scale = ScaleParameter.Value.Value;
100      } else {
101        scale = Math.Exp(2 * p[c]);
102        c++;
103      }
104      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceNeuralNetwork", "p");
105    }
106
107
108    private static Func<Term, UnaryFunc> asin = UnaryFunc.Factory(
109        x => Math.Asin(x),      // evaluate
110        x => 1 / Math.Sqrt(1 - x * x));  // derivative of atan
111    private static Func<Term, UnaryFunc> sqrt = UnaryFunc.Factory(
112      x => Math.Sqrt(x),
113      x => 1 / (2 * Math.Sqrt(x)));
114
115    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
116      double length, scale;
117      GetParameterValues(p, out scale, out length);
118      var fixedLength = HasFixedLengthParameter;
119      var fixedScale = HasFixedScaleParameter;
120
121      var cov = new ParameterizedCovarianceFunction();
122      cov.Covariance = (x, i, j) => {
123        double sx = 1.0;
124        double s1 = 1.0;
125        double s2 = 1.0;
126        foreach (var col in columnIndices) {
127          sx += x[i, col] * x[j, col];
128          s1 += x[i, col] * x[i, col];
129          s2 += x[j, col] * x[j, col];
130        }
131
132        return (scale * Math.Asin(sx / (Math.Sqrt((length + s1) * (length + s2)))));
133      };
134      cov.CrossCovariance = (x, xt, i, j) => {
135        double sx = 1.0;
136        double s1 = 1.0;
137        double s2 = 1.0;
138        foreach (var col in columnIndices) {
139          sx += x[i, col] * xt[j, col];
140          s1 += x[i, col] * x[i, col];
141          s2 += xt[j, col] * xt[j, col];
142        }
143
144        return (scale * Math.Asin(sx / (Math.Sqrt((length + s1) * (length + s2)))));
145      };
146      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, length, scale, columnIndices, fixedLength, fixedScale);
147      return cov;
148    }
149
150    // order of returned gradients must match the order in GetParameterValues!
151    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double length, double scale, IEnumerable<int> columnIndices,
152      bool fixedLength, bool fixedScale) {
153      {
154        double sx = 1.0;
155        double s1 = 1.0;
156        double s2 = 1.0;
157        foreach (var col in columnIndices) {
158          sx += x[i, col] * x[j, col];
159          s1 += x[i, col] * x[i, col];
160          s2 += x[j, col] * x[j, col];
161        }
162        var h = (length + s1) * (length + s2);
163        var f = sx / Math.Sqrt(h);
164        if (!fixedLength) {
165          yield return -scale / Math.Sqrt(1.0 - f * f) * ((length * sx * (2.0 * length + s1 + s2)) / Math.Pow(h, 3.0 / 2.0));
166        }
167        if (!fixedScale) {
168          yield return 2.0 * scale * Math.Asin(f);
169        }
170
171      };
172    }
173
174  }
175}
Note: See TracBrowser for help on using the repository browser.