def __init__(self, zone2queue, alpha = .1, beta = .01, save = 10000):
				
		self.counter = 0
		self.alpha = alpha
		self.beta = beta
                self.file_out = 'MT_zoneB.csv'
                self.file_name = 'MT_zoneB_backup.csv'
                #self.MT = genfromtxt(self.file_name, delimiter=',')
                self.xi = [30, 30]
                self.MT = create_MEGA_THETA(self.xi)
                self.MTDIM = shape(self.MT)
              	self.DELTA = zeros([self.MTDIM[0],self.MTDIM[1]])
		self.zone2queue = zone2queue
		self.save_when = save
	def __init__(self, inlayer, outlayer, alpha = 1, beta = 0.4, mangle_upper = 0, save = 10, threads = 40):
		'''initiate queues and primary variables'''
		self.zone2_queue = Queue()
		self.DELTA_queue = Queue()
		self.errors_queue = Queue()

		# initiate NN variables
		self.counter = 0
		self.mangle_upper = mangle_upper
		self.file_out = 'MT_zoneA.csv'
		self.file_name = 'MT_zoneA_backup.csv'
		#self.MT = genfromtxt(self.file_name, delimiter=',')
		self.xi = [inlayer, outlayer]
		self.MT = create_MEGA_THETA(self.xi)
		self.MTDIM = shape(self.MT)
		self.DELTA = zeros([self.MTDIM[0],self.MTDIM[1]])
		self.alpha = alpha
		self.beta = beta
		self.save_when = save
		self.num_threads = threads
		self.threads = []
# get data from csv file into array
data = genfromtxt("training_data.csv", delimiter=",")

# get a subset for testing
num_cpus = 32
N = 100 * num_cpus  # batch size of data subset
y_vals = data[:, 0]  # outputs
x_vals = data[:, 1:].T  # inputs
x_vals = (x_vals > 0) * x_vals  # make inputs 0/1
data_size = size(y_vals)

# define some NN layers
xi = array([100, 10])

# randomly initiate NN values
MT = create_MEGA_THETA(xi)
MTDIM = shape(MT)
DELTA = zeros([MTDIM[0], MTDIM[1]])

# learning rate
alpha = 100 * N

# create some Queues for DELTA, time, good
time_queue = Queue()
good_queue = Queue()
DELTA_queue = Queue()

# initiate queues
time_queue.put(1.0)
good_queue.put(0.0)
	def optimise_network(self, xi, all_x, all_y):
		'''run backpropagation for digit = self.digit and save results'''

		self.MT = create_MEGA_THETA(xi)
		self.MTDIM = shape(self.MT)
		self.DELTA = zeros([self.MTDIM[0],self.MTDIM[1]])
		
		self.data_size = size(all_y)
		# execute backprop procedure until accuracy is high
		while self.success < .99999: # success rate goal
			self.selection = random.random_integers(0,self.data_size-1,self.N) # stochastic gradient descent
				
			# get some pixels' labels to mangle
			self.mangle0 = random.randint(0,self.mangle_upper)
			self.mangle1 = random.randint(0,self.mangle_upper)
			self.random_mangle0 = random.random_integers(0,self.base_in, self.mangle0)
			self.random_mangle1 = random.random_integers(0,self.base_in, self.mangle1)
			
			self.batch_x_vals = all_x[:,self.selection]	# SGD batch
			self.batch_y_vals = all_y[self.selection]	# SGD batch
			
			# mangle pixels, some --> 0 some --> 1	
			self.batch_x_vals[self.random_mangle0,:] = 0
			self.batch_x_vals[self.random_mangle1,:] = 1
			
			self.DELTA_queue.put(self.DELTA)
			self.DELTA_queue.task_done() 
			# run backprop optimisation w/ multi-threading
			self.threads = []
			
			# set NN input/output layers
			for i in range(0,self.N):
				# input vector
				self.x = self.batch_x_vals[:,i]
				self.x = kron(self.x, self.x)
				self.y = zeros(2)		# output of NN (row-less)
				if self.batch_y_vals[i] == self.digit:
					self.y[0] = 1	# indicate digit
				else:
					self.y[1] = 1	# indicate NOT digit
				self.thr = threading.Thread(target=forwardBackward,
					args=(xi, self.x, self.y, self.MT, self.time_queue, self.good_queue, self.DELTA_queue))
				self.threads.append(self.thr)

			# start all threads
			for i in range(0,self.N):
				self.threads[i].start()
			
			# spin until all threads finish
			for i in range(0,self.N):
				self.threads[i].join()
        			self.DELTA_queue.join()

			self.good = self.good_queue.get()
			self.time = self.time_queue.get()
			self.success = self.good/self.time

			print 'Success['+ str(self.digit) +']: ', self.success

			self.good_queue.put(self.good)
			self.good_queue.task_done()
			self.time_queue.put(self.time)
			self.time_queue.task_done()
		  	self.DELTA = self.DELTA_queue.get()
			self.MT = self.MT - (self.alpha/self.N)*self.DELTA - self.beta*self.MT
			self.DELTA = 0*self.DELTA
			if self.counter == 50:
				savetxt(self.file_out, self.MT, delimiter=',')
				print 'Success ['+ str(self.digit) +']: ', self.success
				print '###  SAVED DATA to '+ self.file_out +'  ###'
				self.counter = 0 # reset
			self.counter += 1

		savetxt(self.file_out, self.MT, delimiter=',')