def getOwnTheoryABC(self): """ Gets the A B and C from the own theory functions: chi2(p) = pAp + Bp + C """ if not self.chi2init: raise RuntimeError("chi2 not inited, cannot get ABC") nTotal = self.nZero + self.nFunc A = np.zeros((2*nTotal, 2*nTotal)) B = np.zeros((2*nTotal)) C = 0. countNfunc = self.nZero allFuncs = np.zeros((2*nTotal, 2*self.totalBins)) allAmpls = np.zeros((2*self.totalBins)) for b in range(self.totalBins): allAmpls[2*b ] = self.reals[b] allAmpls[2*b+1] = self.imags[b] for z in range(self.nZero): for b in range(self.totalBins): allFuncs[2*z ,2*b ] = self.zeroModes[z][b].real # allFuncs[2*z+1,2*b ] =-self.zeroModes[z][b].imag # Zero modes are real # allFuncs[2*z ,2*b+1] = self.zeroModes[z][b].imag # Zero modes are real allFuncs[2*z+1,2*b+1] = self.zeroModes[z][b].real count = self.nZero for s in range(self.nSect): if not s in self.funcs: continue nFunc = self.nFuncs[s] masses = self.binCenters[self.borders[s]:self.borders[s+1]] ampls = [f(masses, externalKinematicVariables = [self.binCenter]) for f in self.funcs[s]] for ampl in ampls: for b,a in enumerate(ampl): bin = self.borders[s] + b allFuncs[2*count ,2*bin ] =-a.real * self.norms[bin]**.5 allFuncs[2*count+1,2*bin ] = a.imag * self.norms[bin]**.5 allFuncs[2*count ,2*bin+1] =-a.imag * self.norms[bin]**.5 allFuncs[2*count+1,2*bin+1] =-a.real * self.norms[bin]**.5 count += 1 # # # Do not handle mass ranges here, it is take care of by the coma CC = np.dot(allAmpls, np.dot(self.comaInv, allAmpls)) CIZF = np.dot(allFuncs, self.comaInv) # comaInf * zeroModes & Functions BB = 2*np.dot(CIZF, allAmpls) AA = np.dot(CIZF, allFuncs.T) try: utils.pinv(AA+AA.T) except: print allFuncs return AA,BB,CC
def makeComaInv(self): """ Inverts the covariance matrix (To be able to change the inversion method globally) """ # Change here: Check sector range map an invert submatrix # # mapy = np.copy(self.coma) # coMA co PY if self.hasMassRange: zeroIndices = [] for s in range(self.nSect): for i,b in enumerate(range(self.borders[s],self.borders[s+1])): if s in self.massRanges: binCenterMass = self.binCenters[b] if binCenterMass < self.massRanges[s][0] or binCenterMass >= self.massRanges[s][1]: zeroIndices.append(b) for i in range(len(self.coma)): for zi in zeroIndices: mapy[i,2*zi ] = 0. mapy[i,2*zi+1] = 0. mapy[2*zi ,i] = 0. mapy[2*zi+1,i] = 0. if self.ownPinv: self.comaInv = utils.pinv(mapy, numLim = self.numLim) else: self.comaInv = la.pinv(mapy)
def getFcnCpls(self, zeroModePars): A,B,C = self.getFcnCplsABC(zeroModePars) if self.ownPinv: couplings = -np.dot(B, utils.pinv(np.transpose(A) + A, numLim = self.numLim)) else: couplings = -np.dot(B, la.pinv(np.transpose(A) + A)) return couplings
def fixedZMPchi2(self, pars): """ Returns a chi2 for the shape parameters and self.zeroModeParameters. The couplings are calculated. """ if not self.hasZMP and self.nZero > 0: raise RuntimeError("No zero mode parameters set") if pars is not None: self.setShapeParameters(pars) a,b,c = self.getOwnTheoryABC() A = np.zeros((2*self.nFunc, 2*self.nFunc)) B = np.zeros((2*self.nFunc)) C = c for i in range(2*self.nZero): C += b[i]*self.zeroModeParameters[i] for j in range(2*self.nZero): C += self.zeroModeParameters[i]*self.zeroModeParameters[j]*a[i,j] for i in range(2*self.nFunc): B[i] += b[2*self.nZero+i] for j in range(2*self.nZero): B[i] += (a[2*self.nZero+i,j]+a[j,2*self.nZero+i])*self.zeroModeParameters[j] for j in range(2*self.nFunc): A[i,j] += a[2*self.nZero + i, 2*self.nZero+j] if self.ownPinv: couplings = -np.dot(B, utils.pinv(np.transpose(A) + A, numLim = self.numLim)) else: couplings = -np.dot(B, la.pinv(np.transpose(A) + A)) return np.dot(couplings, np.dot(A,couplings)) + np.dot(B,couplings) + C
def chi2(self, pars = [], returnParameters = False): """ Evaluates the chi2 function, with shape parameters. If none are set, it uses, the internally set ones. non-shape parameters are calculated """ if not self.chi2init: raise RuntimeError("chi2 not inited, cannot evaluate") print pars if len(pars) is not 0: self.setShapeParameters(pars) A,B,C = self.getOwnTheoryABC() # print B # print A if self.ownPinv: zmPars = -np.dot(B, utils.pinv(A + np.transpose(A), numLim = self.numLim)) else: zmPars = -np.dot(B, la.pinv(A + np.transpose(A))) chi2 = np.dot(zmPars,np.dot(A,zmPars)) + np.dot(zmPars,B) + C if returnParameters: return chi2, zmPars else: return chi2
def getNonShapeParameters(self, pars = []): """ Gets the non-shape parameters at the minimum of chi2(...) """ if not self.chi2init: raise RuntimeError("Chi2 not initialized, cannot evaluate") if len(pars) > 0: self.setShapeParameters(pars) A,B,C = self.getOwnTheoryABC() if self.ownPinv: return -np.dot(B, utils.pinv(A + np.transpose(A), numLim = self.numLim)) else: return -np.dot(B, la.pinv(A + np.transpose(A)))
def getSpecialComaInv(self, mode = PHASE): """ Returns the transformed covarinace matrix for a special method. Stores it also, to do not have to do this over and over again """ if mode in self.specialCOMAs: return self.specialCOMAs[mode] mapy = np.copy(self.coma) # coMA co PY if self.hasMassRange: zeroIndices = [] for s in range(self.nSect): for i,b in enumerate(range(self.borders[s],self.borders[s+1])): if s in self.massRanges: binCenterMass = self.binCenters[b] if binCenterMass < self.massRanges[s][0] or binCenterMass >= self.massRanges[s][1]: zeroIndices.append(b) for i in range(len(mapy)): for zi in zeroIndices: mapy[i,2*zi ] = 0. mapy[i,2*zi+1] = 0. mapy[2*zi ,i] = 0. mapy[2*zi+1,i] = 0. jacobian = np.zeros((self.totalBins, 2*self.totalBins)) for i in range(self.totalBins): if mode == INTENS: jacobian[i, 2*i ] = 2*self.reals[i] jacobian[i, 2*i+1] = 2*self.imags[i] elif mode == PHASE: re = self.reals[i] im = self.imags[i] if re == 0.: if im > 0.: jacobian[i,2*i ] = -1./im else: jacobian[i,2*i ] = 1./im else: common = 1. + im**2/re**2 jacobian[i,2*i ] = -im/re**2/common jacobian[i,2*i+1] = 1./re/common if self.onwPinv: retVal = utils.pinv(np.dot(jacobian, np.dot(mapy, np.transpose(jacobian))), numLim = self.numLim) else: retVal = la.pinv(np.dot(jacobian, np.dot(mapy, np.transpose(jacobian)))) self.specialCOMAs[mode] = retVal return retVal
def fixedZMPchi2_realCouplings(self, pars, phase, scan = True): """ Returns a chi2 for the shape parameters and self.zeroModeParameters. The real magnitudes of the couplings are calculated, they share a complex phase, which is given. """ if not self.hasZMP and self.nZero > 0: raise RuntimeError("No zero mode parameters set") if pars is not None: self.setShapeParameters(pars) a,b,c = self.getOwnTheoryABC() cosP = cos(phase) sinP = sin(phase) A = np.zeros((self.nFunc, self.nFunc)) B = np.zeros((self.nFunc)) C = c for i in range(2*self.nZero): C += b[i]*self.zeroModeParameters[i] for j in range(2*self.nZero): C += self.zeroModeParameters[i]*self.zeroModeParameters[j]*a[i,j] for i in range(self.nFunc): B[i] += cosP*b[2*self.nZero+2*i ] B[i] += sinP*b[2*self.nZero+2*i+1] for j in range(2*self.nZero): B[i] += cosP*(a[2*self.nZero+2*i ,j]+a[j,2*self.nZero+2*i ])*self.zeroModeParameters[j] B[i] += sinP*(a[2*self.nZero+2*i+1,j]+a[j,2*self.nZero+2*i+1])*self.zeroModeParameters[j] for j in range(self.nFunc): A[i,j] += cosP**2 * a[2*self.nZero + 2*i , 2*self.nZero + 2*j ] A[i,j] += cosP*sinP * a[2*self.nZero + 2*i , 2*self.nZero + 2*j+1] A[i,j] += sinP*cosP * a[2*self.nZero + 2*i+1, 2*self.nZero + 2*j ] A[i,j] += sinP**2 * a[2*self.nZero + 2*i+1, 2*self.nZero + 2*j+1] if self.ownPinv: couplings = -np.dot(B, utils.pinv(np.transpose(A) + A, numLim = self.numLim)) else: couplings = -np.dot(B, la.pinv(np.transpose(A) + A)) retVal = np.dot(couplings, np.dot(A,couplings)) + np.dot(B,couplings) + C return retVal
def train(Config): ''' 模型训练的整个流程,包括: step1: 数据 step2: 定义模型 step3: 目标函数与优化器 step4: 统计指标:平滑处理之后的损失,还有混淆矩阵(无监督训练时不需要) 训练并统计 ''' # step1: 数据 train_dataset = torchvision.datasets.MNIST(root=Config.train_data_root, train=True, transform=transforms.ToTensor(), download=False) train_dataloader = DataLoader(dataset=train_dataset, batch_size=Config.batch_size, shuffle=True, num_workers=Config.num_workers) # step2: 定义模型 decoder = Decoder(z_dim=10) if Config.load_model_path: decoder.load(Config.load_model_path) if Config.use_gpu: decoder.to(Config.device) # step3: 目标函数与优化器 lr = Config.lr optimizer = torch.optim.Adam(decoder.parameters(), lr=lr, weight_decay=Config.weight_decay) # 训练 N1 = Config.N1 N2 = Config.N2 N3 = Config.N3 bls = BLS(N1,N2,N3,28*28,10) images,_ = iter(train_dataloader).next() if Config.use_gpu: images = images.cuda() images = images.double().view(-1, 28 * 28) FeatureMaps, EnhancementNodes = bls(images.cpu(), train=True) # 使用矩阵伪逆求出对应的参数矩阵W A = torch.cat([FeatureMaps, EnhancementNodes], dim=1) A_inv = pinv(A) W = 0.1 * torch.randn(A.size()[1], 2 * decoder.z_dim) for epoch in range(Config.max_epoch): parameters = A.mm(W) # 使用reparameter trick # 注意:由于pytorch中并不会保存中间变量的梯度值(故须要使用hook机制进行保存) mu = parameters[:, :decoder.fc1.in_features].to(Config.device) mu.register_hook(save_grad('mu')) logvar = parameters[:, decoder.fc1.in_features:].to(Config.device) logvar.register_hook(save_grad('logvar')) std = torch.exp(0.5 * logvar) epslon = torch.randn_like(mu) z = epslon * std + mu # 将encoder产生的z放入到encoder中,并计算loss optimizer.zero_grad() re_images = decoder(z) loss = VAE_Loss(images, re_images, mu, logvar) loss.backward() print(grads['mu'], grads['logvar']) mu = mu - 100 * grads['mu'] logvar = logvar - 100 * grads['logvar'] W = W - A_inv.mm(torch.cat(100*[grads['mu'],grads['logvar']],dim=1).cpu()) WW = A_inv.mm(torch.cat(100*[mu,logvar],dim=1)) optimizer.step() for epoch in range(Config.max_epoch): for i, (images,_) in enumerate(train_dataloader): if Config.use_gpu: images = images.cuda() images = images.double().view(-1, 28 * 28) FeatureMaps, EnhancementNodes = bls(images.cpu(),train=True) _,enhancementnode = bls.AddEnhancementNodes(50) # 使用矩阵伪逆求出对应的参数矩阵W A = torch.cat([FeatureMaps, EnhancementNodes], dim=1) A_inv = pinv(A) W = 0.1*torch.randn(A.size()[1], 2 * decoder.z_dim) parameters = A.mm(W) # 使用reparameter trick # 注意:由于pytorch中并不会保存中间变量的梯度值(故须要使用hook机制进行保存) mu = parameters[:, :decoder.fc1.in_features].to(Config.device) mu.register_hook(save_grad('mu')) logvar = parameters[:, decoder.fc1.in_features:].to(Config.device) logvar.register_hook(save_grad('logvar')) # sns.set_style('darkgrid') # sns.distplot(mu.view(-1).cpu().detach()) # plt.show() # sns.set_style('darkgrid') # sns.distplot(logvar.view(-1).cpu().detach()) # plt.show() std = torch.exp(0.5 * logvar) epslon = torch.randn_like(mu) z = epslon*std+mu # 将encoder产生的z放入到encoder中,并计算loss optimizer.zero_grad() re_images = decoder(z) loss = VAE_Loss(images,re_images,mu,logvar) loss.backward() print(grads['mu'],grads['logvar']) mu = mu - lr*grads['mu'] logvar = logvar - lr*grads[logvar] optimizer.step() if i % Config.print_freq == Config.print_freq - 1: # 当达到指定频率时,显示损失函数并画图 print('Epoch:', epoch + 1, 'Round:', i + 1, 'Loss:', loss.item()) ImageVsReImagePlot(images, re_images, Config) decoder.save() GenerativePlot(decoder, Config)
def main(): nF0, nRho, nF2 = loadN() bin = 34 # Seed # neg log like # seedAppendix = "_1498549364" # # seedAppendix = "_1498570556" # -1.31183e+07 # seedAppendix = "_1498570525" # -1.31178e+07 # seedAppendix = "_1498570546" # -1.31174e+07 # seedAppendix = "_1498570532" # -1.31184e+07 # seedAppendix = "_1498570552" # -1.31156e+07 # seedAppendix = "_1498652006" # -1.34472e+07 # seedAppendix = "_1498652015" # -1.34515e+07 # seedAppendix = "_1498652011" # -1.34499e+07 # seedAppendix = "_1498652008" # -1.34471e+07 # seedAppendix = "_1498652038" # -1.34464e+07 # seedAppendix = "_1498815114" # -1.34505e+07 # seedAppendix = "_1498815131" # -1.34466e+07 # seedAppendix = "_1498815125" # -1.34459e+07 # seedAppendix = "_1498815128" # -1.34462e+07 # seedAppendix = "_1498815121" # -1.34475e+07 # seedAppendix = "_1512582427" seedAppendix = "_1512637090" amplFileName = "./build/largeErrorStudy_amplitudes" + seedAppendix + ".dat" hessFileName = "./build/largeErrorStudy_hessian" + seedAppendix + ".dat" inteFileName = "./build/largeErrorStudy_integral.dat" binFfileName = "./build/largeErrorStudy_binningF0.dat" binRfileName = "./build/largeErrorStudy_binningRho.dat" binF2fileName = "./build/binningF2.dat" conjugate = True binningF0 = loadBinning(binFfileName) binningRho = loadBinning(binRfileName) binningF2 = loadBinning(binF2fileName) nBins = 0 eigenString = "" sectors = {} if nF2 > 1: dnb = len(binningF2) - 1 sectors["Dp[pi,pi]2++PiD"] = (nBins, nBins + dnb) nBins += dnb eigenString += "Dp[pi,pi]2++PiD" if nF0 > 1: dnb = len(binningF0) - 1 sectors["Dp[pi,pi]0++PiS"] = (nBins, nBins + dnb) nBins += dnb if len(eigenString) > 0: eigenString += "<|>" eigenString += "Dp[pi,pi]0++PiS" if nRho > 1: dnb = len(binningRho) - 1 sectors["Dp[pi,pi]1--PiP"] = (nBins, nBins + dnb) nBins += dnb if len(eigenString) > 0: eigenString += "<|>" eigenString += "Dp[pi,pi]1--PiP" print nF0, nRho, nF2, nBins ampl = loadAmplitudeFile(amplFileName, conjugate) hessian = loadRealMatrixFile(hessFileName) inte = integral(inteFileName) if nRho == 1: # Remove fixed waves from the integral matrix inte.removeIndices(nF0 + nF2) ampl, hessian = removeIndex(nF0 + nF2, ampl, hessian) if nF0 == 1: inte.removeIndices(nF2) ampl, hessian = removeIndex(nF2, ampl, hessian) if nF2 == 1: inte.removeIndices(0) ampl, hessian = removeIndex(0, ampl, hessian) inte.norm() inte.eigen() norm = inte.norms svals, sev = inte.getSmallVectors(0.001) hasZeroMode = False if len(sev) > 0: hasZeroMode = True else: print "No zero-mode found" comaName = "COMA_0_" + str(bin) histReName = "INTEGRAL_r_0_" + str(bin) histImName = "INTEGRAL_i_0_" + str(bin) # COMA = la.inv(hessian) COMA = utils.pinv(hessian, 1.e-4) if conjugate: for i in range(2 * nBins): for j in range(2 * nBins): iNdex = i jNdex = j sign = (-1)**(iNdex + jNdex) COMA[iNdex, jNdex] *= sign # COMA = projectOutPhaseDirection(COMA, ampl) with root_open("DpPiPiPi_largeErrorStudy.root", "RECREATE") as outFile: COMAhist = pyRootPwa.ROOT.TH2D(comaName, comaName, 2 * nBins, 0., 1., 2 * nBins, 0., 1.) intReHist = pyRootPwa.ROOT.TH2D(histReName, histReName, nBins, 0., 1., nBins, 0., 1.) intImHist = pyRootPwa.ROOT.TH2D(histImName, histImName, nBins, 0., 1., nBins, 0., 1.) for i in range(nBins): for j in range(nBins): intReHist.SetBinContent(i + 1, j + 1, inte[i, j].real) intImHist.SetBinContent(i + 1, j + 1, inte[i, j].imag) intReHist.Write() intImHist.Write() for i in range(2 * nBins): # COMAhist.SetBinContent(i+1, i+1, 1.) # first two are fixed isobar for j in range(2 * nBins): iNdex = i jNdex = j COMAhist.SetBinContent( i + 1, j + 1, COMA[iNdex, jNdex]) # first two are fixed isobar pass COMAhist.Write() for i, zeroMode in enumerate(sev): eigenHist = pyRootPwa.ROOT.TH1D("eigen" + str(i) + "_0", eigenString, 50, .5, 2.5) eigenHist.SetBinContent(bin + 1, svals[i]) eigenHist.Write() zeroHist = pyRootPwa.ROOT.TH2D("zero" + str(i) + "_0", eigenString, 50, .5, 2.5, nBins, 0., 1.) for i in range(nBins): zeroHist.SetBinContent(bin + 1, i + 1, zeroMode[i].real) zeroHist.Write() for sector in sectors: if "1--" in sector: isobarBinning = binningRho elif "0++" in sector: isobarBinning = binningF0 elif "2++" in sector: isobarBinning = binningF2 else: "Sector not valid: '" + sector + "'" histIntens = pyRootPwa.ROOT.TH2D(sector + "_0_intens", sector + "_0_intens", len(binning3Pi) - 1, binning3Pi, len(isobarBinning) - 1, isobarBinning) histReal = pyRootPwa.ROOT.TH2D(sector + "_0_real", sector + "_0_real", len(binning3Pi) - 1, binning3Pi, len(isobarBinning) - 1, isobarBinning) histImag = pyRootPwa.ROOT.TH2D(sector + "_0_imag", sector + "_0_imag", len(binning3Pi) - 1, binning3Pi, len(isobarBinning) - 1, isobarBinning) histNorm = pyRootPwa.ROOT.TH2D(sector + "_0_norm", sector + "_0_norm", len(binning3Pi) - 1, binning3Pi, len(isobarBinning) - 1, isobarBinning) histIndex = pyRootPwa.ROOT.TH2D(sector + "_0_index", sector + "_0_index", len(binning3Pi) - 1, binning3Pi, len(isobarBinning) - 1, isobarBinning) for b, B in enumerate(range(sectors[sector][0], sectors[sector][1])): histIntens.SetBinContent(bin + 1, b + 1, abs(ampl[B])**2) histReal.SetBinContent(bin + 1, b + 1, ampl[B].real) histImag.SetBinContent(bin + 1, b + 1, ampl[B].imag) histNorm.SetBinContent(bin + 1, b + 1, norm[B]) histIndex.SetBinContent(bin + 1, b + 1, B) histIntens.Write() histReal.Write() histImag.Write() histNorm.Write() histIndex.Write()