activeLearningGPGenKprototype.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. import math
  2. import scipy
  3. import numpy
  4. import sklearn.kernel_ridge
  5. import sys
  6. import os
  7. sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)),os.pardir))
  8. import helperFunctions
  9. class ClassifierPrototype:
  10. def __init__(self, sigmaN=0.01, gamma=None, kernel='rbf', configFile=None, probSampleRuns=1000):
  11. self.sigmaN = helperFunctions.getConfig(configFile, 'activeLearning', 'sigmaN', sigmaN, 'float', True)
  12. self.kernel = helperFunctions.getConfig(configFile, 'activeLearning', 'kernel', kernel, 'str', True)
  13. self.gamma = helperFunctions.getConfig(configFile, 'activeLearning', 'gamma', gamma, 'float', True)
  14. self.numKernelCores = helperFunctions.getConfig(configFile, 'activeLearning', 'numKernelCores', 1, 'int', True)
  15. self.probSampleRuns = helperFunctions.getConfig(configFile, 'activeLearning', 'probSampleRuns', probSampleRuns, 'float', True)
  16. self.K = []
  17. self.alpha = []
  18. self.X = []
  19. self.y = []
  20. self.yBin = []
  21. self.yUni = []
  22. self.allowedKernels = ['rbf', 'sigmoid', 'polynomial', 'poly', 'linear', 'cosine']
  23. if self.kernel not in self.allowedKernels:
  24. raise Exception('Unknown kernel %s!'%self.kernel)
  25. def kernelFunc(self, x1, x2=None, gamma=None):
  26. if gamma is not None:
  27. self.gamma = gamma
  28. if self.kernel in ['rbf']:
  29. return numpy.asmatrix(sklearn.kernel_ridge.pairwise_kernels(x1, x2, metric=self.kernel, gamma=self.gamma, n_jobs=self.numKernelCores), dtype=numpy.float)
  30. else:
  31. return numpy.asmatrix(sklearn.kernel_ridge.pairwise_kernels(x1, x2, metric=self.kernel, n_jobs=self.numKernelCores), dtype=numpy.float)
  32. def checkModel(self):
  33. if not numpy.all(numpy.isfinite(self.K)):
  34. raise Exception('not numpy.all(numpy.isfinite(self.K))')
  35. if not numpy.all(numpy.isfinite(self.alpha)):
  36. raise Exception('not numpy.all(numpy.isfinite(self.alpha))')
  37. if not numpy.all(numpy.isfinite(self.X)):
  38. raise Exception('not numpy.all(numpy.isfinite(self.X))')
  39. if not numpy.all(numpy.isfinite(self.y)):
  40. raise Exception('not numpy.all(numpy.isfinite(self.y))')
  41. def train2(self, X, y, sigmaN=None):
  42. self.train(X[0,:],y[0,:],sigmaN)
  43. for idx in range(1,X.shape[0]):
  44. self.update(X[idx,:],y[idx,:])
  45. def train(self, X, y, sigmaN=None, gamma=None, kernel=None, numKernelCores=None):
  46. if sigmaN is not None:
  47. self.sigmaN = sigmaN
  48. if gamma is not None:
  49. self.gamma = gamma
  50. if kernel is not None and kernel in self.allowedKernels:
  51. self.kernel = kernel
  52. if numKernelCores is not None:
  53. self.numKernelCores = numKernelCores
  54. self.X = X
  55. self.y = y
  56. self.yUni = numpy.asmatrix(numpy.unique(numpy.asarray(self.y)))
  57. tmpVec = numpy.asmatrix(numpy.empty([self.y.shape[0],1]))
  58. self.yBin = numpy.asmatrix(numpy.empty([self.y.shape[0],self.yUni.shape[1]]))
  59. for cls in range(self.yUni.shape[1]):
  60. mask = (self.y == self.yUni[0,cls])
  61. tmpVec[mask == True] = 1
  62. tmpVec[mask == False] = -1
  63. self.yBin[:,cls] = tmpVec
  64. self.K = numpy.dot(X,X.T)
  65. self.alpha = numpy.linalg.solve(numpy.add(self.K, numpy.identity(self.X.shape[0], dtype=numpy.float)*self.sigmaN), self.yBin)
  66. self.checkModel()
  67. def update(self, x, y):
  68. # update for known classes
  69. binY = numpy.asmatrix(numpy.ones((1,self.alpha.shape[1])))*(-1)
  70. if self.alpha.shape[1] > 1:
  71. binY[0,numpy.asarray(numpy.squeeze(numpy.asarray(y == self.yUni)))] = 1
  72. elif y == self.yUni:
  73. binY[0,0] = 1
  74. # get new kernel columns
  75. k = self.kernelFunc(self.X, x)
  76. selfK = self.getSelfK(x)
  77. # update alpha
  78. term1 = 1.0 / (self.sigmaN + self.calcSigmaF(x, k, selfK).item(0))
  79. term2 = numpy.asmatrix(numpy.ones((self.X.shape[0] + 1,x.shape[0])), dtype=numpy.float) * (-1.0)
  80. term2[0:self.X.shape[0],:] = numpy.linalg.solve(numpy.add(self.K, numpy.identity(self.X.shape[0], dtype=numpy.float)*self.sigmaN), k)
  81. term3 = self.infer(x, k=k) - binY
  82. self.alpha = numpy.add(numpy.append(self.alpha, numpy.zeros((1,self.alpha.shape[1])), axis=0), numpy.dot(numpy.dot(term1,term2),term3))
  83. # update K
  84. self.K = numpy.append(numpy.append(self.K, k, axis=1), numpy.append(k.T, selfK, axis=1), axis=0)
  85. # update samples
  86. self.X = numpy.append(self.X, x, axis=0)
  87. self.y = numpy.append(self.y, y, axis=0)
  88. # update binary labels for knwon class
  89. if (self.yUni == y).any():
  90. mask = (y == self.yUni)
  91. tmpVec = numpy.empty([self.yBin.shape[1], 1])
  92. tmpVec[mask.T == True] = 1
  93. tmpVec[mask.T == False] = -1
  94. self.yBin = numpy.append(self.yBin, tmpVec.T, axis=0)
  95. # create labels and alpha for new class
  96. else:
  97. # create bigger matrices
  98. tmpyBin = numpy.asmatrix(numpy.empty([self.yBin.shape[0] + 1, self.yBin.shape[1] + 1]))
  99. tmpAlpha = numpy.asmatrix(numpy.empty([self.alpha.shape[0], self.alpha.shape[1] + 1]))
  100. # index of new class
  101. tmpIdx = -1
  102. # check all knwon classes
  103. for cls in range(self.yUni.shape[1]):
  104. # just copy all classes with lower label
  105. if y > self.yUni[0,cls]:
  106. tmpyBin[0:-1,cls] = self.yBin[:,cls]
  107. tmpyBin[tmpyBin.shape[0] - 1,cls] = -1
  108. tmpAlpha[:,cls] = self.alpha[:,cls]
  109. tmpIdx = cls
  110. # copy classes with higher label to shiftet position
  111. else: # y < self.yUni[cls]
  112. tmpyBin[0:-1,cls + 1] = self.yBin[:,cls]
  113. tmpyBin[tmpyBin.shape[0] - 1,cls + 1] = -1
  114. tmpAlpha[:,cls + 1] = self.alpha[:,cls]
  115. # add new binary label vector for new class
  116. tmpyBin[0:-1,tmpIdx + 1] = -1
  117. tmpyBin[tmpyBin.shape[0] - 1,tmpIdx + 1] = 1
  118. # set new binary matrix and append new label
  119. self.yBin = tmpyBin
  120. self.yUni = numpy.sort(numpy.append(self.yUni, y, axis=1))
  121. # train new alpha for new class
  122. tmpAlpha[:,tmpIdx + 1] = numpy.linalg.solve(numpy.add(self.K, numpy.identity(self.X.shape[0], dtype=numpy.float)*self.sigmaN), self.yBin[:,tmpIdx + 1])
  123. self.alpha = tmpAlpha
  124. self.checkModel()
  125. # X.shape = (number of samples, feat dim), loNoise = {0,1}
  126. def infer(self, x, loNoise=False, k=None):
  127. if k is None:
  128. k = self.kernelFunc(self.X, x)
  129. loNoise = loNoise and (self.yUni == -1).any()
  130. pred = numpy.asmatrix(numpy.dot(k.T,self.alpha[:,int(loNoise):]))
  131. if not numpy.all(numpy.isfinite(pred)):
  132. raise Exception('not numpy.all(numpy.isfinite(pred))')
  133. return pred
  134. # X.shape = (number of samples, feat dim)
  135. def test(self, x, loNoise=False):
  136. loNoise = loNoise and (self.yUni == -1).any()
  137. return self.yUni[0,numpy.argmax(self.infer(x, loNoise), axis=1) + int(loNoise)]
  138. def calcSigmaF(self, x, k=None, selfK=None):
  139. if k is None:
  140. k = self.kernelFunc(self.X, x)
  141. if selfK is None:
  142. selfK = self.getSelfK(x)
  143. sigmaF = numpy.subtract(selfK, numpy.sum(numpy.multiply(numpy.linalg.solve(numpy.add(self.K, numpy.identity(self.X.shape[0], dtype=numpy.float)*self.sigmaN), k),k).T, axis=1))
  144. if not numpy.all(numpy.isfinite(sigmaF)):
  145. raise Exception('not numpy.all(numpy.isfinite(sigmaF))')
  146. return sigmaF
  147. def getSelfK(self, x):
  148. selfK = numpy.asmatrix(numpy.empty([x.shape[0],1], dtype=numpy.float))
  149. for idx in range(x.shape[0]):
  150. selfK[idx,:] = self.kernelFunc(x[idx,:])
  151. return selfK
  152. # X.shape = (number of samples, feat dim)
  153. def calcProbs(self, x, mu=None, sigmaF=None, nmb=None):
  154. # set number of sampling iterations
  155. if nmb is None:
  156. nmb = self.probSampleRuns
  157. # get mu and sigma
  158. if mu is None:
  159. mu = self.infer(x)
  160. if sigmaF is None:
  161. sigmaF = self.calcSigmaF(x)
  162. # prepare
  163. probs = numpy.asmatrix(numpy.zeros(mu.shape))
  164. for idx in range(nmb):
  165. draws = numpy.asmatrix(numpy.random.randn(mu.shape[0],mu.shape[1]))
  166. draws = numpy.add(numpy.multiply(draws, numpy.repeat(sigmaF, draws.shape[1], axis=1)), mu)
  167. maxIdx = numpy.argmax(draws, axis=1)
  168. idxs = (range(len(maxIdx)),numpy.squeeze(maxIdx))
  169. probs[idxs] = probs[idxs] + 1
  170. # convert absolute to relative amount
  171. return probs/float(nmb)
  172. # x.shape = (feat dim, number of samples)
  173. def calcAlScores(self, x):
  174. return None
  175. # x.shape = (feat dim, number of samples)
  176. def getAlScores(self, x):
  177. alScores = self.calcAlScores(x)
  178. if not numpy.all(numpy.isfinite(alScores)):
  179. raise Exception('not numpy.all(numpy.isfinite(alScores))')
  180. if alScores.shape[0] != x.shape[0] or alScores.shape[1] != 1:
  181. raise Exception('alScores.shape[0] != x.shape[0] or alScores.shape[1] != 1')
  182. return alScores
  183. # x.shape = (feat dim, number of samples)
  184. def chooseSample(self, x):
  185. return numpy.argmax(self.getAlScores(x), axis=0).item(0)