Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

Cortex研究所 view 50620 2020-9-7 15:32
share to
Scan QR code with WeChat

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

Cortex 是第一个支持人工智能(AI)模型的上链与执行的去中心化人工智能区块链平台。Cortex 提供了一个开源AI平台来实现人工智能民主化,使模型可以轻松写入智能合约中,并创建支持 AI 的去中心化程序(DApps)。此篇文章将为你介绍怎样部署简单的“ Hello World” AI DApp的教程。如果你想了解更多关于Cortex技术文档请点击此链接:

(https://github.com/CortexFoundation/tech-doc)。

本教程结束时,你将初步掌握如何在Cortex链上编写手写数字识别AI Dapp的操作,该合约从用户那里获取输入图像,通过调用链上AI模型来判断图像0-9的数字,呈现最终数字。

“Hello World”AI DApp

基础配置

~ Chrome浏览器

~ Cortex Wallet Chrome扩展程序

~ Cortex测试网代币(来自faucet或支持ERC20代币的交易所)准备好以上配置之后,确定你的Cortex钱包在测试网上。

单击Cortex钱包扩展名,输入密码,然后在钱包顶部,将看到:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

如果还没有看到,请单击下拉箭头,然后切换到Dolores Test Network。(可能需要刷新,然后再重复上述步骤)

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

编辑合约

本教程的合约编辑是在Cortex官方IDE Remix进行的,也可以在其他的编辑器中编辑稍后将代码粘贴到Cortex官方IDE Remix上。

现在打开Cortex官方IDE Remix(链接:cerebro.cortexlabs.ai/remix/),然后编写这个合约,之后就可以分发了。

教程全部合约代码

pragma solidity ^0.4.18; contract Infer {  // initiate the variables uint256[] public input_data; // address of the on-chain model address modelAddr = 0x420bD8d2FE73514E9b77fdBc78c0306Fd8a12866; // the output will be stored in this variable uint256 public currentInferResult;  constructor() public { // Here we define the dimension of the input_data. To feed an image input of dimension 1 * 1 * 28 * 28 into the model, we need 1 * 1 * 28 * 28 bytes. // Now, each uint256 in Solidity is 32 bytes. That's why we need divide 1 * 1 * 28 * 28 by 32 and round up. // To express this division in Solidity, we write (1 * 1 * 28 * 28 + 31) >> 5, where >> 5 means divide by 2^5 and adding the 31 allows us to effectively round up. input_data = new uint256[]((1 * 1 * 28 * 28 + 31) >> 5); }  // you can choose to randomly generate input as opposed to taking the input image from the user function GenerateRandomInput() public { input_data[0] = uint(sha256(now)); for(uint i = 1; i < input_data.length; ++i) { input_data[i] = uint(sha256(input_data[i - 1])); } }  function SetInput(uint256[] data) public { for(uint i = 0; i < input_data.length; ++i) { input_data[i] = data[i]; } } // recognize digit using randomly generated input image function DigitRecognitionInfer() public { uint256[] memory output = new uint256[](uint256(1)); inferArray(modelAddr, input_data, output); currentInferResult = (output[0] >> (256 - 32)) & ((1 << 32) - 1); currentInferResult = currentInferResult % 10; }}

这里是我们要编译的全部代码,现在我们将逐步讲解在Cortex官方IDE Remix中编辑:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

Cortex官方IDE Remix界面,新建一个界面,如下所示:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

开始创建合约,如下所示:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

将上述合约代码放置于Cortex官方IDE Remix编辑区请注意。这是此合同中最重要的功能。它采用尺寸为1 x 3 x 32 x 32的输入图像数组,并返回0-9之间的数字作为输出,告诉你图像中的哪个数字。

开始进行合约启动准备工作,代码布置完成后编译此合约,请首先单击页面左侧插头的选项,然后激活两个模组:“部署并执行交易”“ Solidity 编辑器”如下所示:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

首先需要编制这份合约。因此,单击左侧类似上下括号的选项卡。然后单击“编译”以编译你的合约。成功编译后,左侧的图标会有一个绿色的标识,如下所示:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

现在把这份合约部署到测试网上,单击左侧的Cortex徽标,进入Deploy选项卡,如下所示:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

现在,如果没有弹出窗口,请单击右上角的Cortex钱包以查看交易窗口。可以将所有内容保留为默认值,然后单击“确认”。(应该会看到帐户已自动填写;否则,可能需要先登录钱包并重新加载),然后会弹出一个钱包窗口,要求你像下面的一样确认交易。查看详细信息,然后再次单击“确认”,如下所示:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

几分钟后,你的合同应该已经成功部署,并显示在“部署合约”一节,如下所示:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

点击下拉菜单,你会看到所有的功能并且可以选择调用。点击剪贴板,你会看到你的合同地址。请确保保存此地址,以便你知道你的合同部署在哪里。

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

在这个阶段,你已经完成了很多工作:可以单击“生成随机输入”来生成一个随机输入(记住一定要到你的Cortex钱包确认函数调用),然后单击“数字识别信息”来确定随机生成的输入是什么数字。如果你单击currentInferResult,将看到类似于“0:uint256:数字编号”,其中数字编号是你的推断结果。

现在,我们已经完成了在Cortex上开发的整个工作流程。然而,在随机生成的输入图像上运行程序是无聊的。因此为了完整和有趣,将继续展示如何获取用户输入,其中包括编写一个Python脚本!

Python脚本操作

使用此Python脚本将自定义图像转换为支持大小的数组。

打开终端,第一次运行(首先要确定你的电脑上已经安装过Python,如果不会的可以自行搜索一下网上很多此类教程)

终端中输入代码 :

pip3 install Pillow

启动一个Python文件,并将其命名为“convert.py”,它将把自定义图像输入,并输出一个像素值数组,其尺寸与我们上面的合约兼容!请确保将自定义图像放在与此脚本相同的目录中。

(小编的操作是使用Sublime Text编辑器将Python代码复制进去保存好就可以了)

Python文件代码:

import sysfrom PIL import Image img = Image.open(sys.argv[1])img = img.resize((28,28))img = img.load() h = '0123456789abcdef's = ''for i in range(28): for j in range(28): t = 0 if type(img[j, i]) is int: t = img[j, i] // 2 else: for k in img[j, i]: t += k t //= len(img[j, i]) * 2 s += h[t // 16] + h[t % 16]ret = []for i in range(0, len(s), 64): if i <= len(s): e = i+64 if e > len(s): e = len(s) subs = s[i:e] if len(subs) < 64: subs = subs + '0' * (64 - len(subs)) ret.append('0x' + subs) else: ret.append('0x' + '0' * (len(s) - i + 64) + s[i:]) print('[' + ','.join(['"' + x + '"' for x in ret]) + ']')

注意:上面的python脚本只适用于MNIST测试设置-如果你想获得自定义图像的像素值,你可能需要相应地修改它。

我们保存好Python文件之后 就可以在终端操作以下代码:

python3 convert.py your_img_name.jpg

你的_img_name.jpg转换为Python3,将你的_img_name替换为你的实际图像名称!如果一切进展顺利,终端应输出一个像素值数组,你可以复制。(如果您需要更多的测试,在Kaggle https://www.Kaggle.com/scolianni/mnistasjpg上可以找到更多类似的数字图像。)

Python程序应该返回一个这样的数组:

["0x0000000000000000000001000002010005000007000009000000000000000000","0x0000000000060000030000050001010800010100000000000000000000000000","0x030400040000040000090000000a000200000000000000000000000000000000","0x000000000000000500000501000000000000000000000000060007050d110826","0x5a5911020000000000000000000000000000000000004b7f7d7d797e7e7f1603","0x000200040000000000000000000000000324667f77797f7f7d7c64631c000900","0x000000000000000000000000006d7f787f7c7d7d7d7f7f797018000600000000","0x00000001010101000020727f7f7a3b1114377d7f7c3e0a000000000000000000","0x0000000006001f33383a11000000647a7f7f0006000000000100000000000001","0x00000102000500030300257a7f7f020000000000000000000101020200070000","0x000400010000117f7f7e05050000000000000001010100000101000605000000","0x0306317f7f7c0706000000000000000000000000000000000203050000085c7b","0x7f79060000000000010100000000010202000500192f2a02020c7b7b7f680004","0x00000000020000000003070931335b5e767e7e5f5f71797e6909030000000000","0x0002000010365c7b7f797f7a7f7f797d7f787f7f6d3e04000000000001000000","0x3f7f757f7f7b726a797d7f7f7c7f7e7c7f79550600000000000500047e7f7f74","0x652a001a62777f71774736607f787f5a0000000003000b007a797f7f6c75716a","0x7a7d7f772600000a5b7b77790000000000000002527d7f7a7f797e7d7f62351d","0x00090103001b7f4f00000000000c000003115361585b52160105030300000200","0x0000070100000000050007000600020000000300030000000400050002000005","0x000000000007000200000c000004000004000500000000010000030000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"]

完成以上操作后,让我们回到Cortex官方IDE Remix来推断合约。

在At Address中,键入你的合约地址,然后单击按钮加载你的合约。(如果不加载,请重新编译你的合约)现在点击下拉箭头,你可以看到合约中可调用函数的列表,如下所示:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

将你的自定义图像输入(上面那个巨大的数组)粘贴到SetInput中,然后单击按钮,在弹出窗口中确认交易。

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

将你的自定义图像输入(上面的那个可怕的数组)粘贴到SetInput中,然后单击按钮,在弹出窗口中确认交易。等待直到确认交易。这可能需要一段时间!

最后,点击DigitRecognitionInfer,确认交易。你的最终推断结果应currentInferResult在几秒钟内存储!

期望看到这样的内容:

Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

不必担心前面的0;(最终结果存储在“ uint256”后面)。如你所见,模型已成功确定图像为2。

恭喜你!你现在已经可以掌握编写,编译,部署和执行AI DApp啦。

btcfans公众号

Scan QR code with WeChat

Link
Disclaimer:

Tags: Dapp Cortex
Previous: 使用Java集成测试Pantheon运行节点情况 Next: Cortex技术教程 | Cortex 全节点

Related