Google Cloud AI API 简单使用记录

2,155 阅读4分钟

最近实习公司做的项目要使用到Google Cloud上有关Machine Learning的API接口,所以最近一直看这方面的资料比较多,在这里整理一下简单的使用方法,免得之后自己走弯路。

公司需求

公司想做的是在一张图片中找到一串电表号(Numero de Compteur Electrique),并且提取中间的一部分。在之前的版本中都是用正则来做的,这一回试图用Google Cloud上的人工智能 API 进行尝试。尽管本人感觉熟悉之后用起来应该不是特别困难,但是感觉老板不是特别重视,让我尝试一下也只是看看前景。

主要用到的是:Google Cloud Vision API 和 Google Natural Language API
想要详细了解的话,肯定是去看google docs最方便,但是其中有些beta版的只支持英文,这里附上链接:Google AI Docs

Google Cloud Vision

Google Cloud Vision主要是为了把图片中的text转出来,使用的是ocr的接口。Github上有相当成熟的例子:OCR。主要流程就是,把图片上传到Cloud Storage之后,触发调用包含了OCR接口的Cloud Fonction,把处理之后的.txt在存回Cloud Storage里面。在Github上的例子里,Cloud Fonction还是包含其他API的,比如Translation API等,真正的大项目可能会触及费用问题。 部署函数时,需要用到:

gcloud functions deploy NAME --runtime RUNTIME

其中NAME必须和export的文件名保持一致,RUNTIME是运行环境(比如Python2.7)。

Google Natural Language

如果完全按照了上面的流程的话,OCR最终输出是在一个Cloud文件夹中的.txt文件。接下来用Natural Language做的就是在这些.txt文件中找到有用的数据。现有的Google IA 可以自主训练的AutoML中大多都是贴标签,但是Natural Language中的实物提取貌似可以抓住对应标签的对象,所以我就进行了尝试。

为了建立自己的模型,我先导出了一大批OCR的结果,自己写出了每个里的关键词。然后把他们逐个合并成立一群.jsonl文件。这里提及一下,训练自己的模型的使用流程是,先处理自己的数据使它变成.jsonl文件格式,之后上传云端的Cloud Storage,在之后制作一个.csv文件,用来把.jsonl文件们倒入Natural Language 的dataset。有点坑的是,跟着Google docs做的话很容易看着导入数据格式的文件,不小心把数据导入到Google Table里。这里要说的是Google docs有很棒的能帮忙把.txt文件转.jsonl文件并且自行生成.csv的脚本:Python Script这样做了之后,你需要在网站上自己添加Key和标签。

Jsonl文件的格式为:

{
  "annotations": [
     {
      "text_extraction": {
         "text_segment": {
            "end_offset": number, "start_offset": number
          }
       },
       "display_name": string
     },
     {
       "text_extraction": {
          "text_segment": {
             "end_offset": number, "start_offset": number
           }
        },
        "display_name": string
     },
   ...
  ],
  "text_snippet":
    {"content": string}
}

我有两个.txt文件,一个每一行是text,另一个每一行是标签对应的Key。我的办法是自己先在本地添加好标签在上传(只有一个标签),附上代码:

const fs = require('fs');
const readline = require('readline');

readFileToArr("./catchinformation.txt", function (data) {
  for (var i = 0; i < 88; i++) {
    var index = fs.readFileSync("./Image/F" + (i + 1) + ".txt", 'utf-8');
    var object = {
      annotations: [],
      text_snippet:
        { content: index }
    };
    if (data[i] != "") {
      var annotation = {
        text_extraction: {
          text_segment: {
            end_offset: index.search(data[i]) + data[i].length, start_offset: index.search(data[i])
          }
        },
        display_name: "n_Matricule"
      }
      object.annotations.push(annotation);
    }
    var resultJson = JSON.stringify(object);
    fs.writeFile("./Jsonl/F" + (i + 1) + ".jsonl", resultJson, 'utf8', function (err) {
      if (err) {
        console.log("An error occured while writing JSON Object to File.");
        return console.log(err);
      }
      //console.log("JSON file" + (i + 1) + " has been saved.");
    });
  }
}
)

function readFileToArr(fReadName, callback) {
  var fRead = fs.createReadStream(fReadName);
  var objReadline = readline.createInterface({
    input: fRead
  });
  var arr = new Array();
  objReadline.on('line', function (line) {
    arr.push(line);
    //console.log('line:'+ line);
  });
  objReadline.on('close', function () {
    // console.log(arr);
    callback(arr);
  });
}

//readFileToArr函数来源:https://blog.csdn.net/yajie_china/article/details/79407851 

在这之后,导入一个格式如下的.csv文件用来生成dataset,你可以在这里自行定义自己的训练集和测试集,也可以不定义,那么Google将以 Train : Validate : Test = 8 : 1 : 1 进行随机分配。

TRAIN,gs://my-project-lcm/training-data/traindata.jsonl
VALIDATE,gs://my-project-lcm/training-data/validatedata.jsonl
TEST,gs://my-project-lcm/training-data/testdata.jsonl

结果与使用

等待的时间还是很漫长的,至少我坐在电脑旁边等了三个小时都没有出训练好的模型。而在此例中我也仅用了千余个数据和一个标签。

我们最终获得了98.1%的precision。鉴于这只是一个测试用的例子,数据集质量并不高,所以我们对evaluation这里不做太多的分析。在test一栏中可以直接使用训练好的模型。Google给我们提供了 REST API 和 python 的使用接口,方便直接在代码中调用训练好的模型。

个人认为,对于用各种特点的对象,还是应当根据对象特点的不同多做标签,以达到更高的精度。这也是接下来,我构建真正要使用的模型要做的事。