RoBoLoG

[Python, librosa] AI 학습을 위한 오디오 데이터 wav 파일 증강 (Audio Augmentation) 본문

Study/Python

[Python, librosa] AI 학습을 위한 오디오 데이터 wav 파일 증강 (Audio Augmentation)

SKJun 2024. 3. 8. 16:09

AI 학습을 위한 오디오 데이터 wav 파일 증강 (Audio Augmentation)

 

1. 데이터 폴더 예시

dataset-speech 폴더 안에 각 class에 대한 폴더가 있고, 그 아래 wav 파일들이 있을 때 데이터를 증강해보겠습니다.

dataset-speech
-- up
---- up1.wav
---- up2.wav
-- down
---- down1.wav
-- left
---- left1.wav
---- left2.wav
---- left3.wav
-- right
---- right1.wav
---- right2.wav
-- background
---- background1.wav
---- background2.wav
---- background3.wav

 


2. 데이터 증강 코드 step-by-step

DATA IMPORT

import os
import numpy as np
import librosa
import soundfile as sf
  • librosa: librosa는 오디오 분석과 음악 정보 검색을 위한 Python 라이브러리입니다. 오디오 파일을 로딩하고, 음성 신호를 분석하여 특성을 추출하는 다양한 기능을 제공합니다. 예를 들어, 멜 스펙트로그램 생성, 음향 특성 계산, 음악 박자 추정 등 오디오 관련 연구 및 개발에 유용한 기능들이 포함되어 있습니다.
  • soundfile: soundfile은 오디오 파일을 읽고 쓰기 위한 Python 라이브러리입니다. WAV, FLAC, OGG 등 다양한 오디오 파일 포맷을 지원합니다. 이 라이브러리를 사용하면 오디오 데이터를 파일로부터 쉽게 로드하거나, 처리한 결과를 파일로 저장할 수 있습니다.

 

NOISE 추가 함수 (add_noise)

# 오디오 데이터에 노이즈를 추가하는 함수
def add_noise(data, noise_level=0.005):
    noise = np.random.randn(len(data))  # 정규 분포를 따르는 노이즈 생성
    augmented_data = data + noise_level * noise  # 데이터에 노이즈 추가
    augmented_data = np.clip(augmented_data, -1, 1)  # 값이 -1과 1 사이로 유지되도록 함
    return augmented_data
  • data: 오디오 데이터의 배열을 나타내며, 이 데이터에 노이즈를 추가하게 됩니다.
  • noise_level: 추가되는 노이즈의 강도를 조절합니다. 기본값은 0.005로 설정되어 있습니다. 이 값이 클수록 더 많은 노이즈가 추가됩니다.
  • np.random.randn(len(data)): numpy의 random.randn 함수를 사용하여 data의 길이와 동일한 길이의 랜덤 노이즈 배열을 생성합니다. 이 노이즈는 평균이 0이고 표준편차가 1인 정규 분포를 따릅니다.
  • 생성된 노이즈에 noise_level을 곱하여 실제 데이터에 추가하기 전에 노이즈의 강도를 조절합니다. 그런 다음 이 조절된 노이즈를 원본 오디오 데이터에 추가합니다.
  • np.clip(augmented_data, -1, 1): 오디오 데이터의 값이 일반적으로 -1에서 1 사이의 범위에 있어야 하기 때문에, numpyclip 함수를 사용하여 데이터의 모든 값을 이 범위 내로 제한합니다. 이는 데이터가 특정 범위를 넘어서지 않도록 하여 왜곡을 방지합니다.

 

피치 변경 함수 (pitch_shift)

# 오디오의 피치를 변경하는 함수
def pitch_shift(data, sr, n_steps):
    return librosa.effects.pitch_shift(data, sr, n_steps)  # n_steps만큼 피치 이동
  • data: 피치를 변경할 오디오 데이터의 배열입니다.
  • sr (sampling rate): 오디오 데이터의 샘플링 레이트를 나타냅니다. 샘플링 레이트는 초당 샘플 수를 의미하며, 오디오의 품질과 처리 방식을 결정하는 중요한 요소입니다.
  • n_steps: 피치를 이동시킬 단계의 수입니다. 이 값이 양수면 오디오의 피치가 높아지고, 음수면 피치가 낮아집니다. n_steps의 절대값이 클수록 피치 변경의 정도가 커집니다.
  • librosa.effects.pitch_shift 함수는 세 가지 주요 인자를 받습니다: 오디오 데이터(data), 샘플링 레이트(sr), 그리고 피치 이동 단계(n_steps). 이 함수는 주어진 n_steps 값에 따라 오디오 데이터의 피치를 변경합니다.

 

시간 변경 함수 (time_stretch)

# 오디오의 시간을 늘리거나 줄이는 함수
def time_stretch(data, rate=0.8):
    return librosa.effects.time_stretch(data, rate)  # rate < 1.0은 늘림, > 1.0은 줄임
  • data: 시간을 조절할 오디오 데이터의 배열입니다.
  • rate: 시간 스트레치의 비율을 나타냅니다. rate 값이 1.0보다 작으면 오디오의 재생 시간이 늘어나며(즉, 속도가 느려지며), 1.0보다 크면 재생 시간이 줄어듭니다(즉, 속도가 빨라집니다). rate가 정확히 1.0이면 오디오의 속도가 변경되지 않습니다.
  • librosa.effects.time_stretch 함수는 두 가지 주요 인자를 받습니다: 오디오 데이터(data)와 시간 스트레치 비율(rate). 이 함수는 주어진 rate 값에 따라 오디오 데이터의 재생 시간을 조절합니다.

 

볼륨 변경 함수 (change_volume)

# 오디오의 볼륨을 조절하는 함수
def change_volume(data, volume_factor=0.5):
    return data * volume_factor  # 볼륨 조절
  • data: 볼륨을 조절할 오디오 데이터의 배열입니다. 이 데이터는 일반적으로 실수(float) 형태의 샘플 값으로 구성되어 있으며, 이 값들은 오디오의 강도를 나타냅니다.
  • volume_factor: 볼륨 조절 계수로, 오디오 데이터의 볼륨을 조절하기 위해 사용됩니다. 이 값에 따라 오디오의 볼륨이 조절됩니다.
  • 오디오 데이터의 각 샘플 값에 volume_factor를 곱하여 볼륨을 조절합니다. volume_factor가 1보다 크면 볼륨이 증가하고, 1보다 작으면 볼륨이 감소합니다. volume_factor가 1인 경우, 볼륨에 변화가 없습니다.

 

데이터 증강 및 저장 함수 (augment_and_save)

# 증강된 오디오 데이터를 저장하는 함수
def augment_and_save(file_path, sr, data, augmentation_function, augmentation_name):
    # 피치 변화 시 n_steps를 지정해야 하므로 조건문 사용
    if augmentation_name == 'pitch_shift':
        augmented_data = augmentation_function(data, sr, n_steps=4)
    else:
        # 볼륨 조절은 volume_factor가 필요하므로 별도 처리
        augmented_data = augmentation_function(data) if augmentation_function != change_volume else augmentation_function(data, volume_factor=0.5)
    new_file_path = file_path.replace('.wav', f'_{augmentation_name}.wav')  # 새 파일 경로 생성
    sf.write(new_file_path, augmented_data, sr)  # 파일 저장
  • file_path: 원본 오디오 파일의 경로입니다.
  • sr (sampling rate): 오디오 데이터의 샘플링 레이트를 나타냅니다.
  • data: 증강을 적용할 오디오 데이터의 배열입니다.
  • augmentation_function: 적용할 증강 기능을 나타내는 함수입니다.
  • augmentation_name: 적용할 증강 기법의 이름입니다. 이 이름은 새로운 파일 이름을 생성하는 데 사용됩니다.
  • 새로운 파일 경로는 원본 파일 이름에 증강 기법의 이름을 추가하여 생성됩니다. 예를 들어, 원본 파일이 audio.wav이고 증강 기법이 pitch_shift인 경우, 새 파일 이름은 audio_pitch_shift.wav가 됩니다.
  • soundfile 라이브러리의 write 함수를 사용하여 증강된 오디오 데이터를 새 파일로 저장합니다. 여기서 augmented_data는 증강 처리된 오디오 데이터, sr은 샘플링 레이트, new_file_path는 새로 생성된 파일 경로입니다.

 

폴더에 작업 실행 함수 (process_folder)

# 지정된 폴더의 모든 WAV 파일에 대해 데이터 증강을 수행하는 함수
def process_folder(folder_path, target_sr=16000):
    for subdir, dirs, files in os.walk(folder_path):  # 모든 하위 디렉토리 순회
        for file in files:
            if file.endswith('.wav'):  # .wav 파일인지 확인
                file_path = os.path.join(subdir, file)  # 파일의 전체 경로
                data, sr = librosa.load(file_path, sr=target_sr)  # 파일 로드 및 샘플링 레이트 설정
                
                # 적용할 데이터 증강 기법 목록
                augmentations = [
                    (add_noise, 'noisy'),
                    (time_stretch, 'stretch'),
                    (pitch_shift, 'pitch_shift'),
                    (change_volume, 'volume')
                ]
                
                # 각 증강 기법을 순회하며 적용
                for augmentation_function, augmentation_name in augmentations:
                    augment_and_save(file_path, sr, data, augmentation_function, augmentation_name)

 

 

코드 실행

# 데이터셋의 경로 - 실제 경로로 변경 필요
dataset_path = 'dataset-speech'
process_folder(dataset_path)  # 함수 호출

3. 전체 코드

import os
import numpy as np
import librosa
import soundfile as sf

# 오디오 데이터에 노이즈를 추가하는 함수
def add_noise(data, noise_level=0.005):
    noise = np.random.randn(len(data))  # 정규 분포를 따르는 노이즈 생성
    augmented_data = data + noise_level * noise  # 데이터에 노이즈 추가
    augmented_data = np.clip(augmented_data, -1, 1)  # 값이 -1과 1 사이로 유지되도록 함
    return augmented_data

# 오디오의 시간을 늘리거나 줄이는 함수
def time_stretch(data, rate=0.8):
    return librosa.effects.time_stretch(data, rate)  # rate < 1.0은 늘림, > 1.0은 줄임

# 오디오의 피치를 변경하는 함수
def pitch_shift(data, sr, n_steps):
    return librosa.effects.pitch_shift(data, sr, n_steps)  # n_steps만큼 피치 이동

# 오디오의 볼륨을 조절하는 함수
def change_volume(data, volume_factor=0.5):
    return data * volume_factor  # 볼륨 조절

# 증강된 오디오 데이터를 저장하는 함수
def augment_and_save(file_path, sr, data, augmentation_function, augmentation_name):
    # 피치 변화 시 n_steps를 지정해야 하므로 조건문 사용
    if augmentation_name == 'pitch_shift':
        augmented_data = augmentation_function(data, sr, n_steps=4)
    else:
        # 볼륨 조절은 volume_factor가 필요하므로 별도 처리
        augmented_data = augmentation_function(data) if augmentation_function != change_volume else augmentation_function(data, volume_factor=0.5)
    new_file_path = file_path.replace('.wav', f'_{augmentation_name}.wav')  # 새 파일 경로 생성
    sf.write(new_file_path, augmented_data, sr)  # 파일 저장

# 지정된 폴더의 모든 WAV 파일에 대해 데이터 증강을 수행하는 함수
def process_folder(folder_path, target_sr=16000):
    for subdir, dirs, files in os.walk(folder_path):  # 모든 하위 디렉토리 순회
        for file in files:
            if file.endswith('.wav'):  # .wav 파일인지 확인
                file_path = os.path.join(subdir, file)  # 파일의 전체 경로
                data, sr = librosa.load(file_path, sr=target_sr)  # 파일 로드 및 샘플링 레이트 설정
                
                # 적용할 데이터 증강 기법 목록
                augmentations = [
                    (add_noise, 'noisy'),
                    (time_stretch, 'stretch'),
                    (pitch_shift, 'pitch_shift'),
                    (change_volume, 'volume')
                ]
                
                # 각 증강 기법을 순회하며 적용
                for augmentation_function, augmentation_name in augmentations:
                    augment_and_save(file_path, sr, data, augmentation_function, augmentation_name)

# 데이터셋의 경로 - 실제 경로로 변경 필요
dataset_path = 'dataset-speech'
process_folder(dataset_path)  # 함수 호출

 

함수 설명

  • add_noise(data, noise_level=0.005): 입력된 오디오 데이터(data)에 정규 분포를 따르는 랜덤 노이즈를 추가합니다. noise_level 매개변수는 노이즈의 강도를 조절합니다.
  • time_stretch(data, rate=0.8): 오디오의 속도를 변경하지 않고 길이를 늘리거나 줄입니다. rate가 1보다 작으면 오디오가 늘어나고, 1보다 크면 오디오가 줄어듭니다.
  • pitch_shift(data, sr, n_steps): 오디오의 피치를 변경합니다. n_steps는 피치를 몇 반음 올릴지 또는 내릴지를 결정합니다. 양수는 피치를 올리고, 음수는 피치를 내립니다.
  • change_volume(data, volume_factor=0.5): 오디오의 볼륨을 조절합니다. volume_factor를 조절하여 볼륨을 높이거나 낮출 수 있습니다.
  • augment_and_save(file_path, sr, data, augmentation_function, augmentation_name): 지정된 데이터 증강 함수를 오디오 데이터에 적용하고, 결과를 새 파일로 저장합니다. 새 파일의 이름은 원본 파일명에 증강 기법의 이름을 추가하여 구성됩니다.
  • process_folder(folder_path, target_sr=16000): 지정된 폴더 내의 모든 .wav 파일에 대해 위에서 정의된 데이터 증강 기법을 순차적으로 적용합니다. 모든 오디오 파일은 명시적으로 16000Hz의 샘플링 레이트로 로드됩니다.

전체 프로세스

  1. process_folder 함수가 주어진 데이터셋 폴더(dataset-speech)를 순회합니다.
  2. 각 하위 폴더와 파일을 순회하면서, .wav 확장자를 가진 파일을 찾습니다.
  3. 찾은 각 파일에 대해 librosa.load를 사용하여 16000Hz의 샘플링 레이트로 데이터를 로드합니다.
  4. 로드된 오디오 데이터에 대해 다음 네 가지 증강 기법을 순차적으로 적용합니다:
    • 노이즈 추가
    • 시간 스트레칭
    • 피치 변화
    • 볼륨 조절
  5. 각 증강 기법을 적용한 후, 결과 오디오 파일은 원본 파일명에 증강 기법의 이름을 추가하여 같은 폴더에 저장됩니다.
  6. 이 과정은 지정된 폴더 내의 모든 .wav 파일에 대해 반복됩니다.

이 스크립트는 오디오 데이터셋의 다양성을 증가시키기 위한 데이터 증강 목적으로 사용됩니다. 다양한 환경에서 녹음된 데이터를 모사하거나, 모델이 다양한 오디오 조건에 대해 더 잘 일반화할 수 있도록 도와줍니다.


4. 결과

원본 (tree.wav)

 

NOISE 추가 (tree_noisy.wav)

 

피치 변경 (tree_pitch_shift.wav)

 

시간 변경 (tree_stretch.wav)

 

볼륨 변경 (tree_volume.wav)


728x90
반응형