Python TensorFlow model does not work in Java TensorFlow
17:30 16 Feb 2025

I am training a model in Python using TensorFlow and Keras, and attempting to load it in a Java application. However, I am encountering an error when trying to perform inference.

Java Code

public static void main(String[] args) {
        final String MODEL_PATH = "/home/himitsu/Desktop/PhD/SMA/SMACarev1/src/main/resources/ecg_model_to_java";

        try (SavedModelBundle model = SavedModelBundle.load(MODEL_PATH, "serve")) {
            System.out.println("Modelo carregado com sucesso!");

            // 🔹 Criar uma sessão para executar a inicialização das variáveis
            Session session = model.session();

            // 1. Gerar dados de teste
            float[][][] ecgSample = generateECGTestSample();

            // 2. Criar tensor de entrada corretamente
            try (TFloat32 inputTensor = TFloat32.tensorOf(
                    Shape.of(1, 100, 1),
                    data -> {
                        for (int i = 0; i < 100; i++) {
                            data.setFloat(ecgSample[0][i][0], 0, i, 0);
                        }
                    }
            )) {
                // 3. Executar inferência diretamente sem lista
                try (Tensor outputTensor = model.function("serving_default").call(inputTensor)) {
                    if (outputTensor instanceof TFloat32) {
                        processOutput((TFloat32) outputTensor);
                    } else {
                        System.err.println("Erro: O modelo não retornou um TFloat32.");
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("Erro durante a inferência:");
            e.printStackTrace();
        }
    }

    private static float[][][] generateECGTestSample() {
        float[][][] sample = new float[1][100][1];
        for (int i = 0; i < 100; i++) {
            sample[0][i][0] = (float) (0.5 * Math.sin(2 * Math.PI * i / 20));
        }
        return sample;
    }

    private static void processOutput(TFloat32 tensor) {
        // Corrigido para a nova API: acessar os dados corretamente
        FloatDataBuffer buffer = tensor.asRawTensor().data().asFloats();
        float[] predictions = new float[(int) tensor.shape().size(1)];
        buffer.read(predictions);

        System.out.println("\nResultado da Predição:");
        for (int i = 0; i < predictions.length; i++) {
            System.out.printf("Classe %d: %.2f%%%n", i, predictions[i] * 100);
        }

        // Encontrar a classe com maior probabilidade
        int predictedClass = 0;
        float maxProb = 0;
        for (int i = 0; i < predictions.length; i++) {
            if (predictions[i] > maxProb) {
                maxProb = predictions[i];
                predictedClass = i;
            }
        }
        System.out.printf("\nDiagnóstico Previsto: Classe %d (%.2f%% de confiança)%n",
                predictedClass, maxProb * 100);
    }

Python Code




df = pd.read_csv('/home/himitsu/Desktop/PhD/SMA/Databases/arrhythmia_dataset_with_ecg.csv')

# Extrair features (ECG bruto: 100 amostras por batimento)
ecg_columns = [f'ecg_{i}' for i in range(100)]
X = df[ecg_columns].values  # Shape: (n_amostras, 100)

# Extrair rótulos e codificar para números
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(df['label'].values)  # y: inteiros (0, 1, 2, ...)

# Dividir em treino e teste (estratificado)
X_train, X_test, y_train, y_test = train_test_split(
    X, y,
    test_size=0.2,
    stratify=y,
    random_state=42
)

# Redimensionar para formato de entrada da CNN + LSTM (n_amostras, 100, 1)
X_train = X_train.reshape(-1, 100, 1)
X_test = X_test.reshape(-1, 100, 1)

# ======================================
# 2. Construir o Modelo (CNN + LSTM)
# ======================================

model = Sequential([
    # Camadas Convolucionais
    Conv1D(32, kernel_size=3, activation='relu', input_shape=(100, 1)),
    MaxPooling1D(2),
    Conv1D(64, kernel_size=3, activation='relu'),
    MaxPooling1D(2),

    # Camada LSTM
    LSTM(50, return_sequences=False),

    # Camadas Densas
    Dense(128, activation='relu'),
    Dropout(0.5),
    Dense(len(label_encoder.classes_), activation='softmax')
])

# Compilar o modelo
model.compile(
    optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

model.summary()

# ======================================
# 3. Treinar o Modelo
# ======================================

# Callbacks para evitar overfitting
callbacks = [
    EarlyStopping(patience=5, restore_best_weights=True),
    ModelCheckpoint('best_model_cnn_lstm.keras', save_best_only=True)
]

# Treinamento
history = model.fit(
    X_train, y_train,
    epochs=50,
    batch_size=32,
    validation_split=0.2,
    callbacks=callbacks
)

# ======================================
# 4. Avaliar o Modelo
# ======================================

test_loss, test_accuracy = model.evaluate(X_test, y_test)
print(f'\nAcurácia no teste: {test_accuracy * 100:.2f}%')

# Plotar curvas de aprendizado
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Treino')
plt.plot(history.history['val_accuracy'], label='Validação')
plt.title('Acurácia por Época')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Treino')
plt.plot(history.history['val_loss'], label='Validação')
plt.title('Loss por Época')
plt.legend()
plt.show()

# ======================================
# 5. Fazer Previsões
# ======================================

sample_idx = 0  # Escolha uma amostra
test_sample = X_test[sample_idx].reshape(1, 100, 1)
true_label = y_test[sample_idx]
predicted_prob = model.predict(test_sample)
predicted_label = np.argmax(predicted_prob)

print(f'\nExemplo Real: {label_encoder.inverse_transform([true_label])[0]}')
print(f'Previsão: {label_encoder.inverse_transform([predicted_label])[0]}')
print(f'Probabilidades: {predicted_prob}')

# ======================================
# 6. Salvar o Modelo para TensorFlow Java
# ======================================

# Certifique-se de que o modelo foi treinado antes de exportar
export_dir = "ecg_model_to_javav2"

# Salvar o modelo corretamente sem definir manualmente a assinatura
tf.saved_model.save(model, export_dir)

Error Message

2025-02-15 22:47:37.247065: I tensorflow/cc/saved_model/reader.cc:83] Reading SavedModel from: /home/himitsu/Desktop/PhD/SMA/SMACarev1/src/main/resources/ecg_model_to_javav2
2025-02-15 22:47:37.250045: I tensorflow/cc/saved_model/reader.cc:51] Reading meta graph with tags { serve }
2025-02-15 22:47:37.250082: I tensorflow/cc/saved_model/reader.cc:146] Reading SavedModel debug info (if present) from: /home/himitsu/Desktop/PhD/SMA/SMACarev1/src/main/resources/ecg_model_to_javav2
2025-02-15 22:47:37.250161: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
2025-02-15 22:47:37.309389: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:388] MLIR V1 optimization pass is not enabled
2025-02-15 22:47:37.315025: I tensorflow/cc/saved_model/loader.cc:234] Restoring SavedModel bundle.
2025-02-15 22:47:37.459839: I tensorflow/cc/saved_model/loader.cc:218] Running initialization op on SavedModel bundle at path: /home/himitsu/Desktop/PhD/SMA/SMACarev1/src/main/resources/ecg_model_to_javav2
2025-02-15 22:47:37.505041: I tensorflow/cc/saved_model/loader.cc:317] SavedModel load for tags { serve }; Status: success: OK. Took 257993 microseconds.
Modelo carregado com sucesso!
2025-02-15 22:47:37.915743: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: FAILED_PRECONDITION: Could not find variable sequential/dense_1/kernel. This could mean that the variable has been deleted. In TF1, it can also mean the variable is uninitialized. Debug info: container=localhost, status error message=Resource localhost/sequential/dense_1/kernel/N10tensorflow3VarE does not exist.
     [[{{function_node __inference_serving_default_338688}}{{node sequential_1/dense_1_2/Cast/ReadVariableOp}}]]
Erro durante a inferência:
org.tensorflow.exceptions.TFFailedPreconditionException: Could not find variable sequential/dense_1/kernel. This could mean that the variable has been deleted. In TF1, it can also mean the variable is uninitialized. Debug info: container=localhost, status error message=Resource localhost/sequential/dense_1/kernel/N10tensorflow3VarE does not exist.
     [[{{function_node __inference_serving_default_338688}}{{node sequential_1/dense_1_2/Cast/ReadVariableOp}}]]
    at org.tensorflow.internal.c_api.AbstractTF_Status.throwExceptionIfNotOK(AbstractTF_Status.java:84)
    at org.tensorflow.Session.run(Session.java:826)
    at org.tensorflow.Session$Runner.runHelper(Session.java:549)
    at org.tensorflow.Session$Runner.run(Session.java:476)
    at org.tensorflow.SessionFunction.call(SessionFunction.java:115)
    at org.tensorflow.TensorFunction.call(TensorFunction.java:83)
    at org.example.EcgModelTester.main(EcgModelTester.java:34)

Additional Information

saved_model_cli show --dir './ecg_model_to_java/' --tag_set serve --signature_def serving_default 

2025-02-15 22:08:37.125957: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory
2025-02-15 22:08:37.125985: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
The given SavedModel SignatureDef contains the following input(s):
  inputs['inputs'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 100, 1)
      name: serving_default_inputs:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['output_0'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 15)
      name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict

Question How can I resolve the error Could not find variable sequential/dense_1/bias when loading the TensorFlow model in Java?

python java tensorflow