H2O DeepLearning训练报错:无法将""200""转换为int类型
Let's break down what's happening here and how to fix that frustrating type conversion error when setting the hidden layers for your H2O deep learning model.
The Problem Recap
You're hitting this error when calling h2o.train_deeplearning(dlParams):
Illegal argument for field: hidden of schema: DeepLearningParametersV3: cannot convert ""200"" to type int
Even after explicitly setting dlParams.hidden=new int[]{200,200};, the error persists. The key clue here is the double-quoted "200" in the message—this means your integer values are being wrapped in quotes during serialization, and the H2O server is trying to parse that quoted string as a raw integer, which fails.
Why This Happens
The root issue is almost always related to how the Java API serializes the int[] hidden array when sending it to the H2O server. The client is turning your integer array elements into quoted strings (like "200" instead of 200), and the server's parser (seen in that parse method snippet) can't handle that.
Fixes to Try (In Order)
1. Match H2O Client and Server Versions
First rule of H2O troubleshooting: make sure your Java client library version is exactly the same as your H2O server version. Version mismatches often break parameter serialization logic, especially for array types. Update or roll back your dependencies to match the server and try again.
2. Use the Builder Pattern for Parameters
H2O's newer Java APIs prefer builder-style parameter construction, which handles serialization correctly out of the box. Replace your manual parameter assignment with the builder:
// Replace your dlParams setup with this DeepLearningParametersV3 dlParams = new DeepLearningParametersV3() .setTrainingFrame(H2oApi.stringToFrameKey("train")) .setValidationFrame(H2oApi.stringToFrameKey("test")) .setHidden(new int[]{200, 200}) .setResponseColumn(responseColumn);
Builders are designed to avoid serialization bugs that come from direct field assignment.
3. Check Your Custom H2oApi Utility Class
You're using custom helper methods like H2oApi.copyFields and stringToFrameKey. There's a chance that copyFields is incorrectly handling the int[] hidden field—maybe converting it to a string array or adding quotes during the copy process. Debug this method to ensure it preserves the integer array type correctly.
4. Try a String Array Workaround
If the builder doesn't work, try passing the hidden layer sizes as a string array instead of an integer array. This might align with how the server expects the data to be formatted:
// Replace int[] with String[] dlParams.hidden = new String[]{"200", "200"};
This bypasses any broken integer array serialization logic in the client, letting the server parse the string values directly.
5. Direct REST API Call (Last Resort)
If all else fails, skip the Java API wrapper and send a raw HTTP POST request to the H2O REST endpoint /3/DeepLearning. The correct JSON body for the hidden parameter is a plain integer array:
{ "training_frame": "train", "validation_frame": "test", "hidden": [200, 200], "response_column": "class" }
You can use a library like OkHttp or Apache HttpClient to send this request, ensuring the parameter is formatted correctly.
Code Context for Reference
Your core training code, hidden field definition, and error-triggering parser snippet are included below for clarity:
Training Code
private void DL() throws IOException { //H2O start String url = "http://localhost:54321/"; H2oApi h2o = new H2oApi(url); //STEP 0: init a session String sessionId = h2o.newSession().sessionKey; //STEP 1: import raw file String path = "hdfs://kbmst:9000/user/spark/datasets/iris.csv"; ImportFilesV3 importBody = h2o.importFiles(path, null); System.out.println("import: " + importBody); //STEP 2: parse setup ParseSetupV3 parseSetupParams = new ParseSetupV3(); parseSetupParams.sourceFrames = H2oApi.stringArrayToKeyArray(importBody.destinationFrames, FrameKeyV3.class); ParseSetupV3 parseSetupBody = h2o.guessParseSetup(parseSetupParams); System.out.println("parseSetupBody: " + parseSetupBody); //STEP 3: parse into columnar Frame ParseV3 parseParams = new ParseV3(); H2oApi.copyFields(parseParams, parseSetupBody); parseParams.destinationFrame = H2oApi.stringToFrameKey("iris.hex"); parseParams.blocking = true; ParseV3 parseBody = h2o.parse(parseParams); System.out.println("parseBody: " + parseBody); //STEP 4: Split into test and train datasets String tmpVec = "tmp_" + UUID.randomUUID().toString(); String splitExpr = "(, " + " (tmp= " + tmpVec + " (h2o.runif iris.hex 906317))" + " (assign train " + " (rows iris.hex (<= " + tmpVec + " 0.75)))" + " (assign test " + " (rows iris.hex (> " + tmpVec + " 0.75)))" + " (rm " + tmpVec + "))"; RapidsSchemaV3 rapidsParams = new RapidsSchemaV3(); rapidsParams.sessionId = sessionId; rapidsParams.ast = splitExpr; h2o.rapidsExec(rapidsParams); // STEP 5: Train the model DeepLearningParametersV3 dlParams = new DeepLearningParametersV3(); dlParams.trainingFrame = H2oApi.stringToFrameKey("train"); dlParams.validationFrame = H2oApi.stringToFrameKey("test"); dlParams.hidden=new int[]{200,200}; ColSpecifierV3 responseColumn = new ColSpecifierV3(); responseColumn.columnName = "class"; dlParams.responseColumn = responseColumn; System.out.println("About to train DL. . ."); DeepLearningV3 dlBody = h2o.train_deeplearning(dlParams); System.out.println("dlBody: " + dlBody); //后续步骤略 }
Hidden Field Definition
public class DeepLearningParametersV3 extends ModelParametersSchemaV3 { /** * Hidden layer sizes (e.g. [100, 100]). */ public int[] hidden; //other params }
Error-Triggering Parser Code
static <E> Object parse(String field_name, String s, Class fclz, boolean required, Class schemaClass) { if (fclz.isPrimitive() || String.class.equals(fclz)) { try { return parsePrimitve(s, fclz); } catch (NumberFormatException ne) { String msg = "Illegal argument for field: " + field_name + " of schema: " + schemaClass.getSimpleName() + ": cannot convert \"" + s + "\" to type " + fclz.getSimpleName(); throw new H2OIllegalArgumentException(msg); } } //数组处理逻辑略 }
内容的提问来源于stack exchange,提问作者liyuhui

