분명히 모델 초기화 코드를 제대로 패키징 하고 다른 파이썬 파일에서 import 하면 제대로 작동하는 반면, Flask API 에서 적용하려 하면 에러가 나는 경우가 있다

 

This could mean that the variable was uninitialized.
Tensor("mrcnn_detection/Reshape_1:0", shape=(1, 100, 6), dtype=float32) is not an element of this graph.

내가 직면했던 에러는 이 두 가지 에러였다

 

말 그대로 텐서플로의 세션 또는 그래프가 제대로 초기화되지 않아 발생하는 에러이다

 

하지만 왜 Flask API 에 가져오려하면 이런 에러가 발생하는 것인가?

 

Flask 는 여러 스레드를 사용한다. 이런 에러가 발생하는 이유는 tensorflow 모델이 로드되지 않은 채로 스레드에서 사용되기 때문이다

내가 찾은 해결 방법은 tensorflow 가 graph 와 session 을 global 변수로 사용하도록 하는 방법이다

 

 

flask_API.py

import InferenceClass

class InferenceServer:
    def __init__(self):
        self.tensorflow_obj = InferenceClass(self.model_path)
        self.tensorflow_obj.model_init()

        self.app = self.create_flask_app()

    def create_flask_app(self):
        app = Flask(__name__)

        @app.route('/image', methods=['POST'])
        def mask_rcnn_inference():
			
            ...

            inference_image, inference_time = self.tensorflow_obj.inference(img)
            
            ...


        return app

 

 

InferenceClass.model_init()

    def model_init(self):
        self.model = modellib.MaskRCNN(mode="inference", model_dir=self.MODEL_DIR,
                                  config=self.config)
                                  
        self.model.load_weights(self.weights_path, by_name=True)

  

 

 

InferenceClass.inference()

def inference(self, image):
	...
	
	results = self.model.detect([image], verbose=1)

	...

 

 

위 와 같은 형태의 코드에서 Flask 코드에선 global 변수로 session 과 model 을 넣어주면 되고, Flask 에서 import 하는 코드엔 global 로 선언된 graph 를 기반으로 inference 코드가 돌게 하면 된다

 

 

 

 

 

flask_API.py

global model  # 추가됨
global session  # 추가됨


class InferenceServer:
    def __init__(self):
        global model  # 추가됨
        global session  # 추가됨

        session = tf.Session()  # 추가됨
        keras.backend.set_session(session)  # 추가됨

        model = InferenceClass(self.model_path)  # 클래스 변수가 아닌 global 변수 사용
        model.model_init()  # 클래스 변수가 아닌 global 변수 사용
        self.app = self.create_flask_app()

    def create_flask_app(self):
        app = Flask(__name__)

        @app.route('/image', methods=['POST'])
        def mask_rcnn_inference():
            with session.as_default():  # 추가됨
				
                ...
                
                inference_image, inference_time = model.inference(img)  # 클래스 변수가 아닌 global 변수 사용
                
                ...
        return app

 

 

InferenceClass.model_init()

    def model_init(self):
        global graph  # 추가됨
        self.model = modellib.MaskRCNN(mode="inference", model_dir=self.MODEL_DIR,
                                  config=self.config)
        print(self.weights_path)
        self.model.load_weights(self.weights_path, by_name=True)

        graph = tf.get_default_graph()  # 추가됨

 

 

InferenceClass.inference()

def inference(self, image):
	with graph.as_default():  # 추가됨
    
		...
	
		results = self.model.detect([image], verbose=1)

		...
블로그 이미지

우송송

,

Ubuntu 에서 pip install 을 통해 파이썬 패키지를 설치하는 경우 UnicodeDecodeError 가 발생하는 경우가 종종 있다.

 

 

 

 

내 경우에는 Docker 안에서 우분투를 사용할 때 이런 에러가 나타났는데 Dockerfile 을 빌드할 때 Locale 설정을 해주지 않은 것이 그 이유였다.

 

해결방법은 Dockerfile 의 상단에 아래의 코드를 추가하고 새로 빌드하거나

FROM ubuntu:18.04

#Set the locale
RUN apt-get update
RUN apt-get install locales
ENV LANG ko_KR.UTF-8
ENV LANGUAGE ko_KR.UTF-8
RUN update-locale LANG=ko_KR.UTF-8

 

 

도커를 새로 빌드하긴 싫고 당장의 에러만 해결하고 싶다면 아래의 명령어를 먼저 입력 후 pip install 을 진행해주면 된다

$ export LC_ALL=C.UTF-8

 

블로그 이미지

우송송

,

지금 한창 maskrcnn 체크포인트를 로드해서 inference 를 하기 위한 코드를 작성중이다

 

학습을 돌리다보면 한 체크포인트에서 다양한 파일들이 만들어진다

 

checkpoint, data-00000-of-0000*, index, meta 파일이 생성된다

 

하지만 지금까지 pretrained 모델 (주로 pb, h5) 을 사용했던 터라 tensorflow 의 체크포인트인 data-00001-of-00002, data-0000-of-00002, index, meta 파일들을 직접적으로 다루는건 처음이라 많은 시행착오를 겪고있다.

 

저 파일들을 pb 로 만들던 h5 로 만들던 우선 체크포인트 파일들을 불러오기부터 해야하기 때문에 기본적인 작업이라 생각되어 잊어버리지 않기 위해 여기다가 글을 쓴다

 

우선 아래는 특정 체크포인트 파일들을 읽어들이는 기본 코드이다

import tensorflow as tf

meta_ckpt_path = "C:/Users/user/Desktop/models/maskrcnn_models/model.ckpt-2396686.meta"
model_ckpt_path = "C:/Users/user/Desktop/models/maskrcnn_models/model.ckpt-2396686"

with tf.Session() as sess:
    # Restore the graph
    saver = tf.train.import_meta_graph(meta_ckpt_path)

    # Load weights
    saver.restore(sess, model_ckpt_path)

 

 

아래는 가장 최근 checkpoint 파일들을 읽어들이는 기본 코드이다

 

import tensorflow as tf

meta_ckpt_path = "C:/Users/user/Desktop/models/maskrcnn_models/model.ckpt-2396686.meta"
model_ckpt_path = "C:/Users/user/Desktop/models/maskrcnn_models/"

with tf.Session() as sess:
    # Restore the graph
    saver = tf.train.import_meta_graph(meta_ckpt_path)

    # Load weights
    saver.restore(sess, tf.train.latest_checkpoint(model_ckpt_path))
    

 

 

두 코드의 차이는

1. saver.restore 함수에서 tf.train.latest_checkpoint 함수로 checkpoint 들이 저장되는 경로를 파라미터로 주는지

      ex) "C:/Users/user/Desktop/models/maskrcnn_models/"

 

2. saver.restore 함수에서 tf.train.latest_checkpoint 를 사용하지 않고 특정 체크포인트를 지목해주는지 이다

      ex) "C:/Users/user/Desktop/models/maskrcnn_models/model.ckpt-2396686"

 

 

 

1 번 처럼 checkpoint 들이 저장되는 경로를 파라미터로 주는 경우에 주의해야 할 점이 있는데 위에 파일 리스트를 캡쳐한 이미지를 보면 'checkpoint' 라는 파일이 하나 보일것이다

 

해당 파일을 열어보면 

 

 

위 와 같이 체크포인트들의 경로가 기록되어 있는 것을 볼 수 있다.

저 목록 중 가장 최신에 기록 된 체크포인트의 경로를 찾아내는 것 이므로 저 중 맨 첫번 째 줄과 맨 마지막 줄의 경로를 수정해 주면 된다

 

내 경우엔 ubuntu 에서 만들어진 체크포인트를 윈도우에서 사용 중 이므로 윈도우 경로로 지정해주었다

 

 

 

하지만 위와 같이 제대로 코드를 작성했음에도

 

C:\ProgramData\Anaconda3\envs\tf12_env\python.exe C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py
C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\dtypes.py:523: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint8 = np.dtype([("qint8", np.int8, 1)])
C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\dtypes.py:524: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint8 = np.dtype([("quint8", np.uint8, 1)])
C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint16 = np.dtype([("qint16", np.int16, 1)])
C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint16 = np.dtype([("quint16", np.uint16, 1)])
C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\dtypes.py:527: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint32 = np.dtype([("qint32", np.int32, 1)])
C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\dtypes.py:532: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  np_resource = np.dtype([("resource", np.ubyte, 1)])
2020-04-16 15:52:45.147591: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2020-04-16 15:52:45.248758: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 0 with properties: 
name: GeForce GTX 1080 with Max-Q Design major: 6 minor: 1 memoryClockRate(GHz): 1.468
pciBusID: 0000:01:00.0
totalMemory: 8.00GiB freeMemory: 6.61GiB
2020-04-16 15:52:45.249101: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1511] Adding visible gpu devices: 0
2020-04-16 15:52:46.118933: I tensorflow/core/common_runtime/gpu/gpu_device.cc:982] Device interconnect StreamExecutor with strength 1 edge matrix:
2020-04-16 15:52:46.119121: I tensorflow/core/common_runtime/gpu/gpu_device.cc:988]      0 
2020-04-16 15:52:46.119212: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 0:   N 
2020-04-16 15:52:46.119427: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 6370 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1080 with Max-Q Design, pci bus id: 0000:01:00.0, compute capability: 6.1)
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\client\session.py", line 1334, in _do_call
    return fn(*args)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\client\session.py", line 1317, in _run_fn
    self._extend_graph()
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\client\session.py", line 1352, in _extend_graph
    tf_session.ExtendSession(self._session)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Cannot assign a device for operation IteratorToStringHandle: Could not satisfy explicit device specification '' because the node {{colocation_node IteratorToStringHandle}} was colocated with a group of nodes that required incompatible device '/device:GPU:0'
Colocation Debug Info:
Colocation group had the following types and devices: 
IteratorToStringHandle: GPU CPU 
OneShotIterator: CPU 
IteratorGetNext: GPU CPU 

Colocation members and user-requested devices:
  OneShotIterator (OneShotIterator) 
  IteratorToStringHandle (IteratorToStringHandle) 
  clone_0/IteratorGetNext (IteratorGetNext) /device:GPU:0

	 [[{{node IteratorToStringHandle}} = IteratorToStringHandle[](OneShotIterator)]]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\training\saver.py", line 1546, in restore
    {self.saver_def.filename_tensor_name: save_path})
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\client\session.py", line 929, in run
    run_metadata_ptr)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\client\session.py", line 1152, in _run
    feed_dict_tensor, options, run_metadata)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\client\session.py", line 1328, in _do_run
    run_metadata)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\client\session.py", line 1348, in _do_call
    raise type(e)(node_def, op, message)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Cannot assign a device for operation IteratorToStringHandle: Could not satisfy explicit device specification '' because the node node IteratorToStringHandle (defined at C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py:11) having device No device assignments were active during op 'IteratorToStringHandle' creation.  was colocated with a group of nodes that required incompatible device '/device:GPU:0'
Colocation Debug Info:
Colocation group had the following types and devices: 
IteratorToStringHandle: GPU CPU 
OneShotIterator: CPU 
IteratorGetNext: GPU CPU 

Colocation members and user-requested devices:
  OneShotIterator (OneShotIterator) 
  IteratorToStringHandle (IteratorToStringHandle) 
  clone_0/IteratorGetNext (IteratorGetNext) /device:GPU:0

	 [[node IteratorToStringHandle (defined at C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py:11)  = IteratorToStringHandle[](OneShotIterator)]]

No node-device colocations were active during op 'IteratorToStringHandle' creation.
No device assignments were active during op 'IteratorToStringHandle' creation.

Caused by op 'IteratorToStringHandle', defined at:
  File "C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py", line 11, in <module>
    saver = tf.train.import_meta_graph(meta_ckpt_path)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\training\saver.py", line 1674, in import_meta_graph
    meta_graph_or_file, clear_devices, import_scope, **kwargs)[0]
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\training\saver.py", line 1696, in _import_meta_graph_with_return_elements
    **kwargs))
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\meta_graph.py", line 806, in import_scoped_meta_graph_with_return_elements
    return_elements=return_elements)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\util\deprecation.py", line 488, in new_func
    return func(*args, **kwargs)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\importer.py", line 442, in import_graph_def
    _ProcessNewOps(graph)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\importer.py", line 234, in _ProcessNewOps
    for new_op in graph._add_new_tf_operations(compute_devices=False):  # pylint: disable=protected-access
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\ops.py", line 3440, in _add_new_tf_operations
    for c_op in c_api_util.new_tf_operations(self)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\ops.py", line 3440, in <listcomp>
    for c_op in c_api_util.new_tf_operations(self)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\ops.py", line 3299, in _create_op_from_tf_operation
    ret = Operation(c_op, self)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\ops.py", line 1770, in __init__
    self._traceback = tf_stack.extract_stack()

InvalidArgumentError (see above for traceback): Cannot assign a device for operation IteratorToStringHandle: Could not satisfy explicit device specification '' because the node node IteratorToStringHandle (defined at C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py:11) having device No device assignments were active during op 'IteratorToStringHandle' creation.  was colocated with a group of nodes that required incompatible device '/device:GPU:0'
Colocation Debug Info:
Colocation group had the following types and devices: 
IteratorToStringHandle: GPU CPU 
OneShotIterator: CPU 
IteratorGetNext: GPU CPU 

Colocation members and user-requested devices:
  OneShotIterator (OneShotIterator) 
  IteratorToStringHandle (IteratorToStringHandle) 
  clone_0/IteratorGetNext (IteratorGetNext) /device:GPU:0

	 [[node IteratorToStringHandle (defined at C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py:11)  = IteratorToStringHandle[](OneShotIterator)]]

No node-device colocations were active during op 'IteratorToStringHandle' creation.
No device assignments were active during op 'IteratorToStringHandle' creation.


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py", line 14, in <module>
    saver.restore(sess, model_ckpt_path)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\training\saver.py", line 1582, in restore
    err, "a mismatch between the current graph and the graph")
tensorflow.python.framework.errors_impl.InvalidArgumentError: Restoring from checkpoint failed. This is most likely due to a mismatch between the current graph and the graph from the checkpoint. Please ensure that you have not altered the graph expected based on the checkpoint. Original error:

Cannot assign a device for operation IteratorToStringHandle: Could not satisfy explicit device specification '' because the node node IteratorToStringHandle (defined at C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py:11) having device No device assignments were active during op 'IteratorToStringHandle' creation.  was colocated with a group of nodes that required incompatible device '/device:GPU:0'
Colocation Debug Info:
Colocation group had the following types and devices: 
IteratorToStringHandle: GPU CPU 
OneShotIterator: CPU 
IteratorGetNext: GPU CPU 

Colocation members and user-requested devices:
  OneShotIterator (OneShotIterator) 
  IteratorToStringHandle (IteratorToStringHandle) 
  clone_0/IteratorGetNext (IteratorGetNext) /device:GPU:0

	 [[node IteratorToStringHandle (defined at C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py:11)  = IteratorToStringHandle[](OneShotIterator)]]

No node-device colocations were active during op 'IteratorToStringHandle' creation.
No device assignments were active during op 'IteratorToStringHandle' creation.

Caused by op 'IteratorToStringHandle', defined at:
  File "C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py", line 11, in <module>
    saver = tf.train.import_meta_graph(meta_ckpt_path)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\training\saver.py", line 1674, in import_meta_graph
    meta_graph_or_file, clear_devices, import_scope, **kwargs)[0]
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\training\saver.py", line 1696, in _import_meta_graph_with_return_elements
    **kwargs))
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\meta_graph.py", line 806, in import_scoped_meta_graph_with_return_elements
    return_elements=return_elements)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\util\deprecation.py", line 488, in new_func
    return func(*args, **kwargs)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\importer.py", line 442, in import_graph_def
    _ProcessNewOps(graph)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\importer.py", line 234, in _ProcessNewOps
    for new_op in graph._add_new_tf_operations(compute_devices=False):  # pylint: disable=protected-access
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\ops.py", line 3440, in _add_new_tf_operations
    for c_op in c_api_util.new_tf_operations(self)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\ops.py", line 3440, in <listcomp>
    for c_op in c_api_util.new_tf_operations(self)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\ops.py", line 3299, in _create_op_from_tf_operation
    ret = Operation(c_op, self)
  File "C:\ProgramData\Anaconda3\envs\tf12_env\lib\site-packages\tensorflow\python\framework\ops.py", line 1770, in __init__
    self._traceback = tf_stack.extract_stack()

InvalidArgumentError (see above for traceback): Restoring from checkpoint failed. This is most likely due to a mismatch between the current graph and the graph from the checkpoint. Please ensure that you have not altered the graph expected based on the checkpoint. Original error:

Cannot assign a device for operation IteratorToStringHandle: Could not satisfy explicit device specification '' because the node node IteratorToStringHandle (defined at C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py:11) having device No device assignments were active during op 'IteratorToStringHandle' creation.  was colocated with a group of nodes that required incompatible device '/device:GPU:0'
Colocation Debug Info:
Colocation group had the following types and devices: 
IteratorToStringHandle: GPU CPU 
OneShotIterator: CPU 
IteratorGetNext: GPU CPU 

Colocation members and user-requested devices:
  OneShotIterator (OneShotIterator) 
  IteratorToStringHandle (IteratorToStringHandle) 
  clone_0/IteratorGetNext (IteratorGetNext) /device:GPU:0

	 [[node IteratorToStringHandle (defined at C:/Users/chzhq/Desktop/roof_detection_bbox/tf_inference/make_ckpt_to_pb.py:11)  = IteratorToStringHandle[](OneShotIterator)]]

No node-device colocations were active during op 'IteratorToStringHandle' creation.
No device assignments were active during op 'IteratorToStringHandle' creation.


Process finished with exit code 1

 

위 와 같이

 

Restoring from checkpoint failed. This is most likely due to a mismatch between the current graph and the graph from the checkpoint. Please ensure that you have not altered the graph expected based on the checkpoint.

 

에러가 발생하는 경우가 있다

 

찾아보니 CUDA 와 cuDNN 환경변수를 추가하라는 답변이 있었지만 나는 이미 추가가 되어있는 상태였기 때문에 검색해보고 나오는 코드들을 족족 적용해보기 시작했다.

 

그 중 얻어걸린 옵션이 있었는데

 

tf.Session() 을 만들 때 옵션으로 allow_soft_placement=True 를 주는 것 이었다.

 

allow_soft_placement 옵션은 텐서플로우가 자동으로 존재하는 디바이스 중 하나를 선택한다

 

 

log_device_placement=True 를 같이 주면 어떤 디바이스에 배치되었는지 로그가 함께 출력된다.

 

아래 코드는 해당 옵션들이 적용된 코드이다

 

import tensorflow as tf

meta_ckpt_path = "C:/Users/user/Desktop/models/maskrcnn_models/model.ckpt-2396686.meta"
model_ckpt_path = "C:/Users/user/Desktop/models/maskrcnn_models/"

# 이 부분에 옵션을 적용해주면 된다
with tf.Session(config=tf.ConfigProto(
        allow_soft_placement=True, log_device_placement=True)) as sess:
        
    # Restore the graph
    saver = tf.train.import_meta_graph(meta_ckpt_path)

    # Load weights
    saver.restore(sess, tf.train.latest_checkpoint(model_ckpt_path))
    

 

 

위 옵션 적용 후 정상적으로 체크포인트가 로드 된 것을 확인할 수 있다.

 

 

 

잘못된 부분에 대한 지적은 언제나 환영입니다 :)

블로그 이미지

우송송

,

텐서플로우를 빌드하며 수 많은 옵션을 보다가 문득 눈에 들어온 것이 있었다

 

어떤건 N가 대문자고 어떤건 Y 가 대문자이다

 

바로 옵션을 선택할 때 어떤 선택지는 Y 가 대문자이고 어떤건 N가 표기되어있어 뭐가 다른걸까 생각이 들었다

 

 

어느 운영체제든 패키지 등을 설치할 때

 

"계속 하시겠습니까? [Y/n]"

 

와 같이 선택지 항목에 대소문자가 같이 병행표기되어있는 경우를 많이 봤을것이다

 

 

 

찾아보니 생각보다 간단하고 직관적이었다

 

대문자로 적힌것이 default 이며, 굳이 대답을 입력하지 않고 Enter 만 쳐도 default 값으로 넘어가는 것이다

 

예를 들어 [y/N] 으로 되어있는 경우, 그냥 Enter 를 치면 default 인 N 이 입력이 된다

 

앞으로 어떤걸 입력해야 할지 모르겠으면 default 를 입력하면 되겠다

 

블로그 이미지

우송송

,

반복문을 돌리다보면 현재 얼마나 진행되었는지 보고싶을것이다

 

for index in range(1000):
    print(index)

나도 귀찮으니 보통 index 를 출력하는 방법으로 보긴 하지만 로그 창이 더러워지는걸 감수해야 한다

 

 

 

 

이럴 때 코드 몇 줄 추가하면 전체 진행상황을 진행바로 표시해주는 파이썬 패키지가 있다

 

바로 tqdm 이다

 

https://github.com/tqdm/tqdm

 

tqdm/tqdm

A Fast, Extensible Progress Bar for Python and CLI - tqdm/tqdm

github.com

위 사이트에 들어가면 기본적인 tqdm 사용법이 정리되어 있다.

 

for 구문의 범위를 tqdm 으로 묶어주면 자동으로 상태진행바가 표시가 된다

from tqdm import tqdm

for i in tqdm(range(10000000)):
    pass

 

실행결과

현재 진행상황과 경과시간, 남은 시간, 속도를 표시해준다

 

 

 

만약 이미 작성해둔 코드가 복잡해서 중간에 for 문을 끼워놓기 힘든 경우엔 직접 로그를 업데이트 시키는 방법도 있다.

 

from tqdm import tqdm

progress = tqdm(total=10000000)

for i in range(10000000):
    progress.update(1)

 

실행결과

이미 짜여진 코드에 tqdm 을 적용할 때 편한 방법인 듯 하다

 

 

 

 

상태바 앞에 문자나 숫자를 표시하고 싶을 땐 set_description() 또는 set_description_str() 함수를 사용하면 된다

하지만 반복 횟수가 커질수록 반복문이 훨씬 무거워지니 가벼운 반복문에서만 사용하는것을 추천한다

from tqdm import tqdm

progress = tqdm(total=10000000)
for i in range(10000000):
    progress.update(1)
    progress.set_description_str("Progress status : {}".format(i))

 

 

실행결과

위 예시에서 10초 내외로 끝나던 반복문이 20분을 기다리라고 한다

블로그 이미지

우송송

,

프로젝트를 릴리즈 하다보면 다른사람에게 보이고싶지 않은 코드가 종종 있을 것이다.

 

그럴 경우 파이썬 파일을 라이브러리화 하여 코드를 공개하지 않는 방법이 있는데 그 중 한 가지 방법은 nuitka 를 사용하여 *.py 파일을 *.so (mac, ubuntu 기준) 으로 바꾸는 것이다

 

간단하게 테스트 코드를 짜봤다

# LibraryClass.py

class LibraryClass:
    def __init__(self):
        pass

    def add_number(self, a, b):
        return a + b
# main.py

from LibraryClass import *

if __name__ == "__main__":
    inst = TestClass()

    result = inst.add_number(10, 20)
    print(result)

 

LibraryClass.py 의 add_number 함수는 두 수를 파라미터로 받고 합을 return 해주는 함수고

main.py 는 간단하게 두 수를 add_number 함수에 넘겨주고 return 을 받아 그 값을 출력해주는 역할을 한다

 

당연히 결과는 30이 출력이 되겠지만 우리는 LibraryClass.py 파일을 라이브러리화 하는것이 목적이다

 

Nuikta 를 사용하려면 해당 패키지가 설치되어있어야 한다.

pyinstaller 와 같이 파이썬 pip 로 설치가 가능하니 준비시간도 매우 짧은 편이다

만약 설치되어 있지 않다면 아래의 명령어로 설치해 주도록 한다

$ pip install nuitka

nuitka 가 준비되었다면 명령어 한 줄로 바로 라이브러리화 할 수 있다.

 

파일 하나를 라이브러리 파일로 만들어 주는 명령어는 아래와 같다

$ python -m nuitka --module *.py

 

끝나면 *.build, *.pyi, *.so 이렇게 3개의 파일이 만들어 진다

 

 

 

 

*.pyi, *.build 는 필요 없으니 삭제하고 *.so 파일만 남겨둔다  *.so 파일 위치는 기존의 *.py 가 위치하고 있던 곳에 위치하고 있으면 된다

 

 

블로그 이미지

우송송

,

caffe 를 빌드하다보면 참 많은 에러를 만나게 되는데 그 중 가장 잔인한 에러는 build가 끝나고 runtest 할 때 발생하는 에러라고 생각한다...(희망고문)

 

.build_release/tools/caffe
.build_release/tools/caffe: error while loading shared libraries: libcudart.so.9.0: cannot open shared object file: No such file or directory
Makefile:533: recipe for target 'runtest' failed
make: *** [runtest] Error 127

 

이 에러가 발생했다면 우선 ~/.bashrc 에 환경변수를 추가해준다

bashrc 에 위의 두 줄을 추가해준 뒤 터미널로 나와 마지막 명령어를 실행한다.

export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:$LD_LIBRARY_PATH
export PATH=/usr/local/cuda-9.0/bin:$PATH


source ~/.bashrc

 

 

 

이 방법을 사용하고나서도 runtest 에러가 발생한다면 아래의 명령어를 통해 Library 의 링크를 직접 추가해줘야 한다.

** 먼저 해당 경로에 들어가 파일이 존재하는지 확인부터 하는게 좋다

sudo cp /usr/local/cuda-9.0/lib64/libcudart.so.9.0 /usr/local/lib/libcudart.so.9.0 && sudo ldconfig
sudo cp /usr/local/cuda-9.0/lib64/libcublas.so.9.0 /usr/local/lib/libcublas.so.9.0 && sudo ldconfig
sudo cp /usr/local/cuda-9.0/lib64/libcurand.so.9.0 /usr/local/lib/libcurand.so.9.0 && sudo ldconfig
sudo cp /usr/local/cuda-9.0/lib64/libcudnn.so.7 /usr/local/lib/libcudnn.so.7 && sudo ldconfig

 

 

runtnest 가 성공하면 이런 화면이 나와야 한다

블로그 이미지

우송송

,

Pycharm 을 이용해 개발하다 보면 파이썬 코드가 여기저기 생기고 각 파이썬 파일마다 main 함수가 있을 것이다.

 

그런데 각 파이썬 파일들이 하나의 동일한  파일을 참조하게 되는 경우 (tensorflow model, sample image 등) 각 파이썬 파일마다 경로를 일일이 수정해줘야 하는 불편함이 있다.

 

다른 방법은 생각해보지 않았지만 그냥 단순하게 프로젝트 폴더를 root 로 삼으면 모든 파일에 대해 동일한 경로 값으로 접근이 가능하다.

 

get_root_dir.py



from pathlib import Path

def get_project_root() -> Path:
    return str(Path(__file__).parent.parent) + '/'

 

이렇게 프로젝트의 root 경로를 return 하는 간단한 파일을 작성해두고 import 해서 사용하면 각 파이썬 코드마다 참조하는 파일들의 경로를 동일하게 줄 수 있다.

 

아래는 예시 코드

from get_root_dir import get_project_root

ROOT_DIR = get_project_root()


model_path = ROOT_DIR + "/models/frozen_inference_graph.pb"
labelmap_path = ROOT_DIR + "/models/labelmap.pbtxt"

 

블로그 이미지

우송송

,