728x90

오늘은 간단하면서도, 막상 찾아보긴 힘든, 벡터를 여러개로 복사하는 것에 대해 글을 쓰겠다.

 

먼저 아래와 같은 변수가 있다고 가정

 

A = tf.random.uniform(shape=[64, 100, 256])

B = tf.random.uniform(shape=[64, 256])

 

하고 싶은 것은, A에 B를 concat 하고싶다고 가정하겠다.

 

이럴 경우 어떻게 해야하나?

 

먼저 Concat을 하려면, 차원이 맞아야 되는데, A의 2차원 즉 100에 해당하는 것이 B에는 없다.

 

이럴 경우 B에서 256짜리를 100번 복사해서 해야된다.

 

즉 A = [Batch, T, hidden], B = [Batch, hidden] 일 경우, B의 2번째 dimension에 B를 T번 복사해야된다.

 

최종으로 원하는것은 B = [Batch, T, hidden] 인 것이다.

 

tf.repeat 함수 (https://www.tensorflow.org/api_docs/python/tf/repeat)를 사용할 건데, 나는 현재 tensorflow 2.0 버전을 쓰고 있고, 여기에서 tf.repeat을 그대로 가져오면 없다고 오류 메시지가 뜬다.

 

tf.repeat 함수는 아래와 같은데,

 

tf.repeat(
    input
, repeats, axis=None, name=None
)

 

위에서 말 했듯이 나는 이게 안되므로,

tf.keras.backend.repeat(https://www.tensorflow.org/api_docs/python/tf/keras/backend/repeat) 함수를 사용 할 것이다.

 

tf.keras.backend.repeat 함수는 아래와 같은데,

 

tf.keras.backend.repeat(
    x
, n
)

 

tf.repeat과 다른 점은 딱히 없는 것 같다. 

 

B = [Batch, hidden] 인 것을, T=100으로 가정하여 B=[Batch, T, hidden]으로 만드는 코드는 아래와 같다.

 

import tensorflow as tf

batch_size = 100
seq_len = 100
hidden_size = 256

a = tf.random.uniform(shape=[batch_size, seq_len, hidden_size])
b = tf.random.uniform(shape=[batch_size, hidden_size])

print('a shape {} b shape {}'.format(a.shape, b.shape))

new_b = tf.keras.backend.repeat(b, n=100)

print('new_b shape {}'.format(new_b.shape))

concat_output = tf.concat(values=(a, new_b), axis=-1)

print('concat_output shape', concat_output.shape)

 

실행 결과는 아래와 같고,

이제 검증을 해야되는데, 100개로 늘렸을 경우 모든 100개가 기존 b의 hidden_size 내의 vector와 값이 같은가? 를 검증해야 된다.

 

아래와 같이 할 수 있다.

 

for i in range(len(new_b[0])):
    check = (b[0] == new_b[0][i])
    print('{}th check {}'.format(i, check))

 

이에 대한 결과는 모두 True

전체 코드

import tensorflow as tf

batch_size = 100
seq_len = 100
hidden_size = 256

a = tf.random.uniform(shape=[batch_size, seq_len, hidden_size])
b = tf.random.uniform(shape=[batch_size, hidden_size])

print('a shape {} b shape {}'.format(a.shape, b.shape))

new_b = tf.keras.backend.repeat(b, n=100)

print('new_b shape {}'.format(new_b.shape))

concat_output = tf.concat(values=(a, new_b), axis=-1)

print('concat_output shape', concat_output.shape)
 
for i in range(len(new_b[0])):
    check = (b[0] == new_b[0][i])
    print('{}th check {}'.format(i, check))

 

 

728x90
728x90

글이 많이 늦었습니다. 졸업 준비하느라 바빠져서...

 

 

이전 포스팅에 TfRecord로 모든 음성 데이터에 대해 byte로 읽고, 저장하는 것 까지 처리하였다.

 

이제 해야되는 것은? 모델 설계 한 이후 tensorflow 에서 제공하는 tf.Data를 사용하여 shuffle -> prefetch -> batch로 데이터를 나눈 뒤 모델에 넣는 것을 해주면 된다.

 

 

import tensorflow as tf

record_file = './tf_records_example.tfrecords' # previously saved tfrecords dataset
batch_size = 20

 

먼저 https://kaen2891.tistory.com/65 글을 참조해주셔서, record file이 저장되는것을 확인한 뒤, 이 파일을 불러오면 된다. 이 파일을 record_file='' << ' ' 사이에 directory에 넣는다.

 

그 후, 매 train step 마다 몇 개의 batch_size로 할 지에 대해 선언한다.

 

spectrum_feature_description = {
    'enc_inp': tf.io.FixedLenSequenceFeature ([], tf.float32, allow_missing=True),
    'dec_inp': tf.io.FixedLenSequenceFeature ([], tf.float32, allow_missing=True),
    'tar_inp': tf.io.FixedLenSequenceFeature ([], tf.float32, allow_missing=True)
}

def _parse_spec_function(example_proto):
    # Parse the input tf.Example proto using the dictionary above.
    return tf.io.parse_single_example(example_proto, spectrum_feature_description)

def input_fn(record_file, batch_size, buffer_size):
    dataset = tf.data.TFRecordDataset(record_file)
    print('raw_dataset', dataset) # ==> raw_dataset <TFRecordDatasetV2 shapes: (), types: tf.string>    

    parsed_spec_dataset = dataset.map(_parse_spec_function)
    print('map', parsed_spec_dataset)
    
    #parsed_spec_dataset = parsed_spec_dataset.cache()
    #print('cache', parsed_spec_dataset)
    
    train_dataset = parsed_spec_dataset.shuffle(buffer_size).batch(batch_size, drop_remainder=True)
    print('buffer + batch', train_dataset)
    
    train_dataset = train_dataset.prefetch(tf.data.experimental.AUTOTUNE)
    print('train_dataset autotune', train_dataset)
    
    return train_dataset
   
 
 
train_dataset = input_fn(record_file, batch_size=batch_size, buffer_size=10)
print(train_dataset)

 

그 다음 할 일은, input_fn 의 함수에서 매 dataset을 불러오는 것을 만들어 줄 것이다.

 

input_fn에는 record_file과 batch_size, buffer_size 를 함수 인자로 받은 뒤 record_file을 읽는다.

 

여기까지 해주면 byte type의 data들을 읽은 것이고, 이전 글에서 나는 데이터를 3가지 형태로 받았다.

 

enc_inp, dec_inp, tar_inp 이렇게 3개로 받았다.

 

즉 이 3가지의 data 형태로 복원해주기 위해서는 _parse_spec_function이 필요하다. 

 

여기에서 spectrum_feature_description dictionary 를 호출하여 이 dict 형태로 저장할 수 있다.

 

이렇게까지 받은 것이, parsed_spec_dataset 이다. 그 이후, 일반적인 tensorflow의 dataset 처리해주는 것처럼 해주면 된다.

 

위에서 처리된 parsed_spec_dataset에 shuffle을 buffer_size 넣어서 해주고, 이것을 batch_size 만큼 batch 형태로 해준다.

 

drop_remainder는 데이터 개수가 batch에 나뉘어지지 않을 경우, 마지막에는 빈 만큼 넣어주는 것으로 이해하면 된다. 

 

마지막으로, prefetch를 사용하여 queue에 넣어준 뒤, dataset을 model에 넣어주면 된다.

 

for (batch, spec) in enumerate(train_dataset):
    enc_raw = spec['enc_inp'].numpy()
    enc_raw = tf.reshape(enc_raw, [batch_size, 201, 21]) # batch, d_model, seq_len        
             
            
    dec_raw = spec['dec_inp'].numpy()
    dec_raw = tf.reshape(dec_raw, [batch_size, 201, 22])
            
    tar_raw = spec['tar_inp'].numpy()
    tar_raw = tf.reshape(tar_raw, [batch_size, 201, 22])
    
    print('batch = {}, enc_raw = {}, dec_raw = {}, tar_raw = {}'.format(batch, enc_raw.shape, dec_raw.shape, tar_raw.shape))
    
    print(enc_raw[0])

 

실제로 모델에 넣어서 돌리는 것이 아닌, 가상으로 위의 코드처럼 짜보았다. train_dataset은 현재 TfRecordfile을 batch_size 만큼 받아올 수 있다.

 

 

여기에서 끝인가? 아니다. batch, spec 에서 spec에는 위의 dictionary형태로 저장되어 있다. 이것을 긁어와야 한다. 어떻게? key를 사용하여

 

enc_raw = spec['enc_inp'].numpy() 를 사용하여 spec에서 enc_inp를 가져온다.

 

그럼 이대로 쓰면 되지 않냐고 할 수 있는데, 안된다. 

 

왜냐하면 위의 dictionary를 사용하여 3개의 데이터를 받았고, 이를 numpy 형태로 바꾸었지만, 우리는 아직 이 데이터셋의 shape에 대해서는 모른다.

 

그래서 바로 아래의 enc_raw = tf.reshape(enc_raw, [batch_size, 201, 21]) 을 하여 shape을 살려줘야 한다. 

 

batch, enc_raw, dec_raw, tar_raw의 shape을 출력하면 아래와 같은 결과를 얻을 수 있다.

 

 

마지막으로 enc_raw[0]를 출력하면, (20, 201, 21)의 첫 번째 vector를 가져오는 것이므로 (201, 21)의 tensorflow Tensor를 볼 수 있다.

 

 

 

전체 코드는 아래와 같으며,

import tensorflow as tf

'''
This code is for read form tfrecords file and get batch for training in tensorflow 2.0
In tf_records_example.tfrecords files, dataset is consist of 2d array with 50 batch size. So the enc_inp shape is (50, 201, 21) and the dec_inp and tar_inp shape is (50, 201, 22)
You can use this code for tfrecords file to training
Authors: June-Woo Kim (kaen2891@gmail.com)
'''

spectrum_feature_description = {
    'enc_inp': tf.io.FixedLenSequenceFeature ([], tf.float32, allow_missing=True),
    'dec_inp': tf.io.FixedLenSequenceFeature ([], tf.float32, allow_missing=True),
    'tar_inp': tf.io.FixedLenSequenceFeature ([], tf.float32, allow_missing=True)
}

def _parse_spec_function(example_proto):
    # Parse the input tf.Example proto using the dictionary above.
    return tf.io.parse_single_example(example_proto, spectrum_feature_description)


def input_fn(record_file, batch_size, buffer_size):
    dataset = tf.data.TFRecordDataset(record_file)
    print('raw_dataset', dataset) # ==> raw_dataset <TFRecordDatasetV2 shapes: (), types: tf.string>    

    parsed_spec_dataset = dataset.map(_parse_spec_function)
    print('map', parsed_spec_dataset)
    
    #parsed_spec_dataset = parsed_spec_dataset.cache()
    #print('cache', parsed_spec_dataset)
    
    train_dataset = parsed_spec_dataset.shuffle(buffer_size).batch(batch_size, drop_remainder=True)
    print('buffer + batch', train_dataset)
    
    train_dataset = train_dataset.prefetch(tf.data.experimental.AUTOTUNE)
    print('train_dataset autotune', train_dataset)
    
    return train_dataset


record_file = './tf_records_example.tfrecords'
batch_size = 20
train_dataset = input_fn(record_file, batch_size=batch_size, buffer_size=10)
print(train_dataset)

for (batch, spec) in enumerate(train_dataset):
    enc_raw = spec['enc_inp'].numpy()
    enc_raw = tf.reshape(enc_raw, [batch_size, 201, 21]) # batch, d_model, seq_len        
             
            
    dec_raw = spec['dec_inp'].numpy()
    dec_raw = tf.reshape(dec_raw, [batch_size, 201, 22])
            
    tar_raw = spec['tar_inp'].numpy()
    tar_raw = tf.reshape(tar_raw, [batch_size, 201, 22])
    
    print('batch = {}, enc_raw = {}, dec_raw = {}, tar_raw = {}'.format(batch, enc_raw.shape, dec_raw.shape, tar_raw.shape))
    
    print(enc_raw[0])

 

출력 output은 아래와 같다.

 

 

 

 

제 코드는  https://github.com/kaen2891/utils 에서 깔끔하게 확인하실 수 있습니다.

728x90
728x90

Tensorflow는 pytorch의 dataloader처럼 queue를 사용하여, 전체 데이터셋을 가져온 뒤 그것을 batch 만큼 쪼개서 하는 것이 살짝 번거롭다.

 

즉 이말을 다시 풀어보면, pytorch에서는 dataloader를 사용하여 여러 queue를 사용해서 batch 만큼 데이터셋을 가져온 뒤, 이것을 tensor로 바꿔서 model에 넣는 것이 수월한데 비해

 

Tensorflow에서는 tf.data.Dataset.from_tensor_slices 를 사용해서 전체 데이터셋을 가져오는 예제가 많다.

 

게다가 대용량 데이터셋을 사용하게 될 경우, 데이터셋의 총 사이즈가 3GB 정도가 넘어가면 tensorflow 는 API 관련 오류가 생기면서 data load가 안 될 때가 있다.

 

근 3일 정도 고생하면서 찾아본 정보들을 합쳐서, 음성 데이터셋의 stft 한 결과인 2차원 데이터셋을 tfrecord로 저장하는 방법을 소개한다.

 

 

# 전처리

음성(.wav)파일 모두에 대해, 2차원 stft를 얻었다고 가정하고 진행하겠다.

stft를 바꾸는 방법은 이 블로그 내에 있다.

 

import tensorflow as tf
print(tf.__version__)
import os
import librosa
from glob import glob
import numpy as np


list_inp = sorted(glob('/your/input/dataset/*/*.npz'))
list_tar = sorted(glob('/your/target/dataset/*/*.npz'))

print(len(list_inp))

위의 코드는 모든 음성 파일을 .npz 라는 numpy 형태의 data format으로 미리 저장해둔 상태이고, 이것을 glob으로 가져오는 모습이다. Seq2Seq 모델의 Encoder input인 list_inp와 Decoder input, Real value input인 list_tar의 전체를 가져온다.

 

 

# Writing Tfrecords file


def serialize_example(batch, list1, list2):
    filename = "./train_set.tfrecords"
    writer = tf.io.TFRecordWriter(filename)
    
    for i in range(batch):
        feature = {}
        feature1 = np.load(list1[i])
        feature2 = np.load(list2[i])
        print('feature1 shape {} feature2 shape {}'.format(feature1.shape, feature2.shape)) 
        feature['input'] = tf.train.Feature(float_list=tf.train.FloatList(value=feature1.flatten()))
        feature['target'] = tf.train.Feature(float_list=tf.train.FloatList(value=feature2.flatten()))
        
        features = tf.train.Features(feature=feature)
        example = tf.train.Example(features=features)
        serialized = example.SerializeToString()
        writer.write(serialized)
        print("{}th input {} target {} finished".format(i, list1[i], list2[i]))
        

serialize_example(len(list_inp), list_inp, list_tar)

 

먼저 저장할 tfrecords filename을 정해주고, tensorflow에서 제공해주는 TFRecordWriter로 writer를 선언한다.

for i in range(batch)는 전체 batch 사이즈만큼 반복하는 것이다. 즉 전체 데이터셋을 저장할 것이다. (나의 경우에는 총 8백만개이다.)

 

numpy 형태의 파일을 sorted(glob())으로 가져왔기 때문에, 현재 함수의 인자값인 list1과 list2는 파일 경로이다. 그러므로, np.load를 사용하여 feature1과 feature2에 값을 넣어준다.

 

그 뒤 tfrecords에 저장할 feature['name'] tf.train.Feature(float_list=tf.train.FloatList(value=feature1.flatten()))을 하여 선언해준다.

 

2d numpy 값을 그대로 value=feature1 를 해주면, 오류가 생긴다. 이를 찾아보게 되면, tensorflow에서의 FloatList는 1차원 값만 넣어줄 수 있기 때문이다. 그러므로, flatten()을 하여 넣어준다.

 

나 같은 경우 input과 target을 모두 maximum legnth를 구하고 zeropadding하여 shape을 아는 상태이지만, 만약 데이터셋이 모두 다를 경우 feature['shape'] = tf.train.Feature(int_list=tf.train.IntList(value=feature1.shape) 을 대입하여 나중에 데이터셋을 실제로 model에 넣을 때 shape을 기억하여 변환할 수 있다.

 

그다음 features = tf.train.Features(feature=feature)를 통해 tensorflow의 tensor로 변환해주고,

example 또한 마찬가지로 변환해준다.

 

serialized = example.SerializeToString() 을 통하여 binary? 로 변환해준다. 마지막으로 tf.records 파일을 write 해주는 writer.write(serialized)를 해주면 끝난다.

이것을 batch size만큼 해준다...

 

전체코드는 아래와 같다.

 

 

# 전체 코드

import tensorflow as tf
print(tf.__version__)
import os
import librosa
from glob import glob
import numpy as np


def serialize_example(batch, list1, list2):
    filename = "./train_set.tfrecords"
    writer = tf.io.TFRecordWriter(filename)
    
    for i in range(batch):
        feature = {}
        feature1 = np.load(list1[i])
        feature2 = np.load(list2[i])
        print('feature1 shape {} feature2 shape {}'.format(feature1.shape, feature2.shape)) 
        feature['input'] = tf.train.Feature(float_list=tf.train.FloatList(value=feature1.flatten()))
        feature['target'] = tf.train.Feature(float_list=tf.train.FloatList(value=feature2.flatten()))
        
        features = tf.train.Features(feature=feature)
        example = tf.train.Example(features=features)
        serialized = example.SerializeToString()
        writer.write(serialized)
        print("{}th input {} target {} finished".format(i, list1[i], list2[i]))
        


list_inp = sorted(glob('/your/input/dataset/*/*.npz'))
list_tar = sorted(glob('/your/target/dataset/*/*.npz'))

print(len(list_inp))
serialize_example(len(list_inp), list_inp, list_tar)

 

input, target 각각 8백만개 씩 있는데, 이것들이 과연 tfrecords를 통해 저장하였을 때의 공간적 이득과, 시간이 얼마나 걸리는지 체크해봐야겠다.

 

체크 해본 뒤, Tfrecord 파일을 다시 원래대로 음성 데이터 spectrogram으로 복구하는 것을 이번주내로 올릴 예정이다.

728x90
728x90

tensorboard 안될 때 해결법에 대해서 얘기하고자한다.

 

1. tf-nightly

 

나는 위 라이브러리를 설치하면서 tensorboard가 안되었다. 

또한 train code를 돌려도 gpu 메모리 할당이 안되고, cpu로 돌아가는 현상이 있었다.

 

그래서 tf-nightly 를 삭제했는데, 완전 삭제도 안되고 tensorboard도 안됐다.

 

이건 꼭 필요한 이유가 아니면 설치하지말자...

 

 

2. grpcio 문제

pkg_resources.VersionConflict: (grpcio 1.24.1 (dir), Requirement.parse('grpcio>=1.24.3')

 

위의 문제가 생겼을 때, pip로 grpcio를 지우고 하여도 안된다.

 

Duplicate plugins for name projector 라는 에러가 생기면서 안된다.

 

3. 완전 삭제가 안됨

tensorflow-gpu, tensorboard 를 지우고, 재설치하여도 안될때가 있다.

 

 

** 해결법

아래의 코드를 그대로 복사하여 하나의 .py 로 만들고, 실행하면 다음과 같은 step을 알려준다.

 

# Copyright 2019 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Self-diagnosis script for TensorBoard.

Instructions: Save this script to your local machine, then execute it in
the same environment (virtualenv, Conda, etc.) from which you normally
run TensorBoard. Read the output and follow the directions.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

# This script may only depend on the Python standard library. It is not
# built with Bazel and should not assume any third-party dependencies.
import collections
import errno
import functools
import hashlib
import inspect
import logging
import os
import pipes
import shlex
import socket
import subprocess
import sys
import tempfile
import textwrap
import traceback


# A *check* is a function (of no arguments) that performs a diagnostic,
# writes log messages, and optionally yields suggestions. Each check
# runs in isolation; exceptions will be caught and reported.
CHECKS = []


# A suggestion to the end user.
#   headline (str): A short description, like "Turn it off and on
#     again". Should be imperative with no trailing punctuation. May
#     contain inline Markdown.
#   description (str): A full enumeration of the steps that the user
#     should take to accept the suggestion. Within this string, prose
#     should be formatted with `reflow`. May contain Markdown.
Suggestion = collections.namedtuple("Suggestion", ("headline", "description"))


def check(fn):
  """Decorator to register a function as a check.

  Checks are run in the order in which they are registered.

  Args:
    fn: A function that takes no arguments and either returns `None` or
      returns a generator of `Suggestion`s. (The ability to return
      `None` is to work around the awkwardness of defining empty
      generator functions in Python.)

  Returns:
    A wrapped version of `fn` that returns a generator of `Suggestion`s.
  """
  @functools.wraps(fn)
  def wrapper():
    result = fn()
    return iter(()) if result is None else result
  CHECKS.append(wrapper)
  return wrapper


def reflow(paragraph):
  return textwrap.fill(textwrap.dedent(paragraph).strip())


def pip(args):
  """Invoke command-line Pip with the specified args.

  Returns:
    A bytestring containing the output of Pip.
  """
  # Suppress the Python 2.7 deprecation warning.
  PYTHONWARNINGS_KEY = "PYTHONWARNINGS"
  old_pythonwarnings = os.environ.get(PYTHONWARNINGS_KEY)
  new_pythonwarnings = "%s%s" % (
      "ignore:DEPRECATION",
      ",%s" % old_pythonwarnings if old_pythonwarnings else "",
  )
  command = [sys.executable, "-m", "pip", "--disable-pip-version-check"]
  command.extend(args)
  try:
    os.environ[PYTHONWARNINGS_KEY] = new_pythonwarnings
    return subprocess.check_output(command)
  finally:
    if old_pythonwarnings is None:
      del os.environ[PYTHONWARNINGS_KEY]
    else:
      os.environ[PYTHONWARNINGS_KEY] = old_pythonwarnings


def which(name):
  """Return the path to a binary, or `None` if it's not on the path.

  Returns:
    A bytestring.
  """
  binary = "where" if os.name == "nt" else "which"
  try:
    return subprocess.check_output([binary, name])
  except subprocess.CalledProcessError:
    return None


def sgetattr(attr, default):
  """Get an attribute off the `socket` module, or use a default."""
  sentinel = object()
  result = getattr(socket, attr, sentinel)
  if result is sentinel:
    print("socket.%s does not exist" % attr)
    return default
  else:
    print("socket.%s = %r" % (attr, result))
    return result


@check
def autoidentify():
  """Print the Git hash of this version of `diagnose_tensorboard.py`.

  Given this hash, use `git cat-file blob HASH` to recover the relevant
  version of the script.
  """
  module = sys.modules[__name__]
  try:
    source = inspect.getsource(module).encode("utf-8")
  except TypeError:
    logging.info("diagnose_tensorboard.py source unavailable")
  else:
    # Git inserts a length-prefix before hashing; cf. `git-hash-object`.
    blob = b"blob %d\0%s" % (len(source), source)
    hash = hashlib.sha1(blob).hexdigest()
    logging.info("diagnose_tensorboard.py version %s", hash)


@check
def general():
  logging.info("sys.version_info: %s", sys.version_info)
  logging.info("os.name: %s", os.name)
  na = type("N/A", (object,), {"__repr__": lambda self: "N/A"})
  logging.info("os.uname(): %r", getattr(os, "uname", na)(),)
  logging.info(
      "sys.getwindowsversion(): %r",
      getattr(sys, "getwindowsversion", na)(),
  )


@check
def package_management():
  conda_meta = os.path.join(sys.prefix, "conda-meta")
  logging.info("has conda-meta: %s", os.path.exists(conda_meta))
  logging.info("$VIRTUAL_ENV: %r", os.environ.get("VIRTUAL_ENV"))


@check
def installed_packages():
  freeze = pip(["freeze", "--all"]).decode("utf-8").splitlines()
  packages = {line.split(u"==")[0]: line for line in freeze}
  packages_set = frozenset(packages)

  # For each of the following families, expect exactly one package to be
  # installed.
  expect_unique = [
      frozenset([
          u"tensorboard",
          u"tb-nightly",
          u"tensorflow-tensorboard",
      ]),
      frozenset([
          u"tensorflow",
          u"tensorflow-gpu",
          u"tf-nightly",
          u"tf-nightly-2.0-preview",
          u"tf-nightly-gpu",
          u"tf-nightly-gpu-2.0-preview",
      ]),
      frozenset([
          u"tensorflow-estimator",
          u"tensorflow-estimator-2.0-preview",
          u"tf-estimator-nightly",
      ]),
  ]

  found_conflict = False
  for family in expect_unique:
    actual = family & packages_set
    for package in actual:
      logging.info("installed: %s", packages[package])
    if len(actual) == 0:
      logging.warning("no installation among: %s", sorted(family))
    elif len(actual) > 1:
      logging.warning("conflicting installations: %s", sorted(actual))
      found_conflict = True

  if found_conflict:
    preamble = reflow(
        """
        Conflicting package installations found. Depending on the order
        of installations and uninstallations, behavior may be undefined.
        Please uninstall ALL versions of TensorFlow and TensorBoard,
        then reinstall ONLY the desired version of TensorFlow, which
        will transitively pull in the proper version of TensorBoard. (If
        you use TensorBoard without TensorFlow, just reinstall the
        appropriate version of TensorBoard directly.)
        """
    )
    packages_to_uninstall = sorted(
        frozenset().union(*expect_unique) & packages_set
    )
    commands = [
        "pip uninstall %s" % " ".join(packages_to_uninstall),
        "pip install tensorflow  # or `tensorflow-gpu`, or `tf-nightly`, ...",
    ]
    message = "%s\n\nNamely:\n\n%s" % (
        preamble,
        "\n".join("\t%s" % c for c in commands),
    )
    yield Suggestion("Fix conflicting installations", message)


@check
def tensorboard_python_version():
  from tensorboard import version
  logging.info("tensorboard.version.VERSION: %r", version.VERSION)


@check
def tensorflow_python_version():
  import tensorflow as tf
  logging.info("tensorflow.__version__: %r", tf.__version__)
  logging.info("tensorflow.__git_version__: %r", tf.__git_version__)


@check
def tensorboard_binary_path():
  logging.info("which tensorboard: %r", which("tensorboard"))


@check
def addrinfos():
  sgetattr("has_ipv6", None)
  family = sgetattr("AF_UNSPEC", 0)
  socktype = sgetattr("SOCK_STREAM", 0)
  protocol = 0
  flags_loopback = sgetattr("AI_ADDRCONFIG", 0)
  flags_wildcard = sgetattr("AI_PASSIVE", 0)

  hints_loopback = (family, socktype, protocol, flags_loopback)
  infos_loopback = socket.getaddrinfo(None, 0, *hints_loopback)
  print("Loopback flags: %r" % (flags_loopback,))
  print("Loopback infos: %r" % (infos_loopback,))

  hints_wildcard = (family, socktype, protocol, flags_wildcard)
  infos_wildcard = socket.getaddrinfo(None, 0, *hints_wildcard)
  print("Wildcard flags: %r" % (flags_wildcard,))
  print("Wildcard infos: %r" % (infos_wildcard,))


@check
def readable_fqdn():
  # May raise `UnicodeDecodeError` for non-ASCII hostnames:
  # https://github.com/tensorflow/tensorboard/issues/682
  try:
    logging.info("socket.getfqdn(): %r", socket.getfqdn())
  except UnicodeDecodeError as e:
    try:
      binary_hostname = subprocess.check_output(["hostname"]).strip()
    except subprocess.CalledProcessError:
      binary_hostname = b"<unavailable>"
    is_non_ascii = not all(
        0x20 <= (ord(c) if not isinstance(c, int) else c) <= 0x7E  # Python 2
        for c in binary_hostname
    )
    if is_non_ascii:
      message = reflow(
          """
          Your computer's hostname, %r, contains bytes outside of the
          printable ASCII range. Some versions of Python have trouble
          working with such names (https://bugs.python.org/issue26227).
          Consider changing to a hostname that only contains printable
          ASCII bytes.
          """ % (binary_hostname,)
      )
      yield Suggestion("Use an ASCII hostname", message)
    else:
      message = reflow(
          """
          Python can't read your computer's hostname, %r. This can occur
          if the hostname contains non-ASCII bytes
          (https://bugs.python.org/issue26227). Consider changing your
          hostname, rebooting your machine, and rerunning this diagnosis
          script to see if the problem is resolved.
          """ % (binary_hostname,)
      )
      yield Suggestion("Use a simpler hostname", message)
    raise e


@check
def stat_tensorboardinfo():
  # We don't use `manager._get_info_dir`, because (a) that requires
  # TensorBoard, and (b) that creates the directory if it doesn't exist.
  path = os.path.join(tempfile.gettempdir(), ".tensorboard-info")
  logging.info("directory: %s", path)
  try:
    stat_result = os.stat(path)
  except OSError as e:
    if e.errno == errno.ENOENT:
      # No problem; this is just fine.
      logging.info(".tensorboard-info directory does not exist")
      return
    else:
      raise
  logging.info("os.stat(...): %r", stat_result)
  logging.info("mode: 0o%o", stat_result.st_mode)
  if stat_result.st_mode & 0o777 != 0o777:
    preamble = reflow(
        """
        The ".tensorboard-info" directory was created by an old version
        of TensorBoard, and its permissions are not set correctly; see
        issue #2010. Change that directory to be world-accessible (may
        require superuser privilege):
        """
    )
    # This error should only appear on Unices, so it's okay to use
    # Unix-specific utilities and shell syntax.
    quote = getattr(shlex, "quote", None) or pipes.quote  # Python <3.3
    command = "chmod 777 %s" % quote(path)
    message = "%s\n\n\t%s" % (preamble, command)
    yield Suggestion("Fix permissions on \"%s\"" % path, message)


@check
def source_trees_without_genfiles():
  roots = list(sys.path)
  if "" not in roots:
    # Catch problems that would occur in a Python interactive shell
    # (where `""` is prepended to `sys.path`) but not when
    # `diagnose_tensorboard.py` is run as a standalone script.
    roots.insert(0, "")

  def has_tensorboard(root):
    return os.path.isfile(os.path.join(root, "tensorboard", "__init__.py"))
  def has_genfiles(root):
    sample_genfile = os.path.join("compat", "proto", "summary_pb2.py")
    return os.path.isfile(os.path.join(root, "tensorboard", sample_genfile))
  def is_bad(root):
    return has_tensorboard(root) and not has_genfiles(root)

  tensorboard_roots = [root for root in roots if has_tensorboard(root)]
  bad_roots = [root for root in roots if is_bad(root)]

  logging.info(
      "tensorboard_roots (%d): %r; bad_roots (%d): %r",
      len(tensorboard_roots),
      tensorboard_roots,
      len(bad_roots),
      bad_roots,
  )

  if bad_roots:
    if bad_roots == [""]:
      message = reflow(
          """
          Your current directory contains a `tensorboard` Python package
          that does not include generated files. This can happen if your
          current directory includes the TensorBoard source tree (e.g.,
          you are in the TensorBoard Git repository). Consider changing
          to a different directory.
          """
      )
    else:
      preamble = reflow(
          """
          Your Python path contains a `tensorboard` package that does
          not include generated files. This can happen if your current
          directory includes the TensorBoard source tree (e.g., you are
          in the TensorBoard Git repository). The following directories
          from your Python path may be problematic:
          """
      )
      roots = []
      realpaths_seen = set()
      for root in bad_roots:
        label = repr(root) if root else "current directory"
        realpath = os.path.realpath(root)
        if realpath in realpaths_seen:
          # virtualenvs on Ubuntu install to both `lib` and `local/lib`;
          # explicitly call out such duplicates to avoid confusion.
          label += " (duplicate underlying directory)"
        realpaths_seen.add(realpath)
        roots.append(label)
      message = "%s\n\n%s" % (preamble, "\n".join("  - %s" % s for s in roots))
    yield Suggestion("Avoid `tensorboard` packages without genfiles", message)


# Prefer to include this check last, as its output is long.
@check
def full_pip_freeze():
  logging.info("pip freeze --all:\n%s", pip(["freeze", "--all"]).decode("utf-8"))


def set_up_logging():
  # Manually install handlers to prevent TensorFlow from stomping the
  # default configuration if it's imported:
  # https://github.com/tensorflow/tensorflow/issues/28147
  logger = logging.getLogger()
  logger.setLevel(logging.INFO)
  handler = logging.StreamHandler(sys.stdout)
  handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
  logger.addHandler(handler)


def main():
  set_up_logging()

  print("### Diagnostics")
  print()

  print("<details>")
  print("<summary>Diagnostics output</summary>")
  print()

  markdown_code_fence = "``````"  # seems likely to be sufficient
  print(markdown_code_fence)
  suggestions = []
  for (i, check) in enumerate(CHECKS):
    if i > 0:
      print()
    print("--- check: %s" % check.__name__)
    try:
      suggestions.extend(check())
    except Exception:
      traceback.print_exc(file=sys.stdout)
      pass
  print(markdown_code_fence)
  print()
  print("</details>")

  for suggestion in suggestions:
    print()
    print("### Suggestion: %s" % suggestion.headline)
    print()
    print(suggestion.description)

  print()
  print("### Next steps")
  print()
  if suggestions:
    print(reflow(
        """
        Please try each suggestion enumerated above to determine whether
        it solves your problem. If none of these suggestions works,
        please copy ALL of the above output, including the lines
        containing only backticks, into your GitHub issue or comment. Be
        sure to redact any sensitive information.
        """
    ))
  else:
    print(reflow(
        """
        No action items identified. Please copy ALL of the above output,
        including the lines containing only backticks, into your GitHub
        issue or comment. Be sure to redact any sensitive information.
        """
    ))


if __name__ == "__main__":
  main()

 

이대로 따라한 뒤 다시 설치하면 잘 되는것을 볼 수 있다.

 

결과사진

 

 

reference: https://github.com/pytorch/pytorch/issues/22676

728x90
728x90

Keras를 사용하다보면, 간단하게 구현된 라이브러리를 사용할 때가 있다.

그래서 더 사랑을 받는게 아닐까. 너무 간결하고 간단한 라이브러리들이 많다.


최근에 사용했던 간단한 라이브러리 Transformer 모델의 Self-Attention이다.


이 Function을 사용하기 위해서는 따로 import를 해줘야하는데 아래와 같이 하면 된다.


from keras_self_attention import SeqSelfAttention


자 이제 CNN 몇개와 RNN 몇개를 쌓고, 그 아래에 Self-Attention을 쌓았다고 가정해보자.


이 모델을 Fine-tune 하기 위해 일정 learning rate로 돌려놓고, 어느정도 loss를 깎은 다음 일정 이상 loss가 떨어지지 않으면 early stopping을 하여 learning rate를 기존보다 0.1배 정도로 낮춰서 fine-tune 할 예정이다. 이를 위해 모델을 save해야한다.


그럼 모델을 load할 때 종속성 문제가 생길 수 있다. 위의 SeqSelfAttention 인식을 못 할 수 있는 것이다.


내가 안되었던 경우는 다음과 같다. 

from keras.models import load_model, Model
import tensorflow as tf
import os
import time
from keras_self_attention import SeqSelfAttention
global graph, model
graph = tf.get_default_graph()
### GPU Setting : Not Using GPU
os.environ["CUDA_VISIBLE_DEVICES"]="-1"

# Load Model
model = load_model('/data/Auditory_Emotion_Recognition/model_attention/fianl_emotion_model.h5')


코드를 보면 단지 model을 load하는데, Unknown layer라고 뜬다. 아래의 사진은 그 현상을 얘기한다.


즉 SeqSelfAttention을 import 하였는데도 이러한 문제가 생긴다.



이를 해결 하기 위해 model load시 다음과 같은 줄을 선언해주면 쉽게 해결할 수 있다.


model = load_model('/data/Auditory_Emotion_Recognition/model_attention/fianl_emotion_model.h5',custom_objects={'SeqSelfAttention':SeqSelfAttention})


custom_objects={'name':import_library_name}


위와 같이 custom_objects 를 선언해주면 사용 가능하다.




728x90
728x90

오늘은 Keras로 구축해놓은 모델을 png나 jpg인 그림 포멧으로 저장하는 법에 대해 써볼까 한다.



우선 Keras 공식 홈페이지를 들어가서 plot_model library를 검색해본다.


https://keras.io/visualization/


들어가보면 맨 윗창에 Model Visualization이라고 나와 있다. 뜻 그대로 모델을 시각화 하겠다라는 뜻일듯.


예제에 나와 있는 것 처럼 그림으로 보고 싶은 모델을 불러온 뒤 예제처럼 코딩을 하면 저장이 된다.


나의 코드는 다음과 같다.


from keras.utils import plot_model


from keras.models import load_model
from keras_self_attention import SeqSelfAttention

model = load_model('/data/Auditory_Emotion_Recognition/model_attention/4emotions_auditory_cnn_model_self_GAP_pati50_epoch200_dropout0.2,relu_lr1e-05_8conv5dim+1GRU2FC_Zscore_lrdecay5.4e-08_acc:0.5498_test:_57.42.h5',custom_objects={'SeqSelfAttention':SeqSelfAttention})
plot_model(model, to_file='./model.png')


from keras.utils import plot_model: keras에서 모델을 그리기 위해 필요한 라이브러리 import


from keras.models import load_model: 저장된 모델을 불러오기 위한 라이브러리 import

from ~ SeqSelfAttention: SelfAttention을 보기 위한 라이브러리 import


model ~ -> 불러올 모델의 위치를 load_model을 통해 불러온 뒤 model로 선언


plot_model(model, to_file='./model.png'): model 을 그림으로 그리는 건데, 이 때 ./ 는 코드상의 디렉토리에 model.png 로 저장하겠다는 뜻이다.


저장된 모델은 다음과 같다.


728x90

+ Recent posts