def dmlpred(self): self._mdmlalist = [] out = True self.verbose("Hosting DML test") for i in range(self._hostnum): conn = self._mdmlconnlist[i] rcv = smsg.recv(conn) if (rcv == None): self.error("aggregate rcv has failed from donor", i) out = False #Error occurred else: ra = deserialize(rcv) #ra = numpy.array( json.loads(rcv)) self._mdmlalist.append(ra) conn.send('ACKN'.encode('utf-8')) if (len(self._mdmlalist) < 1): self.error("No aggregates received, Aborting") out = False #Error occurred self.__abortAll() else: asum = numpy.zeros(self._mdmlalist[0].shape, dtype=self.compd) for i, a in enumerate(self._mdmlalist): self.info("aggregate", i, a.shape) asum = a + asum # only test against the first TODO: selectable testing for i in range(self._hostnum): conn = self._mdmlconnlist[i] dumped = serialize(asum) smsg.send(conn, dumped) self.verbose("DML done. ASUM pushed to donors") return out
def negotiate(self, ahostaddr): '''start negotation, first sends in the donor's own prepared negform to inform the central about the number of entries/features, it is expected that _mDmat is read from a file/stdin before this @params ahostaddr - a tuple ('localhost',portnumber i.e 8000)''' _mnegform = NegForm(self) #creates the negotiation form self.verbose("Negform created. Beginning Negotation...") try: negstr = json.dumps( _mnegform.primary) #obtains the primary neg data self._msocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._msocket.connect( ahostaddr) #attempting to connect to the host (central) self.debug("Host connected. Sending negstr") smsg.send(self._msocket, negstr) self.debug( "Negotiation form sent to central. Awaiting synchronization") self._mnegform = NegForm(json.loads(smsg.recv(self._msocket))) self.info("Synchronized form:") self._mnegform.display() self.partition_internals(self._mnegform.primary["bsize"]) self.kernel = self._npdc.computeKernel() if not type(self.kernel) == numpy.ndarray: self.warn("Kernel computational error!") else: self.verbose("Partitioned and computed the kernel", self.kernel.shape) except Exception as e: self.expt(str(e), traceback.format_exc()) finally: return self.hasNegotiated()
def negotiate(self,ahostaddr,train=True): '''start negotation, first sends in the donor's own prepared negform to inform the central about the number of entries/features, it is expected that _mDmat is read from a file/stdin before this @params ahostaddr - a tuple ('localhost',portnumber i.e 8000)''' if( train ): # TRAINING MODE _mnegform = NegForm(self) #creates the negotiation form self.verbose("Negform created. Beginning Negotation...") try: negstr = json.dumps(_mnegform.primary) #obtains the primary neg data self._msocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._msocket.connect( ahostaddr ) #attempting to connect to the host (central) self.debug("Host connected. Sending negstr") smsg.send( self._msocket, negstr ) self.debug("Negotiation form sent to central. Awaiting synchronization") self._mnegform = NegForm( json.loads( smsg.recv( self._msocket ) ) ) self.info("Synchronized form:") self._mnegform.display() except Exception as e: self.expt(str(e),traceback.format_exc()) finally: return self.hasNegotiated() else: # PREDICTION MODE try: self._msocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._msocket.connect( ahostaddr ) return True except Exception as e: self.expt(str(e),traceback.format_exc()) return False
def connpred(self): #TODO: figure out how to implement this if( self.isTrained ): aggregate = self._npdc.df.dot( self._mweights ) self.verbose("Sending test prediction to central",aggregate.shape) #self.raw( aggregate ) dumped = serialize( aggregate ) smsg.send( self._msocket, dumped ) repmsg = self._msocket.recv(4) if( repmsg.decode('utf-8') == "ACKN" ): #proceed self.info("All Aggregates sent. Awaiting results.") rcv = smsg.recv( self._msocket ) if(rcv != None): try: if( rcv.decode('utf-8') == 'ABRT'): self.error("Abort request by central.") except UnicodeDecodeError: self._mres = deserialize( rcv ) self.verbose("Received DML pred results:") self.info( self._mres ) return True else: self.error("rcv is null. Receiving error on _mres") else: self.error("Failed to receive ACKN from host. Terminating conntest") else: self.error("Weights not available. Is the donor trained ?") return False
def conntrain(self,targetname=None): '''conntrain should begin connection with the central, send in the _mDmat_train and (if it has the target) _mTvct_train. await response from server and fill in the received alpha to _mdist_alpha''' if( self.hasNegotiated() ): self.targetname = targetname if(self.targetname is not None): self.train_x, self.test_x, self.train_y, self.test_y = \ self._npdc.obtrain( self._mnegform.primary["bsize"] , targetname ) else: self.train_x, self.test_x = self._npdc.obtrain( self._mnegform.primary["bsize"] ) self.kernel = computeKernel( self.train_x ) if not type(self.kernel) == numpy.ndarray: self.warn("Kernel computational error!") else: self.verbose("Partitioned and computed the kernel",self.kernel.shape) self.verbose("Sending kernel to central") #dumped = json.dumps( self.kernel.tolist() ) # THIS line is crashing the system (for size 10k) self.debug("Training headers (include targets) :") self.raw( self._npdc.hlist ) dumped = serialize( self.kernel ) self.verbose("Total serial dump: {} bytes".format(len(dumped))) smsg.send( self._msocket, dumped ) #json dump and send the array # await confirmation repmsg = self._msocket.recv(4) if( repmsg.decode('utf-8') == "ACKN" ): # proceed if( self.targetname is not None ): # dump the target_train to bytes and send it on over socket dumped = serialize( self.train_y ) smsg.send( self._msocket, dumped) # await for alpha self.info("All Kernels sent. Awaiting central response.") rcv = smsg.recv( self._msocket ) if(rcv != None): try: if( rcv.decode('utf-8') == 'ABRT'): self.error("Abort request by central.") self.hasAlpha = False except UnicodeDecodeError : self.verbose("Unicode decode failed. Proceeding with deserialization") self._mdistalpha = deserialize(rcv) self.info("Distributed alpha received.") self.hasAlpha=True self.recover_weights() # perform weight recovery else: self.error("rcv is null. Receiving error _mdistalpha") self.hasAlpha = False else: #failed self.error("Failed to receive ACKN from host. Terminating conntrain") self.hasAlpha = False else: self.error("This donor has not synchronized the params with the central,\ please run negotiate( addr ) first !") self.hasAlpha = False return self.hasAlpha
def conntrain(self): '''conntrain should begin connection with the central, send in the _mDmat_train and (if it has the target) _mTvct_train. await response from server and fill in the received alpha to _mdist_alpha''' if (self.hasNegotiated()): self.verbose("Sending kernel to central") #dumped = json.dumps( self.kernel.tolist() ) # THIS line is crashing the system (for size 10k) dumped = serialize(self.kernel) self.verbose("Total serial dump: {} bytes".format(len(dumped))) smsg.send(self._msocket, dumped) #json dump and send the array # await confirmation repmsg = self._msocket.recv(4) if (repmsg.decode('utf-8') == "ACKN"): # proceed if (self.hasTarget): # dump the target_train to bytes and send it on over socket dumped = serialize( self._npdc.get(side='target', batch='train')) smsg.send(self._msocket, dumped) # await for alpha self.info("All Kernels sent. Awaiting central response.") rcv = smsg.recv(self._msocket) if (rcv != None): try: if (rcv.decode('utf-8') == 'ABRT'): self.error("Abort request by central.") self.hasAlpha = False except UnicodeDecodeError: self.verbose( "Unicode decode failed. Proceeding with deserialization" ) self._mdistalpha = deserialize(rcv) self.info("Distributed alpha received.") self.hasAlpha = True self.recover_weights() # perform weight recovery else: self.error("rcv is null. Receiving error _mdistalpha") self.hasAlpha = False else: #failed self.error( "Failed to receive ACKN from host. Terminating conntrain") self.hasAlpha = False else: self.error( "This donor has not synchronized the params with the central,\ please run negotiate( addr ) first !") self.hasAlpha = False return self.hasAlpha
def conntest(self): '''conntest should begin connection with the central, send in the _mDmat_train and (if it has the target) _mTvct_train. await response from server which it will return the error rating of the model RETURNS True upon No errors. False otherwise''' if (self.isTrained): aggregate = self._npdc.get(side="data", batch="test").dot(self._mweights) self.verbose("Sending test prediction to central", aggregate.shape) #self.raw( aggregate ) dumped = serialize(aggregate) smsg.send(self._msocket, dumped) repmsg = self._msocket.recv(4) if (repmsg.decode('utf-8') == "ACKN"): #proceed if (self.hasTarget): # dump the target_test to bytes and send it on over socket dumped = serialize( self._npdc.get(side='target', batch='test')) smsg.send(self._msocket, dumped) #await for test results self.info("All Aggregates sent. Awaiting results.") rcv = smsg.recv(self._msocket) if (rcv != None): if (rcv.decode('utf-8') == 'ABRT'): self.error("Abort request by central.") else: self._mres = json.loads(rcv) self.verbose("Received DML test results:") self.info("MSE:", self._mres.get("mse")) self.info("R2S:", self._mres.get("r2s")) return True else: self.error("rcv is null. Receiving error on _mres") else: self.error( "Failed to receive ACKN from host. Terminating conntest") else: self.error("Weights not available. Is the donor trained ?") return False
def dmltrain(self): '''dmltrain should start listen on the ahostaddr bounded during negotations, and attempts to receive the numpy arrays obtained from the various donors. it then has to generate the distributed alpha from the operations''' self._mdmlklist = [] self._mdmltlist = [] out = True if (self.hasNegotiated()): f = StringIO() lval = self._mnegformlist[0].primary['rrlambda'] self.verbose("Hosting DML training lval:", lval, "bsize:", self._mnegformlist[0].primary['bsize']) for i in range(self._hostnum): conn = self._mdmlconnlist[i] self.verbose("Receiving kernel from donor", i) rcv = smsg.recv(conn) if (rcv == None): self.error("kernel rcv has failed from donor", i) out = False else: rk = deserialize(rcv) #rk = numpy.array(json.loads( rcv )) self.verbose("kernel rcv has succeeded from donor", i) self._mdmlklist.append(rk) # sends the ACK conn.send('ACKN'.encode('utf-8')) if (self._mnegformlist[i].primary['dflag']): # this donor possess target, receives it rcv = smsg.recv(conn) if (rcv == None): self.error("train targets rcv has failed from donor", i) out = False else: rt = deserialize(rcv) #rt = numpy.array(json.loads( rcv )) self._mdmltlist.append(rt) if (len(self._mdmlklist) < 1): self.error("No kernels received") out = False self.__abortAll() elif (len(self._mdmltlist) < 1): self.error( "No Targets. Please check if target donor is specified correctly" ) out = False self.__abortAll() else: # all kernels and targets received # sum all kernels ksum = numpy.zeros(self._mdmlklist[0].shape, dtype=self.compd) for i, k in enumerate(self._mdmlklist): self.info("kernel", i, k.shape) ksum += k # only train against the first TODO : selectable training targ = self._mdmltlist[0] self.verbose("Starting Ridge Solver") if (len(targ.shape) < 2): tdim = 1 else: tdim = targ.shape[1] alpha = pyplasma.ridge_solve(ksum.flatten(), ksum.shape[0], ksum.shape[1], targ.flatten(), targ.shape[0], tdim, lval, 1, ksum.shape[0] * tdim) self.info("Alpha meta:", type(alpha), alpha.shape) dumped = serialize(alpha) for i in range(self._hostnum): conn = self._mdmlconnlist[i] smsg.send(conn, dumped) #dump to bytes and send self.info("DML training complete") self.donorTrained = out return out
def __abortAll(self): for i in range(self._hostnum): conn = self._mdmlconnlist[i] smsg.send(conn, "ABRT") #send the abort message to all host
def host_negotiations(self, asrvaddr, batchfactor=0.1, rrlambda=1.0, train=True): '''begins negotiations by listening on ahostaddr. receives the negform and syncs them up with the donors @params ahostaddr - a tuple ('localhost',portnumber i.e 8000) @params batchfactor - the value to batch up the train/test set @params rrlamdda - the ridge regressor's hyperparam''' # the host are indexed based on the order in which they connect self._mdmlconnlist = [] self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if (train): # TRAINING MODE self.verbose("Negotiation for DML TRAIN") self._mnegformlist = [] try: self.sock.bind(asrvaddr) self.sock.listen(self._hostnum) # Negotiations round 1 for i in range(self._hostnum): self.debug("Listening on address:", asrvaddr) connection, rcliaddr = self.sock.accept() self.debug("Connection established with", rcliaddr) # receives the json obj negf = NegForm(json.loads(smsg.recv(connection))) negf.display() self._mnegformlist.append(negf) self._mdmlconnlist.append(connection) # Process to formulate the batchsizes bsize = aux.evaluate_bsize(aux.find_minesz(self._mnegformlist), batchfactor) self.info("bsize decided on", bsize) # Negotiations round 2 for i in range(self._hostnum): self._mnegformlist[i].primary['bsize'] = bsize self._mnegformlist[i].primary['rrlambda'] = rrlambda smsg.send(self._mdmlconnlist[i], json.dumps(self._mnegformlist[i].primary)) self.debug("Negotiation forms pushed back to host", i) except Exception as e: self.expt(str(e), traceback.format_exc()) finally: return self.hasNegotiated() else: # PREDICTION MODE self.verbose("Negotiation for DML PRED") try: self.sock.bind(asrvaddr) self.sock.listen(self._hostnum) for i in range(self._hostnum): self.debug("Listening on address:", asrvaddr) connection, rcliaddr = self.sock.accept() self.debug("Connection established with", rcliaddr) self._mdmlconnlist.append(connection) return True except Exception as e: self.expt(str(e), traceback.format_exc()) return False
def dmltest(self): '''dmltest should start to listen on the _npdc_hostadr bounded during negotiations, and attempts to receive the numpy arrays (TEST BATCH) from the same donors, it then returns the evaluation metrics RETURNS Ture upon No errors. False otherwise''' self._mdmlalist = [] self._mdmlvlist = [] out = True if (self.hasNegotiated() and self.donorTrained): self.verbose("Hosting DML test") for i in range(self._hostnum): conn = self._mdmlconnlist[i] rcv = smsg.recv(conn) if (rcv == None): self.error("aggregate rcv has failed from donor", i) out = False #Error occurred else: ra = deserialize(rcv) #ra = numpy.array( json.loads(rcv)) self._mdmlalist.append(ra) conn.send('ACKN'.encode('utf-8')) if (self._mnegformlist[i].primary['dflag']): rcv = smsg.recv(conn) if (rcv == None): self.error("test targets rcv has failed from donor", i) out = False #Error occurred else: rt = deserialize(rcv) #rt = numpy.array(json.loads(rcv)) self._mdmlvlist.append(rt) self.verbose("received test targets from donor", i) if (len(self._mdmlalist) < 1): self.error("No aggregates received, Aborting") out = False #Error occurred self.__abortAll() if (len(self._mdmlvlist) < 1): self.error( "No verifying targets. Is target donor specified correctly?" ) out = False self.__abortAll() else: asum = numpy.zeros(self._mdmlalist[0].shape, dtype=self.compd) for i, a in enumerate(self._mdmlalist): self.info("aggregate", i, a.shape) asum = a + asum # only test against the first TODO: selectable testing varg = self._mdmlvlist[0] jrep = { "mse": mean_squared_error(asum, varg), "mae": mean_absolute_error(asum, varg), "max": max_error(asum, varg), "evs": explained_variance_score(asum, varg), "r2s": r2_score(asum, varg) } self.verbose("mse", jrep.get("mse")) self.verbose("mae", jrep.get("mae")) self.verbose("max", jrep.get("max")) self.verbose("evs", jrep.get("evs")) self.verbose("r2s", jrep.get("r2s")) for i in range(self._hostnum): conn = self._mdmlconnlist[i] smsg.send(conn, json.dumps(jrep)) self.verbose("DML done. JREP pushed to donors") else: self.error( "Not negotiated or donor is not trained yet, unable to test") out = False return out