| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- """
- This module contains some example Generative Adversarial Networks for testing.
- The classes StupidToyPointGan and StupidToyListGan are not really Networks. This classes are used
- for testing the interface. Hope your actually GAN will perform better than this two.
- The class SimpleGan is a simple standard Generative Adversarial Network.
- """
- import numpy as np
- import math
- from library.interfaces import GanBaseClass
- def square(x):
- return (x*x)
- def fold0(f, xs):
- if xs == []:
- return None
-
- s = xs[0]
- for x in xs[1:]:
- s = f(s, x)
- return s
- def fold1(f, s0, xs):
- if xs == []:
- return None
-
- s = s0
- for x in xs:
- s = f(s, x)
- return s
- def dist(x, y):
- return math.sqrt(fold1(lambda s, a: s + square(a[0] - a[1]), 0, list(zip(x, y))))
- def minDistPointToSet(x, setB):
- return fold0(lambda m,y: min(m,y), [dist(x,y) for y in setB])
- def minDistSetToSet(setA, setB):
- return fold0(lambda m,x: min(m, minDistPointToSet(x,setB)), setA)
- def normInf(xs):
- return fold0(lambda m, x: max(m, abs(x)), xs)
- def norm2Sq(xs):
- return fold0(lambda s, x: s + (x*x), xs)
- def norm2(xs):
- return math.sqrt(norm2Sq(xs))
- def minmax(xs):
- if xs == []:
- return None
-
- (mi, mx) = (xs[0][1], xs[0][1])
- for x in xs[1:]:
- mi = min(mi, x[1])
- mx = max(mx, x[1])
- return (mi, mx)
- def createSquare(pointCount, noiseSize):
- noise = [
- [np.random.uniform(-1.0, 1.0) for n in range(noiseSize)]
- for m in range(pointCount)
- ]
- return np.array(noise)
- def createDisc(pointCount, noiseSize):
- noise = []
- for n in range(pointCount):
- p = [np.random.uniform(-1.0, 1.0)]
- for m in range(noiseSize - 1):
- d = norm2Sq(p)
- d = math.sqrt(1.0 - d)
- p.append(np.random.uniform(0.0 - d, d))
- noise.append(p)
- return np.array(noise)
- class SpheredNoise(GanBaseClass):
- """
- A class for a simple GAN.
- """
- def __init__(self, noiseSize=101):
- self.isTrained = False
- self.noiseSize = noiseSize
- self.disc = []
- self.reset()
- def reset(self):
- """
- Resets the trained GAN to an random state.
- """
- self.pointDists = []
- self.nextId = 0
- self.numPoints = 0
- self.nextDiscPoint = 0
- self.minDist = 0.0
- def train(self, dataset):
- majoritySet = dataset.data0
- minoritySet = dataset.data1
- trainDataSize = minoritySet.shape[0]
- numOfFeatures = minoritySet.shape[1]
-
- print(f"Train {majoritySet.shape[0]}/{trainDataSize} points")
- if minoritySet.shape[0] <= 0 or majoritySet.shape[0] <= 0:
- raise AttributeError("Train: Expected each data class to contain at least one point.")
- if numOfFeatures <= 0:
- raise AttributeError("Train: Expected at least one feature.")
- print("-> new disc")
- self.disc = createDisc(self.noiseSize, minoritySet.shape[1])
- print("-> calc distances")
- self.pointDists = list(filter(lambda x: x[1] > 0.0, [(x, minDistPointToSet(x, majoritySet)) for x in minoritySet]))
- print("-> statistics")
- self.nextId = 0
- self.numPoints = len(self.pointDists)
- self.isTrained = True
- (minD, maxD) = minmax(self.pointDists)
- self.minDist = minD
- print(f"trained {trainDataSize} points min:{minD} max:{maxD}")
- def generateDataPoint(self):
- (x, d) = self.pointDists[self.nextId]
- self.nextId = (self.nextId + 1) % self.numPoints
- disc = (0.5 * self.minDist) * self.disc
- p = disc[self.nextDiscPoint]
- self.nextDiscPoint = (self.nextDiscPoint + 1) % disc.shape[0]
- return p
- def generateData(self, numOfSamples=1):
- return np.array([self.generateDataPoint() for n in range(numOfSamples)])
|