Как запустить команду оболочки из модуля подпроцесса python в tf.py_function в конвейере tf.data? - PullRequest
0 голосов
/ 05 февраля 2020

Я создал tf.data.Dataset конвейерную переменную, в которую я передаю функцию python, которая пытается запустить команду sox через модуль python subprocess. Код работает нормально на процессоре с windows os, но не может работать на графическом процессоре Google Colab с linux os. Вот код -

from scipy.io import wavfile
import tensorflow as tf

    def tf_func(inp_sample):

        def func(inp_sample,<tf.string object>):
            try:
                fdesc, infile = tempfile.mkstemp(suffix=".wav")
                os.close(fdesc)
                fdesc, outfile = tempfile.mkstemp(suffix=".wav")
                os.close(fdesc)
                wavfile.write(infile,<sample rate>,inp_sample.numpy()) //writes audio file to disk
                arguments = ['sox',infile,outfile,'-q','compand',
                            *DRC_PRESET[<tf.string object>.numpy().decode('utf-8')]] 

                subprocess.check_call(arguments)

            finally:
                os.unlink(infile)
                os.unlink(outfile)

            return tf.convert_to_tensor(inp_sample,dtype=tf.float32)

        drc = np.random.choice(<lis of string>)
        [inp_sample,] = tf.py_function(dynamic_compression, 
                        [inp_sample,tf.constant(drc)],[tf.float32])
        inp_sample.set_shape(target_sample_size) //target_size=<some int>

        return inp_sample
...

inp=tf.data.Dataset.from_tensor_slices(inp) // inp shape eg: (4, 500)
inp = inp.map(tf_dynamic_compression)
for i in inp:
    print(i.numpy())

И ошибку, которую он выдает -

UnknownError: 2 root error(s) found.
  (0) Unknown:   CalledProcessError: Command 'None' died with <Signals.SIGINT: 2>.
Traceback (most recent call last):

  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/script_ops.py", line 233, in __call__
    return func(device, token, args)

  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/script_ops.py", line 122, in __call__
    ret = self._func(*args)

  File "/tmp/tmpn_9q_jxm.py", line 24, in dynamic_compression
    ag__.converted_call(subprocess.check_call, dynamic_compression_scope.callopts, (arguments,), None, dynamic_compression_scope)

  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/autograph/impl/api.py", line 541, in converted_call
    result = converted_f(*effective_args)

  File "/tmp/tmpozf4qyav.py", line 50, in tf__check_call
    ag__.if_stmt(cond_1, if_true_1, if_false_1, get_state_1, set_state_1, (), ())

  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/autograph/operators/control_flow.py", line 895, in if_stmt
    return _py_if_stmt(cond, body, orelse)

  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/autograph/operators/control_flow.py", line 1004, in _py_if_stmt
    return body() if cond else orelse()

  File "/tmp/tmpozf4qyav.py", line 44, in if_true_1
    raise ag__.converted_call(CalledProcessError, check_call_scope.callopts, (retcode, cmd), None, check_call_scope)

Как решить эту проблему?

1 Ответ

0 голосов
/ 07 февраля 2020

Проблема возникла из-за того, что sox не выполняется модулем subprocess. Ответ был ранее. Есть два решения -

Сначала измените строку arguments

arguments = " ".join(['sox',infile,outfile,'-q','compand',*DRC_PRESET[<tf.string object>.numpy().decode('utf-8')]])

, а затем

  1. os.system(arguments)

    ИЛИ

  2. subprocess.check_call(arguments, shell=True)

Для меня секунда работал.

...