def strict_flip_sample(self, vis_start, iterations, beta=1): """Flips a randomly chosen bit and accepts the change if the resulting free energy is lower. Repeats for given iterations.""" vis = vis_start.copy() fes = self.free_energy(vis) n_total_flips = 0 for i in range(iterations): # flip a bit at random f = np.random.randint(0, vis.shape[1]) vis_prop = vis.copy() vis_prop[:,f] = 1-vis[:,f] # calculate new free energy and accept change if it is lower fes_prop = self.free_energy(vis_prop, beta=beta) acc_prop = fes_prop <= fes n_flips = gp.sum(acc_prop) n_total_flips += n_flips # compose new state acc_prop_t = gp.tile(acc_prop, (vis.shape[1], 1)).T vis = acc_prop_t * vis_prop + (1-acc_prop_t) * vis fes = acc_prop * fes_prop + (1-acc_prop) * fes return vis
def forward_pass(self, batch, O=None): if len(batch)==2 and type(batch)==tuple: V,O=batch assert len(V)==len(O) elif len(batch)==3 and type(batch)==tuple: V,O,M=batch assert len(V)==len(O)==len(M) else: V=batch if V[0] is not None: V = [None] + V T = len(V)-1 batch_size = len(V[1]) A, B, H, OX = [[None]*(T+1) for _ in range(4)] H[0] = g.tile(self.h_init, (batch_size, 1)) for t in range(1, T+1): B[t] = g.dot(V[t], self.W_vf).tanh() A[t] = g.dot(H[t-1], self.W_hf) C_t = g.dot(V[t], self.W_vh) # + hh stuff AB = A[t]*(B[t] + self.f_bias) HX_t = g.dot(AB, self.W_fh) + C_t H[t] = self.hid_nonlin(HX_t) OX[t] = g.dot(H[t], self.W_ho) return (V[1:], A, B, H, OX[1:])
def R_forward_pass(self, state, R): """ Apply the R-operator on RNN. R is an RNN object which represents the vector we multiply by. Note that it needs to know the RNN's state, so that it doesn't have to unnecessarily recompute the state. """ V, H, OX = state if V[0] is not None: V = [None] + V assert V[0] is None T = len(V)-1 batch_size = len(V[1]) R_OX, R_HX = [[None]*(T+1) for _ in range(2)] import numpy as np R_H_t = g.tile(R.h_init, (batch_size, 1)) for t in range(1, T+1): R_H_1t = R_H_t R_HX[t] = g.dot(R_H_1t, self.W_hh) + g.dot(H[t-1], R.W_hh) + g.dot(V[t], R.W_vh) R_H_t = self.hid_nonlin.grad_y(H[t]) * R_HX[t] R_OX[t] = g.dot(H[t], R.W_ho) + g.dot(R_H_t, self.W_ho) # \/---(for the structured reg). return (R_HX, R_OX[1:])
def R_forward_pass(self, state, R): V, A, B, H, OX = state if V[0] is not None: V = [None] + V # if A[0] is not None: # A = [None] + A # if B[0] is not None: # B = [None] + B # if H[0] is not None: # H = [None] + H if OX[0] is not None: OX = [None] + OX T = len(V)-1 batch_size = len(V[1]) R_OX, R_HX = [None]*(T+1), [None]*(T+1) R_H_t = g.tile(R.h_init, (batch_size, 1)) for t in range(1, T+1): R_H_1t = R_H_t R_B_t = g.dot(V[t], R.W_vf) * (1-B[t]*B[t]) R_A_t = g.dot(R_H_1t, self.W_hf) + g.dot(H[t-1], R.W_hf) R_C_t = g.dot(V[t], R.W_vh) # + hh stuff B_t_f = B[t] + self.f_bias AB = A[t]*B_t_f R_AB = R_A_t*B_t_f + A[t]*(R_B_t + R.f_bias) R_HX[t] = g.dot(R_AB, self.W_fh) + g.dot(AB, R.W_fh) + R_C_t R_H_t = self.hid_nonlin.grad_y(H[t]) * R_HX[t] R_OX[t] = g.dot(H[t], R.W_ho) + g.dot(R_H_t, self.W_ho) return (R_HX, R_OX[1:])
def forward_pass(self, batch): """ Given a batch (V, O, M) (for M, see opt.d.seq.utils.__init__), compute the hidden state sequence and the predictions. """ if type(batch) is tuple: if len(batch)== 3: V, O, M = batch assert len(V) == len(O) == len(M) elif len(batch) == 2: V, O = batch assert len(V) == len(O) else: raise TypeError elif type(batch) is list: V = batch # strictly speaking, forward_pass only needs V. else: # but I allow it to accept batches, for convenience. raise TypeError if V[0] is not None: V = [None] + V assert V[0] is None T = len(V)-1 batch_size = len(V[1]) H, OX = [[None]*(T+1) for _ in range(2)] H[0] = g.tile(self.h_init, (batch_size, 1)) for t in range(1, T+1): HX_t = g.dot(H[t-1], self.W_hh) + g.dot(V[t], self.W_vh) H[t] = self.hid_nonlin(HX_t) OX[t] = g.dot(H[t], self.W_ho) return (V[1:], H, OX[1:])
def metropolis_flip_sample(self, vis_start, iterations, beta=1, abeta=1): """Flips a randomly chosen bit and accepts the change if the resulting free energy is lower or with probability exp(-abeta*dE) where dE is the positive difference in energy. Repeats for given iterations.""" vis = vis_start.copy() fes = self.free_energy(vis) n_total_flips = 0 for i in range(iterations): # flip a bit at random f = np.random.randint(0, vis.shape[1]) vis_prop = vis.copy() vis_prop[:,f] = 1-vis[:,f] # calculate new free energy fes_prop = self.free_energy(vis_prop, beta=beta) fes_diff = fes_prop - fes # accept if it is lower or with negative exponential probability fes_smaller = fes_diff <= 0 acc_p = fes_smaller + (1-fes_smaller) * gp.exp(-(1-fes_smaller)*abeta*fes_diff) acc_rng = gp.rand(acc_p.shape) acc = acc_rng <= acc_p # statistics n_flips = gp.sum(acc) n_total_flips += n_flips # compose new state acc_t = gp.tile(acc, (vis.shape[1], 1)).T vis = acc_t * vis_prop + (1-acc_t) * vis fes = acc * fes_prop + (1-acc) * fes #print "Total number of flips: ", n_total_flips return vis