bigstylee / clarifai-php
Clarifai API 的 PHP 客户端 - 从 darrynten/clarifai-php 分支出来,支持 API 密钥
Requires
- php: ^7.0
- darrynten/any-cache: ^1.0
- guzzlehttp/guzzle: ^6.2.1
Requires (Dev)
- internations/http-mock: ^0.8.1
- mockery/mockery: dev-master
- phpunit/phpunit: ~5.0
This package is auto-updated.
Last update: 2024-09-08 21:07:35 UTC
README
Clarifai API 的 PHP 客户端
这是一个 100% 单元测试和(大部分)功能齐全的非官方 Clarifai PHP 客户端
Clarifai 是一家在视觉识别方面表现出色的人工智能公司,它为企业和开发者解决现实世界的问题。
composer require darrynten/clarifai-php
PHP 7.0+
基本使用
API 相对简单,由输入、概念和模型组成。
定义
输入
您向服务发送输入(图像),它会返回预测。除了接收输入的预测外,您还可以“保存”输入及其预测以供以后搜索。您还可以“保存”具有概念的输入以供以后训练自己的模型。
模型
Clarifai 提供了许多不同的模型,它们以不同的方式“看待”世界。一个模型包含一组概念。一个模型只会看到它所包含的概念。
有时您希望有一个以您的方式看待世界的模型。API 允许您这样做。您可以使用自己的图像和概念创建自己的模型并对其进行训练。一旦训练它以您期望的方式看待,您就可以使用该模型进行预测。
您不需要很多图像就可以开始。我们建议从 10 张开始,并根据需要添加更多。
概念
概念在您使用自己的概念创建自己的模型时发挥着重要作用。概念还有助于您搜索输入。
当您将概念添加到输入时,您需要指示该概念是否存在于图像中或不存在。
功能
这是项目的初步框架,仍在进行中。
请在每个部分放置复选框,提交包含您已覆盖的功能的拉取请求时,请在此说明中勾选它们。
应用程序基础
- 使用 Guzzle 进行通信
- 该库有 100% 的测试覆盖率
- 该库支持框架无关的缓存,因此您不必担心您的包将最终使用哪个框架。
客户端尚不完整,仍在进行中,详细信息见下文。
结构主要受 官方 JS 客户端 启发
身份验证
访问通过 oauth2 处理。
您需要使用您的 Client ID 和 Secret 初始化客户端。
$this->clarifai = new Clarifai('clientId', 'clientSecret');
预测
这是一个使用预测调用的基本库使用示例。模型名称为 aaa03c23b3724a16a56b629203edc62c
include 'vendor/autoload.php'; $clarifai = new \DarrynTen\Clarifai\Clarifai( CLIENT_ID, CLIENT_SECRET ); $modelResult = $clarifai->getModelRepository()->predictUrl( 'https://samples.clarifai.com/metro-north.jpg', \DarrynTen\Clarifai\Repository\ModelRepository::GENERAL ); echo json_encode($modelResult);
响应(摘要)将是
{ "status":{ "code":10000, "description":"Ok" }, "outputs":[ { "id":"db1b183a95a042d3bd873f8ca69ae2e6", "status":{ "code":10000, "description":"Ok" }, "created_at":"2017-02-14T03:18:54.548733Z", "model":{ "name":"general-v1.3", "id":"aaa03c23b3724a16a56b629203edc62c", "created_at":"2016-03-09T17:11:39.608845Z", "app_id":null, "output_info":{ "message":"Show output_info with: GET \/models\/{model_id}\/output_info", "type":"concept" }, "model_version":{ "id":"aa9ca48295b37401f8af92ad1af0d91d", "created_at":"2016-07-13T01:19:12.147644Z", "status":{ "code":21100, "description":"Model trained successfully" } } }, "input":{ "id":"db1b183a95a042d3bd873f8ca69ae2e6", "data":{ "image":{ "url":"https:\/\/samples.clarifai.com\/metro-north.jpg" } } }, "data":{ "concepts":[ { "id":"ai_HLmqFqBf", "name":"\u043f\u043e\u0435\u0437\u0434", "app_id":null, "value":0.9989112 }, // and several others { "id":"ai_VSVscs9k", "name":"\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b", "app_id":null, "value":0.9230834 } ] } } ] }
这可以是通过图像 URL 或
$modelResult = $clarifai->getModelRepository()->predictPath( '/user/images/image.png', \DarrynTen\Clarifai\Repository\ModelRepository::GENERAL );
b64 编码的数据发生
$modelResult = $clarifai->getModelRepository()->predictEncoded( ENCODED_IMAGE_HASH, \DarrynTen\Clarifai\Repository\ModelRepository::GENERAL );
文档
这将最终完全模仿网站上的文档。 https://developer.clarifai.com/guide
每个部分都必须有一个简短的说明和一些示例代码,就像 API 文档页面上的那样。
勾选的位已完成。
- 输入
- 添加
- 添加概念
- 添加自定义元数据
- 添加裁剪
- 获取输入
- 获取输入状态
- 使用概念更新输入
- 从输入中删除概念
- 批量更新输入的概念
- 批量从输入列表中删除概念
- 按 ID 删除输入
- 删除输入列表
- 删除所有输入
- 模型
- 创建模型
- 使用概念创建模型
- 将概念添加到模型中
- 从模型中移除概念
- 更新模型名称和配置
- 获取模型
- 按ID获取模型
- 按ID获取模型输出信息
- 列出模型版本
- 按ID获取模型版本
- 获取模型训练输入
- 按版本获取模型训练输入
- 删除模型
- 删除模型版本
- 删除所有模型
- 训练模型
- 使用模型进行预测
- 搜索
- 按名称和类型搜索模型
- 按预测概念搜索
- 按用户提供的概念搜索
- 按自定义元数据搜索
- 按反向图片搜索
- 搜索匹配URL
- 按概念和预测搜索
- 搜索AND操作
- 分页
- 修补
- 合并
- 移除
- 覆盖
- 批量请求
- 语言
输入
API围绕一个简单的想法构建。您向服务发送输入(图像),它返回预测。除了接收输入的预测外,您还可以“保存”输入及其预测以供以后搜索。您还可以“保存”带有概念的输入以供以后训练自己的模型。
添加输入
您可以逐个或批量添加输入。如果您批量发送,每次最多只能发送128个输入。
图像可以是公开可访问的URL或文件字节。如果您发送文件字节,则必须使用base64编码。
建议您发送带有自己的id的输入。这有助于您以后将输入与自己的数据库匹配。如果您不发送id,则会为您创建一个。
使用公开可访问的URL添加输入
$input = new Input(); $input->setImage('https://samples.clarifai.com/metro-north.jpg')->isUrl(); $inputResult = $clarifai->getInputRepository()->add($input);
使用图像的本地路径添加输入
$input = new Input(); $input->setImage('/samples.clarifai.com/metro-north.jpg')->isPath(); $inputResult = $clarifai->getInputRepository()->add($input);
使用字节添加输入
数据必须是base64编码。当您将base64图像添加到我们的服务器时,将会存储并托管在您的服务器上。如果您已经拥有图像托管服务,我们建议您使用它,并通过URL参数添加图像。
$input = new Input(); $input->setImage(ENCODED_IMAGE_HASH)->isEncoded(); $inputResult = $clarifai->getInputRepository()->add($input);
按ID添加多个输入
$input1 = new Input(); $input1->setImage('https://samples.clarifai.com/metro-north.jpg')->isUrl()->setId('id1'); $input2 = new Input(); $input2->setImage('https://samples.clarifai.com/puppy.jpeg')->isUrl()->setId('id2'); $inputResult = $clarifai->getInputRepository()->add([$input1, $input2]);
添加带有概念的输入
$concept = new Concept(); $concept->setId('boscoe')->setValue(true); $input = new Input(); $input->setImage('https://samples.clarifai.com/puppy.jpeg')->isUrl() ->setConcepts([$concept]); $inputResult = $clarifai->getInputRepository()->add($input);
添加带有元数据的输入
除了添加带有概念的输入外,您还可以添加带有自定义元数据的输入。这些元数据将可供搜索。元数据可以是任何任意的JSON。
$input = new Input(); $input->setImage('https://samples.clarifai.com/metro-north.jpg')->isUrl() ->setMetaData([['key' => 'value', 'list' => [1, 2, 3]]); $inputResult = $clarifai->getInputRepository()->add($input);
添加带有裁剪的输入
在添加输入时,您可以指定裁剪点。API将裁剪图像并使用结果图像。裁剪点以百分比形式给出,从左上角点开始,顺序为上、左、下和右。
例如,如果您提供裁剪为0.2, 0.4, 0.3, 0.6,这意味着裁剪图像的顶部边缘将从原始顶部边缘向下20%开始,左侧边缘将从原始左侧边缘开始40%,底部边缘将从原始顶部边缘开始30%,右侧边缘将从原始左侧边缘开始60%。
$input = new Input(); $input->setImage('https://samples.clarifai.com/metro-north.jpg')->isUrl() ->setCrop([0.2, 0.4, 0.3, 0.6]); $inputResult = $clarifai->getInputRepository()->add($input);
获取输入
您可以列出您之前添加的所有输入(图像),无论是用于搜索还是训练。
如果您添加了带有概念的输入,它们也将包含在响应中。
$inputResult = $clarifai->getInputRepository()->get();
按ID获取输入
如果您想按id获取特定的输入,您也可以这样做。
$inputResult = $clarifai->getInputRepository()->getById('id');
获取输入状态
如果您批量添加输入,它们将在后台处理。您可以像这样获取所有输入的状态(已处理、待处理和错误):
$inputResult = $clarifai->getInputRepository()->getStatus();
使用概念更新输入
要更新输入的新概念,或更改概念值的true/false,您可以这样做
$concept1 = new Concept(); $concept1->setId('tree')->setValue(true); $concept2 = new Concept(); $concept2->setId('water')->setValue(false); $modelResult = $clarifai->getInputRepository()->mergeInputConcepts([$inputId => [$concept1, $concept2]]);
从输入中删除概念
要删除已添加到输入中的概念,您可以这样做
$concept1 = new Concept(); $concept1->setId('mattid2')->setValue(true); $concept2 = new Concept(); $concept2->setId('ferrari')->setValue(false); $modelResult = $clarifai->getInputRepository()->deleteInputConcepts([$inputId => [$concept1, $concept2]]);
使用概念批量更新输入
您可以使用其ID更新现有输入。如果您想在输入已添加后添加概念,这非常有用。
$concept1 = new Concept(); $concept1->setId('tree')->setValue(true); $concept2 = new Concept(); $concept2->setId('water')->setValue(false); $concept3 = new Concept(); $concept3->setId('mattid2')->setValue(true); $concept4 = new Concept(); $concept4->setId('ferrari')->setValue(false); $modelResult = $clarifai->getInputRepository()->mergeInputConcepts( [ $inputId1 => [$concept1, $concept2], $inputId2 => [$concept3, $concept4], ] );
从输入列表中批量删除概念
您可以从输入列表中批量删除多个概念。
$concept1 = new Concept(); $concept1->setId('tree')->setValue(true); $concept2 = new Concept(); $concept2->setId('water')->setValue(false); $concept3 = new Concept(); $concept3->setId('mattid2')->setValue(true); $concept4 = new Concept(); $concept4->setId('ferrari')->setValue(false); $modelResult = $clarifai->getInputRepository()->deleteInputConcepts( [ $inputId1 => [$concept1, $concept2], $inputId2 => [$concept3, $concept4], ] );
通过ID删除输入
您可以通过ID删除单个输入。
$inputResult = $clarifai->getInputRepository()->deleteById('id');
删除多个输入列表
您还可以在一次API调用中删除多个输入。这将异步进行。
$inputResult = $clarifai->getInputRepository()->deleteByIdArray(['id1', 'id2']);
删除所有输入
如果您想从应用程序中删除所有输入,您也可以这样做。这将异步进行。
$inputResult = $clarifai->getInputRepository()->deleteAll();
模型
有许多方法可以与模型交互。
创建模型
您可以创建自己的模型,并使用自己的图像和概念对其进行训练。一旦训练完成,您就可以使用该模型进行预测。
创建模型时,您需要提供模型名称和ID。如果您不提供ID,系统会为您创建一个。所有模型都必须具有唯一的ID。
$model = new Model(); $model->setId('petsID'); $modelResult = $clarifai->getModelRepository()->create($model);
使用概念创建模型
您还可以创建一个模型,并用它将包含的概念进行初始化。您可以在以后添加和删除概念。
$concept = new Concept(); $concept->setId('boscoe'); $model= new Model(); $model->setId('petsId') ->setConcepts([$concept]) ->setConceptsMutuallyExclusive(false) ->setClosedEnvironment(false); $modelResult = $clarifai->getModelRepository()->create($model);
向模型添加概念
您可以在任何时间向模型添加概念。在您向输入添加概念时,您可能希望也将它们添加到模型中。
$concept = new Concept(); $concept->setId('dogs'); $modelResult = $clarifai->getModelRepository()->mergeModelConcepts([$modelId => [$concept]]);
从模型中删除概念
相反,如果您想从模型中删除概念,您也可以这样做。
$concept = new Concept(); $concept->setId('dogs'); $modelResult = $clarifai->getModelRepository()->deleteModelConcepts([$modelId => [$concept]]);
更新模型名称和配置
在此,我们将模型名称更改为'newname',并将模型配置更改为具有concepts_mutually_exclusive=true和closed_environment=true。
$model->setName('newname') ->setClosedEnvironment(true) ->setConceptsMutuallyExclusive(true); $modelResult = $clarifai->getModelRepository()->update($model);
获取模型
获取所有模型的列表,包括您创建的模型以及公共模型
$modelResult = $clarifai->getModelRepository()->get();
通过ID获取模型
所有模型都有唯一的ID。您可以通过ID获取特定的模型。
$modelResult = $clarifai->getModelRepository()->getById($modelId);
通过ID获取模型输出信息
模型的输出信息列出了它包含的概念。
$modelResult = $clarifai->getModelRepository()->getOutputInfoById($modelId);
列出模型版本
每次您训练一个模型时,它都会创建一个新的版本。您可以列出创建的所有版本。
$modelResult = $clarifai->getModelRepository()->getModelVersions($modelId);
通过ID获取模型版本
要获取特定的模型版本,您必须提供modelId以及versionId。您可以检查模型版本的状态,以确定您的模型是否已训练或仍在训练中。
$modelResult = $clarifai->getModelRepository()->getModelVersionById($modelId, $versionId);
获取模型训练输入
您可以列出用于训练模型的全部输入。
$modelResult = $clarifai->getModelRepository()->getTrainingInputsById($modelId);
通过版本获取模型训练输入
您还可以列出用于训练特定模型版本的全部输入。
$modelResult = $clarifai->getModelRepository()->getTrainingInputsByVersion($modelId, $versionId);
删除模型
您可以使用modelId删除模型。
$modelResult = $clarifai->getModelRepository()->deleteById($modelId);
删除模型版本
您还可以使用modelId和versionId删除模型的特定版本。
$modelResult = $clarifai->getModelRepository()->deleteVersionById($modelId, $versionId);
删除所有模型
如果您想删除与应用程序关联的所有模型,您也可以这样做。请谨慎操作,因为这些无法恢复。
$modelResult = $clarifai->getModelRepository()->deleteAll();
训练模型
当您训练一个模型时,您是在告诉系统查看您提供的所有具有概念图像并从中学习。此训练操作是异步的。您的模型可能需要几秒钟才能完全训练并准备好。
注意:您可以随时重复此操作。通过添加更多具有概念的图像并进行训练,您可以训练模型以预测您想要的方式。
$modelResult = $clarifai->getModelRepository()->train($id);
按名称和类型搜索模型
您可以通过名称和模型类型搜索所有模型。
$modelResult = $clarifai->getSearchModelRepository()->searchByNameAndType($modelName, 'concept');
搜索
按预测概念搜索
当您添加输入时,它将自动从通用模型中获得预测。您可以搜索这些预测。
$concept1 = new Concept(); $concept1->setName('dog')->setValue(true); $concept2 = new Concept(); $concept2->setName('cat'); $inputResult = $clarifai->getSearchInputRepository()->searchByPredictedConcepts([$concept1, $concept2]);
按用户提供的概念搜索
在您添加了带有概念的输入后,您可以按这些概念进行搜索。
$concept1 = new Concept(); $concept1->setName('dog'); $concept2 = new Concept(); $concept2->setName('cat'); $inputResult = $clarifai->getSearchInputRepository()->searchByUserSuppliedConcepts([$concept1, $concept2]);
按自定义元数据搜索
在您添加了带有自定义元数据的输入后,您可以按该元数据进行搜索。
$metadata = ['key'=> 'value']; $inputResult = $clarifai->getSearchInputRepository()->searchByCustomMetadata([$metadata]);
按反向图像搜索
您可以使用图片在您的收藏中进行反向图片搜索。API 将根据搜索结果与您提供的查询图片的相似程度返回排名结果。
$input = new Input(); $input->setImage('https://samples.clarifai.com/metro-north.jpg'); $inputResult = $clarifai->getSearchInputRepository()->searchByReversedImage([$input]);
搜索匹配 URL
您也可以通过 URL 搜索输入。
$input = new Input(); $input->setImage('https://samples.clarifai.com/metro-north.jpg'); $inputResult = $clarifai->getSearchInputRepository()->searchByMatchUrl([$input]);
按概念和预测搜索
您可以将搜索与您提供的概念以及模型预测的结果相结合。
$concept1 = new Concept(); $concept1->setName('dog'); $concept2 = new Concept(); $concept2->setName('cat'); $inputResult = $clarifai->getSearchInputRepository()->search( [ \DarrynTen\Clarifai\Repository\SearchInputRepository::INPUT_CONCEPTS => [$concept1], \DarrynTen\Clarifai\Repository\SearchInputRepository::OUTPUT_CONCEPTS => [$concept2] ] );
搜索AND操作
您还可以使用 AND 运算符组合搜索。
$concept1 = new Concept(); $concept1->setName('dog'); $concept2 = new Concept(); $concept2->setName('cat'); $input = new Input(); $input->setImage('https://samples.clarifai.com/metro-north.jpg'); $metadata = ['key' => 'value']; $inputResult = $clarifai->getSearchInputRepository()->search( [ SearchInputRepository::INPUT_CONCEPTS => [$concept1], SearchInputRepository::OUTPUT_CONCEPTS => [$concept2], SearchInputRepository::IMAGE => [$input], SearchInputRepository::METADATA => [$metadata], ] );
分页
许多 API 调用都是分页的。您可以向 API 提供页面和每页参数。在下面的示例中,我们获取所有输入,并指定从第 2 页开始,每页获取 20 个结果。
$inputResult = $clarifai->getInputRepository()->setPage(2)->setPerPage(20)->get();
修补(仅适用于概念)
我们设计了 PATCH 以支持同时处理多个资源(批量处理),并足够灵活以满足您的所有需求,以最大限度地减少对服务器的往返次数。因此,它可能看起来与您之前看到的任何 PATCH 都有所不同,但它并不复杂。所有三个受支持的操作默认情况下都会覆盖,但对于对象列表(例如概念列表)有特殊的行为。
合并
合并操作将覆盖键:值对为键:新值或向现有值列表中追加,合并通过对应 id 字段匹配的字典。
在以下示例中,A 正在修补到 B 中以创建结果
*Merges different key:values*
A = `{"a":[1,2,3]}`
B = `{"blah":true}`
Result = `{"blah":true, "a":[1,2,3]}`
*For id lists, merge will append*
A = `{"a":[{"id": 1}]}`
B = `{"a":[{"id": 2}]}`
Result = `{"a":[{"id": 2}, {"id":1}]}`
*Simple merge of key:values and within a list*
A = `{"a":[{"id": "1", "other":true}], "blah":1}`
B = `{"a":[{"id": "2"},{"id":"1", "other":false}]}`
Result = `{"a":[{"id": "2"},{"id": "1"}], "blah":1}`
*Different types should overwrite fine*
A = `{"a":[{"id": "1"}], "blah":1}`
B = `{"a":[{"id": "2"}], "blah":"string"}`
Result = `{"a":[{"id": "2"},{"id": "1"}], "blah":1}`
*Deep merge, notice the "id":"1" matches, so those dicts are merged in the list*
A = `{"a":[{"id": "1","hey":true}], "blah":1}`
B = `{"a":[{"id": "1","foo":"bar","hey":false},{"id":"2"}], "blah":"string"}`
Result = `{"a":[{"hey":true,"id": "1","foo":"bar"},{"id":"2"}], "blah":1}`
*For non-id lists, merge will append*
A = `{"a":[{"blah": "1"}], "blah":1}`
B = `{"a":[{"blah": "2"}], "blah":"string"}`
Result = `{"a":[{"blah": "2"}, {"blah":"1"}], "blah":1}`
*For non-id lists, merge will append*
A = `{"a":[{"blah": "1"}], "blah":1, "dict":{"a":1,"b":2}}`
B = `{"a":[{"blah": "2"}], "blah":"string"}`
Result = `{"a":[{"blah": "2"}, {"blah":"1"}], "blah":1, "dict":{"a":1,"b":2}}`
*Simple overwrite root element*
A = `{"key1":true}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":true}`
*Overwrite a sub element*
A = `{"key1":{"key2":true}}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":{"key2":true, "key3":"value3"}}`
*Merge a sub element*
A = `{"key1":{"key2":{"key4":"value4"}}}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":{"key2":{"key4":"value4"}, "key3":"value3"}}`
*Merge multiple trees*
A = `{"key1":{"key2":{"key9":"value9"}, "key3":{"key4":"value4", "key10":[1,2,3]}}, "key6":{"key11":"value11"}}`
B = `{"key1":{"key2":"value2", "key3":{"key4":{"key5":"value5"}}}, "key6":{"key7":{"key8":"value8"}}}`
Result = `{"key1":{"key2":{"key9":"value9"}, "key3":{"key4":"value4", "key10":[1,2,3]}}, "key6":{"key7":{"key8":"value8"}, "key11":"value11"}}`
*Merge {} element will replace*
A = `{"key1":{"key2":{}}}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":{"key2":{}, "key3":"value3"}}`
*Merge a null element does nothing*
A = `{"key1":{"key2":null}}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":{"key2":"value2", "key3":"value3"}}`
*Merge a blank list [] will replace root element*
A = `{"key1":[]}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":[]}`
*Merge a blank list [] will replace single element*
A = `{"key1":{"key2":[]}}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":{"key2":[], "key3":"value3"}}`
*Merge a blank list [] will remove nested objects*
A = `{"key1":{"key2":[{"key3":"value3"}]}}`
B = `{"key1":{"key2":{"key3":"value3"}}}`
Result = `{"key1":{"key2":[{"key3":"value3"}]}}`
*Merge an existing list with some other struct*
A = `{"key1":{"key2":{"key3":[{"key4":"value4"}]}}}`
B = `{"key1":{"key2":[]}}`
Result = `{"key1":{"key2":{"key3":[{"key4":"value4"}]}}}`
移除
删除操作将覆盖键:值对为键:新值或删除列表中与提供值 id 匹配的任何内容。
在以下示例中,A 正在修补到 B 中以创建结果
*Remove from list*
A = `{"a":[{"id": "1"}], "blah":1}`
B = `{"a":[{"id": "2"},{"id": "3"}, {"id":"1"}], "blah":"string"}`
Result = `{"a":[{"id": "2"},{"id":"3"}], "blah":1}`
*For non-id lists, remove will append*
A = `{"a":[{"blah": "1"}], "blah":1}`
B = `{"a":[{"blah": "2"}], "blah":"string"}`
Result = `{"a":[{"blah": "2"}, {"blah":"1"}], "blah":1}`
*Empty out a nested dictionary*
A = `{"key1":{"key2":true}}`
B = `{"key1":{"key2":"value2"}}`
Result = `{"key1":{}}`
*Remove the root element, should be empty*
A = `{"key1":true}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{}`
*Remove a sub element*
A = `{"key1":{"key2":true}}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":{"key3":"value3"}}`
*Remove a multiple sub elements*
A = `{"key1":{"key2":{"key3":true}, "key4":true}}`
B = `{"key1":{"key2":{"key3":{"key5":"value5"}}, "key4":{"key6":{"key7":"value7"}}}}`
Result = `{"key1":{"key2":{}}}`
*Remove one of the root elements if there are more than one*
A = `{"key1":true}`
B = `{"key1":{"key2":"value2", "key3":"value3"}, "key4":["a", "b", "c"]}`
Result = `{"key4":["a", "b", "c"]}`
*Remove with false should over write*
A = `{"key1":{"key2":false, "key3":true}, "key4":false}`
B = `{"key1":{"key2":"value2", "key3":"value3"}, "key4":[{"key5":"value5", "key6":"value6"}, {"key7": "value7"}]}`
Result = `{"key1":{"key2":false}, "key4":false}`
*Only objects with id's can be put into lists*
A = `{"key1":[{"key2":true}]}`
B = `{"key1":[{"key2":"value2"}, {"key3":"value3"}]}`
Result = `{}`
*Elements with {} should do nothing*
A = `{"key1":{}}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":{"key2":"value2", "key3":"value3"}}`
*Elements with nil should do nothing*
A = `{"key1":{"key2":null}}`
B = `{"key1":{"key2":"value2", "key3":"value3"}}`
Result = `{"key1":{"key2":"value2", "key3":"value3"}}`
覆盖
覆盖操作将覆盖键:值对为键:新值或用新的值列表覆盖值列表。在大多数情况下,这与合并操作类似。
在以下示例中,A 正在修补到 B 中以创建结果
*Overwrite whole list*
A = `{"a":[{"id": "1"}], "blah":1}`
B = `{"a":[{"id": "2"}], "blah":"string"}`
Result = `{"a":[{"id": "1"}], "blah":1}`
*For non-id lists, overwrite will overwrite whole list*
A = `{"a":[{"blah": "1"}], "blah":1}`
B = `{"a":[{"blah": "2"}], "blah":"string"}`
Result = `{"a":[{"blah": "1"}], "blah":1}`
路线图
- 训练
- 添加带概念的图片
- 创建模型
- 训练模型
- 使用模型进行预测
- 搜索
- 将图片添加到搜索
- 按概念搜索
- 反向图片搜索
- 应用
- 语言
公共模型 ID
- 通用 - aaa03c23b3724a16a56b629203edc62c
- 食品 - bd367be194cf45149e75f01d59f77ba7
- 旅行 - eee28c313d69466f836ab83287a54ed9
- NSFW - e9576d86d2004ed1a38ba0cf39ecb4b1
- 婚礼 - c386b7a870114f4a87477c0824499348
- 颜色 - eeed0b6733a644cea07cf4c60f87ebb7
- 人脸检测 - a403429f2ddf4b49b307e318f00e528b
- 服装 - e0be3b9d6a454f0493ac3a30784001ff
- 名人 - e466caa0619f444ab97497640cefc4dc
支持的图片格式
- JPEG
- PNG
- TIFF
- BMP
缓存
因为这些调用很昂贵(时间和金钱),其中一些可以从缓存中受益。所有缓存默认都应关闭,并且仅在明确设置的情况下使用。
这些通过 darrynten/any-cache 包运行,不需要额外的配置。请确保包含缓存的所有功能都是可选的,并且最初设置为 false 以避免意外的行为。
贡献和测试
目前项目中有 100% 的测试覆盖率,请在贡献时确保更新测试。更多信息请参阅 CONTRIBUTING.md。
我们很高兴得到帮助,让文档变得更好,如果您有任何想法,请与我们联系。
致谢
- Dmitry Semenov 加入我们。
- Andrei Voitik 提供了他的宝贵意见。