darrynten/clarifai-php

此包最新版本(1.0.0)没有可用的许可证信息。

Clarifai API 的 PHP 客户端

1.0.0 2018-03-28 22:07 UTC

This package is auto-updated.

Last update: 2024-09-09 10:31:47 UTC


README

Travis Build Status StyleCI Status codecov Packagist Version MIT License

Clarifai API 的 PHP 客户端

这是一个 100% 单元测试并通过(主要)功能齐全的非官方 Clarifai PHP 客户端

Clarifai 是一家在视觉识别方面表现卓越的人工智能公司,为企业和开发者解决现实世界问题。

composer require darrynten/clarifai-php

PHP 7.0+

基本使用

API 相对简单,包括输入、概念和模型。

定义

输入

您向服务发送输入(图像),它将返回预测。除了接收输入上的预测外,您还可以“保存”输入及其预测以供以后搜索。您还可以“保存”具有概念的输入以供以后训练自己的模型。

模型

Clarifai 提供了许多不同的模型,它们以不同的方式“看”世界。模型包含一组概念。模型将只看到它包含的概念。

有时您可能希望有一个以您的方式“看”世界的模型。API 允许您做到这一点。您可以创建自己的模型,并用您自己的图像和概念对其进行训练。一旦您训练它以按照您的方式“看”,您就可以使用该模型进行预测。

您不需要很多图像就可以开始。我们建议从 10 个开始,根据需要添加更多。

概念

概念在创建使用您自己的概念的自定义模型中起着重要作用。概念还有助于您搜索输入。

当您将一个概念添加到输入时,您需要指出该概念是否在图像中存在或不存在。

功能

这是项目的初步框架,仍在进行中。

在每个部分都放置了复选框,请在提交包含您已覆盖的功能的 pull request 时在此 readme 中勾选它们。

应用程序基础

  • 使用 Guzzle 进行通信
  • 该库具有 100% 的测试覆盖率
  • 该库支持框架无关的缓存,因此您不必担心使用此包的包将最终在哪个框架中。

客户端尚未完成,仍在进行中,详情如下。

结构深受 官方 JS 客户端 启发。

身份验证

通过 oauth2 处理访问。

您需要使用您的客户端 ID 和密钥初始化客户端。

$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提供page和per_page参数。在下面的示例中,我们正在获取所有输入,并指定从第2页开始,每页返回20个结果。

    $inputResult = $clarifai->getInputRepository()->setPage(2)->setPerPage(20)->get();

补丁操作(仅适用于概念)

我们设计了PATCH操作以同时操作多个资源(批量)并足够灵活,以满足所有需求,以最小化对服务器的往返次数。因此,它可能看起来与您之前看到的任何PATCH操作都略有不同,但并不复杂。所有支持的三种操作默认都会覆盖,但针对对象列表(例如概念列表)具有特殊行为。

合并

合并操作将覆盖key:value为key:new_value或向现有值列表追加,通过对应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"}]}}}`

删除

删除操作将覆盖key:value为key:new_value或删除列表中与提供值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"}}`

覆盖

覆盖操作将覆盖key:value为key:new_value或用新的值列表覆盖值列表。在大多数情况下,这与合并操作类似。

以下示例中,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。

我们非常希望得到帮助来完善文档,如果您有任何想法,请与我们联系。

致谢