Exemple #1
0
def computecost(model, data, targets, lossname):
    """compute predictions and cost
    """
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.ffn import FFN

    #get predictions
    if isinstance(model, FFN):
        pred = data
        #pre fwd prop if any
        if model.pre is not None:
            pred, _ = fwdprop(pred, model.pre)

        #body fwd prop
        pred, _ = fwdprop(pred, model.body)

        #post fwd prop if any
        if model.post is not None:
            pred, _ = fwdprop(pred, model.post)

    #ELSE IF model is not FFN object then simply fwd prop to get predictions
    else:
        pred, _ = fwdprop(data, model)

    #calculate cost based on predictions
    cost, _ = loss(lossname, pred, targets)

    #return predictions and cost
    return pred, cost
Exemple #2
0
 def get_target_value(self, state):
     # target network input: array of 6 values representing metabolite conc. and time horizon
     #  output: Value of anticipated return at time horizon from current state
     pred1, _ = fwdprop(state, self.targetnet1)
     pred2, _ = fwdprop(state, self.targetnet2)
     pred3, _ = fwdprop(state, self.targetnet3)
     pred4, _ = fwdprop(state, self.targetnet4)
     #stack predictions
     predstack = np.stack((pred1, pred2, pred3, pred4), axis=-1)
     predmin = np.amin(predstack, axis=2)
     predmax = np.amax(predstack, axis=2)
     # Return weighted average (ala BEAR alg, Kumar, 2019)
     return .75 * predmin + .25 * predmax
Exemple #3
0
def computeforces(model, data, targets, lossname):
    """compute forces on weights and biases
    """
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.backprop import backprop
    from crpm.ffn import FFN

    if isinstance(model, FFN):
        pred = data
        #pre fwd prop if any
        if model.pre is not None:
            pred, _ = fwdprop(pred, model.pre)

        #body fwd prop
        pred, state = fwdprop(pred, model.body)
        logit = state[-1]["stimulus"]
        activation = model.body[-1]["activation"]

        #post fwd prop if any
        if model.post is not None:
            pred, poststate = fwdprop(pred, model.post)
            logit = poststate[-1]["stimulus"]
            activation = model.post[-1]["activation"]

        #turn off from-logit if final layer was not logit and loss name is not bce
        if not (activation == "logit" and lossname == "bce"):
            logit = None
        #get derivative of loss function
        _, dloss = loss(lossname, pred, targets, logit)

        #post back prop if any
        if model.post is not None:
            _, dloss = backprop(model.post, poststate, dloss)

        #body back prop to get forces
        forces, _ = backprop(model.body, state, dloss)

        #return FFN forces
        return forces

    #If not FFN object then simply return body forces
    pred, state = fwdprop(data, model)
    #turn off from-logit if final layer was not logit with bce lossfunction
    if not (model[-1]["activation"] == "logit" and lossname == "bce"):
        logit = None
    _, dloss = loss(lossname, pred, targets, logit)
    forces, _ = backprop(model, state, dloss)
    return forces
Exemple #4
0
def test_fwdprop_numberadder():
    """test that unit weights will make a number adder.
    """
    import numpy as np
    from crpm.ffn_bodyplan import read_bodyplan
    from crpm.ffn_bodyplan import init_ffn
    from crpm.dataset import load_dataset
    from crpm.fwdprop import fwdprop

    #create shallow bodyplan with 5 inputs and 1 output for number adder data
    bodyplan = read_bodyplan("crpm/data/numberadder_bodyplan.csv")

    #create model
    model = init_ffn(bodyplan)

    #manually set layer 1 weights to 1 and biases to 0
    model[1]["weight"] = np.ones(model[1]["weight"].shape)

    #run forward propagation with example data in numberadder.csv
    __, data = load_dataset("crpm/data/numberadder.csv")
    indepvars = data[0:5, ]
    depvars = data[-1, ]
    prediction, __ = fwdprop(indepvars, model)

    assert np.allclose(depvars, prediction, rtol=1E-7)
def test_solve_nestedcs_bce():
    """test nested cs can be solved
    """
    import numpy as np
    from crpm.setup_nestedcs import setup_nestedcs
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.gradientdecent import gradientdecent

    #init numpy seed
    np.random.seed(40017)

    #setup model
    model, data = setup_nestedcs()

    #calculate initial binary cross entropy error
    pred, _ = fwdprop(data[0:2, ], model)
    icost, _ = loss("bce", pred, data[-1, ])

    #train model
    pred, cost, _ = gradientdecent(model, data[0:2, ], data[-1, ], "bce")

    #print(model)
    #print(icost)
    #print(cost)
    assert icost > cost
    assert cost < .29
def test_solve_nestedcs_bce():
    """test nested cs can be solved
    """
    import numpy as np
    from crpm.setup_nestedcs import setup_nestedcs
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.langevindynamics import langevindynamics

    #init numpy seed
    np.random.seed(40017)

    #setup model
    model, data = setup_nestedcs()

    #calculate initial binary cross entropy error
    pred, __ = fwdprop(data[0:2,], model)
    icost, __ = loss("bce", pred, data[-1,])

    #train model
    pred, cost = langevindynamics(model, data[0:2,], data[-1,], "bce",
                                  maxepoch=int(2E3), maxbuffer=int(1E2))

    #print(model)
    #print(icost)
    #print(cost)
    assert icost > cost
    assert cost < .29
Exemple #7
0
def test_numadd_forcedir():
    """test that number adder with initial wieghts >1 will have negative forces.
    """
    import numpy as np
    from crpm.ffn_bodyplan import read_bodyplan
    from crpm.ffn_bodyplan import init_ffn
    from crpm.dataset import load_dataset
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.backprop import backprop

    #create shallow bodyplan for numberadder.csv data
    bodyplan = read_bodyplan("crpm/data/numberadder_bodyplan.csv")

    #create numberadder model
    addermodel = init_ffn(bodyplan)

    #manually set layer 1 weights to 1.1 and biases to 0
    addermodel[1]["weight"] = 1.1 * np.ones(addermodel[1]["weight"].shape)

    #compute forces using numberadder.csv data with mean squared error
    __, data = load_dataset("crpm/data/numberadder.csv")
    pred, state = fwdprop(data[0:5,], addermodel)
    __, dloss = loss("mse", pred, data[-1,])
    forces, _ = backprop(addermodel, state, dloss)

    assert np.all(forces[-1]["fweight"] < 0)
Exemple #8
0
def test_backprop_numberadder():
    """test that solved number adder will have zero forces with proper shape.
    """
    import numpy as np
    from crpm.ffn_bodyplan import read_bodyplan
    from crpm.ffn_bodyplan import init_ffn
    from crpm.dataset import load_dataset
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.backprop import backprop

    #create shallow bodyplan for numberadder.csv data
    bodyplan = read_bodyplan("crpm/data/numberadder_bodyplan.csv")

    #create numberadder model
    addermodel = init_ffn(bodyplan)

    #manually set layer 1 weights to 1 and biases to 0
    addermodel[1]["weight"] = np.ones(addermodel[1]["weight"].shape)

    #compute forces using numberadder.csv data with mean squared error
    __, data = load_dataset("crpm/data/numberadder.csv")
    pred, state = fwdprop(data[0:5,], addermodel)
    __, dloss = loss("mse", pred, data[-1,])
    forces, _ = backprop(addermodel, state, dloss)

    assert forces[-1]["fweight"].shape == (1, 5)
    assert np.allclose(1+forces[-1]["fweight"], 1, rtol=1E-7)
    assert forces[-1]["fbias"].shape == (1, 1)
    assert np.allclose(1+forces[-1]["fbias"], 1, rtol=1E-7)
Exemple #9
0
def r_test_som2d_init_pca():
    """test inital node coordinates for 2D SOM follow known PCA for nested Cs data.

    We know for Nested Cs data - first 2 PCs point roughly in x and y directions
    """

    import numpy as np
    from crpm.setup_nestedcs import setup_nestedcs
    from crpm.fwdprop import fwdprop
    from crpm.som import init_som
    from crpm.som import som

    #init numpy seed
    np.random.seed(40017)

    #setup model with nested Cs
    model, data = setup_nestedcs()

    #update state of model
    _, state = fwdprop(data[0:2, ], model)

    #create and init 2D map with model and its current state
    map, _ = init_som(model, state, n=100, nx=10, ny=10, hcp=True)

    #check nodes map to points along x and y direction with reasonable span
    xmin = min(data[0, ])
    xmax = max(data[0, ])
    xvar = np.var(data[0, ])
    wxmin = min(map[-1]["weight"][:, 0])
    wxmax = max(map[-1]["weight"][:, 0])
    wxdel = map[-1]["weight"][-1, 0] - map[-1]["weight"][0, 0]
    ymin = min(data[1, ])
    ymax = max(data[1, ])
    yvar = np.var(data[1, ])
    wymin = min(map[-1]["weight"][:, 1])
    wymax = max(map[-1]["weight"][:, 1])
    wydel = map[-1]["weight"][-1, 1] - map[-1]["weight"][0, 1]
    slope = (ymax - ymin) / (xmax - xmin)

    #assert nodes point in the correct x direction
    assert (np.sign(wxmax - wxmin) == np.sign(xmax - xmin))
    #assert nodes point in the correct y direction
    assert (np.sign(wymax - wymin) == np.sign(ymax - ymin))
    #assert fist and last nodes point with slope similar to data range
    assert (abs(wydel / wxdel - slope) / slope < 0.4)
    #asset span of x points is comperable to span of input x points
    assert (abs(np.var(map[-1]["weight"][:, 0]) - xvar) / xvar < 1.0)
    #asset span of y points is comperable to span of input y points
    assert (abs(np.var(map[-1]["weight"][:, 1]) - yvar) / yvar < 1.0)
def test_solve_numberadder():
    """test number adder can be solved begining with init weights set
    """
    import numpy as np
    from crpm.ffn_bodyplan import read_bodyplan
    from crpm.dataset import load_dataset
    from crpm.ffn_bodyplan import init_ffn
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.langevindynamics import langevindynamics


    #load data
    __, data = load_dataset("crpm/data/numberadder.csv")
    __, testdata = load_dataset("crpm/data/numberadder_test.csv")

    #create shallow bodyplan with 5 inputs and 1 output for numebr adder data
    bodyplan = read_bodyplan("crpm/data/numberadder_bodyplan.csv")

    #create numberadder model
    model = init_ffn(bodyplan)

    #manually set layer weights to 1.5 and biases to 0
    model[1]["weight"] = 1.5*np.ones(model[1]["weight"].shape)

    #calculate initial mean squared error
    pred, __ = fwdprop(data[0:5,], model)
    icost, __ = loss("mse", pred, data[-1,])
    print("icost = "+str(icost))
    print(model[1]["weight"])

    #train numberadder model  with mean squared error
    __, cost = langevindynamics(model, data[0:5,], data[-1,],
                                "mse", testdata[0:5,], testdata[-1,],
                                maxepoch=int(3E5), maxbuffer=int(1E3))
    print("cost ="+str(cost))
    print(model[1]["weight"])

    assert icost > cost
    assert np.allclose(model[1]["weight"], 1.0, rtol=.005)
Exemple #11
0
def test_som1d_init_pca():
    """test inital node coordinates for 1D SOM follow known PCA for nested Cs data.

    We know for Nested Cs data - first 2 PCs point roughly in x and y directions
    """

    import numpy as np
    from crpm.setup_nestedcs import setup_nestedcs
    from crpm.fwdprop import fwdprop
    from crpm.som import init_som
    from crpm.som import som

    #init numpy seed
    np.random.seed(40017)

    #setup model with nested Cs
    model, data = setup_nestedcs()

    #update state of model
    _, state = fwdprop(data[0:2, ], model)

    #create and init 1D map with model and its current state
    map, _ = init_som(model, state)

    #check nodes map to points along x direction with reasonable span
    xmin = min(data[0, ])
    xmax = max(data[0, ])
    wmin = min(map[-1]["weight"][:, 0])
    wmax = max(map[-1]["weight"][:, 0])
    xvar = np.var(data[0, ])
    #assert nodes point in the correct x direction
    assert (np.sign(wmax - wmin) == np.sign(xmax - xmin))
    #asset span of x points is comperable to span of input x points
    assert (abs(np.var(map[-1]["weight"][:, 0]) - xvar) / xvar < 1.0)
    #assert node points have no (little) y component
    assert (np.var(map[-1]["weight"][:, 1]) < 0.1)
Exemple #12
0
def r_test_spectra2():
    """test spectra2 can be encoded and generated
    """

    import numpy as np
    from crpm.setup_spectra2 import setup_spectra2
    from crpm.dynamics import computecost
    from crpm.analyzebinaryclassifier import analyzebinaryclassifier
    #from crpm.lossfunctions import loss
    #from crpm.analyzebinaryclassifier import plotroc
    from crpm.gradientdecent import gradientdecent
    from crpm.contrastivedivergence import contrastivedivergence
    #from crpm.ffn import FFN
    from crpm.ffn_bodyplan import stack_new_layer
    from crpm.ffn_bodyplan import copy_ffn
    from crpm.fwdprop import fwdprop
    from crpm.backprop import backprop
    #from crpm.dynamics import computeforces
    #from crpm.dynamics import maxforce

    from crpm.gan import gan
    #import matplotlib
    #matplotlib.use('TkAgg')
    #import matplotlib.pyplot as plt

    #init numpy seed
    np.random.seed(40017)

    #setup model
    prototype, data = setup_spectra2()

    #get prototype depth
    nlayer = len(prototype)

    #get data dimensions
    nfeat = data.shape[0]
    nobv = data.shape[1]

    #zscore data
    tdata = np.divide(data - np.mean(data, axis=1, keepdims=True),
                      np.std(data, axis=1, keepdims=True))

    #transform features into boltzmann like probs
    #tdata = np.exp(-data)
    #partfunc = np.sum(tdata, axis=1, keepdims = True)
    #tdata = np.divide(tdata,partfunc) #normalize
    #tdata = np.divide(tdata, np.max(tdata, axis=1, keepdims=True))#scale features by maxintensity

    #plt.plot(data[:,0])
    #plt.show()
    #plt.plot(tdata[:,0])
    #plt.show()
    #data = tdata

    #partition data (labels on first row)
    ntrain = 2 * nobv // 3
    target = data[0, :ntrain]
    train = data[1:, :ntrain]
    vtarget = data[0, ntrain:]
    valid = data[1:, ntrain:]

    #return untrained autoencoder
    _, autoencoder = contrastivedivergence(prototype, train, maxepoch=0)

    #calculate initial reconstruction error
    pred, ireconerr = computecost(autoencoder, valid, valid, "mse")
    print("init recon error = " + str(ireconerr))

    ##train prototype
    #_, autoencoder = contrastivedivergence(prototype, train,
    #                                       ncd=2,
    #                                       batchsize=50,
    #                                       nadj=10,
    #                                       maxepoch=100,
    #                                       momentum=0.1)
    #train prototype
    _, autoencoder = contrastivedivergence(prototype,
                                           train,
                                           validata=valid,
                                           ncd=1,
                                           batchsize=50,
                                           nadj=10,
                                           maxepoch=100,
                                           momentum=0.0)

    #calculate final reconstruction error
    pred, reconerr = computecost(autoencoder, valid, valid, "mse")
    print("pretrained recon error = " + str(reconerr))

    #assert learning is taking place by reduced recon error.
    assert ireconerr > reconerr

    # ----- Discriminator -----
    #create discriminator
    discriminator = copy_ffn(autoencoder[0:len(prototype)])
    discriminator = stack_new_layer(discriminator, n=1, activation="logistic")
    #analyze trained binary classifier
    pred, icost = computecost(discriminator, valid, vtarget, "bce")
    roc, ireport = analyzebinaryclassifier(pred, vtarget)
    if ireport["AreaUnderCurve"] < .5:
        #flip labels
        pred, icost = computecost(discriminator, valid, 1 - vtarget, "bce")
        roc, ireport = analyzebinaryclassifier(pred, 1 - vtarget)
    print(ireport)
    #plotroc(roc)

    #train discriminator
    pred, cost, _ = gradientdecent(discriminator,
                                   train,
                                   target,
                                   "bce",
                                   valid,
                                   vtarget,
                                   earlystop=True,
                                   finetune=6)

    #analyze trained binary classifier
    pred, cost = computecost(discriminator, valid, vtarget, "bce")
    roc, report = analyzebinaryclassifier(pred, vtarget)
    if report["AreaUnderCurve"] < .5:
        #flip labels
        pred, cost = computecost(discriminator, valid, 1 - vtarget, "bce")
        roc, report = analyzebinaryclassifier(pred, 1 - vtarget)
    print(report)
    #plotroc(roc)

    #assert discriminator can be trained by binary cross entropy error
    assert icost > cost

    #assert discriminator has potential to iden two calsses
    assert report["AreaUnderCurve"] > ireport["AreaUnderCurve"]
    #assert report["AreaUnderCurve"] > .6

    # ----- generator -----

    #create generator from decoder
    generator = copy_ffn(autoencoder[len(prototype):len(autoencoder)])

    #adjust regularization
    for layer in generator:
        layer["regval"] = 0  #.00001

    #correct label idecies
    idx = 0
    for layer in generator:
        generator[idx]["layer"] = idx
        idx += 1

    #generate fake samples
    nfake = 600
    ncode = generator[0]["n"]
    fake, _ = fwdprop(np.random.rand(ncode, nfake), generator)

    #calculate initial reconstruction error
    pred, fkreconerr = computecost(autoencoder, fake, fake, "mse")
    print("init fake recon error = " + str(fkreconerr))

    #assert fake data recon error is better than untrained recon error
    assert fkreconerr < ireconerr

    #-- Start GAN training---

    ganerr = gan(generator,
                 discriminator,
                 train,
                 maxepoch=20000,
                 batchsize=50,
                 finetune=6.3)

    #assert generator fools discriminator at least some of the time bce<80%.
    assert ganerr[-1, 1] < .8

    #def moving_average(a, n=3) :
    #    ret = np.cumsum(a, dtype=float)
    #    ret[n:] = ret[n:] - ret[:-n]
    #    return ret[n - 1:] / n

    #fig = plt.figure()
    #plt.plot(ganerr[:, 0], ganerr[:, 1])
    #plt.plot(moving_average(ganerr[:, 0], n=20), moving_average(ganerr[:, 1], n=20))
    #plt.plot(ganerr[0, 0], ganerr[0, 1], marker="D", color="green", markersize=10)
    #plt.plot(ganerr[-1, 0], ganerr[-1, 1], marker="8", color="red", markersize=10)
    #plt.xlabel("discriminator error")
    #plt.ylabel("generator error")
    #plt.show()

    #print("final report")
    #print(report)
    #plotroc(roc)

    assert False
Exemple #13
0
def test_afnetwork():
    """test AF network patients can be encoded and generated
    """
    #import matplotlib
    #matplotlib.use('TkAgg')
    #import matplotlib.pyplot as plt
    #import matplotlib.patches as mpatches

    import numpy as np
    from crpm.setup_afmodel import setup_afmodel

    from crpm.dynamics import computecost
    from crpm.analyzebinaryclassifier import analyzebinaryclassifier
    #from crpm.lossfunctions import loss
    from crpm.analyzebinaryclassifier import plotroc
    from crpm.gradientdecent import gradientdecent
    from crpm.contrastivedivergence import contrastivedivergence
    #from crpm.ffn import FFN
    from crpm.ffn_bodyplan import stack_new_layer
    from crpm.ffn_bodyplan import copy_ffn
    from crpm.fwdprop import fwdprop
    #from crpm.backprop import backprop
    #from crpm.dynamics import computeforces
    #from crpm.dynamics import maxforce

    from crpm.gan import gan

    #init numpy seed
    np.random.seed(40017)

    #setup model
    prototype, train, target, valid, vtarget = setup_afmodel()

    #trim data
    #maxobv = 150
    #train = train[:,:maxobv]
    #valid = valid[:,:maxobv]
    #target = target[:maxobv]
    #vtarget = vtarget[:maxobv]

    #get prototype depth
    nlayer = len(prototype)

    #get data dimensions
    nfeat = train.shape[0]
    nobv = train.shape[1]

    #return untrained autoencoder
    _, autoencoder = contrastivedivergence(prototype, train, maxepoch=0)

    # ----- Discriminator -----

    #create discriminator
    discriminator = copy_ffn(autoencoder[0:len(prototype)])
    discriminator = stack_new_layer(discriminator, n=1, activation="logistic")

    print("analyze untrained discriminator to iden subtype")
    pred, icost = computecost(discriminator, valid, vtarget, "bce")
    roc, ireport = analyzebinaryclassifier(pred, vtarget)
    if ireport["AreaUnderCurve"] < .5:
        #flip labels
        pred, icost = computecost(discriminator, valid, 1 - vtarget, "bce")
        roc, ireport = analyzebinaryclassifier(pred, 1 - vtarget)
    print(ireport)
    #plotroc(roc)

    #train discriminator
    pred, cost, _ = gradientdecent(discriminator,
                                   train,
                                   target,
                                   "bce",
                                   valid,
                                   vtarget,
                                   earlystop=True,
                                   finetune=7)

    print("analyze trained discriminator to iden subtype")
    pred, cost = computecost(discriminator, valid, vtarget, "bce")
    roc, report = analyzebinaryclassifier(pred, vtarget)
    if report["AreaUnderCurve"] < .5:
        #flip labels
        pred, cost = computecost(discriminator, valid, 1 - vtarget, "bce")
        roc, report = analyzebinaryclassifier(pred, 1 - vtarget)
    print(report)
    #plotroc(roc)

    #assert discriminator can be trained by binary cross entropy error
    #assert icost > cost

    #assert discriminator has potential to iden two classes
    #assert report["AreaUnderCurve"] > ireport["AreaUnderCurve"]
    #assert report["AreaUnderCurve"] > .55

    # ----- GENERATOR -----

    #create generator from decoder
    generator = copy_ffn(autoencoder[len(prototype) - 1:len(autoencoder)])

    #correct label idecies
    idx = 0
    for layer in generator:
        generator[idx]["layer"] = idx
        idx += 1

    #assert False
    #-- Main GAN training---
    #ganerr = gan(generator, discriminator, train,
    #                   maxepoch=100000, batchsize=1, finetune=6)
    ganerr = gan(generator,
                 discriminator,
                 train,
                 maxepoch=100000,
                 batchsize=1,
                 finetune=6)

    #def moving_average(a, n=3) :
    #    ret = np.cumsum(a, dtype=float)
    #    ret[n:] = ret[n:] - ret[:-n]
    #    return ret[n - 1:] / n

    #ganerr[:,2] = np.log(ganerr[:,2]) #plot density error on logscale
    #discerrbar = moving_average(ganerr[:, 0], n=20)
    #generrbar = moving_average(ganerr[:, 1], n=20)
    #autoerrbar = moving_average(ganerr[:, 2], n=20)

    #assert generator fools discriminator at least some of the time bce<65%.
    print(ganerr[-1, 1])
    assert ganerr[-1, 1] < .65

    #fig = plt.figure()
    #plt.plot(ganerr[:, 0], ganerr[:, 1])
    #plt.plot(discerrbar, generrbar)
    #plt.plot(discerrbar[0], generrbar[0], marker="D", color="green", markersize=10)
    #plt.plot(discerrbar[-1], generrbar[-1], marker="8", color="red", markersize=10)
    #plt.xlabel("discriminator error")
    #plt.ylabel("generator error")
    #plt.show()

    #fig = plt.figure()
    #plt.plot(ganerr[:, 0], ganerr[:, 2])
    #plt.plot(discerrbar, autoerrbar)
    #plt.plot(discerrbar[0], autoerrbar[0], marker="D", color="green", markersize=10)
    #plt.plot(discerrbar[-1], autoerrbar[-1], marker="8", color="red", markersize=10)
    #plt.xlabel("discriminator error")
    #plt.ylabel("encoder error")
    #plt.show()

    #generate fake data for every training sample
    nsample = train.shape[1]
    fake, _ = fwdprop(np.random.rand(generator[0]["n"], nsample), generator)
    #merge training and fake data
    gandata = np.hstack((train, fake))
    ganlabels = np.hstack((np.repeat(1, nsample), np.repeat(0, nsample)))

    print("analyze trained discriminator on fake vs training set")
    pred, cost = computecost(discriminator, gandata, ganlabels, "bce")
    roc, report = analyzebinaryclassifier(pred, ganlabels)
    if report["AreaUnderCurve"] < .5:
        #flip labels
        pred, cost = computecost(discriminator, gandata, ganlabels, "bce")
        roc, report = analyzebinaryclassifier(pred, 1 - ganlabels)
    print(report)
    #plotroc(roc)

    #gen fake data for every validation sample
    nsample = valid.shape[1]
    fake, _ = fwdprop(np.random.rand(generator[0]["n"], nsample), generator)
    #merge validation and fake data
    gandata = np.hstack((valid, fake))
    ganlabels = np.hstack((np.repeat(1, nsample), np.repeat(0, nsample)))

    print("analyze trained discriminator on fake vs vaidation set")
    pred, costv = computecost(discriminator, gandata, ganlabels, "bce")
    roc, reportv = analyzebinaryclassifier(pred, ganlabels)
    if reportv["AreaUnderCurve"] < .5:
        #flip labels
        pred, costv = computecost(discriminator, gandata, 1 - ganlabels, "bce")
        roc, reportv = analyzebinaryclassifier(pred, 1 - ganlabels)
    print(reportv)
    #plotroc(roc)

    #assert discriminator has poor potential to iden fake data
    assert reportv["AreaUnderCurve"] < .55

    #get fake data the discriminator thinks is real
    pred, _ = fwdprop(fake, discriminator)
    spoof = fake[:, pred[0, :] > report["OptimalThreshold"]]
Exemple #14
0
    def pretrain(self, state, validation=None):
        """ will pretrain deep network model by contrastive divergence """

        #make sure input all have the same number of observations
        nobv = state.shape[1]
        failcheck = False
        if validation is not None and validation.shape[0] != nobv:
            failcheck = True
        if failcheck:
            print(
                "runtime error in pretrain: inconsistent number of observations!"
            )
            return

        #get network input size
        nfeat = state.shape[0]  #network input size

        if validation is None:
            #manually set validation data to False
            validation = np.full(state.shape[0], False)

        #partition out validation patients from dataset
        intrain = ~validation
        nobv = np.sum(intrain)
        #exit if too few participated
        if nobv < 1:
            print("too few participants found for training")
            return
        #otherwise proceed with training
        data = state[:, intrain].reshape((nfeat, nobv))

        #Left off here - need to pop off last layer in model and add random weight to target and prediction nets

        #return untrained autoencoder
        _, autoencoder = contrastivedivergence(self.prednet, data, maxepoch=0)
        print(autoencoder)

        #calculate initial mean squared error
        pred, _ = fwdprop(data, autoencoder)
        icost, _ = loss("mse", pred, data)
        print(icost)

        #train model
        _, autoencoder = contrastivedivergence(self.prednet,
                                               data,
                                               maxepoch=100)

        #calculate final mean squared error
        pred, _ = fwdprop(data, autoencoder)
        cost, _ = loss("mse", pred, data)

        #print(autoencoder)
        print(icost)
        print(cost)

        #reinit the target network(s)
        #with the prediciton network
        #self.targetnet = copy_ffn(self.prednet)
        self.targetnet1 = copy_ffn(self.prednet)
        self.targetnet2 = copy_ffn(self.prednet)
        self.targetnet3 = copy_ffn(self.prednet)
        self.targetnet4 = copy_ffn(self.prednet)
Exemple #15
0
    def get_value(self, state):
        # prediction network input: array of 6 values representing metabolite conc. and time horizon
        #  output: Value of anticipated return at time horizon from current state

        prediction, _state = fwdprop(state, self.prednet)
        return prediction
Exemple #16
0
def r_test_solve_nestedcs():
    """test nested cs can be solved
    """
    import matplotlib
    matplotlib.use('TkAgg')
    import matplotlib.pyplot as plt

    import numpy as np
    from crpm.setup_nestedcs import setup_nestedcs
    from crpm.fwdprop import fwdprop
    from crpm.som import init_som
    from crpm.som import som
    from crpm.analyzebinaryclassifier import analyzebinaryclassifier

    #init numpy seed
    np.random.seed(40017)

    #setup model
    model, data = setup_nestedcs()

    #update state of model
    _, state = fwdprop(data[0:2, ], model)

    #create and init map with model and its current state
    map, _ = init_som(model, state, n=100, nx=100, ny=1, hcp=True)

    #plot data and map in real space
    plt.scatter(data[0, ], data[1, ], c=data[-1, ])
    plt.plot(map[-1]["weight"][:, 0], map[-1]["weight"][:, 1])
    plt.scatter(map[-1]["weight"][:, 0], map[-1]["weight"][:, 1])
    plt.show()

    #conduct mapping
    pred, map = som(map,
                    state,
                    lstart=.2,
                    lend=.001,
                    nstart=50.0,
                    nend=0.001,
                    maxepoch=5000)

    #plot data and map in real space
    plt.scatter(data[0, ], data[1, ], c=data[-1, ])
    plt.plot(map[-1]["weight"][:, 0], map[-1]["weight"][:, 1])
    plt.scatter(map[-1]["weight"][:, 0], map[-1]["weight"][:, 1])
    plt.show()

    #plot map and centroids in mapping space
    plt.scatter(map[-1]["coord"][:, 0],
                map[-1]["coord"][:, 1],
                c=map[-1]["bias"][:, 0],
                cmap='gray')
    #plt.scatter(map[-1]["centroid"][:,0],map[-1]["centroid"][:,1], s=100)
    plt.show()

    #plot predictions in real space
    #plt.scatter(data[0,], data[1,], c=data[-1,]-pred[0,])
    #plt.show()

    #analyze binary classifier
    _, report = analyzebinaryclassifier(pred, data[-1, ])
    print(report)

    assert report["MatthewsCorrCoef"] >= .5
def test_solve_toruscases_bce():
    """test toruscases can be solved
    """
    import numpy as np
    from crpm.setup_toruscases import setup_toruscases
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.gradientdecent import gradientdecent
    from crpm.analyzebinaryclassifier import analyzebinaryclassifier

    #init numpy seed
    np.random.seed(40017)

    #setup model
    model, data = setup_toruscases()
    nx = data.shape[0]
    nsample = data.shape[1]

    #partition training and validation data
    valid = data[1:data.shape[0], 0:nsample // 3]
    validtargets = data[0, 0:nsample // 3]
    train = data[1:data.shape[0], nsample // 3:nsample]
    targets = data[0, nsample // 3:nsample]

    #calculate initial binary cross entropy error
    pred, _ = fwdprop(train, model)
    icost, _ = loss("bce", pred, targets)

    #analyze binary classifier
    pred, _ = fwdprop(valid, model)
    roc, ireport = analyzebinaryclassifier(pred, validtargets)
    if ireport["AreaUnderCurve"] < .5:
        pred = 1 - pred
        icost, _ = loss("bce", pred, validtargets)
        roc, ireport = analyzebinaryclassifier(pred, validtargets)
    print(ireport)
    #plotroc(roc)

    #train model
    pred, cost, _ = gradientdecent(model,
                                   train,
                                   targets,
                                   "bce",
                                   valid,
                                   validtargets,
                                   earlystop=True)

    #analyze binary classifier
    pred, _ = fwdprop(valid, model)
    roc, report = analyzebinaryclassifier(pred, validtargets)
    if report["AreaUnderCurve"] < .5:
        pred = 1 - pred
        cost, _ = loss("bce", pred, validtargets)
        roc, report = analyzebinaryclassifier(pred, validtargets)
    print(report)
    #plotroc(roc)

    #print(model)
    print(icost)
    print(cost)
    assert icost > cost
    assert cost < .4
    assert report["MatthewsCorrCoef"] > .1
Exemple #18
0
def gan(generator,
        discriminator,
        data,
        maxepoch=500,
        batchsize=10,
        finetune=6):
    """ Trains generative adversarial network by semi gradientdecent.
        Args:
            data: training data with features in rows and observations in columns
            generator: ffn model with number of nodes in output layer equal to
                the number of features in the training data.
            discriminator: ffn model with sigle node logistic in the output layer
                and number of nodes in the input layer equal to the number of
                features in the training data.
            maxepoch: optional maximum number of training steps.
            batchsize: optional size of minibatch for SGD training.
            finetune: tuning parameter that scales inversely with learning step.
        Returns:
        cost: discriminator final binary cross entropy error
    """

    import numpy as np
    from crpm.fwdprop import fwdprop
    from crpm.lossfunctions import loss
    from crpm.backprop import backprop
    from crpm.dynamics import computeforces
    from crpm.dynamics import maxforce
    from crpm.ffn_bodyplan import copy_ffn

    #get data dimensions
    nfeat = data.shape[0]
    nobv = data.shape[1]

    # ----- check input -----

    def isnotpositiveint(var):
        """ will return true if var is not a positive integer"""
        if not isinstance(var, int):
            return True
        if var <= 0:
            return True
        return False

    #check discriminator has logistic output
    if discriminator[-1]["activation"] != "logistic":
        print("Warning: discriminator should have logistic output.")
        return None
    #check discriminator has single node output
    if discriminator[-1]["n"] != 1:
        print("Warning: discriminator should output a single number.")
        return None
    #check generator outputs a value for all features in the training data
    if generator[-1]["n"] != nfeat:
        print("Warning: number of nodes in generator ouptut layer should be " +
              "equal to number of rows in data.")
        return None
    #check generator has linear or logistic input
    if (generator[0]["activation"] != "linear"
            and generator[0]["activation"] != "logistic"):
        print("Warning: generator must have linear or logistic input.")
        return None
    #check discriminator penultimate layer has same size and activation as generator input layer
    if (discriminator[-2]["activation"] != generator[0]["activation"]
            or discriminator[-2]["n"] != generator[0]["n"]):
        print(
            "Warning: discriminator penultimate layer must match generator input layer."
        )
        return None
    #check for positive number of training steps
    if isnotpositiveint(maxepoch):
        #throw error msg and return nothing
        print("Warning maxepoch is not a positive integer!")
        return None
    #check for positive number of training steps
    if isnotpositiveint(batchsize):
        #throw error msg and return nothing
        print("Warning batchsize is not a positive integer!")
        return None

    #-- Start GAN training---

    #save only 5k-10k points
    nadj = 1
    delay = 0
    maxpts = 5000
    if (maxepoch > maxpts):
        nadj = maxepoch // maxpts
        delay = maxepoch % maxpts
    else:
        maxpts = maxepoch

    #init ganerr record for discriminator bce, generator bce, encoder mse, and epoch
    ganerr = np.empty((maxpts, 4))

    #init best disc and gen models
    #best_discriminator = copy_ffn(discriminator)
    #best_generator = copy_ffn(generator)
    #besterr = None

    #correct minibatch size if larger than number of observations in data
    minibatch = min(batchsize, nobv)

    #learning rate regulator
    alpha_norm = 10**(-finetune)

    #get number of generator encoding nodes
    ncode = generator[0]["n"]

    ##select initial 1/2 batch from data
    #sel = np.random.choice(nobv, size=minibatch, replace=False)
    ##sample initial 1/2 batch of noise
    #noise = np.random.rand(ncode, minibatch)

    #loop over epochs
    for epoch in range(maxepoch):

        #select mini batch from data
        sel = np.random.choice(nobv, size=minibatch, replace=False)

        #sample mini batch of noise
        if (generator[0]["activation"] == "linear"):
            #sample gaussian distribution
            noise = np.random.randn(ncode, minibatch)
        if (generator[0]["activation"] == "logistic"):
            #sample uniform distribution
            noise = np.random.rand(ncode, minibatch)

        # - - Train discriminator to detect real data:
        #     increase TPR (decr T1err)

        #compute forces on discriminator
        pred, discstate = fwdprop(data[:, sel], discriminator)
        derr, dloss = loss("bce", pred, np.repeat(1, minibatch))
        forces, _ = backprop(discriminator, discstate, dloss)

        #normalize learning rate alpha based on current forces
        alpha = alpha_norm * maxforce(discriminator, forces)

        #update discriminator weights and biases
        for layer in forces:
            index = layer["layer"]
            discriminator[index]["weight"] = (discriminator[index]["weight"] +
                                              alpha * layer["fweight"])
            discriminator[index]["bias"] = (discriminator[index]["bias"] +
                                            alpha * layer["fbias"])

        # - - Train generator to reproduce discriminator latent representation:
        #     autoencoding to increase FNR? (incr T2err?)
        #     should improve mode collapse

        #fwd prop encoder(discriminator upto penultimate layer) state
        latent, encstate = fwdprop(data[:, sel], discriminator[:-1])
        #fwd prop decoder(generator) state
        recon, genstate = fwdprop(latent, generator)

        #compute autoencoder reconstruction error
        autoerr, dloss = loss("mse", recon, data[:, sel])

        #compute forces on decoder(generator)
        forces, _ = backprop(generator, genstate, dloss)

        #normalize learning rate alpha based on current forces
        alpha = alpha_norm * maxforce(generator, forces)

        #update decoder weights and biases
        for layer in forces:
            index = layer["layer"]
            generator[index]["weight"] = (generator[index]["weight"] +
                                          alpha * layer["fweight"])
            generator[index]["bias"] = (generator[index]["bias"] +
                                        alpha * layer["fbias"])

        # - - Train discriminator to detect fake data:
        #     increase TNR (decr T2err)

        # generate fake data
        fake, genstate = fwdprop(noise, generator)

        #compute forces on discriminator
        pred, discstate = fwdprop(fake, discriminator)
        derr, dloss = loss("bce", pred, np.repeat(0, minibatch))
        forces, _ = backprop(discriminator, discstate, dloss)

        #normalize learning rate alpha based on current forces
        alpha = alpha_norm * maxforce(discriminator, forces)

        #update discriminator weights and biases
        for layer in forces:
            index = layer["layer"]
            discriminator[index]["weight"] = (discriminator[index]["weight"] +
                                              alpha * layer["fweight"])
            discriminator[index]["bias"] = (discriminator[index]["bias"] +
                                            alpha * layer["fbias"])

        # - - Train generator to fool discriminator:
        #     increase FPR (incr T1err)

        # compute discriminator state due to fake data
        pred, discstate = fwdprop(fake, discriminator)

        # calculate derivative of missclassification error
        gerr, dloss = loss("bce", pred, np.repeat(1, minibatch))

        # back prop gradient on generator coming from disccr missclassification
        _, dact = backprop(discriminator, discstate, dloss)

        # get forces on generator
        forces, _ = backprop(generator, genstate, dact)

        # normalize learning rate alpha based on current forces
        alpha = alpha_norm * maxforce(generator, forces)

        # update body wieghts and biases
        for layer in forces:
            index = layer["layer"]
            generator[index]["weight"] = (generator[index]["weight"] +
                                          alpha * layer["fweight"])
            generator[index]["bias"] = (generator[index]["bias"] +
                                        alpha * layer["fbias"])

        #save best autoencoding discriminator-generator pair
        #if besterr is None:
        #    besterr = autoerr
        #if autoerr < besterr:
        #    best_discriminator = copy_ffn(discriminator)
        #    best_generator = copy_ffn(generator)

        #book keeping
        idx = epoch - delay
        if idx % nadj == 0 and idx >= 0:
            ganerr[idx // nadj, :] = [derr, gerr, autoerr, epoch]

    #Overwrite discriminator and generator
    #discriminator = copy_ffn(best_discriminator)
    #generator = copy_ffn(best_generator)

    return ganerr