본문 바로가기
PROGRAMING📚/Python📑

Issues :: PyTorch .h 학습 모델을 ONNX로 변환 안되는 문제 해결하기

Ta이니 2024. 12. 20.
728x90
반응형

Issues :: PyTorch .h 학습 모델을 ONNX로 변환 안되는 문제 해결하기 

 

해당 문제로 2-3일 정도 사용해서 문제를 해결했다

일단 내가 하고싶었던 코드는 개랑 고양이를 구별하는 학습모델(.h5) 를 ONNX로 변환하려고 하는데

# test-modelData.py
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os

# GPU 메모리 설정
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
    for gpu in gpus:
        tf.config.experimental.set_memory_growth(gpu, True)

# 데이터 경로 설정
train_dir = 'kagglecatsanddogs_3367a/PetImages'

# 데이터 전처리
train_datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)

train_generator = train_datagen.flow_from_directory(
    train_dir, target_size=(224, 224), batch_size=32, class_mode='binary', subset='training')

validation_generator = train_datagen.flow_from_directory(
    train_dir, target_size=(224, 224), batch_size=32, class_mode='binary', subset='validation')

# CNN 모델 구축
model = Sequential([
    Conv2D(32, (3,3), activation='relu', input_shape=(224, 224, 3)),
    MaxPooling2D(2,2),
    Conv2D(64, (3,3), activation='relu'),
    MaxPooling2D(2,2),
    Conv2D(128, (3,3), activation='relu'),
    MaxPooling2D(2,2),
    Flatten(),
    Dense(128, activation='relu'),
    Dropout(0.5),
    Dense(1, activation='sigmoid')  # 이진 분류
])

# 모델 컴파일
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])


# 모델 훈련
model.fit(train_generator, validation_data=validation_generator, epochs=10)

# 모델 평가
loss, acc = model.evaluate(validation_generator)
print(f"Validation Accuracy: {acc:.2f}")

model.save('./epoch_001/model.h5')

 

.h5 파일을 ONNX 파일로 변환하려면 TensorFlow/Keras 모델을 ONNX 포맷으로 변환하는 과정이 필요합니다. 이 작업을 수행하려면 tf2onnx 패키지를 사용하면 유용합니다. 라고 해서 다음과 같이 코드를 작성하였다.

# sample.py
import tensorflow as tf
import tf2onnx

# 1. .h5 파일 로드
h5_model_path = "./epoch_001/model.h5"  # .h5 파일 경로
model = tf.keras.models.load_model(h5_model_path)

# 2. tf2onnx 변환
onnx_model_path = "./epoch_001/model.onnx"  # 변환된 ONNX 파일 경로
spec = (tf.TensorSpec((None,) + model.input_shape[1:], tf.float32, name="input"),)
model_proto, _ = tf2onnx.convert.from_keras(model, input_signature=spec, opset=13)

# 3. ONNX 모델 저장
with open(onnx_model_path, "wb") as f:
    f.write(model_proto.SerializeToString())

print(f"ONNX 모델이 {onnx_model_path}에 저장되었습니다.")

 

문제는 onnx 로 모델을 저장하려고 하면 다음과 같은 오류가 나면서 저장이 되지 않는 문제가 생겼다

 

Traceback (most recent call last):
File "/Users/xisu/PycharmProjects/pythonProject/Sample2.py", line 10, in
model.save(saved_model_path)
File "/opt/homebrew/anaconda3/lib/python3.12/site-packages/keras/src/utils/traceback_utils.py", line 122, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/opt/homebrew/anaconda3/lib/python3.12/site-packages/keras/src/saving/saving_api.py", line 114, in save_model
raise ValueError(
ValueError: Invalid filepath extension for saving. Please add either a `.keras` extension for the native Keras format (recommended) or a `.h5` extension. Use `model.export(filepath)` if you want to export a SavedModel for use with TFLite/TFServing/etc. Received: filepath=./epoch_001/saved_model.

 

해당 문제를 해결하기 위해서 구글링과 gpt를 사용해서 문제를 찾아봤는데

tf2onnx.convert.from_keras 가 나의 버전(2.17.0) 과 맞지 않아서 오류가 나는 것이라고 판단하였다

구글링 했을 때, 2.16.0 이상부터 제공을 하지 않는것 같았다. 그래서 2.15 이하 버전으로 TensorFlow를 다운그레이드 해주려했다

주의사항

호환성 문제: Keras 2.x는 TensorFlow 2.x에서만 동작하며, TensorFlow 1.x에서는 호환되지 않습니다.
다른 라이브러리 의존성 확인: Keras 및 TensorFlow의 버전 변경은 다른 라이브러리와의 의존성 충돌을 유발할 수 있으므로, 의존성을 주의 깊게 확인하세요.
최신 코드를 검토: 코드가 Keras 3.x에 맞춰 작성된 경우, 일부 함수와 API가 2.x에서 다르게 동작할 수 있으니 확인 후 수정이 필요할 수 있습니다.

 

Keras 버전 확인

pip show keras

TensorFlow 버전 확인

pip show tensorflow

 

현재 나의 버전은 Tensorflow:2.17.0 와 keras : 3.6.0 버전이였다

엉망진창인 Tensorflow와 Keras를 삭제해준다

TensorFlow /Keras 삭제 

pip uninstall keras tensorflow -y

그리고 이제 무슨 버전을 다운 받냐가 문제였는데

TensorFlow와 Keras의 실제 버전 범위

  1. TensorFlow:
    • 현재 최신 버전은 TensorFlow 2.13.x 또는 TensorFlow 2.14.x입니다.
  2. Keras:
    • Keras는 TensorFlow 2.6 이후 TensorFlow에 포함되어 관리됩니다.
    • 독립적인 Keras는 2.4.3 또는 2.7.x 이후를 사용할 수 있습니다.

그래서 TensorFlow 2.13 을 설치하기로 했다

pip install tensorflow==2.13.0

 

ERROR: Could not find a version that satisfies the requirement tensorflow==2.13.0 (from versions: 2.16.0rc0, 2.16.1, 2.16.2, 2.17.0rc0, 2.17.0rc1, 2.17.0, 2.17.1, 2.18.0rc0, 2.18.0rc1, 2.18.0rc2, 2.18.0) ERROR: No matching distribution found for tensorflow==2.13.0

 

텐서플로 설치 명령어를 입력하니 위와 같은 명령어가 나왔고

Python 버전 확인

TensorFlow는 Python 버전에 따라 지원 범위가 다릅니다.

  • TensorFlow 2.16.x 이상은 Python 3.9 이상이 필요합니다.
  • TensorFlow 2.13.x는 Python 3.7, 3.8에서 안정적으로 지원됩니다.
python --version

 

라고 하길래 이제 파이썬 버전을 확인했더니 3.12.0 버전으로 설치되어 있었다

나같은 경우는 맥북m1에서 작업을 하고 있어서 homebrew 를 사용해서 아나콘다와 파이썬을 설치했다

 

Homebrew를 사용하여 Python 3.7 또는 3.8 설치

Homebrew는 기본적으로 최신 Python만 설치합니다. 하지만 pyenv를 사용하면 특정 버전을 설치할 수 있습니다.

brew install pyenv

 

원하는 버전 설치하기

pyenv install 3.8.10

설치 확인하기

python --version

 

아나콘다를 통해서 파이썬을 설치했다면 위 명령어를 사용해도 파이썬 버전이 변경되지 않을 것이다 (내가 그럼)

Anaconda 기본 Python 설정 변경

기본 환경을 변경하려면 base 환경의 Python 버전을 수정해야 합니다:

conda activate base
conda install python=3.8

기본 Python 버전 확인

기본 Python 버전을 확인하여 변경이 적용되었는지 확인합니다:

conda deactivate
python --version

 

파이썬 버전을 바꾸고 나면 tensorflow 가 문제 없이 설치됨..

pip install tensorflow==2.13.0

 

그리고 이제 끝난줄 알았는데 

 

opt/homebrew/anaconda3/bin/python /Users/xisu/PycharmProjects/pythonProject/sample.py Traceback (most recent call last): File "/Users/xisu/PycharmProjects/pythonProject/sample.py", line 6, in <module> model = tf.keras.models.load_model(h5_model_path) File "/opt/homebrew/anaconda3/lib/python3.8/site-packages/keras/src/saving/saving_api.py", line 238, in load_model return legacy_sm_saving_lib.load_model( File "/opt/homebrew/anaconda3/lib/python3.8/site-packages/keras/src/utils/traceback_utils.py", line 70, in error_handler raise e.with_traceback(filtered_tb) from None File "/opt/homebrew/anaconda3/lib/python3.8/site-packages/keras/src/engine/base_layer.py", line 870, in from_config raise TypeError( TypeError: Error when deserializing class 'InputLayer' using config={'batch_shape': [None, 224, 224, 3], 'dtype': 'float32', 'sparse': False, 'name': 'input_layer'}. Exception encountered: Unrecognized keyword arguments: ['batch_shape']

 

이 문제는 다행이 간단했다 내가 만들어둔 .h5 모델을 생성한 모델의 버전과 현재 내 버전이 맞지 않아서 그런 문제였다

새로 모델을 학습 시켜서 .h5 모델을 만들어 주었다

 

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os

# GPU 메모리 설정
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
    for gpu in gpus:
        tf.config.experimental.set_memory_growth(gpu, True)

# 데이터 경로 설정
train_dir = 'kagglecatsanddogs_3367a/PetImages'

# 데이터 전처리
train_datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)

train_generator = train_datagen.flow_from_directory(
    train_dir, target_size=(224, 224), batch_size=32, class_mode='binary', subset='training')

validation_generator = train_datagen.flow_from_directory(
    train_dir, target_size=(224, 224), batch_size=32, class_mode='binary', subset='validation')

# CNN 모델 구축
model = Sequential([
    Conv2D(32, (3,3), activation='relu', input_shape=(224, 224, 3)),
    MaxPooling2D(2,2),
    Conv2D(64, (3,3), activation='relu'),
    MaxPooling2D(2,2),
    Conv2D(128, (3,3), activation='relu'),
    MaxPooling2D(2,2),
    Flatten(),
    Dense(128, activation='relu'),
    Dropout(0.5),
    Dense(1, activation='sigmoid')  # 이진 분류
])

# 모델 컴파일
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])


# 모델 훈련
model.fit(train_generator, validation_data=validation_generator, epochs=10)

# 모델 평가
loss, acc = model.evaluate(validation_generator)
print(f"Validation Accuracy: {acc:.2f}")

model.save('./epoch_001/my_model.keras')

 

UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.
  saving_api.save_model(

위 에러는  model.save('./epoch_001/model.h5') 로 모델을 저장했을때 나오던 경고 문이였는데 keras 로 저장하기를 권장하는 경고문이였다  model.save('./epoch_001/my_model.keras') 

드디어 코드 실행...

import tensorflow as tf
import tf2onnx

# 1. .h5 파일 로드
h5_model_path = "./epoch_001/model.h5"  # .h5 파일 경로
model = tf.keras.models.load_model(h5_model_path)

# 2. tf2onnx 변환
onnx_model_path = "./epoch_001/model.onnx"  # 변환된 ONNX 파일 경로
spec = (tf.TensorSpec((None,) + model.input_shape[1:], tf.float32, name="input"),)
model_proto, _ = tf2onnx.convert.from_keras(model, input_signature=spec, opset=13)

# 3. ONNX 모델 저장
with open(onnx_model_path, "wb") as f:
    f.write(model_proto.SerializeToString())

print(f"ONNX 모델이 {onnx_model_path}에 저장되었습니다.")

 

728x90
반응형

'PROGRAMING📚 > Python📑' 카테고리의 다른 글

thinter-데이터 불러오기  (0) 2024.12.03
Python - Database  (1) 2024.12.02
dataAnalysis  (0) 2024.12.01
RawImageViewer / NoteFile  (0) 2024.11.30
python - windowLocationInfo  (2) 2024.11.29

댓글