Ejemplo n.º 1
0
def func(pars, obs, obserr, order):
    """ Return minimization quantity
    """
    scaled_labels = (np.array(pars) - NN_coeffs['x_min']) / (
        NN_coeffs['x_max'] - NN_coeffs['x_min']) - 0.5
    tmp = np.dot(NN_coeffs['w_array_0'],
                 scaled_labels) + NN_coeffs['b_array_0']
    nlayers = len(NN_coeffs['num_neurons'])
    for i in range(nlayers):
        spec = np.dot(sigmoid(tmp), NN_coeffs['w_array_{:d}'.format(
            i + 1)].T) + NN_coeffs['b_array_{:d}'.format(i + 1)]
        tmp = spec

    try:
        spec = spec[NN_coeffs['gdmodel']]
    except:
        pass

    if order > 0:
        cont = norm.cont(spec,
                         obserr,
                         poly=True,
                         order=order,
                         chips=True,
                         apstar=False)
        spec /= cont

    return ((obs - spec)**2 / obserr**2).sum()
Ejemplo n.º 2
0
def normalize(pars):
    """ bundled normalize for multi-threading
    """
    spec = pars[0]
    specerr = pars[1]
    pixels = pars[2]

    cont = norm.cont(spec,
                     specerr,
                     poly=False,
                     chips=False,
                     apstar=False,
                     medfilt=400)
    nspec = spec / cont
    nspecerr = specerr / cont
    bd = np.where(np.isinf(nspec) | np.isnan(nspec))[0]
    nspec[bd] = 0.
    nspecerr[bd] = 1.e10
    bd = np.where(np.isinf(nspecerr) | np.isnan(nspecerr))[0]
    nspec[bd] = 0.
    nspecerr[bd] = 1.e10
    if pixels is not None:
        nspec = nspec[pixels[0]:pixels[1]]
        nspecerr = nspecerr[pixels[0]:pixels[1]]
    return nspec, nspecerr
Ejemplo n.º 3
0
def spectrum(x, *pars):
    """ Return full spectrum given input list of pixels, parameters
    """
    scaled_labels = (np.array(pars) - NN_coeffs['x_min']) / (
        NN_coeffs['x_max'] - NN_coeffs['x_min']) - 0.5
    #pdb.set_trace()
    #inside = np.einsum('ij,j->i', NN_coeffs['w_array_0'], scaled_labels) + NN_coeffs['b_array_0']
    #outside = np.einsum('ij,j->i', NN_coeffs['w_array_1'], sigmoid(inside)) + NN_coeffs['b_array_1']
    #spec = np.einsum('ij,j->i', NN_coeffs['w_array_2'], sigmoid(outside)) + NN_coeffs['b_array_2']

    tmp = np.dot(NN_coeffs['w_array_0'],
                 scaled_labels) + NN_coeffs['b_array_0']
    nlayers = len(NN_coeffs['num_neurons'])
    for i in range(nlayers):
        spec = np.dot(sigmoid(tmp), NN_coeffs['w_array_{:d}'.format(
            i + 1)].T) + NN_coeffs['b_array_{:d}'.format(i + 1)]
        tmp = spec

    try:
        spec = spec[NN_coeffs['gdmodel']]
        cont = norm.cont(spec,
                         spec * 0. + 1.,
                         poly=True,
                         order=4,
                         chips=True,
                         apstar=False)
        spec /= cont
    except:
        pass

    return spec
Ejemplo n.º 4
0
def plot(file='all_noelem',
         model='GKh_300_0',
         raw=True,
         plotspec=False,
         validation=True,
         normalize=False,
         pixels=None,
         teff=[0, 10000],
         logg=[-1, 6],
         mh=[-3, 1],
         am=[-1, 1],
         cm=[-2, 2],
         nm=[-2, 2],
         trim=True,
         ids=False):
    ''' plots to assess quality of a model
    '''
    # load model and set up for use
    NN_coeffs = get_model(model)

    # read spectra and labels, and get indices for training and validation set
    if ids:
        true, labels, iden = read(file,
                                  raw=raw,
                                  label_names=NN_coeffs['label_names'],
                                  trim=trim,
                                  ids=ids)
    else:
        true, labels = read(file,
                            raw=raw,
                            label_names=NN_coeffs['label_names'],
                            trim=trim)
    if normalize:
        print('normalizing...')
        gdspec = []
        n = 0
        for i in range(true.shape[0]):
            print(i, labels[i])
            cont = norm.cont(true[i, :],
                             true[i, :],
                             poly=False,
                             chips=False,
                             medfilt=400)
            true[i, :] /= cont
            if pixels is None:
                gd = np.where(np.isfinite(true[i, :]))[0]
                ntot = len(true[i, :])
            else:
                gd = np.where(np.isfinite(true[i, pixels[0]:pixels[1]]))[0]
                ntot = len(true[i, pixels[0]:pixels[1]])
            if len(gd) == ntot:
                gdspec.append(i)
                n += 1
        print(n, true.shape)
        if pixels is None: true = true[gdspec, :]
        else: true = true[gdspec, pixels[0]:pixels[1]]
        labels = labels[gdspec]
        if ids: iden = iden[gdspec]

    #gd=np.where((labels[:,0]>=teff[0]) & (labels[:,0]<=teff[1]) &
    #            (labels[:,1]>=logg[0]) & (labels[:,1]<=logg[1]) &
    #            (labels[:,2]>=mh[0]) & (labels[:,2]<=mh[1]) &
    #            (labels[:,3]>=am[0]) & (labels[:,3]<=am[1]) &
    #            (labels[:,4]>=cm[0]) & (labels[:,4]<=cm[1])  &
    #            (labels[:,5]>=nm[0]) & (labels[:,5]<=nm[1])
    #           )[0]
    #pdb.set_trace()
    #true = true[gd]
    #labels = labels[gd]

    nfit = NN_coeffs['nfit']
    ind_shuffle = NN_coeffs['ind_shuffle']
    true = true[ind_shuffle]
    labels = labels[ind_shuffle]
    if ids: iden = iden[ind_shuffle]
    if validation:
        true = true[nfit:]
        labels = labels[nfit:]
        if ids: iden = iden[nfit:]
    else:
        true = true[:nfit]
        labels = labels[:nfit]
        if ids: iden = iden[:nfit]

    # loop over the spectra
    if plotspec: plt.figure()
    nn = []
    diff2 = []
    for i, lab in enumerate(labels):
        # calculate model spectrum and accumulate model array
        pix = np.arange(8575)
        spec = spectrum(pix, *lab)
        nn.append(spec)
        tmp = np.sum((spec - true[i, :])**2)
        print(i, tmp, lab)
        diff2.append(tmp)
        if plotspec and tmp > 100:
            plt.clf()
            plt.plot(true[i, :], color='g')
            plt.plot(spec, color='b')
            plt.plot(spec - true[i, :], color='r')
            plt.show()
            pdb.set_trace()
        #n=len(np.where(np.abs(apstar[j]-true[i,j]) > 0.05)[0])
    nn = np.array(nn)
    diff2 = np.array(diff2)
    #fig,ax=plots.multi(2,2,hspace=0.001,wspace=0.001,sharex=True,sharey=True)
    #plots.plotc(ax[0,0],labels[:,0],labels[:,1],labels[:,2],xr=[8000,3000],yr=[6,-1],zr=[-2.5,0.5])
    #plots.plotc(ax[1,0],labels[:,0],labels[:,1],labels[:,3],xr=[8000,3000],yr=[6,-1],zr=[-0.25,0.5])
    #plots.plotc(ax[1,1],labels[:,0],labels[:,1],diff2,xr=[8000,3000],yr=[6,-1],zr=[0,10])
    #ax[1,1].text(0.,0.9,'diff**2',transform=ax[1,1].transAxes)
    fig, ax = plots.multi(1,
                          1,
                          hspace=0.001,
                          wspace=0.001,
                          sharex=True,
                          sharey=True)
    plots.plotc(ax,
                labels[:, 0],
                labels[:, 1],
                diff2,
                xr=[8000, 3000],
                yr=[6, -1],
                zr=[0, 10])
    if ids:
        data = Table()
        data.add_column(Column(name='ID', data=iden))
        data.add_column(Column(name='TEFF', data=labels[:, 0]))
        data.add_column(Column(name='LOGG', data=labels[:, 1]))
        data.add_column(Column(name='MH', data=labels[:, 2]))
        data.add_column(Column(name='AM', data=labels[:, 3]))
        plots._data = data
        plots._id_cols = ['ID', 'TEFF', 'LOGG', 'MH', 'AM']
    plots.event(fig)
    plt.draw()
    key = ' '
    sfig, sax = plots.multi(1, 2, hspace=0.001, sharex=True)
    pdb.set_trace()
    print('entering event loop....')
    while key != 'e' and key != 'E':
        x, y, key, index = plots.mark(fig)
        sax[0].cla()
        sax[0].plot(true[index, :], color='g')
        sax[0].plot(nn[index, :], color='b')
        sax[1].cla()
        sax[1].plot(nn[index, :] / true[index, :], color='g')
        plt.figure(sfig.number)
        plt.draw()

    fig.savefig(file + '_' + model + '.png')

    # histogram of ratio of nn to true
    print("making nn/raw comparison histogram ...")
    # pixels across sample
    fig, ax = plots.multi(2, 2, figsize=(12, 8))
    # percentiles across wavelength
    fig2, ax2 = plots.multi(1, 3, hspace=0.001)
    # in parameter space
    fig3, ax3 = plots.multi(2, 3, hspace=0.001, wspace=0.001)
    for f in [fig, fig2, fig3]:
        if validation: f.suptitle('validation set')
        else: f.suptitle('training set')

    # consider full sample and several bins in Teff and [M/H]
    tbins = [[3000, 8000], [3000, 4000], [4000, 5000], [5000, 6000],
             [3000, 4000], [4000, 5000], [5000, 6000]]
    mhbins = [[-2.5, 1.0], [-0.5, 1.0], [-0.5, 1.0], [-0.5, 1.0], [-2.5, -0.5],
              [-2.5, -0.5], [-2.5, -0.5]]
    names = [
        'all', '3000<Te<4000, M/H>-0.5', '4000<Te<5000, M/H>-0.5',
        '5000<Te<6000, M/H>-0.5', '3000<Te<4000, M/H<-0.5',
        '4000<Te<5000, M/H<-0.5', '5000<Te<6000, M/H<-0.5'
    ]
    colors = ['k', 'r', 'g', 'b', 'c', 'm', 'y']
    lws = [3, 1, 1, 1, 1, 1, 1]

    for tbin, mhbin, name, color, lw in zip(tbins, mhbins, names, colors, lws):
        gd = np.where((labels[:, 0] >= tbin[0]) & (labels[:, 0] <= tbin[1])
                      & (labels[:, 2] >= mhbin[0])
                      & (labels[:, 2] <= mhbin[1]))[0]
        print(tbin, len(gd))
        if len(gd) > 0:
            t1 = nn[gd, :]
            t2 = true[gd, :]

            # differential fractional error of all pixels
            err = (t1 - t2) / t2
            hist, bins = np.histogram(err.flatten(),
                                      bins=np.linspace(-0.2, 0.2, 4001))
            plots.plotl(ax[0, 0],
                        np.linspace(-0.200 + 0.005, 0.2, 4000),
                        hist / hist.sum(),
                        semilogy=True,
                        xt='(nn-true)/true',
                        label=name,
                        xr=[-0.1, 0.25],
                        color=color,
                        linewidth=lw)
            ax[0, 0].legend(fontsize='x-small')

            # cumulative fractional error of all pixels
            err = np.abs(err)
            hist, bins = np.histogram(err.flatten(),
                                      bins=np.logspace(-7, 3, 501))
            plots.plotl(ax[0, 1],
                        np.logspace(-7, 3, 500),
                        np.cumsum(hist) / np.float(hist.sum()),
                        xt='nn/true',
                        label=name,
                        color=color,
                        linewidth=lw)
            ax[0, 1].set_ylabel('Cumulative fraction, all pixels')

            # get percentiles across models at each wavelength
            p = [50, 95, 99]
            perc = np.percentile(err, p, axis=0)
            npix = perc.shape[1]
            for i in range(3):
                plots.plotl(ax2[i],
                            np.arange(npix),
                            perc[i, :],
                            color=color,
                            linewidth=lw,
                            xt='Pixel number')
                ax2[i].text(0.05,
                            0.9,
                            'error at {:d} percentile'.format(p[i]),
                            transform=ax2[i].transAxes)

            # cumulative of 50 and 95 percentile across models
            hist, bins = np.histogram(perc[0, :], bins=np.logspace(-7, 3, 501))
            plots.plotl(ax[1, 0],
                        np.logspace(-7, 3, 500),
                        np.cumsum(hist) / np.float(hist.sum()),
                        color=color,
                        ls=':',
                        linewidth=lw)
            hist, bins = np.histogram(perc[1, :], bins=np.logspace(-7, 3, 501))
            plots.plotl(ax[1, 0],
                        np.logspace(-7, 3, 500),
                        np.cumsum(hist) / np.float(hist.sum()),
                        color=color,
                        linewidth=lw,
                        ls='--')
            hist, bins = np.histogram(perc[1, :], bins=np.logspace(-7, 3, 501))
            plots.plotl(ax[1, 0],
                        np.logspace(-7, 3, 500),
                        np.cumsum(hist) / np.float(hist.sum()),
                        color=color,
                        linewidth=lw)
            ax[1, 0].set_ylabel('Cumulative, fraction of pixels')

            # cumulative of 50 and 95 percentile across wavelengths
            p = [50, 95, 99, 100]
            perc = np.percentile(err, p, axis=1)
            hist, bins = np.histogram(perc[0, :], bins=np.logspace(-7, 3, 501))
            plots.plotl(ax[1, 1],
                        np.logspace(-7, 3, 500),
                        np.cumsum(hist) / np.float(hist.sum()),
                        color=color,
                        ls=':',
                        linewidth=lw)
            hist, bins = np.histogram(perc[1, :], bins=np.logspace(-7, 3, 501))
            plots.plotl(ax[1, 1],
                        np.logspace(-7, 3, 500),
                        np.cumsum(hist) / np.float(hist.sum()),
                        color=color,
                        linewidth=lw,
                        ls='--')
            hist, bins = np.histogram(perc[1, :], bins=np.logspace(-7, 3, 501))
            plots.plotl(ax[1, 1],
                        np.logspace(-7, 3, 500),
                        np.cumsum(hist) / np.float(hist.sum()),
                        color=color,
                        linewidth=lw)
            ax[1, 1].set_ylabel('Cumulative, fraction of models')

            for ix, iy in zip([1, 0, 1], [0, 1, 1]):
                ax[iy, ix].set_xlim(0., 0.01)
                ax[iy, ix].set_ylim(0., 1.0)
                ax[iy, ix].set_xlabel('|(nn-true)/true|')
                ax[iy, ix].set_xscale('log')
                ax[iy, ix].set_xlim(1.e-4, 0.01)

            # Kiel diagram plots color-coded
            if lw == 3:
                # color-code by value of 50, 95, and 99 percentile of wavelengths for each model
                p = [50, 95, 99]
                perc_mod = np.percentile(err, p, axis=1)
                dx = np.random.uniform(size=len(gd)) * 50 - 25
                dy = np.random.uniform(size=len(gd)) * 0.2 - 0.1
                for i in range(3):
                    plots.plotc(ax3[i, 0],
                                labels[gd, 0] + dx,
                                labels[gd, 1] + dy,
                                perc_mod[i, :],
                                xr=[8000, 3000],
                                yr=[6, -1],
                                zr=[0, 0.1],
                                xt='Teff',
                                yt='log g')
                    ax3[i, 0].text(0.1,
                                   0.9,
                                   'error at {:d} percentile'.format(p[i]),
                                   transform=ax3[i, 0].transAxes)
                # color-code by fraction of pixels worse than 0.01
                for i, thresh in enumerate([0.01, 0.05, 0.1]):
                    mask = copy.copy(err)
                    mask[mask <= thresh] = 0
                    mask[mask > thresh] = 1
                    bdfrac = mask.sum(axis=1) / mask.shape[1]
                    axim = plots.plotc(ax3[i, 1],
                                       labels[gd, 0] + dx,
                                       labels[gd, 1] + dy,
                                       bdfrac,
                                       xr=[8000, 3000],
                                       yr=[6, -1],
                                       zr=[0, 0.1],
                                       xt='Teff')
                    ax3[i,
                        1].text(0.1,
                                0.9,
                                'Fraction of pixels> {:4.2f}'.format(thresh),
                                transform=ax3[i, 1].transAxes)
                cax = plt.axes([0.05, 0.03, 0.9, 0.02])
                fig3.colorbar(axim, cax=cax, orientation='horizontal')

    fig.tight_layout()
    plt.draw()
    fig.savefig(file + '_' + model + '_1.png')
    fig2.savefig(file + '_' + model + '_2.png')
    fig3.savefig(file + '_' + model + '_3.png')
    pdb.set_trace()
    plt.close()
    plt.close()
    plt.close()
    plt.close()
    return nn, true, labels
Ejemplo n.º 5
0
def train(file='all_noelem',
          name='test',
          plot=False,
          suffix='',
          fitfrac=0.5,
          steps=1e5,
          weight_decay=0.,
          num_neurons=[300, 300],
          lr=0.001,
          ind_label=np.arange(9),
          pixels=None,
          teff=[0, 10000],
          logg=[-1, 6],
          mh=[-3, 1],
          am=[-1, 1],
          cm=[-2, 2],
          nm=[-2, 2],
          raw=True,
          rot=False,
          elem=False,
          normalize=False,
          elems=None,
          label_names=None,
          trim=True,
          seed=777):
    """ Train a neural net model on an input training set
    """

    spectra, labels = read(file, raw=raw, label_names=label_names, trim=trim)

    if normalize:
        print('normalizing...')
        gdspec = []
        for i in range(spectra.shape[0]):
            cont = norm.cont(spectra[i, :],
                             spectra[i, :],
                             poly=False,
                             chips=False,
                             medfilt=400)
            spectra[i, :] /= cont
            if pixels is None:
                gd = np.where(np.isfinite(spectra[i, :]))[0]
                ntot = len(spectra[i, :])
            else:
                gd = np.where(np.isfinite(spectra[i, pixels[0]:pixels[1]]))[0]
                ntot = len(spectra[i, pixels[0]:pixels[1]])
            if len(gd) == ntot: gdspec.append(i)
        if pixels is None: spectra = spectra[gdspec, :]
        else: spectra = spectra[gdspec, pixels[0]:pixels[1]]
        labels = labels[gdspec]

    # shuffle them and get fit and validation set
    print('shuffling...')
    shape = labels.shape
    np.random.seed(seed)
    ind_shuffle = np.random.permutation(shape[0])

    #----------------------------------------------------------------------------------------
    # choose only a certain labels

    try:
        gd = np.where((labels[ind_shuffle, 0] >= teff[0])
                      & (labels[ind_shuffle, 0] <= teff[1])
                      & (labels[ind_shuffle, 1] >= logg[0])
                      & (labels[ind_shuffle, 1] <= logg[1])
                      & (labels[ind_shuffle, 2] >= mh[0])
                      & (labels[ind_shuffle, 2] <= mh[1])
                      & (labels[ind_shuffle, 3] >= am[0])
                      & (labels[ind_shuffle, 3] <= am[1])
                      & (labels[ind_shuffle, 4] >= cm[0])
                      & (labels[ind_shuffle, 4] <= cm[1])
                      & (labels[ind_shuffle, 5] >= nm[0])
                      & (labels[ind_shuffle, 5] <= nm[1]))[0]
    except:
        gd = np.where((labels[ind_shuffle, 0] >= teff[0])
                      & (labels[ind_shuffle, 0] <= teff[1])
                      & (labels[ind_shuffle, 1] >= logg[0])
                      & (labels[ind_shuffle, 1] <= logg[1])
                      & (labels[ind_shuffle, 2] >= mh[0])
                      & (labels[ind_shuffle, 2] <= mh[1])
                      & (labels[ind_shuffle, 3] >= am[0])
                      & (labels[ind_shuffle, 3] <= am[1]))[0]

    nfit = int(fitfrac * len(gd))
    # separate into training and validation set
    training_spectra = spectra[ind_shuffle[gd], :][:nfit, :]
    training_labels = labels[ind_shuffle[gd], :][:nfit, :][:, ind_label]
    validation_spectra = spectra[ind_shuffle[gd], :][nfit:, :]
    validation_labels = labels[ind_shuffle[gd], :][nfit:, :][:, ind_label]
    model = training.neural_net(training_labels, training_spectra,\
                                validation_labels, validation_spectra,\
                                num_neurons = num_neurons, num_steps=steps, learning_rate=lr, weight_decay=weight_decay)
    model['label_names'] = label_names
    model['data_file'] = file
    model['nfit'] = nfit
    model['ind_shuffle'] = ind_shuffle[gd]
    model['teff_lim'] = teff
    model['logg_lim'] = logg
    model['mh_lim'] = mh
    model['am_lim'] = am
    model['cm_lim'] = cm
    model['nm_lim'] = nm
    model['learning_rate'] = lr
    model['weight_decay'] = weight_decay
    model['num_neurons'] = num_neurons
    model['steps'] = steps

    with open('{:s}.pkl'.format(name), 'wb') as f:
        pickle.dump(model, f, protocol=2)