[Python] Python TensorFlow model does not work in Java TensorFlow

Discussão em 'Python' iniciado por Stack, Fevereiro 16, 2025.

  1. Stack

    Stack Membro Participativo

    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][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][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 * 100);
    }

    // Encontrar a classe com maior probabilidade
    int predictedClass = 0;
    float maxProb = 0;
    for (int i = 0; i < predictions.length; i++) {
    if (predictions > maxProb) {
    maxProb = predictions;
    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?

    Continue reading...

Compartilhe esta Página