我正在尝试向Google云端的ml-engine上的模型发送Json请求。这需要一个形式为
的json我需要将float数组转换为单个base64编码的字符串。
我想也许google protobuf ByteString可能就是我想要的,但这似乎与字节数组(stackoverflow question on the difference between the two)的行为相同。
我目前为“b64”键创建值的方法会创建一个字节字符串数组,从而导致谷歌云错误(see other question)。
public static String[] convertToBase64Bytes(float[] audio) {
String[] data = new String[audio.length];
for (int i = 0; i < audio.length; i++) {
float amplitude = audio[i];
byte[] byteArray = ByteBuffer.allocate(4).putFloat(amplitude).array();
data[i] = Base64.encodeToString(byteArray, Base64.DEFAULT);
}
return data;
}
我一直无法找到如何将整个float数组转换为单个base64字节字符串,然后ml-engine可以转换回原始数组。
如果它有用,我这样做的方式就是Python
bytes_string = audio_array.tostring() #audio_array is a numpy array
encoded = base64.b64encode(bytes_string)
有人能帮忙解决这个问题吗?感谢。
答案 0 :(得分:2)
public static String convertToBase64Bytes(float[] audio) {
ByteBuffer buff = ByteBuffer.allocate(4 * audio.length);
for (int i = 0; i < audio.length; i++) {
float amplitude = audio[i];
buff.putFloat(amplitude);
}
String data = Base64.getEncoder().encodeToString(buff.array(), Base64.DEFAULT);
return data;
}
答案 1 :(得分:0)
对于此解决方案,我使用Gson()(you can the jar or the maven dependencies from here) 生成最终字符串,如示例所示。
我已经创建了一些辅助类,你可以把它放在项目的其他地方(不一定是内部类)。
主要方法是提供运行代码的方法。
输出如下:
编辑我
每个浮动一个b64项目的原始解决方案。
{"instances":[{"b64":"QUczMw=="},{"b64":"QgpmZg=="},{"b64":"wgHS8g=="},{"b64":"QU+uFA=="}]}
代码:
public class FloatEncoder {
public static void main(String args[]) {
FloatEncoder encoder = new FloatEncoder();
float [] floats = new float[] {12.45f, 34.6f, -32.456f, 12.98f};
String encodedJson = encoder.encode(floats);
System.out.println(encodedJson);
}
private String encode(float[] floats) {
String rtn;
DataHolder holder = new DataHolder();
String [] audios = convertToBase64Bytes(floats);
for(String audio : audios) {
B64 b64 = new B64();
b64.b64 = audio;
holder.instances.add(b64);
}
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
rtn = gson.toJson(holder);
return rtn;
}
public static String[] convertToBase64Bytes(float[] audio) {
String[] data = new String[audio.length];
for (int i = 0; i < audio.length; i++) {
float amplitude = audio[i];
byte[] byteArray = ByteBuffer.allocate(4).putFloat(amplitude).array();
data[i] = Base64.getEncoder().encodeToString(byteArray);
}
return data;
}
public static class DataHolder{
public ArrayList<B64> instances = new ArrayList<>();
}
public static class B64{
public String b64;
}
}
编辑II
一个b64项的解决方案,浮点数组编码为单个 字符串。
{"instances":[{"b64":"QUczM0IKZmbCAdLyQU+uFA=="}]}
字符串是字节数组的Base64编码,其中前4个字节是第一个浮点数,第二个4是第二个浮点数,依此类推。
public class FloatEncoder {
public static void main(String args[]) {
FloatEncoder encoder = new FloatEncoder();
float [] floats = new float[] {12.45f, 34.6f, -32.456f, 12.98f};
String encodedJson = encoder.encode(floats);
System.out.println(encodedJson);
}
private String encode(float[] floats) {
String rtn;
DataHolder holder = new DataHolder();
String audios = convertToBase64Bytes(floats);
B64 b64 = new B64();
b64.b64 = audios;
holder.instances.add(b64);
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
rtn = gson.toJson(holder);
return rtn;
}
public static String convertToBase64Bytes(float[] audio) {
ByteBuffer byteBuffer = ByteBuffer.allocate(4 * audio.length);
for (int i = 0; i < audio.length; i++) {
float amplitude = audio[i];
byteBuffer.putFloat(amplitude);
}
byte[] data = byteBuffer.array();
String rtn = Base64.getEncoder().encodeToString(data);
return rtn;
}
public static class DataHolder{
public ArrayList<B64> instances = new ArrayList<>();
}
public static class B64{
public String b64;
}
}