示例#1
0
    def __init__(self, V, rank, t_win, alphaWf=0, alphaWt=0, betaWf=0, betaWt=0,
                 betaHf=0, betaHt=0):
        # Find out if other H parameters are necessary?
        # TODO: incremental V
        self.V = V / V.sum()
        self.f_steps, self.t_steps = self.V.shape
        self.t_win = t_win
        self.rank = rank
        H = np.concatenate([self.V]*rank, axis=1)
        Hflat = H.flatten()[newaxis,:]
        Vflat = self.V.flatten()[newaxis,:]

        # Make the time-independent frequency analyzer
        self.freq_analyzer = SIPLCA2(H, rank, (self.f_steps, 1),
                                     alphaW=alphaWf[...,newaxis],
                                     betaW=betaWf, betaH=betaHf)
        self.meta_freq_analyzer = SIPLCA2(self.V, rank, (self.f_steps, 1),
                                          alphaW=alphaWf[...,newaxis],
                                          betaW=betaWf, betaH=0)

        # Make the frequency-independent time-envelope analyzer
        self.time_analyzer = SIPLCA(Hflat, rank, self.t_win,
                                    alphaW=alphaWt[newaxis,...],
                                    betaW=betaWt, betaH=betaHt)
        self.meta_time_analyzer = SIPLCA(Vflat, rank, self.t_win,
                                         alphaW=alphaWt[newaxis,...],
                                         betaW=betaWt, betaH=0)
示例#2
0
class Basilica(object):
    def __init__(self, V, rank, t_win, alphaWf=0, alphaWt=0, betaWf=0, betaWt=0,
                 betaHf=0, betaHt=0):
        # Find out if other H parameters are necessary?
        # TODO: incremental V
        self.V = V / V.sum()
        self.f_steps, self.t_steps = self.V.shape
        self.t_win = t_win
        self.rank = rank
        H = np.concatenate([self.V]*rank, axis=1)
        Hflat = H.flatten()[newaxis,:]
        Vflat = self.V.flatten()[newaxis,:]

        # Make the time-independent frequency analyzer
        self.freq_analyzer = SIPLCA2(H, rank, (self.f_steps, 1),
                                     alphaW=alphaWf[...,newaxis],
                                     betaW=betaWf, betaH=betaHf)
        self.meta_freq_analyzer = SIPLCA2(self.V, rank, (self.f_steps, 1),
                                          alphaW=alphaWf[...,newaxis],
                                          betaW=betaWf, betaH=0)

        # Make the frequency-independent time-envelope analyzer
        self.time_analyzer = SIPLCA(Hflat, rank, self.t_win,
                                    alphaW=alphaWt[newaxis,...],
                                    betaW=betaWt, betaH=betaHt)
        self.meta_time_analyzer = SIPLCA(Vflat, rank, self.t_win,
                                         alphaW=alphaWt[newaxis,...],
                                         betaW=betaWt, betaH=0)

    def run_freq(self, Vf, Wf=None, Zf=None, Hf=None, niter=5):
        self.freq_analyzer.V = Vf
        if Wf is None or Zf is None or Hf is None:
            initW, initZ, initH = self.freq_analyzer.initialize()
            if Wf is None: Wf = initW
            if Zf is None: Zf = initZ
            if Hf is None: Hf = initH
        
        for iter in xrange(niter):
            logprob, WZH = self.freq_analyzer.do_estep(Wf, Zf, Hf)
            logger.info('Iteration f%d: logprob = %f', iter, logprob)
            Wf, Zf, Hf = self.freq_analyzer.do_mstep(iter)
            plt.clf()
            plt.plot(Wf[...,0])
            plt.draw()

        # Hf : (rank, F, rank*T)
        # Hf_sum : (rank, F, T)
        meta_Hf = self.sum_pieces(Hf)
        
        meta_logprob, meta_WZH = self.meta_freq_analyzer.do_estep(
          Wf, Zf, meta_Hf)
        logger.info('Meta f%d: logprob = %f', iter, logprob)
        meta_Wf, meta_Zf, meta_Hf = self.meta_freq_analyzer.do_mstep(0)
        return Wf, Zf, Hf, meta_Hf
    
    # now do the same for run_time
    def run_time(self, Vt, Wt=None, Zt=None, Ht=None, niter=5):
        self.time_analyzer.V = Vt
        if Wt is None or Zt is None or Ht is None:
            initW, initZ, initH = self.time_analyzer.initialize()
            if Wt is None: Wt = initW
            if Zt is None: Zt = initZ
            if Ht is None: Ht = initH

        for iter in xrange(niter):
            logprob, WZH = self.time_analyzer.do_estep(Wt, Zt, Ht)
            logger.info('Iteration t%d: logprob = %f', iter, logprob)
            Wt, Zt, Ht = self.time_analyzer.do_mstep(iter)
            assert Wt.ndim == 3
            assert Zt.ndim == 1
            assert Ht.ndim == 2

        # Ht : (rank, rank*F*T)
        # Ht_sum : (rank, F*T)
        meta_Ht = self.sum_pieces(Ht)

        Htt = meta_Ht.reshape(self.rank, self.f_steps, self.t_steps)
        Hmax = np.max(Htt)
        plt.clf()
        plt.imshow(np.rollaxis(Htt[0:3]/Hmax*2, 0, 3), origin='lower', aspect='auto', interpolation='nearest')
        plt.draw()
        
        meta_logprob, meta_WZH = self.meta_time_analyzer.do_estep(Wt, Zt, meta_Ht)
        logger.info('Meta t%d: logprob = %f', iter, logprob)
        meta_Wt, meta_Zt, meta_Ht = self.meta_time_analyzer.do_mstep(0)
        return Wt, Zt, Ht, meta_Ht

    def run(self, V, niter=5, nsubiter=10, Wf=None, Zf=None, Hf=None, Wt=None, Zt=None, Ht=None, play_func=None):
        meta_Hf = np.dstack([self.V] * self.rank).transpose(2,0,1)
        for iter in xrange(niter):
            # run_freq returns Hf : (rank, F, T)
            # flatten to get (1, rank*F*T)
            Vt = meta_Hf.flatten()[newaxis,:]
            
            Wt, Zt, Ht, meta_Ht =\
              self.run_time(Vt, Wt, Zt, Ht, nsubiter)

            # run_time returns Ht : (rank, F*T)
            # reshape to get (rank, F, T)
            temp = meta_Ht.reshape(self.rank, self.f_steps, self.t_steps)
            # transpose to get (F, rank, T)
            temp = temp.transpose(1,0,2)
            # reshape to get (F, rank*T)
            Vf = np.reshape(temp, (self.f_steps, self.rank*self.t_steps))

            Wf, Zf, Hf, meta_Hf =\
              self.run_freq(Vf, Wf, Zf, Hf, nsubiter)
            rec = self.reconstruct(Wf, Zf, Wt, Zt, Ht**2)
            if play_func: play_func(rec)
        return Wf, Zf, Hf, Wt, Zt, Ht, meta_Hf, meta_Ht, rec
    
    def reconstruct(self, Wf, Zf, Wt, Zt, Ht):
        # V = convolve(Wf * Zf, meta_Hf)
        # meta_Hf = Vt = convolve(Wt * Zt, Ht)
        # V = convolve(Wf * Zf, Wt * Zt, Ht)
        Hf = self.time_analyzer.reconstruct(Wt, Zt, Ht).reshape(self.rank, self.f_steps, self.t_steps)
        rec = self.freq_analyzer.reconstruct(Wf, Zf, Hf)
        return rec

    def sum_pieces(self, array):
        """
        Given an array made of `r` equal-sized pieces that are concatenated
        along the array's last axis, return the smaller array that results
        from summing these pieces. `r` is defined to be `self.rank`.
        """
        assert array.shape[-1] % self.rank == 0
        width = array.shape[-1] // self.rank
        shape = list(array.shape)
        shape[-1] = width
        result = np.zeros(tuple(shape))
        for i in xrange(self.rank):
            result += array[..., i*width : (i+1)*width]
        return result