def _grad_beta(self, gen, real_state): G = gen.getGen() psi = self.getPsi() phi = self.getPhi() zero_state = get_zero_state(self.size) fake_state = np.matmul(G , zero_state) try: A = expm((-1 / lamb) * phi) except Exception: print('grad_beta -1/lamb:\n', (-1 / lamb)) print('size of phi:\n', phi.shape) try: B = expm((1 / lamb) * psi) except Exception: print('grad_beta 1/lamb:\n', (1 / lamb)) print('size of psi:\n', psi.shape) cs = -1 / lamb grad_psi_term = np.zeros_like(self.beta, dtype=complex) grad_phi_term = np.zeros_like(self.beta, dtype=complex) grad_reg_term = np.zeros_like(self.beta, dtype=complex) for type in range(len(self.herm)): gradphi = self._grad_phi(type) gradpsi_list = list() gradphi_list = list() gradreg_list = list() for grad_phi in gradphi: gradpsi_list.append(0) gradphi_list.append(np.asscalar(np.matmul(fake_state.getH() ,np.matmul( grad_phi , fake_state)))) term1 = cs * np.matmul(fake_state.getH() ,np.matmul( grad_phi ,np.matmul( A , fake_state))) * np.matmul(real_state.getH() ,np.matmul( B , real_state)) term2 = cs * np.matmul(fake_state.getH() , np.matmul(B , real_state)) * np.matmul(real_state.getH() ,np.matmul( grad_phi ,np.matmul( A , fake_state))) term3 = cs * np.matmul(fake_state.getH() ,np.matmul( grad_phi ,np.matmul( A , real_state))) * np.matmul(real_state.getH() ,np.matmul( B , fake_state)) term4 = cs * np.matmul(fake_state.getH() ,np.matmul(B , fake_state)) * np.matmul(real_state.getH() ,np.matmul( grad_phi ,np.matmul( A , real_state))) gradreg_list.append( np.asscalar(lamb / np.e * (cst1 * term1 - cst2 * term2 - cst2 * term3 + cst3 * term4))) # calculate grad of psi term grad_psi_term[:, type] = np.asarray(gradpsi_list) # calculate grad of phi term grad_phi_term[:, type] = np.asarray(gradphi_list) # calculate grad of reg term grad_reg_term[:, type] = np.asarray(gradreg_list) # print("grad_beta:\n",np.real(grad_psi_term - grad_phi_term - grad_reg_term)) return np.real(grad_psi_term - grad_phi_term - grad_reg_term)
def compute_cost(gen, dis, real_state): ''' calculate the loss :param gen: generator(Generator) :param dis: discriminator(Discriminator) :return: ''' G = gen.getGen() psi = dis.getPsi() phi = dis.getPhi() zero_state = get_zero_state(gen.size) fake_state = np.matmul(G, zero_state) try: A = expm(np.float(-1 / lamb) * phi) except Exception: print('cost function -1/lamb:\n', (-1 / lamb)) print('size of phi:\n', phi.shape) try: B = expm(np.float(1 / lamb) * psi) except Exception: print('cost function 1/lamb:\n', (1 / lamb)) print('size of psi:\n', psi.shape) term1 = np.matmul(fake_state.getH(), np.matmul(A, fake_state)) term2 = np.matmul(real_state.getH(), np.matmul(B, real_state)) term3 = np.matmul(fake_state.getH(), np.matmul(B, real_state)) term4 = np.matmul(real_state.getH(), np.matmul(A, fake_state)) term5 = np.matmul(fake_state.getH(), np.matmul(A, real_state)) term6 = np.matmul(real_state.getH(), np.matmul(B, fake_state)) term7 = np.matmul(fake_state.getH(), np.matmul(B, fake_state)) term8 = np.matmul(real_state.getH(), np.matmul(A, real_state)) psiterm = np.asscalar( np.matmul(real_state.getH(), np.matmul(psi, real_state))) phiterm = np.asscalar( np.matmul(fake_state.getH(), np.matmul(phi, fake_state))) regterm = np.asscalar(lamb / np.e * (cst1 * term1 * term2 - cst2 * term3 * term4 - cst2 * term5 * term6 + cst3 * term7 * term8)) return np.real(psiterm - phiterm - regterm)
def compute_cost(gen, dis, real_state): G_list = gen.getGen() zero_state = get_zero_state(gen.size) P = np.zeros_like(G_list[0]) for p, g in zip(gen.prob_gen, G_list): state_i = np.matmul(g, zero_state) P += p * (np.matmul(state_i, state_i.getH())) Q = real_state psi = dis.getPsi() phi = dis.getPhi() try: A = expm(np.float(-1 / lamb) * phi) except Exception: print('cost function -1/lamb:\n', (-1 / lamb)) print('size of phi:\n', phi.shape) try: B = expm(np.float(1 / lamb) * psi) except Exception: print('cost function 1/lamb:\n', (1 / lamb)) print('size of psi:\n', psi.shape) psiterm = np.trace(np.matmul(Q, psi)) phiterm = np.trace(np.matmul(P, phi)) term1 = np.trace(np.matmul(A, P)) * np.trace(np.matmul(B, Q)) term2 = np.trace(np.matmul(A, np.matmul(P, np.matmul(B, Q)))) term3 = np.trace(np.matmul(P, np.matmul(A, np.matmul(Q, B)))) term4 = np.trace(np.matmul(B, P)) * np.trace(np.matmul(A, Q)) regterm = lamb / np.e * (cst1 * term1 - cst2 * term2 - cst2 * term3 + cst3 * term4) return np.real(psiterm - phiterm - regterm)
def getState(self): G = self.getGen() zero_state = get_zero_state(self.size) fake_state = np.matmul(G, zero_state) return fake_state
def _grad_theta(self, dis, real_state): G = self.getGen() phi = dis.getPhi() psi = dis.getPsi() zero_state = get_zero_state(self.size) fake_state = np.matmul(G, zero_state) try: A = expm((-1 / lamb) * phi) except Exception: print('grad_gen -1/lamb:\n', (-1 / lamb)) print('size of phi:\n', phi.shape) try: B = expm((1 / lamb) * psi) except Exception: print('grad_gen 1/lamb:\n', (1 / lamb)) print('size of psi:\n', psi.shape) grad_g = list() grad_g_psi = list() grad_g_phi = list() grad_g_reg = list() for i in range(self.qc.depth): grad_g.append(self.qc.get_grad_mat_rep(i)) for grad_i in grad_g: # for psi term grad_g_psi.append(0) # for phi term fake_grad = np.matmul(grad_i, zero_state) tmp_grad = np.matmul(fake_grad.getH(), np.matmul( phi, fake_state)) + np.matmul(fake_state.getH(), np.matmul(phi, fake_grad)) grad_g_phi.append(np.asscalar(tmp_grad)) # for reg term term1 = np.matmul(fake_grad.getH(), np.matmul( A, fake_state)) * np.matmul(real_state.getH(), np.matmul(B, real_state)) term2 = np.matmul(fake_state.getH(), np.matmul( A, fake_grad)) * np.matmul(real_state.getH(), np.matmul(B, real_state)) term3 = np.matmul(fake_grad.getH(), np.matmul( B, real_state)) * np.matmul(real_state.getH(), np.matmul(A, fake_state)) term4 = np.matmul(fake_state.getH(), np.matmul( B, real_state)) * np.matmul(real_state.getH(), np.matmul(A, fake_grad)) term5 = np.matmul(fake_grad.getH(), np.matmul( A, real_state)) * np.matmul(real_state.getH(), np.matmul(B, fake_state)) term6 = np.matmul(fake_state.getH(), np.matmul( A, real_state)) * np.matmul(real_state.getH(), np.matmul(B, fake_grad)) term7 = np.matmul(fake_grad.getH(), np.matmul( B, fake_state)) * np.matmul(real_state.getH(), np.matmul(A, real_state)) term8 = np.matmul(fake_state.getH(), np.matmul( B, fake_grad)) * np.matmul(real_state.getH(), np.matmul(A, real_state)) tmp_reg_grad = lamb / np.e * (cst1 * (term1 + term2) - cst2 * (term3 + term4) - cst2 * (term5 + term6) + cst3 * (term7 + term8)) grad_g_reg.append(np.asscalar(tmp_reg_grad)) g_psi = np.asarray(grad_g_psi) g_phi = np.asarray(grad_g_phi) g_reg = np.asarray(grad_g_reg) grad = np.real(g_psi - g_phi - g_reg) return grad
# Learning Scripts initial_eta = 1e-1 epochs = 10 decay = False eta = initial_eta step_size = 1 prob_gen_lr = eta theta_lr = eta psi_lr = eta phi_lr = eta label = 'mixed_state' fidelities = list() losses = list() # System setting// system_size = 2 num_to_mix = 2 zero_state = get_zero_state(system_size) # file settings figure_path = './figure' model_gen_path = './saved_model/{}qubit_model-gen(mixed).mdl'.format( system_size) model_dis_path = './saved_model/{}qubit_model-dis(mixed).mdl'.format( system_size)
def main(): angle = np.random.randint(1,10,size=[cf.system_size,3]) matrix = Identity(cf.system_size) for j in range(cf.system_size): row_i_mat = np.matmul(Z_Rotation(cf.system_size, j, np.pi * angle[j][2], False), np.matmul(Y_Rotation(cf.system_size, j, np.pi * angle[j][1], False), X_Rotation(cf.system_size, j, np.pi * angle[j][0], False))) matrix = np.matmul(row_i_mat, matrix) param = np.random.rand(6) XX1 = XX_Rotation(cf.system_size, 0, 1, param[0], False) XX2 = XX_Rotation(cf.system_size, 0, 2, param[1], False) XX3 = XX_Rotation(cf.system_size, 0, 3, param[2], False) XX4 = XX_Rotation(cf.system_size, 1, 2, param[3], False) XX5 = XX_Rotation(cf.system_size, 1, 3, param[4], False) XX6 = XX_Rotation(cf.system_size, 2, 3, param[5], False) zero_state = get_zero_state(cf.system_size) real_state_tmp = np.matmul(XX6 ,np.matmul( XX5 ,np.matmul( XX4 ,np.matmul( XX3 ,np.matmul(XX2 , np.matmul(XX1 ,np.matmul( matrix , zero_state))))))) real_state = np.matmul(real_state_tmp , real_state_tmp.getH()) starttime = datetime.now() # define generator gen = Gen(cf.system_size, cf.num_to_mix, cf.mu, cf.sigma) gen.set_qcircuit(construct_qcircuit(gen.qc_list)) # define discriminator herm = [I, X, Y, Z] dis = Dis(herm, cf.system_size, cf.mu,cf.sigma) fidelities = list() losses = list() f = compute_fidelity(gen, zero_state, real_state) while (f < 0.99): starttime = datetime.now() for iter in range(cf.epochs): print("==================================================") print("Epoch {}, Step_size {}".format(iter + 1, cf.eta)) compute_cost(gen, dis, real_state) print('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') if iter % cf.step_size == 0: # Generator gradient descent gen.update_gen(dis,real_state) print("Loss after generator step: {}".format(compute_cost(gen, dis,real_state))) # Discriminator gradient ascent dis.update_dis(gen,real_state) print("Loss after discriminator step: {}".format(compute_cost(gen, dis, real_state))) cost = compute_cost(gen, dis, real_state) fidelity = compute_fidelity(gen, zero_state,real_state) losses.append(cost) fidelities.append(fidelity) print("Fidelity between real and fake state: {}".format(fidelity)) print("==================================================") if iter % 10 == 0: endtime = datetime.now() training_duration = (endtime - starttime).seconds / np.float(3600) param = 'epoches:{:4d} | fidelity:{:8f} | time:{:10s} | duration:{:8f}\n'.format(iter, round(fidelity, 6),time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()),round(training_duration, 2)) train_log(param, './{}qubit_log_noise.txt'.format(cf.system_size)) if (cf.decay): eta = (cf.initial_eta * (cf.epochs - iter - 1) + (1e-2 * cf.initial_eta) * iter) / cf.epochs f = compute_fidelity(gen, zero_state, real_state) plt_fidelity_vs_iter(fidelities, losses, cf) save_model(gen, cf.model_gen_path) save_model(dis, cf.model_dis_path) fidelities[:] = [] losses[:] = [] print("end")
def _grad_beta(self, gen, real_state): G_list = gen.getGen() psi = self.getPsi() phi = self.getPhi() zero_state = get_zero_state(self.size) P = np.zeros_like(G_list[0]) for p, g in zip(gen.prob_gen, G_list): state_i = np.matmul(g, zero_state) P += p * (np.matmul(state_i, state_i.getH())) Q = real_state try: A = expm((-1 / lamb) * phi) except Exception: print('grad_beta -1/lamb:\n', (-1 / lamb)) print('size of phi:\n', phi.shape) try: B = expm((1 / lamb) * psi) except Exception: print('grad_beta 1/lamb:\n', (1 / lamb)) print('size of psi:\n', psi.shape) grad_psi_term = np.zeros_like(self.beta, dtype=complex) grad_phi_term = np.zeros_like(self.beta, dtype=complex) grad_reg_term = np.zeros_like(self.beta, dtype=complex) for type in range(len(self.herm)): gradphi = self._grad_phi(type) gradpsi_list = list() gradphi_list = list() gradreg_list = list() for grad_phi in gradphi: gradpsi_list.append(0) gradphi_list.append(np.trace(np.matmul(P, grad_phi))) tmp_grad_phi = -1 / lamb * np.matmul(grad_phi, A) term1 = np.trace(np.matmul(tmp_grad_phi, P)) * np.trace( np.matmul(B, Q)) term2 = np.trace( np.matmul(tmp_grad_phi, np.matmul(P, np.matmul(B, Q)))) term3 = np.trace( np.matmul(P, np.matmul(tmp_grad_phi, np.matmul(Q, B)))) term4 = np.trace(np.matmul(B, P)) * np.trace( np.matmul(tmp_grad_phi, Q)) gradreg_list.append( lamb / np.e * (cst1 * term1 - cst2 * term2 - cst2 * term3 + cst3 * term4)) # calculate grad of psi term grad_psi_term[:, type] += np.asarray(gradpsi_list) # calculate grad of phi term grad_phi_term[:, type] += np.asarray(gradphi_list) # calculate grad of reg term grad_reg_term[:, type] += np.asarray(gradreg_list) for i in range(len(gradphi)): grad_psi_term[i, type] += random.gauss(self.mu, self.sigma) grad_phi_term[i, type] += random.gauss(self.mu, self.sigma) grad_reg_term[i, type] += random.gauss(self.mu, self.sigma) return np.real(grad_psi_term - grad_phi_term - grad_reg_term)
def _grad_theta(self, dis, real_state): G_list = self.getGen() Q = real_state zero_state = get_zero_state(self.size) phi = dis.getPhi() psi = dis.getPsi() grad = list() try: A = expm((-1 / lamb) * phi) except Exception: print('grad_gen -1/lamb:\n', (-1 / lamb)) print('size of phi:\n', phi.shape) try: B = expm((1 / lamb) * psi) except Exception: print('grad_gen 1/lamb:\n', (1 / lamb)) print('size of psi:\n', psi.shape) for G, j in zip(G_list, range(len(self.qc_list))): fake_state = np.matmul(G, zero_state) grad_g_psi = list() grad_g_phi = list() grad_g_reg = list() for i in range(self.qc_list[j].depth): grad_i = self.qc_list[j].get_grad_mat_rep(i) # for psi term grad_g_psi.append(0) # for phi term fake_grad = np.matmul(grad_i, zero_state) g_Gi = self.prob_gen[j] * ( np.matmul(fake_grad, fake_state.getH()) + np.matmul(fake_state, fake_grad.getH())) grad_g_phi.append(np.trace(np.matmul(g_Gi, phi))) # for reg term term1 = np.trace(np.matmul(A, g_Gi)) * np.trace(np.matmul( B, Q)) term2 = np.trace(np.matmul(A, np.matmul(g_Gi, np.matmul(B, Q)))) term3 = np.trace(np.matmul(g_Gi, np.matmul(A, np.matmul(Q, B)))) term4 = np.trace(np.matmul(B, g_Gi)) * np.trace(np.matmul( A, Q)) tmp_reg_grad = lamb / np.e * (cst1 * term1 - cst2 * term2 - cst2 * term3 + cst3 * term4) grad_g_reg.append(tmp_reg_grad) g_psi = np.asarray(grad_g_psi) g_phi = np.asarray(grad_g_phi) g_reg = np.asarray(grad_g_reg) for i in range(len(g_psi)): g_psi[i] += random.gauss(self.mu, self.sigma) g_phi[i] += random.gauss(self.mu, self.sigma) g_reg[i] += random.gauss(self.mu, self.sigma) grad.append(np.real(g_psi - g_phi - g_reg)) return grad
def main(img): # 生成したい画像 nqubits = 5 # 各ステップのフィデリティー fidelities = list() #各ステップのコスト関数 losses = list() # 学習する量子状態 関数get_real_state4は ./frqi/frqi.pyをご覧下さい real_state = encode4(img) # Generator zero_state = get_zero_state(nqubits) gen = Generator(nqubits) # Generatorの量子回路を設置する 関数circ_frqiEncoderに関しては ./generator/circuit.py及び #./generator/gates.pyをご覧下さい gen.set_qcircuit(circ_encode4(gen.qc)) # Discriminator herm = [I, Pauli_X, Pauli_Y, Pauli_Z] dis = Discriminator(herm, nqubits) f = compute_fidelity(gen, zero_state, real_state) # optional term, this is for controlling the initial fidelity is small. # while(compute_fidelity(gen,zero_state,real_state)>0.5): # ¥gen.reset_angles() while (compute_fidelity(gen, zero_state, real_state) < 0.001): gen.reset_angles() # 学習 while (f < 0.99): starttime = datetime.now() for iter in range(cf.epochs): # print("==================================================") # print("Epoch {}, Step_size {}".format(iter + 1, cf.eta)) if iter % cf.step_size == 0: # Generator gradient descent gen.update_gen(dis, real_state) # print("Loss after generator step: {}".format(compute_cost(gen, dis,real_state))) # Discriminator gradient ascent dis.update_dis(gen, real_state) # print("Loss after discriminator step: {}".format(compute_cost(gen, dis,real_state))) cost = compute_cost(gen, dis, real_state) fidelity = compute_fidelity(gen, zero_state, real_state) losses.append(cost) fidelities.append(fidelity) # print("Fidelity between real and fake state: {}".format(fidelity)) # print("==================================================") if iter % 10 == 0: endtime = datetime.now() training_duration = (endtime - starttime).seconds / np.float(3600) param = 'epoches:{:4d} | fidelity:{:8f} | time:{:10s} | duration:{:8f}\n'.format( iter, round(fidelity, 6), time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), round(training_duration, 2)) train_log(param, './{}qubit_log_pure.txt'.format(cf.system_size)) if (cf.decay): eta = (cf.initial_eta * (cf.epochs - iter - 1) + (cf.initial_eta) * iter) / cf.epochs f = compute_fidelity(gen, zero_state, real_state) #plt_fidelity_vs_iter(fidelities, losses, cf, indx=0) save_model(gen, cf.model_gen_path) save_model(dis, cf.model_dis_path) fidelities[:] = [] losses[:] = [] #生成した状態 fake_state = gen.getState() genimg = decode4(fake_state) return genimg
def _grad_prob(self, dis, real_state): G_list = self.getGen() psi = dis.getPsi() phi = dis.getPhi() Q = real_state zero_state = get_zero_state(self.size) try: A = expm((-1 / lamb) * phi) except Exception: print('grad_gen -1/lamb:\n', (-1 / lamb)) print('size of phi:\n', phi.shape) try: B = expm((1 / lamb) * psi) except Exception: print('grad_gen 1/lamb:\n', (1 / lamb)) print('size of psi:\n', psi.shape) grad_psi_term = np.zeros_like(self.W_classical, dtype=complex) grad_phi_term = np.zeros_like(self.W_classical, dtype=complex) grad_reg_term = np.zeros_like(self.W_classical, dtype=complex) # (#mix,(#output,#input)) grad = np.zeros((self.num_to_mix, self.num_output, self.num_input)) for k in range(self.num_output): for l in range(self.num_input): for i in range(self.num_to_mix): tmp = 0 for j in range(self.num_output): # to calculate {\partial prob_gen[i]}{\partial W_classical[b][a]} # \[\frac{{\partial {g_i}}}{{\partial {z_j}}} \cdot \frac{{\partial {z_j}}}{{\partial {w_{ba}}}}\] # because j can be different so we fix i,k,l if j == i: if j == k: tmp_equal = ( self.prob_gen[i] - self.prob_gen[i]**2) * self.input[l] tmp += tmp_equal else: tmp_equal = 0 tmp += tmp_equal else: if j == k: tmp_notequal = -self.prob_gen[ i] * self.prob_gen[j] * self.input[l] tmp += tmp_notequal else: tmp_notequal = 0 tmp += tmp_notequal grad[i][k][l] = tmp for b in range(self.num_to_mix): for a in range(self.num_input): gW = np.zeros(G_list[0].shape, dtype=complex) for i in range(self.num_to_mix): state_i = np.matmul(G_list[i], zero_state) gW += grad[i][b][a] * (np.matmul(state_i, state_i.getH())) # calculate grad of psi term grad_psi_term[b][a] = 0 # calculate grad of phi term grad_phi_term[b][a] = np.trace(np.matmul(gW, phi)) # calculate grad of reg term term1 = np.trace(np.matmul(A, gW)) * np.trace(np.matmul(B, Q)) term2 = np.trace(np.matmul(A, np.matmul(gW, np.matmul(B, Q)))) term3 = np.trace(np.matmul(gW, np.matmul(A, np.matmul(Q, B)))) term4 = np.trace(np.matmul(B, gW)) * np.trace(np.matmul(A, Q)) grad_reg_term[b][a] = lamb / np.e * ( cst1 * term1 - cst2 * term2 - cst2 * term3 + cst3 * term4) grad_w = np.real(grad_psi_term - grad_phi_term - grad_reg_term) return grad_w