Google 机器学习 API 问题

Google Machine Learning API Issue

我正在尝试使用 Google 机器学习 API,但我遇到了两个问题。 在 API explorer 中,我输入了正确的信息,但收到响应错误:

Code 200 "error": "Missing \"instances\" field in request body: {\n \"httpBody\": \n
{\n \"data\": \"\"instances\" : \"teste\"\",\n
\"contentType\": \"application/json\"\n }\n}"

请求找到我的模型(如果我更改字段名称中的值,我会收到另一个错误)但不理解我的 json。那就是 json:

{"instances" : [{"key":"0", "image_bytes": {"b64": "mybase64"} }]}

当我使用 gcloud 在命令行上进行预测时,我没有收到任何错误并且一切正常。我为 gcloud 创建的 Json 有点不同:

{"key":"0", "image_bytes": {"b64": "mybase64"} }

我已经在 API 资源管理器中尝试过那个,但没有成功。

所以,我决定使用 .Net Api 来尝试预测,但我得到了其他情况:响应为空 (???)。

这是我的代码:

   'get the service credential that I created
    Dim credential = Await GetCredential()


    Dim myService As New CloudMachineLearningEngineService(New BaseClientService.Initializer() With {
                                                                    .ApplicationName = "my Project Name (Is That It???)",
                                                                    .ApiKey = "my API Key",
                                                                    .HttpClientInitializer = credential
                                                               })

    Dim myBase64 As String = GetBase64("my image path to convert into a base64 String")
    Dim myJsonRequest As String = "{""instances"" : [{""key"":""0"", ""image_bytes"": {""b64"": """ + myBase64 + """}}]}"

    Dim myRequest = New GoogleCloudMlV1PredictRequest With {
        .HttpBody = New GoogleApiHttpBody With {.Data = myJsonRequest,
                                                .ContentType = "application/json"
                                                }
    }

    'If I change the model name I get error
    Dim myPredictRequest = myService.Projects.Predict(myRequest, "projects/myProject/models/myModel/versions/v1")
    myPredictRequest.AccessToken = credential.Token.AccessToken
    myPredictRequest.OauthToken = credential.Token.AccessToken
    myPredictRequest.Key = "my API Key

    'Execute the request
    Dim myResponse = myPredictRequest.Execute()

    'at this point, myResponse is Empty (myResponse.ContentType Is Nothing, myResponse.Data Is Nothing And myResponse.ETag Is Nothing)

如果我更改模型名称,我会收到一条错误消息,通知我找不到我的模型,所以我的凭据是正确的。

我不知道我做错了什么。有人可以帮助解决这些问题吗?

谢谢!

更新:------------------------

我更改了这个执行命令: Dim myResponse = myPredictRequest.Execute()
致此: Dim s = StreamToString(myPredictRequest.ExecuteAsStream())

现在我可以在 .Net API 和 google 开发人员界面(缺少实例字段...)中得到相同的错误。 因此,如果有人知道我的 Json 请求有什么问题,那将大有帮助。

您在 API 浏览器中输入的 JSON 确实是正确的(当然,假设您的模型有输入 keyimage_bytes)。这似乎是我将报告的资源管理器的错误。

您在 .NET 代码中收到错误的原因是您使用的是 .HttpBody 字段。此代码:

Dim myJsonRequest As String = "{""instances"" : [{""key"":""0"", ""image_bytes"": {""b64"": """ + myBase64 + """}}]}"
Dim myRequest = New GoogleCloudMlV1PredictRequest With {
    .HttpBody = New GoogleApiHttpBody With {.Data = myJsonRequest,
                                            .ContentType = "application/json"
                                            }
}

将生成一个 JSON 请求,如下所示:

{
  "httpBody": {
    "data": "{\"instances\" : [{\"key\":\"0\", \"image_bytes\": {\"b64\": \"mybase64\"} }]}",
    "contentType": "application\/json"
  }
}

当你真正需要的是:

{"instances" : [{"key":"0", "image_bytes": {"b64": "mybase64"} }]}

因此您会看到错误消息。

我不知道如何使用 .NET 库生成正确的响应;根据 docs 中的 Python 示例,我猜测:

Dim myJsonRequest As String = "{""instances"" : [{""key"":""0"", ""image_bytes"": {""b64"": """ + myBase64 + """}}]}"
Dim myPredictRequest = myService.Projects.Predict(myJsonRequest, "projects/myProject/models/myModel/versions/v1")

但我没有好的测试方法。作为参考,Python 等价于:

response = service.projects().predict(
    name=name,
    body=myJsonRequest
).execute()

我用.Net 解决了这个问题API。 我创建了两个新的 类 继承了 Google API 的 类。 类似的东西:

Imports Google.Apis.CloudMachineLearningEngine.v1.Data
Imports Newtonsoft.Json

Public Class myGoogleCloudMlV1PredictRequest
    Inherits GoogleCloudMlV1PredictRequest

    <JsonProperty("instances")>
    Public Property MyHttpBody As List(Of myGoogleApiHttpBody)
End Class



Imports Google.Apis.CloudMachineLearningEngine.v1.Data
Imports Newtonsoft.Json

Public Class myGoogleApiHttpBody
    Inherits GoogleApiHttpBody

    <JsonProperty("image_bytes")>
    Public Property MyData As image_byte

    <JsonProperty("key")>
    Public Property key As String

End Class

因此,在我的原始代码中,我更改了这部分:

    Dim myBase64 As String = GetBase64("my_image_path_to_convert_into_a _base64_String")
    Dim myJsonRequest As String = "{""instances"" : [{""key"":""0"", ""image_bytes"": {""b64"": """ + myBase64 + """}}]}"

    Dim myRequest = New GoogleCloudMlV1PredictRequest With {
        .HttpBody = New GoogleApiHttpBody With {.Data = myJsonRequest,
                                               .ContentType = "application/json"
                                            }
    }

对于这个:

Dim myBase64 As String = GetBase64("my_image_path_to_convert_into_a _base64_String")
Dim myRequest = New myGoogleCloudMlV1PredictRequest With {
            .MyHttpBody = New List(Of myGoogleApiHttpBody)()
        }

        Dim item As myGoogleApiHttpBody = New myGoogleApiHttpBody With {
                                                    .key = "0",
                                                    .MyData = New image_byte With {
                                                        .b64 = myBase64
                                                    }
                                                 }
        myRequest.MyHttpBody.Add(item)

瞧,它正在工作!

谢谢大家!!

Github issue #1068 显示了解决此问题的两个解决方法。

总而言之,使用 service.ModifyRequest 插入原始 JSON 内容。

或直接使用service.HttpClient.PostAsync(...)