sugiyama404
@sugiyama404 (sugi 404)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

マルチプロセス内でTensorflow2.Xが動かない。

解決したいこと

マルチプロセス内でTensorflow2.Xが動かしたいです。

エラーメッセージは出ていません。

解決方法を教えて下さい。

該当するソースコード

import time
import tensorflow as tf
import tensorflow.keras.layers as kl
import numpy as np
import random
from multiprocessing import Process, Pool
import multiprocessing
class NeuralNetwork(tf.keras.Model):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.action_space = 1
        self.dense1 = kl.Dense(128, activation="relu")
        self.dense2 = kl.Dense(128, activation="relu")
        self.out = kl.Dense(self.action_space)
        self.optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)

    @tf.function
    def call(self, x):
        x = self.dense1(x)
        x = self.dense2(x)
        out = self.out(x)
        return out
def get_data():
    images = np.random.randn(12, 3)
    labels = np.array([])
    for m in images:
        num = 4 * m[0] ** 3 + 5 * m[1] ** 2 + 6 * m[2] + random.random()
        labels = np.append(labels, num)

    labels = labels.astype(np.float32)
    return images, labels
def worker(i):
        net = NeuralNetwork()
        images, labels = get_data()
        arr = tf.constant([[1 ,2 ,3]], dtype = tf.float32)
        print(arr)
        net(arr)

with multiprocessing.Pool(processes=4) as pool:
        pool.map(worker, range(4))
1

1Answer

def worker(i):
    print(i)


with multiprocessing.Pool(processes=4) as pool:
        pool.map(worker, range(4))

としたときに、0~3は(順序関係なく)表示されるでしょうか?

1Like

Comments

  1. @sugiyama404

    Questioner

    @yusuke_s_yusuke 様回答ありがとうございます。


    実行した結果以下の様になりました。

    2130
  2. まだ問題がわかっていないのですが、@sugiyama404さんの質問時のコードを実行するとどのように返ってきますでしょうか。
    -------
    2つ試してほしいことは
    1つ目は
    print(multiprocessing.cpu_count())
    はどうでしょうか。結果が1だとmultiprocessできません。
    2つ目は
    def worker(i):
    net = NeuralNetwork()
    images, labels = get_data()
    arr = tf.constant([[1 ,2 ,3]], dtype = tf.float32)
    print(arr)
    print(vars(net))
    net(arr)
    print(vars(net))

    with multiprocessing.Pool(processes=4) as pool:
    pool.map(worker, range(1))
    の結果はどうでしょうか。net(arr)がしっかり代入されているか確認して、下のように返ってきますか?
    tf.Tensor([[1. 2. 3.]], shape=(1, 3), dtype=float32)
    {'_self_setattr_tracking': True, '_is_model_for_instrumentation': True, '_instrumented_keras_api': True, '_instrumented_keras_layer_class': False, '_instrumented_keras_model_class': True, '_trainable': True, '_stateful': False, 'built': False, '_input_spec': None, '_build_input_shape': None, '_saved_model_inputs_spec': None, '_saved_model_arg_spec': None, '_supports_masking': False, '_name': 'neural_network', '_activity_regularizer': None, '_trainable_weights': [], '_non_trainable_weights': [], '_updates': [], '_thread_local': <_thread._local object at 0x7f4d1ece8bf0>, '_callable_losses': [], '_losses': [], '_metrics': [], '_metrics_lock': <unlocked _thread.lock object at 0x7f4d1ecde7b0>, '_dtype_policy': <Policy "float32">, '_compute_dtype_object': tf.float32, '_autocast': True, '_self_tracked_trackables': [<keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>, <keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>, <keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>], '_inbound_nodes_value': [], '_outbound_nodes_value': [], '_expects_training_arg': False, '_default_training_arg': None, '_expects_mask_arg': False, '_dynamic': False, '_initial_weights': None, '_auto_track_sub_layers': True, '_preserve_input_structure_in_config': False, '_outer_name_scope': '', '_is_graph_network': False, 'inputs': None, 'outputs': None, 'input_names': None, 'output_names': None, 'stop_training': False, 'history': None, 'compiled_loss': None, 'compiled_metrics': None, '_compute_output_and_mask_jointly': False, '_is_compiled': False, '_distribution_strategy': None, '_cluster_coordinator': None, '_run_eagerly': None, 'train_function': None, 'test_function': None, 'predict_function': None, 'train_tf_function': None, '_compiled_trainable_state': <WeakKeyDictionary at 0x7f4d1ece4b90>, '_training_state': None, '_trackable_saver': <tensorflow.python.training.tracking.util.TrackableSaver object at 0x7f4d1ece4bd0>, '_steps_per_execution': None, '_train_counter': <tf.Variable 'Variable:0' shape=() dtype=int64, numpy=0>, '_test_counter': <tf.Variable 'Variable:0' shape=() dtype=int64, numpy=0>, '_predict_counter': <tf.Variable 'Variable:0' shape=() dtype=int64, numpy=0>, '_base_model_initialized': True, '_obj_reference_counts_dict': ObjectIdentityDictionary({<_ObjectIdentityWrapper wrapping 1>: 1, <_ObjectIdentityWrapper wrapping <keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>>: 1, <_ObjectIdentityWrapper wrapping <keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>>: 1, <_ObjectIdentityWrapper wrapping <keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>>: 1, <_ObjectIdentityWrapper wrapping <keras.optimizer_v2.adam.Adam object at 0x7f4d1ecf6c90>>: 1}), 'action_space': 1, '_self_unconditional_checkpoint_dependencies': [TrackableReference(name=dense1, ref=<keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>), TrackableReference(name=dense2, ref=<keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>), TrackableReference(name=out, ref=<keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>), TrackableReference(name=optimizer, ref=<keras.optimizer_v2.adam.Adam object at 0x7f4d1ecf6c90>)], '_self_unconditional_dependency_names': {'dense1': <keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>, 'dense2': <keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>, 'out': <keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>, 'optimizer': <keras.optimizer_v2.adam.Adam object at 0x7f4d1ecf6c90>}, '_self_unconditional_deferred_dependencies': {}, '_self_update_uid': -1, '_self_name_based_restores': set(), '_self_saveable_object_factories': {}, 'dense1': <keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>, 'dense2': <keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>, 'out': <keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>, 'optimizer': <keras.optimizer_v2.adam.Adam object at 0x7f4d1ecf6c90>}
    {'_self_setattr_tracking': True, '_is_model_for_instrumentation': True, '_instrumented_keras_api': True, '_instrumented_keras_layer_class': False, '_instrumented_keras_model_class': True, '_trainable': True, '_stateful': False, 'built': True, '_input_spec': None, '_build_input_shape': None, '_saved_model_inputs_spec': TensorSpec(shape=(1, 3), dtype=tf.float32, name='input_1'), '_saved_model_arg_spec': ([TensorSpec(shape=(1, 3), dtype=tf.float32, name='input_1')], {}), '_supports_masking': False, '_name': 'neural_network', '_activity_regularizer': None, '_trainable_weights': [], '_non_trainable_weights': [], '_updates': [], '_thread_local': <_thread._local object at 0x7f4d1ece8bf0>, '_callable_losses': [], '_losses': [], '_metrics': [], '_metrics_lock': <unlocked _thread.lock object at 0x7f4d1ecde7b0>, '_dtype_policy': <Policy "float32">, '_compute_dtype_object': tf.float32, '_autocast': True, '_self_tracked_trackables': [<keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>, <keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>, <keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>], '_inbound_nodes_value': [], '_outbound_nodes_value': [], '_expects_training_arg': False, '_default_training_arg': None, '_expects_mask_arg': False, '_dynamic': False, '_initial_weights': None, '_auto_track_sub_layers': True, '_preserve_input_structure_in_config': False, '_outer_name_scope': '', '_is_graph_network': False, 'inputs': None, 'outputs': None, 'input_names': None, 'output_names': None, 'stop_training': False, 'history': None, 'compiled_loss': None, 'compiled_metrics': None, '_compute_output_and_mask_jointly': False, '_is_compiled': False, '_distribution_strategy': None, '_cluster_coordinator': None, '_run_eagerly': None, 'train_function': None, 'test_function': None, 'predict_function': None, 'train_tf_function': None, '_compiled_trainable_state': <WeakKeyDictionary at 0x7f4d1ece4b90>, '_training_state': None, '_trackable_saver': <tensorflow.python.training.tracking.util.TrackableSaver object at 0x7f4d1ece4bd0>, '_steps_per_execution': None, '_train_counter': <tf.Variable 'Variable:0' shape=() dtype=int64, numpy=0>, '_test_counter': <tf.Variable 'Variable:0' shape=() dtype=int64, numpy=0>, '_predict_counter': <tf.Variable 'Variable:0' shape=() dtype=int64, numpy=0>, '_base_model_initialized': True, '_obj_reference_counts_dict': ObjectIdentityDictionary({<_ObjectIdentityWrapper wrapping 1>: 1, <_ObjectIdentityWrapper wrapping <keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>>: 1, <_ObjectIdentityWrapper wrapping <keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>>: 1, <_ObjectIdentityWrapper wrapping <keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>>: 1, <_ObjectIdentityWrapper wrapping <keras.optimizer_v2.adam.Adam object at 0x7f4d1ecf6c90>>: 1}), 'action_space': 1, '_self_unconditional_checkpoint_dependencies': [TrackableReference(name=dense1, ref=<keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>), TrackableReference(name=dense2, ref=<keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>), TrackableReference(name=out, ref=<keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>), TrackableReference(name=optimizer, ref=<keras.optimizer_v2.adam.Adam object at 0x7f4d1ecf6c90>)], '_self_unconditional_dependency_names': {'dense1': <keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>, 'dense2': <keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>, 'out': <keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>, 'optimizer': <keras.optimizer_v2.adam.Adam object at 0x7f4d1ecf6c90>}, '_self_unconditional_deferred_dependencies': {}, '_self_update_uid': -1, '_self_name_based_restores': set(), '_self_saveable_object_factories': {}, 'dense1': <keras.layers.core.dense.Dense object at 0x7f4d1ed8bc90>, 'dense2': <keras.layers.core.dense.Dense object at 0x7f4d1eec3d90>, 'out': <keras.layers.core.dense.Dense object at 0x7f4d1ecf6850>, 'optimizer': <keras.optimizer_v2.adam.Adam object at 0x7f4d1ecf6c90>}
  3. @sugiyama404

    Questioner

    @yusuke_s_yusuke 様回答ありがとうございます。

    1つ目は
    4になりました。

    そこで、colabをGPUからCPUに切り替えたとこと、少し動作するようになりました。(print(arr)が出力します)


    2つ目は
    以下の標準出力をします。

    tf.Tensor([[1. 2. 3.]], shape=(1, 3), dtype=float32)
    {'_self_setattr_tracking': True, '_is_model_for_instrumentation':

    net(arr)をコメントアウトすると、以下の標準出力をします。

    tf.Tensor([[1. 2. 3.]], shape=(1, 3), dtype=float32)
    {'_self_setattr_tracking': True, '_is_model_for_instrumentation':
    {'_self_setattr_tracking': True, '_is_model_for_instrumentation':

    net(arr)でプロセスが止ます。

    わざと、入力を[1. 2. 3.]にしわざと間違えると、
    エラーメッセージを出力します。
    そして、マルチプロセスをやめた時は、想定通りの出力をします。
  4. @sugiyama404

    Questioner

    @yusuke_s_yusuke 様回答とnotebookの作成ありがとうございます。

    私のnotebookでも、期待通りの動きをしました。
    Tensorflowの仕様かもしれないのですが、

    親プロセス内でNeuralNetworkクラスをインスタンス化した後(挙動確認を行うために実行していた)に、子プロセス内でNeuralNetworkクラスをインスタンス化すると、出力されなくなる様です。

    助けていただいて、ありがとうございます。

    callメソッドをご説明します。

    callメソッドは、Modelクラス(Tensorflow)のオーバライドメソッドです。Modelクラスを継承した自クラス内で、元々のTensorflowのメソッドと同名のメソッド名をつけることで、機能を追加することができます。


    >新しい入力でモデルを呼び出し、出力をテンソルとして返します。
    >この場合、call() はグラフ内のすべての操作を新しい入力に再適用するだけです (たとえば、提供された入力から新しい計算グラフを作成します)。

    https://www.tensorflow.org/api_docs/python/tf/keras/Model#call
  5. それは良かったです。
    callメソッドについての説明ありがとうございます。Tensorflowのメソッドなのですね。

Your answer might help someone💌