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()
최근 tensorflow 2.0이 release 된 이후로, cuda 설치가 매우 간단해졌다.
(저는 cuda+cudnn 설치하는 시간 5분 걸렸습니다.)
Ubuntu 16.04 (CUDA 10) + cudnn + driver 설치
# Add NVIDIA package repositories
# Add HTTPS support for apt-key
sudo apt-get install gnupg-curl
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_10.0.130-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1604_10.0.130-1_amd64.deb
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
sudo apt-get update
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb
sudo apt install ./nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb
sudo apt-get update
# Install NVIDIA driver
# Issue with driver install requires creating /usr/lib/nvidia
sudo mkdir /usr/lib/nvidia
sudo apt-get install --no-install-recommends nvidia-driver-418
# Reboot. Check that GPUs are visible using the command: nvidia-smi
# Install development and runtime libraries (~4GB)
sudo apt-get install --no-install-recommends \
cuda-10-0 \
libcudnn7=7.6.2.24-1+cuda10.0 \
libcudnn7-dev=7.6.2.24-1+cuda10.0
# Install TensorRT. Requires that libcudnn7 is installed above.
sudo apt-get install -y --no-install-recommends libnvinfer5=5.1.5-1+cuda10.0 \
libnvinfer-dev=5.1.5-1+cuda10.0
Ubuntu 16.04 (CUDA 9.0 for TensorFlow < 1.13.0) + cudnn + driver 설치
# Add NVIDIA package repository
sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.1.85-1_amd64.deb
sudo apt install ./cuda-repo-ubuntu1604_9.1.85-1_amd64.deb
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb
sudo apt install ./nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb
sudo apt update
# Install the NVIDIA driver
# Issue with driver install requires creating /usr/lib/nvidia
sudo mkdir /usr/lib/nvidia
sudo apt-get install --no-install-recommends nvidia-410
# Reboot. Check that GPUs are visible using the command: nvidia-smi
# Install CUDA and tools. Include optional NCCL 2.x
sudo apt install cuda9.0 cuda-cublas-9-0 cuda-cufft-9-0 cuda-curand-9-0 \
cuda-cusolver-9-0 cuda-cusparse-9-0 libcudnn7=7.2.1.38-1+cuda9.0 \
libnccl2=2.2.13-1+cuda9.0 cuda-command-line-tools-9-0
# Optional: Install the TensorRT runtime (must be after CUDA install)
sudo apt update
sudo apt install libnvinfer4=4.1.2-1+cuda9.0
위에는 cuda-10.0, 아래는 cuda-9.0 인데, 2개 모두 동시 설치 가능하다.
본인 계정 -> basrhc 에 들어가서 아래와 같이 사용할 버전을 typing 한다.
vi ~/.bashrc
export PATH=/mnt/junewoo/bin:/mnt/junewoo/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
# Path for cuda-9.0
export PATH=$PATH:/usr/local/cuda-9.0/bin
# Path for cuda-10.0
#export PATH=$PATH:/usr/local/cuda-10.0/bin
# Path for cudnn with cuda-9.0
#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/junewoo/utils/cuda-9.0/lib64
# Path for cudnn with cuda-10.0
export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64:/mnt/junewoo/utils/cuda-10.0/lib64
만약 특정 폴더에 cudnn이 있을 경우(하지만 위의 명령어대로 설치할 경우 usr/local/cuda-n.m에 설치된다.
# Path for cudnn with cuda-10.0
export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64:/where/your_dir/cuda-10.0/lib64
요약하자면, matlab은 spectrogram의 마지막 window를 생략하면서, 각 window 가운데에 해당하는 시간 벡터를 출력한다. 예를 들어 3샘플 윈도우와 1개의 겸칩(overlap) 샘플을 갖는 10개의 샘플 길이의 신호는 다음과 같은 4개의 윈도우를 생성한다.
1:3
3:5
5:7
7:9,
m:n은 n번째 샘플을 포함하여 m에서 n까지의 샘플을 포함하는 윈도우를 나타낸다. 그러므로 window의 center가 2,4,6,8이다.
matlab은 (윈도우 크기-1) * 홉 길이 + 윈도우 사이즈 <= 샘플들의 개수로 되는 최대의 윈도우 크기를 필요로 하기 때문이다.
반면 python librosa stft 각 프레임의 첫 번째 샘플이 시간이고, 프레임은 입력 신호보다 많은 부분을 다룬다.
Mel-Spectrogram을 뽑기 위해서는 librosa.load 로 음성 데이터를 load하여 얻은 y를 넣으면 된다. 이렇게 나머지를 지정하지 않고 추출하였을 경우 default 값으로 추출이된다.
2. sr
y, sr = librosa.load(음성데이터) 를 하게 될 경우, 음성의 sr을 얻을 수 있다. 단 여기에서 중요한 것은, sr을 따로 설정해주지 않으면 librosa는 default인 22050을 주게 된다. 나는 이러한 이유로 soundfile을 사용하여 처음 보는 음성 데이터에 대하여 sr을 체크한 뒤, 그대로 아래처럼 설정해서 sr을 얻는 방법을 사용한다.
y, sr = librosa.load(wav_file, sr=16000)
3. S
S는 librosa.stft(y)를 하면 얻을 수 있다. 즉 Short-Time Fourier Transform을 하여 얻어진 magnitude 와 phase의 값인 것이다. 그렇지만 S는 사용하지 않고 음성 데이터인 y만 넣어도 되므로 pass하겠다.
4. n_fft
우리가 보유한 음성 데이터는 현재 time-magnitude domain이다. 이걸 왜 frequency로 바꾸냐면, 주파수 관점에서 바라보았을 때 얻을 수 있는 정보가 많기 때문이다.
음성은 연속적인 신호이다. 그러므로 연속적인 신호를 우리는 frequency로 바꿔야 한다.
n_fft는 이 때 사용되는데, 음성의 길이를 얼마만큼으로 자를 것인가? 라고 이해하면 될 것 같다. 이를 window라고 부른다.
사람의 목소리는 대부분 16kHz안에 포함이 된다. 만약 n_fft를 512라고 가정해보겠다. 이렇게 될 경우 1개의 n_fft는 16000/512 = 약 31.25가 된다. 이것이 자연수로 떨어지기 위해 올림을 해주어 32로 설정해준다. 총 음성 데이터의 길이가 500이라고 가정하면, 32만큼 잘라서 1칸을 그리겠다는 것으로 이해하면 된다.
보유한 음성 데이터의 Sampling Rate가 16000이고, 우리는 n_fft를 512개만 사용할 것이라면, 아래의 공식을 이용하여 구할 수 있다.
아래처럼 함수를 선언하였다. 여기에서 중요한 것은, n_mels이다. 만약 16kHz를 Mel_S로 뽑는다면 약 8kHz에 해당하는 주파수를 얻을 수 있다. 이때, 8kHz를 n_mels 크기 만큼으로 나눠준다. 즉 1개의 n_mels의 height는 0.4kHz를 포함하고 있다.
음성 데이터의 길이와 얻은 Mel_Spectrogram의 크기를 출력해보면 다음과 같다.
총 길이는 3.35초이고, 0.01 단위에서 올림을하여 3.36이 된다. 그리고 0.01에 1칸이므로 336칸을 얻는다.
이렇게 Mel_Spectrogram을 얻었고, 이것을 그려보도록 하겠다. 아래의 코드를 복사하면 된다.
이 함수에서는 wav 파일과 기존 original sr, resample 할 sr을 받고 있다.
보유한 데이터의 음성은 16kHz이므로, original_sr = 16000, resample_sr = 8000으로 진행한다.
음성 처리에 있어서 librosa 라이브러리가 정말 잘 지원해주고 있다. resample을 하기 위해서는 3번째 줄의 resample = librosa.resample(y, sr, resample_sr)을 해주면 된다.
그 아래의 print 한 결과는 다음과 같다.
즉 기존의 y data는 53720이고, 그의 절반으로 하였기 때문에 26860으로 출력이 된다.
이렇게만 보면 이해하기가 어렵다. 아래의 코드를 활용하여 직접 그림을 그려보자.
plt.figure(figsize=(10, 4)) # 10,4 크기로 그림
plt.subplot(2, 1, 1) # 2개를 그릴건데, (총 개수, 가로, 세로) 순서로 그림
time1 = np.linspace(0, len(y) / sr, len(y)) # 음성의 데이터를 이용하여 음성 총 길이를 구함
plt.plot(time1, y) # 음성 flot
plt.title('Original Wav')
plt.subplot(2, 1, 2)
time2 = np.linspace(0, len(resample) / resample_sr, len(resample))
plt.plot(time2, resample)
plt.title('Resampled Wav')
plt.tight_layout()
plt.savefig('compare_16k_vs_8k.png') # 저장
위의 코드에 자세히 주석을 달아놓았다. 위의 코드처럼 입력을 하면 다음의 그림을 얻을 수 있다.
코드에서 subplot은 2,1,1 -> 총 2개의 사진 중 맨 위를, 2,1,2 -> 총 2개의 사진 중 맨 아래에 그림을 그리겠다는 뜻이다.
육안으로 보았을 때 magnitude나 phase의 변화는 없다. 다만 자세히 들여다보면 data의 magnitude가 2개 중 1개씩 비어있다. 즉, 데이터가 총 100개면, resample 하였을 경우 (1/2로 하였기 때문에) 50개의 데이터만 남아있다. 이때, 데이터의 위치는 변화하지 않고 중간중간만 비어지는 것이다.
최근에 사용했던 간단한 라이브러리 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})
예를 들어 44.1kHz 에서 16000으로 변경을 해준다던지, 16000에서 22050으로 변경하여 음성 처리를 해줄 때가 있다.(Downsampling)
python에서 librosa 라이브러리를 이용하여 resampling을 간단히 해줄 수 있는데, 이 때 우분투에서 작업하던 음성 파일이 resampling 되고나서 librosa를 이용하여 그대로 저장을 하고 윈도우에서 그 음성을 다운받아서 확인해볼 때 읽히지 않을때가 있다.
결론적으로 말하자면, librosa 로 resample 이후에 soundfile의 write를 사용하여 저장하면 이 문제를 해결할 수 있다.
librosa.output.write_wav(output_dir+'.wav', data, sr) # 깨지는 현상 존재 sf.write(output_dir, data, sr, format='WAV', endian='LITTLE', subtype='PCM_16') # 깨지지 않음
위의 soundfile write내의 내용을 librosa write_wav의 내용을 그대로 넣어주면 된다.
librosa는 별도로 sr(sampling rate)를 설정하지 않으면 default sr이 22500으로 되어있다.
내가 불러올 음성 파일은 이미 16000 sr이므로 반드시 sr=16000을 붙여주도록 한다.
y, sr = librosa.load(wav, sr=16000) time = np.linspace(0, len(y)/sr, len(y)) # time axis fig, ax1 = plt.subplots() # plot ax1.plot(time, y, color = 'b', label='speech waveform') ax1.set_ylabel("Amplitude") # y 축 ax1.set_xlabel("Time [s]") # x 축 plt.title(file_id) # 제목 plt.savefig(file_id+'.png') plt.show()
들어가보면 맨 윗창에 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 로 저장하겠다는 뜻이다.