def test_3lnn_load_dataset(self): il_nn = 2 hl_nn = [4] ol_nn = 2 nn = NeuralNetwork(il_nn, hl_nn, ol_nn) scd = DemoDataset() scd.init_random_training_indexes() scd.danku_init() nn.load_dataset(scd) nn.init_network() assert (not isinstance(nn.tf_weights, type(None))) assert (not isinstance(nn.tf_init, type(None))) assert (not isinstance(nn.tf_layers, type(None)))
def test_demo(web3, chain): _hashed_data_groups = [] accuracy_criteria = 5000 # 50.00% total_gas_used = 0 timeout = 180 w_scale = 1000 # Scale up weights by 1000x b_scale = 1000 # Scale up biases by 1000x danku, deploy_tx = chain.provider.get_or_deploy_contract('Danku_demo') deploy_receipt = wait_for_transaction_receipt(web3, deploy_tx, timeout=timeout) total_gas_used += deploy_receipt["gasUsed"] dbg.dprint("Deploy gas: " + str(deploy_receipt["gasUsed"])) offer_account = web3.eth.accounts[1] solver_account = web3.eth.accounts[2] # Fund contract fund_tx = web3.eth.sendTransaction({ 'from': offer_account, 'to': danku.address, 'value': web3.toWei(1, "ether") }) fund_receipt = wait_for_transaction_receipt(web3, fund_tx, timeout=timeout) total_gas_used += fund_receipt["gasUsed"] dbg.dprint("Fund gas: " + str(fund_receipt["gasUsed"])) # Check that offerer was deducted bal = web3.eth.getBalance(offer_account) # Deduct reward amount (1 ETH) and gas cost (21040 wei) assert bal == 999998999999999999978960 wallet_amount = 1000000000000000000000000 # minus the reward amount scd = DemoDataset(training_percentage=0.8, partition_size=25) scd.generate_nonce() scd.sha_all_data_groups() dbg.dprint("All data groups: " + str(scd.data)) dbg.dprint("All nonces: " + str(scd.nonce)) # Initialization step 1 dbg.dprint("Hashed data groups: " + str(scd.hashed_data_group)) dbg.dprint("Hashed Hex data groups: " + str(list(map(lambda x: "0x" + x.hex(), scd.hashed_data_group)))) # Keep track of all block numbers, so we can send them in time # Start at a random block between 0-1000 chain.wait.for_block(randbelow(1000)) dbg.dprint("Starting block: " + str(web3.eth.blockNumber)) init1_tx = danku.transact().init1(scd.hashed_data_group, accuracy_criteria, offer_account) init1_receipt = wait_for_transaction_receipt(web3, init1_tx, timeout=timeout) total_gas_used += init1_receipt["gasUsed"] dbg.dprint("Init1 gas: " + str(init1_receipt["gasUsed"])) chain.wait.for_receipt(init1_tx) init1_block_number = web3.eth.blockNumber dbg.dprint("Init1 block: " + str(init1_block_number)) submission_t = danku.call().submission_stage_block_size( ) # get submission timeframe evaluation_t = danku.call().evaluation_stage_block_size( ) # get evaluation timeframe test_reveal_t = danku.call().reveal_test_data_groups_block_size( ) # get revealing testing dataset timeframe # Initialization step 2 # Get data group indexes chain.wait.for_block(init1_block_number + 1) dgi = [] init2_block_number = web3.eth.blockNumber dbg.dprint("Init2 block: " + str(init2_block_number)) for i in range(scd.num_data_groups): dgi.append(i) dbg.dprint("Data group indexes: " + str(dgi)) init2_tx = danku.transact().init2() init2_receipt = wait_for_transaction_receipt(web3, init2_tx, timeout=timeout) total_gas_used += init2_receipt["gasUsed"] dbg.dprint("Init2 gas: " + str(init2_receipt["gasUsed"])) chain.wait.for_receipt(init2_tx) # Can only access one element of a public array at a time training_partition = list(map(lambda x: danku.call().training_partition(x),\ range(scd.num_train_data_groups))) testing_partition = list(map(lambda x: danku.call().testing_partition(x),\ range(scd.num_test_data_groups))) # get partitions dbg.dprint("Training partition: " + str(training_partition)) dbg.dprint("Testing partition: " + str(testing_partition)) scd.partition_dataset(training_partition, testing_partition) # Initialization step 3 # Time to reveal the training dataset training_nonces = [] training_data = [] for i in training_partition: training_nonces.append(scd.nonce[i]) # Pack data into a 1-dimension array # Since the data array is too large, we're going to send them in single data group chunks train_data = scd.pack_data(scd.train_data) test_data = scd.pack_data(scd.test_data) init3_tx = [] for i in range(len(training_partition)): start = i * scd.dps * scd.partition_size end = start + scd.dps * scd.partition_size dbg.dprint("(" + str(training_partition[i]) + ") Train data,nonce: " + str(train_data[start:end]) + "," + str(scd.train_nonce[i])) iter_tx = danku.transact().init3(train_data[start:end], scd.train_nonce[i]) iter_receipt = wait_for_transaction_receipt(web3, iter_tx, timeout=timeout) total_gas_used += iter_receipt["gasUsed"] dbg.dprint("Reveal train data iter " + str(i) + " gas: " + str(iter_receipt["gasUsed"])) init3_tx.append(iter_tx) chain.wait.for_receipt(init3_tx[i]) init3_block_number = web3.eth.blockNumber dbg.dprint("Init3 block: " + str(init3_block_number)) # Get the training data from the contract contract_train_data_length = danku.call().get_train_data_length() contract_train_data = [] for i in range(contract_train_data_length): for j in range(scd.dps): contract_train_data.append(danku.call().train_data(i, j)) contract_train_data = scd.unpack_data(contract_train_data) dbg.dprint("Contract training data: " + str(contract_train_data)) il_nn = 2 hl_nn = [4, 4] ol_nn = 2 # Train a neural network with contract data nn = NeuralNetwork(il_nn, hl_nn, ol_nn, 0.001, 1000000, 5, 100000) contract_train_data = nn.binary_2_one_hot(contract_train_data) nn.load_train_data(contract_train_data) nn.init_network() nn.train() trained_weights = nn.weights trained_biases = nn.bias dbg.dprint("Trained weights: " + str(trained_weights)) dbg.dprint("Trained biases: " + str(trained_biases)) packed_trained_weights = nn.pack_weights(trained_weights) dbg.dprint("Packed weights: " + str(packed_trained_weights)) packed_trained_biases = nn.pack_biases(trained_biases) dbg.dprint("Packed biases: " + str(packed_trained_biases)) int_packed_trained_weights = scale_packed_data(packed_trained_weights,\ w_scale) dbg.dprint("Packed integer weights: " + str(int_packed_trained_weights)) int_packed_trained_biases = scale_packed_data(packed_trained_biases,\ b_scale) dbg.dprint("Packed integer biases: " + str(int_packed_trained_biases)) dbg.dprint("Solver address: " + str(solver_account)) # Submit the solution to the contract submit_tx = danku.transact().submit_model(solver_account, il_nn, ol_nn, hl_nn,\ int_packed_trained_weights, int_packed_trained_biases) submit_receipt = wait_for_transaction_receipt(web3, submit_tx, timeout=timeout) total_gas_used += submit_receipt["gasUsed"] dbg.dprint("Submit gas: " + str(submit_receipt["gasUsed"])) chain.wait.for_receipt(submit_tx) # Get submission index ID submission_id = danku.call().get_submission_id(solver_account, il_nn,\ ol_nn, hl_nn, int_packed_trained_weights, int_packed_trained_biases) dbg.dprint("Submission ID: " + str(submission_id)) # Wait until the submission period ends chain.wait.for_block(init3_block_number + submission_t) # Reveal the testing dataset after the submission period ends reveal_tx = [] for i in range(len(testing_partition)): start = i * scd.dps * scd.partition_size end = start + scd.dps * scd.partition_size dbg.dprint("(" + str(testing_partition[i]) + ") Test data,nonce: " + str(test_data[start:end]) + "," + str(scd.test_nonce[i])) iter_tx = danku.transact().reveal_test_data(test_data[start:end], scd.test_nonce[i]) iter_receipt = wait_for_transaction_receipt(web3, iter_tx, timeout=timeout) total_gas_used += iter_receipt["gasUsed"] dbg.dprint("Reveal test data iter " + str(i) + " gas: " + str(iter_receipt["gasUsed"])) reveal_tx.append(iter_tx) chain.wait.for_receipt(reveal_tx[i]) # Wait until the test reveal period ends chain.wait.for_block(init3_block_number + submission_t + test_reveal_t) # Evaluate the submitted solution eval_tx = danku.transact().evaluate_model(submission_id) eval_receipt = wait_for_transaction_receipt(web3, eval_tx, timeout=timeout) total_gas_used += eval_receipt["gasUsed"] dbg.dprint("Eval gas: " + str(eval_receipt["gasUsed"])) # Wait until the evaluation period ends chain.wait.for_block(init3_block_number + submission_t + test_reveal_t + evaluation_t) bal2 = web3.eth.getBalance(offer_account) # Finalize the contract final_tx = danku.transact().finalize_contract() final_receipt = wait_for_transaction_receipt(web3, final_tx, timeout=timeout) total_gas_used += final_receipt["gasUsed"] dbg.dprint("Final gas: " + str(final_receipt["gasUsed"])) contract_finalized = danku.call().contract_terminated() dbg.dprint("Contract finalized: " + str(contract_finalized)) assert contract_finalized == True # Get best submission accuracy & ID best_submission_accuracy = danku.call().best_submission_accuracy() best_submission_index = danku.call().best_submission_index() dbg.dprint("Best submission ID: " + str(best_submission_index)) dbg.dprint("Best submission accuracy: " + str(best_submission_accuracy)) l_nn = [il_nn] + hl_nn + [ol_nn] input_layer = train_data[:2] hidden_layers = [0] * sum(hl_nn) output_layer = [0] * ol_nn weights = int_packed_trained_weights biases = int_packed_trained_biases # Test forward fwd_pass2 = danku.call().forward_pass2(l_nn, input_layer, hidden_layers, output_layer, weights, biases) dbg.dprint("Test input: " + str(train_data[:2])) dbg.dprint("Expected output: " + str(train_data[2])) dbg.dprint("local nn prediction: " + str(nn.predict([train_data[:2]]))) dbg.dprint("forward_pass2: " + str(fwd_pass2)) dbg.dprint("Total gas used: " + str(total_gas_used)) scatter_x = np.array(list(map(lambda x: x[1:2][0], scd.data))) scatter_y = np.array(list(map(lambda x: x[:1][0], scd.data))) group = np.array(list(map(lambda x: x[2:3][0], scd.data))) cdict = {0: "blue", 1: "red"} fig, ax = plt.subplots() for g in np.unique(group): ix = np.where(group == g) ax.scatter(scatter_x[ix], scatter_y[ix], c=cdict[g], label=g, s=4) ax.legend() plt.show() bal = web3.eth.getBalance(solver_account) # Verify that the solver account received the reward amount assert bal == 1000001000000000000000000 bal = web3.eth.getBalance(offer_account) # Verify the offer account balance assert bal == 999998999999999999978960 assert (False)