์์ํ๋ฉฐ
2019๋ AI๊ด๋ จ ์์ ์ ์๊ฐํ๋ฉฐ computer vision์ ๋ํด์ ๋ฐฐ์ ๋ค. ์ด ์ดํ, ๋น์ ํ ๋ฐ์ดํฐ์ ๋ํ ์์ฌ์ด ์๊ธฐ๊ธฐ ์์ํ์ผ๋ฉฐ 3ํ๋ ์ฃผ์ ์ 4ํ๋ ์ด ์กธ์ ํ๋ก์ ํธ๋ก ๋๊ฐ๋ ํ์ ๋ํ์ ์ฐธ์ฌ๋ฅผ ๋์ ํ๊ฒ ๋์๋ค. 4ํ๋ ์ ์กธ์ ํ๋ก์ ํธ๋ ๊ธฐ์ ์ฐ๊ณ ํ๋ก์ ํธ๋ก ์ค์ ๋ก ๊ธฐ์ ํ์ง์๋ค๊ณผ ํจ๊ปํ๋ ํ๋ก์ ํธ๋ค ์ด์๋ค.
์ด ์ฌ๊ฑด์ ๊ณ๊ธฐ๋ก, ๋ง์ ๋ํ์ ์ฐธ์ฌํ๋ ์ฉ๊ธฐ๋ฅผ ์ป๊ฒ๋๋ค :) ๋, ๋๊ธฐ์๊ฒ ๋์ ํ๊ณ ๊ฒฐ๊ณผ๋ฌผ์ ๋ง์กฑ์ค๋ฝ๊ฒ ๋ฝ์๋ธ ๊ฒฐ๊ณผ ๋ด ์ธ์ ์ฒ์์ผ๋ก ํฐ ๋ํ์์ ์์ ๋ฐ๊ฒ ๋๋ค. ๊ทธ ์ข์ ๊ธฐ์ต์ ๋ ์ฌ๋ฆฌ๋ฉฐ, ์ฐ๋ฆฌํ์ด ๋ง๋ค์๋ ์์คํ ์ ๋ฆฌ๋ทฐํด๋ณด๋ ค๊ณ ํ๋ค .
1. ํ๋ก์ ํธ ๊ฐ์
1.1 ํ๋ก์ ํธ ์ฃผ์ ์ ์ ๋ฐฐ๊ฒฝ
์ฒญ๊ฐ์ฅ์ ์ธ์ด ์๋ฆฌ๋ฅผ ๋ฃ์ง๋ชปํด ๊ฒฉ๋ ๋ฌธ์ ์ ์
โ ์ํ ๊ฐ์ง ์ด๋ ค์
- ์ฐจ ๊ฒฝ์ ์๋ฆฌ, ์ฌ์ด๋ ์๋ฆฌ ๋ฑ ์ํ ๊ฐ์ง ์์๊ฐ ๋ ์ ์๋ ์๋ฆฌ๋ฅผ ํ์ ํ์ง ๋ชปํ์ฌ ์ํ ๋ ธ์ถ ๊ฐ๋ฅ์ฑ์ด ๋๋ค.
- ์ค์ ์ฌ๋ก) ์ฒญ๊ฐ์ฅ์ ์ธ์ ํ์ค๊ณผ ์๊ตฌ์ฌํญ
โก ์ฒญ๊ฐ ๋ณด์กฐ๊ธฐ๊ธฐ์ ๋์ ๊ฐ๊ฒฉ
- ํน์ ์๋ฆฌ๋ฅผ ๊ฐ์งํ๊ธฐ ์ํด ๋์ ๊ฐ๊ฒฉ์ ์ฒญ๊ฐ๋ณด์กฐ๊ธฐ๊ธฐ๋ฅผ ๊ตฌ๋งคํด์ผ ํ๋ค. ์ ๋ถ ์ง์๊ธ ์ ๋๊ฐ ์์ผ๋ ์ด๋ฅผ ์ง์ ๋ฐ์ง ๋ชปํ๋ ์ฅ์ ์ธ์ด ๋ค์์๋ค.
- ์ค์ ์ฌ๋ก) ๋ณด์ฒญ๊ธฐ ๋ณด์กฐ๊ธ์ ํ์ค
โข ํ์ค์ ๋์ ๋ถ์กฑ
- ์ฒญ๊ฐ์ฅ์ ์ธ์ด ํ์ค์ ์ผ๋ก ์๊ตฌํ๋ ํญ๋ชฉ์ ๋ถํฉํ๋ ์ ํ์ด ๊ฑฐ์ ์๋ค.
- ์ค์ ์ฌ๋ก) ํ์ฌ๊ฒฝ๋ณด๊ธฐ ์ค์น ํํฉ
1.2 ๋ชฉํ ์ ์
์ฒญ๊ฐ์ฅ์ ์ธ์ ์ํ ์ฌ์ฉ์ ๋ง์ถคํ ์๋ฆฌ ์๋ฆผ ์ดํ๋ฆฌ์ผ์ด์ ‘์๋ฆฌ๋ฏธ’ ์ ์
- ์ค๋งํธํฐ ์ง๋ ์๋ฆผ ์ดํ์ ๊ตฌํํจ์ผ๋ก์จ ์ฒญ๊ฐ์ฅ์ ์ธ๋ค์ด ๋๋ผ๋ ์ฒญ๊ฐ ๋ณด์กฐ๊ธฐ๊ตฌ์ ๊ฐ๊ฒฉ์ ๋ํ ๋ถ๋ด์ ์ค์ด๊ณ , ์ฌ์ฉ๋ฐฉ๋ฒ์ด ๊ฐ๋จํ๋ฉฐ, ์ธ์ํ๊ณ ์ถ์ ์๋ฆฌ๋ฅผ ์ฌ์ฉ์๊ฐ ์ง์ ์ ํํ์ฌ ์ํ๋ ์๋ฆผ์ ๋ฐ์ ์ ์๋๋ก ํจ
1.3 ๋ฒ์ ์ ์
ํ๋ก์ ํธ์ ๋ฒ์๋ฅผ ์ ์ํจ์ผ๋ก์จ ํ๋ก์ ํธ์ ์์ธํ ์ค๊ณฝ์ ์ก์๋ณด๊ณ , ์ถํ ํด๋น ์ฃผ์ ๋ฅผ ๋ฒ์ด๋์ง ์๋๋ก ๋ฏธ๋ฆฌ ๋ฒ์๋ฅผ ์ ์ํด๋๊ณ ์์ํ๋ค. ์ค์ ๋ก ๋ณธ ์์คํ ์ ๊ตฌํํ ๋, ์ฌ์ฉ์๊ฐ ๋๊ตฌ์ธ์ง, ์ ์ด ์์คํ ์ ๊ฐ๋ฐํด์ผ ํ๋์ง ํท๊ฐ๋ฆฌ๊ฑฐ๋ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ์๊ฐ์ ํ๋ ๊ฒฝ์ฐ๊ฐ ์ข ์ข ์๊ฒผ๋๋ฐ ๋ฒ์ ์ค์ ์ ํด๋์ด์ ์ฃผ์ ๋ฅผ ๋ค์ ๋ค์ก๊ณ ํ ํ์๋ฅผ ์งํํ๋ ์ข์ ์ญํ ์ ํด์ฃผ๊ธฐ๋ ํ์๋ค.
2. ์ค๊ณ ๋ฐ ๊ตฌํ
2.1 ํ๋ก์ ํธ ์ค๊ณ
2.1.1 Activity Diagram
Activity Diagram์ ๊ทธ๋ ค๋ด์ผ๋ก์จ ํ๋ก๊ทธ๋จ์ ํ๋ก์ธ์ค์ ๋ํ ๊ตฌ์ฒด์ ์ธ ์ ์๋ฅผ ํ๊ณ , ์ค๊ณ์ ๋ํ ๋๋ต์ ์ธ ๊ทธ๋ฆผ์ ๊ทธ๋ ค๋ณด์๋ค.
2.1.2 AS-IS, TO-BE ๋ถ์
AS-IS, TO-BE ๋ถ์์ ํตํด ๋ณธ ์์คํ ๊ตฌํ์ ํตํด ์ด๋ค ์ ์ด ํด๊ฒฐ๋๋์ง, ๊ธฐ์กด ์์คํ ์ ๋ํ ๋ฌธ์ ๋ฅผ ํ์ ํด๋ณด๋ ์๊ฐ์ ๊ฐ์ก๋ค.
โ AS-IS ๋ถ์ ๋ฐ ๋ฌธ์ ์ ์
โก TO-BE ๋ถ์
2.1.3 User Journey Map
ํด๋น ์์คํ ์ด ๊ตฌํ๋์์ ๋, ์ฌ์ฉ์๊ฐ ์ด๋ป๊ฒ ๋ฐ์ํ๋์ง์ ๋ํ ์ฌ์ฉ์ ๊ฒฝํ์ ์๊ฐํ ํ์ฌ ํํํจ์ผ๋ก์จ ๋ณธ ์์คํ ์ ๋ํ ํ์์ฑ์ ๋์ฑ ๊ฐ์กฐํ๋ค.
์ด user journey map์ ์ดํด๋ณด์๋, ์ฌ์ฉ์์ ๋์ฆ๊ฐ ๋งค์ฐ ๋ค์ํจ์ ์ ์ ์๋ค. ์ด ๋ชจ๋ ์ฌ์ฉ์์ ๋์ฆ๋ฅผ ์ถฉ์กฑ์์ผ์ฃผ๋ ์์คํ ์ธ ์ฌ์ฉ์ ๋ง์ถคํ ์๋น์ค๋ฅผ ์ ๊ณตํ์ฌ Installed Base๋ฅผ ํ๋ณดํ๋ ๊ฒ์ ์ต์ข ๋ชฉํ๋ก ๋์๋ค.
2.2 ํ๋ก์ ํธ ๊ตฌํ
2.2.1 ๋ฐ์ดํฐ ์์ง
๋๊ฐ์ง์ ๋ฐ์ดํฐ ์ ์ ์ฌ์ฉํ๋ค.
FSD Kaggle 2018 | Kaggle ๋ํ๋ฅผ ์ํด Google AudioSet์์ ๋ฐ์ทํ ๋ฐ์ดํฐ์
์ผ๋ก, 18873๊ฐ์ ์ฌ์ด๋ ๋ฐ์ดํฐ๋ฅผ 41๊ฐ์ ํด๋์ค๋ก ๋ผ๋ฒจ๋งํ ๋ฐ์ดํฐ |
Urbansound8K | ๋์ ์์์์ ์ถ์ถํ ์ฌ์ด๋๋ก ๊ตฌ์ฑ๋ ๋ฐ์ดํฐ์
์ผ๋ก, 8732๊ฐ์ ์ฌ์ด๋ ๋ฐ์ดํฐ๋ฅผ 10๊ฐ์ ํด๋์ค๋ก ๋ผ๋ฒจ๋งํ ๋ฐ์ดํฐ |
์ฌ๊ธฐ์ ์๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ง๋ ์์๊ณ , ํ๋ก์ ํธ ์ฃผ์ ์ ์ ํฉํ 8๊ฐ์ ํด๋์ค๋ง ์ผ๋ถ ์ถ์ถํ์ฌ ์ฌ์ฉํ๋ค.
ํด๋์ค ๋ถ๊ท ํ ๋ฐฉ์ง๋ฅผ ์ํด ์๋ ํด๋์ค์์๋ ๋๋ฌด ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ ํ ๋ฐ์ดํฐ์ ๊ฒฝ์ฐ๋ ์ต๋ 500๊ฐ์ ๋ฐ์ดํฐ๋ง ์ฌ์ฉํ๋ค. ๋ฐ๋ผ์ ์ด 8๊ฐ์ ํด๋์ค๋ก ๋ผ๋ฒจ๋ง ๋ 2721๊ฐ์ ์ฌ์ด๋ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ๋ค.
์ฌ์ฉ๋ 8๊ฐ์ ํด๋์ค | Knock, Cough, Meow, Chime, Engine_idling, Dog-bark, Siren, Car-horn |
print(metadata.class_name.value_counts())
2.2.2 ๋ฐ์ดํฐ ํํ ์๊ฐํ
์๋ฆฌ ๋ฐ์ดํฐ๋ ๋ชจ๋ ํํ์ ํํ์ด ๋ค์ํ๊ธฐ ๋๋ฌธ์ ์๊ฐํํ์ฌ ๊ทธ ๋ชจ์ต์ ์ดํด๋ณด์๋ค.
filename = 'c:/code/dataset/kaggle_sample/00fbb28b.wav'
plt.figure(figsize = (12, 4))
data.sample_rate = librosa.load(filename)
_ = librosa.display.waveplot(data, sr = sample_rate)
2.2.3 ๋ฐ์ดํฐ ์์ฑ ๋ถ์
โ Audio Channels
- ์ค๋์ค๋ ์คํ ๋ ์ค, ๋ชจ๋ ธ ๋ ๊ฐ์ง์ ํ์ ์ผ๋ก ์กด์ฌ
- ์คํ ๋ ์ค๋ ๋๊ฐ์ ์ฑ๋, ๋ชจ๋ ธ๋ ํ ๊ฐ์ ์ฑ๋์ ๊ฐ์ง
- ์์ง๋ฐ์ดํฐ๋ ๋ ๊ฐ์ง์ ํ์ด์ด ํผ์ฌ๋์ด ์๋ ํํ๋ก ๋ณด์
โก Sample Rate
- ์ด์ฐ์ ์ธ ์ ํธ๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ ์ฐ์์ ์ธ ์ ํธ์์ ์ป์ด์ง ๋จ์๋น (์ฃผ๋ก ์ด) ์ํ๋ง ํ์
- ์์ง๋ฐ์ดํฐ์ Sample Rate๋ 96K ~ 11K๋ก ๋ค์
print(audiodf.sample_rate.value_counts(normalize = True))
โข Bit Depth
- ์ค๋์ค๋ฅผ ์ธ๋ถํํ์ฌ ํํํ๋ ์ ๋, ๋นํธ์ ์ฌ๋๋ผ๊ณ ๋ถ๋ฆ.
- ์์ง ๋ฐ์ดํฐ์ Bit Depth ๋ํ ๋งค์ฐ ๋ค์ํ๊ฒ ๋ถํฌํจ.
print(audiodf.bit_depth.value_counts(normalize = True))
2.2.4 ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
โ ํ๋์ ์ฑ๋๋ก ํตํฉ
- ์คํ ๋ ์ค ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ ์ฑ๋์ ํ๊ท ๊ฐ์ ์ด์ฉํ์ฌ ํ๋๋ก ๋ณํฉํ๊ณ , ๋ชจ๋ ธ ํ์ ์ผ๋ก ๋ณํํด ์ฃผ์๋ค.
import matplotlib.pyplot as plt
# ์๋ original ๋ฐ์ดํฐ์ ํํ
plt.figure(figsize=(12, 4))
plt.plot(scipy_audio)
# ํฉ์ณ์ง ์ฑ๋
plt.figure(figsize=(12, 4))
plt.plot(librosa_audio)
โก Sample Rate ๊ฐ๋ค์ ํ์คํ
- ๋ค์ํ๊ฒ ๋ถํฌํ๋ Sample Rate ๊ฐ๋ค์ ํ์คํ ์์ผ์ฃผ๋ ์์ ์ ์ํํ๋ค.
- Sample-rate conversion ๊ธฐ์ ์ ํ์ฉํ์ฌ ๋ค์ํ Sample Rate๋ค์ ํ์คํ ์์ผฐ๋ค.
- Sample-rate conversion? ์ด์ฐ์ ํธ์ ์ํ๋ง ์๋๋ฅผ ๋ณ๊ฒฝํ์ฌ ๊ธฐ๋ณธ ์ฐ์ ์ ํธ์ ์๋ก์ด ์ด์ฐ ํํ์ ์ป๋ ๊ณผ์
- Librosa ๋ชจ๋์ load ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ ๋ฐ์ดํฐ๋ค์ Sample Rate๋ฅผ 22.05KHz๋ก ๋ณํํ๋ค.
- librosa.load(filename, sr=None) ์ด ํํ, sr์ None์ผ๋ก ์ค์ ํด์ฃผ์ง ์์ผ๋ฉด ์๋์ผ๋ก resampling์ด ์งํ๋จ
- ๋ณธ ํ๋ก์ ํธ์์๋ ์ง์ ํด์ฃผ์ง ์์๊ธฐ ๋๋ฌธ์ resampling์ด ์งํ๋์์ ์ ์ ์์.
- resampling๋ ๋ฐ์ดํฐ์ ๋ถํฌ๋ -1๊ณผ 1์ฌ์ด๋ก ์ ๊ทํ๋จ
- ์ฐธ๊ณ ๋งํฌ
import librosa
from scipy.io import wavfile as wav
import numpy as np
filename = 'UrbanSound_Dataset_sample/audio/102857-5-0-0.wav'
librosa_audio, librosa_sample_rate = librosa.load(filename)
scipy_sample_rate, scipy_audio = wav.read(filename)
print('Original sample rate:', scipy_sample_rate)
print('Librosa sample rate:', librosa_sample_rate)
โข Bit Depth ๊ฐ๋ค์ ์ ๊ทํ
- librosa ๋ชจ๋์ load ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ ๊ฐ ๋ฐ์ดํฐ๋ค์ Bit Depth๋ฅผ -1 ๊ณผ 1 ์ฌ์ด์ ๊ฐ์ ๊ฐ๋๋ก ์ ๊ทํ ์์ผ์ฃผ์๋ค.
print('Original audio file min~max range:', np.min(scipy_audio), 'to', np.max(scipy_audio))
print('Librosa audio file min~max range:', np.min(librosa_audio), 'to', np.max(librosa_audio))
2.2.5 ๋ฐ์ดํฐ ํน์ฑ ์ถ์ถ
์๋ฆฌ๋ฐ์ดํฐ๋ ๋ค๋ฅธ ๋น์ ํ ๋ฐ์ดํฐ์๋ ๋ค๋ฅด๊ฒ ์ฃผํ์ ๋ฐ ์๊ณ์ด์ ํน์ฑ์ ๋ชจ๋ ๋ถ์ํ feature๊ฐ ํ์ํ๋ค. ์ฌ๋ฌ๋ฒ์ ์คํจ๋ฅผ ๋ง๋ณด๊ณ , ํ์๋ค๊ณผ ์ด์ฌํ ๊ณต๋ถํ ๊ฒฐ๊ณผ MFCC ์๋ฆฌ์ฆ์ ํ์ฉํด์ Feature๋ฅผ ์ถ์ถํด์ฃผ์ด์ผ ํ๋ค๋ ์ ์ ์๊ฒ ๋์๋ค. MFCC ์ ๋ํ ์์ธํ ํฌ์คํ ์ ๋์ค์ ํ๋๋ก ํ๊ณ , ํ๋ก์ ํธ์ ํ์ํ ๊ฐ๋จํ ์ง์๊ณผ ๊ฐ๋จํ ์ฝ๋๋ฅผ ๊ตฌํํ์ฌ ๋ณธ ํ๋ก์ ํธ๋ฅผ ๋ง์ ์ ๋ก๋ ํด๋ณด๊ฒ ๋ค.
- MFCC (Mel-Frequency Cepstral Coefficients)
- ์๋ฆฌ๋ฐ์ดํฐ๋ฅผ ์ผ์ ๊ตฌ๊ฐ์ผ๋ก ๋๋์ด ํด๋น ๊ตฌ๊ฐ์ ๋ํ ์คํํธ๋ผ์ ๋ถ์ํ์ฌ ํน์ง์ ์ถ์ถํด์ฃผ๋ ๋ํ์ ์ธ ์์ฑ์ธ์ ์๊ณ ๋ฆฌ์ฆ
- ์์ ์ด ๋ณํด๋ MFCC๊ฐ ์ผ์ ํ๊ฒ ์ ์ง๋๊ธฐ ๋๋ฌธ์ ํ์ฉ๋ฒ์๊ฐ ์๋นํ ๋์์ ์ ์์๋ค.
- ์๋ฆฌ์ ์ฃผํ์ ๋ฐ ์๊ฐ์ ํน์ฑ๊น์ง ๋ชจ๋ ๋ถ์ํด์ค๋ค.
- ์๋ฆฌ๋ ์๊ณ์ด ๋ฐ์ดํฐ์ด๊ธฐ ๋๋ฌธ์ ์๊ฐ์ ํน์ฑ๊น์ง ๋ถ์์ด ํ์ํ๊ณ , ์ฃผ๋ณ์ ์ผ์ ํ์ง ์์ ์๋ฆฌ๋ฅผ ์ธ์ํ๊ณ , ์์ ์ด ๋ฌ๋ผ๋ ๊ฐ์์๋ฆฌ๋ก ์ธ์ํด์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ MFCC ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด๋ณด๊ธฐ๋ก ํ๋ค.
import librosa
import numpy as np
import pandas as pd
import os
max = 0
def extract_features(file_name):
try:
audio, sample_rate = librosa.load(file_name, res_type='kaiser_fast')
mfccs = librosa.feature.mfcc(y=audio, sr=sample_rate, n_mfcc=40)
# print(mfccs.shape) # ์ด๊ฑฐ ์ถ๊ฐํด๋ด
mfccsscaled = np.mean(mfccs.T,axis=0)
global max
if mfccs.shape[1] > max:
max = mfccs.shape[1]
# print(max)
except Exception as e:
print("Error encountered while parsing file: ", file_name)
return None
return mfccsscaled
# ๋ฐ์ดํฐ์
path ์ง์
fulldatasetpath = 'C:/code/cap_sound/dataset/final_dataset_500/'
metadata = pd.read_csv('C:/code/cap_sound/dataset/final_500.csv')
features = []
# ๊ฐ ์๋ฆฌ์ ๋ํด feature๋ฅผ ์ถ์ถ
for index, row in metadata.iterrows():
file_name = os.path.join(os.path.abspath(fulldatasetpath)+'/'+str(row["slice_file_name"]))
class_label = row["class_name"]
data = extract_features(file_name)
features.append([data, class_label])
# df๋ก ๋ง๋ค๊ธฐ
featuresdf = pd.DataFrame(features, columns=['feature','class_label'])
print('Finished feature extraction from ', len(featuresdf), ' files')
print('Max :',max)
์์ฝํด์ ์ถ์ถ๋ feature๋ฅผ ์ดํด๋ณด๋ฉด
mfccs = librosa.feature.mfcc(y = librosa_audio, sr = librosa_sample_rate, n_mfcc = 40)
print(mfccs.shape)
import librosa.display
librosa.display.specshow(mfccs, sr = librosa_sample_rate, x_axis = 'time')
2.2.6 ๋ชจ๋ธ ๊ตฌ์ถ
๋ฐฐ์ด ์ง์์ ํ์ฉํด๋ณด๊ณ ์ ์ธ ๊ฐ์ง์ ๋ชจ๋ธ์ ๊ตฌ์ถํ๊ณ , ๊ฐ ๋ชจ๋ธ ๋ณ Accuracy๋ฅผ ๋ณด๊ณ ์ต์ข ๋ชจ๋ธ์ ๊ฒฐ์ ํ์๋ค.
โ ๋ฐ์ดํฐ ๋ถํ ๋ฐ ์ ์ฅ
- ๋ฐ์ดํฐ ๋ณํ ๋ฐ ๋ผ๋ฒจ ์ธ์ฝ๋ ์ ์ฉ
- Sklearn์ labelEncoder๋ฅผ ์ ์ฉํ๋ค.
- ๋ฒ์ฃผํ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ์ดํดํ ์ ์๋ ์์นํ ๋ฐ์ดํฐ๋ก ๋ณํํ๊ธฐ ์ํด์
from sklearn.preprocessing import LabelEncoder
from keras.utils import to_catagorical
x = np.array(featuresdf.feature.tolist())
y = np.array(featuresdf.class_label.tolist())
le = LabelEncoder()
yy = to_categorical(le.fit_transform(y))
โก ๋ฐ์ดํฐ ๋ถํ
- sklearn์ train_test_split์ ์ ์ฉํ์ฌ train:test = 8:2๋ก ๋ถํ ํ๋ค.
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, yy, test_size = 0.2, random_state = 42)
2.2.6.1 MLP (Multi-Layer Perception)
- ๋ชจ๋ธ ์ ์ ์ด์
- ์ ๊ฒฝ๋ง์ ๊ธฐ๋ณธ์ด ๋๋ ๋ชจ๋ธ๋ก์, ์ ๋ ฅ์ธต, ์๋์ธต, ์ถ๋ ฅ์ธต์ ๋จ์ํ ๊ตฌ์กฐ๋ก ๊ตฌํ์ด ์ฉ์ดํ์ฌ ํ์ต ์์์๊ฐ์ด ์งง์ผ๋ฏ๋ก ์ฑํ
- ์ง๋ํ์ต์ด ํ์ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๋ฐ ์ฃผ๋ก ์ฌ์ฉ๋๋ฉฐ, ์์ฑ์ธ์ ํน์ ์ด๋ฏธ์ง ์ธ์์์ ์ฃผ๋ก ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ
- ๋ชจ๋ธ ๊ตฌํ
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.optimizers import Adam
from keras.utils import np_utils
from sklearn import metrics
num_labels = yy.shape[1]
filter_size = 2
# Construct model
model = Sequential()
model.add(Dense(256, input_shape=(40,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_labels))
model.add(Activation('softmax'))
- ์์ ์ฐ๊ฒฐ ๊ณ์ธต 3์ธต์ผ๋ก ๊ตฌ์ฑ
- ํ์ฑํ ํจ์๋ ๊ฐ layer ๋ง๋ค ReLU, ReLU, softmax ํจ์๋ฅผ ์ฌ์ฉ
- Batch 256 / epoch ๋ 100, 150,,,, 1000 ๊น์ง ๋ค์ํ๊ฒ ํ์ต ์งํ
- ํ์ต ์งํ
from keras.callbacks import ModelCheckpoint
from datetime import datetime
num_epochs = 1000
num_batch_size = 32
# ์ ์๋ ์๋ ๋ชจ๋ธ์ ์ฐ๋๊ฒ ๋ง๋์ง
checkpointer = ModelCheckpoint(filepath='C:/code/cap_sound/save_models/weights.best.basic_mlp.hdf5',
verbose=1, save_best_only=True)
start = datetime.now()
model.fit(x_train, y_train, batch_size=num_batch_size, epochs=num_epochs, validation_data=(x_test, y_test), callbacks=[checkpointer], verbose=1)
duration = datetime.now() - start
print("Training completed in time: ", duration)
- ์คํ๊ฒฐ๊ณผ ํ์ต์๊ฐ์ด ๋งค์ฐ ์งง๋ค๋ ์ฅ์ ์ด ์์์. (epoch 1000 ์ผ๋ ํ์ต ์์ ์๊ฐ ์ฝ 38์ด)
- ์ ์ฒ๋ฆฌ ๋ฐ MFCC ๋ฅผ ์ ์ฉํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ก ๋ณํ์์ด ๋ฐ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ค๋ ์ ์ด ํธ๋ฆฌํ์.
2.2.6.2 CNN (Convolutional Nural Network)
- ๋ชจ๋ธ ์ ์ ์ด์
- ๋ณธ์ง์ ์ผ๋ก๋ ๋จ์ํ MLP์ ํ์ฅ์ด์ง๋ง, ์ ๋ ฅ์ธต, ์ปจ๋ณผ๋ฃจ์ ์ธต, ํด๋ง์ธต, ์์ ์ฐ๊ฒฐ๊ณ์ธต์ด ๊ฒฐํฉ๋ ํํ๋ก ๋๋ถ๋ถ์ ๊ฒฝ์ฐ MLP๋ณด๋ค ๋ ์ข์ ์ฑ๋ฅ์ ๋ฐํํ๊ธฐ์ ์ฑํ
โ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ, ํน์ง ์ถ์ถ, ์ ๋กํจ๋ฉ ์ํ
# extract feature ํจ์ ์ฌ์ ์
import numpy as np
max_ped_len = 1287
test_num = 0
def extract_features(file_name):
try:
audio, sample_rate = librosa.load(file_name, res_type = 'kaiser_fast')
mfccs = librosa.feature.mfcc(y=audio, sr = sample_rate, n_mfcc = 40)
pad_width = max_pad_len - mfcc.shape[1]
mfccs = np.pad(mfccs, pad_width = ((0, 0), (0, pad_width)), mode = 'constant')
except Exception as e:
print("Error ๋ฐ์: ", file_name)
return None
return mfccs
import pandas as pd
import os
import librosa
fulldatasetpath = 'C:/AI/final_dataset_500/'
metadata = pd.read_csv("C:/AI/final_500.csv')
features = []
for index, row in metadata.iterrows():
file_name = os.path.join(os.path.abspath(fulldatasetpath) + '/' + str(row["slice_file_name"]))
class_label = row['class_name']
data = extract_features(file_name)
features.append([data, class_label])
featuresdf = pd.DataFrame(features, columns = ['feature', 'class_label'])
print("Finished feature extraction from ', len(featuresdf), ' files')
โก ํ์ต ๋ฐ์ดํฐ reshape
num_rows = 40
num_columns = 1287
num_channels = 1
prnt("train data shape")
print(x_train.shape)
print(x_test.shape)
x_train = x_train.reshape(x_train.shape[0], num_rows, num_columns, num_channels)
x_test = x_test.reshape(x_test.shape[0], num_rows, num_columns, num_channels)
print("\ntrain data reshape ๊ฒฐ๊ณผ")
print(x_train.shape)
print(x_test.shape)
โข ๋ชจ๋ธ ๊ตฌํ
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D, GlobalAveragePooling2D
from keras.optimizers import Adam
from keras.utils import np_utils
from sklearn import metrics
num_labels = yy.shape[1]
filter_size = 2
#CNN๋ชจ๋ธ ๊ตฌํ
model = Sequential()
model.add(Conv2D(filters = 16, kernel_size = 2, input_shape = (num_rows, num_columns, num_channels), activation = 'relu'))
model.add(MaxPooling2D(pool_size = 2))
model.add(Dropout(0.2))
model.add(Conv2D(filters = 32, kernel_size = 2, activation = 'relu'))
model.add(MaxPooling2D(pool_size = 2))
model.add(Dropout(0.2))
model.add(Conv2D(filters = 64, kernel_size = 2, activation = 'relu'))
model.add(MaxPooling2D(pool_size = 2))
model.add(Dropout(0.2))
model.add(Conv2D(filters = 128, kernel_size = 2, activation = 'relu'))
model.add(MaxPooling2D(pool_size = 2))
model.add(Dropout(0.2))
model.add(GlobalAveragePooling2D())
model.add(Dense(num_labels, activation = 'softmax'))
#์ปดํ์ผ
model.compile(loss = 'categorical_crossentropy'
, metrics = ['accuracy']
, optimizer = 'adam')
model.summary()
score = model.evaluate(x_test, y_test, verbose = 1)
accuracy = 100 * score[1]
print('Pre-training accuracy: %.4f%%' % accuracy)
- ๋ชจ๋ธ ์ค๋ช
- 4๊ฐ์ convolution ๊ณ์ธต๊ณผ 4๊ฐ์ Max pooling ๊ณ์ธต์ผ๋ก ๊ตฌ์ฑ
- ๊ฐ layer์ ํ์ฑํํจ์๋ ReLUํจ์, ์ถ๋ ฅ์ธต์ softmaxํจ์๋ฅผ ์ด์ฉ
- drop out ๊ฐ์ 0.2
- ํ์ต ์งํ
- batch 256
- epoch๋ 100, 150,,, 1000 ๊น์ง ๋ค์ํ๊ฒ ์ํํด๋ด
- ํน์ด์ฌํญ
- CNN๋ชจ๋ธ์์๋ ์ธํ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ (3์ฐจ์)์ผ๋ก ๋ชจ๋ ๋์ผํด์ผํจ
- ๊ทธ๋ฌ๋ MFCC ์ ์ฒ๋ฆฌ๊ฐ ์ ์ฉ๋ ๋ฐ์ดํฐ์ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ผ ๋ชจ๋ ๋ค์ํ shape์ ๋ณด์ ํ๊ธฐ์ ๋ชจ๋ ๋์ผํ ํํ๋ก reshape์ด ๋ฐ๋ก ํ์ํ์.
- ๋ฐ๋ผ์ max len = 1287๋ก ์ ๋กํจ๋ฉ์ ์ํํด์ฃผ์์.
- ๊ฒฐ๋ก ์ ์ผ๋ก ๋ฐ์ดํฐ shape๋ ์๋ ํ ์ฒ๋ผ ๋ณํํจ
2.2.6.3 LSTM (Long Short-Term Memory)
- ๋ชจ๋ธ ์ ์ ์ด์
- RNN์ ์ฝ์ ์ผ๋ก ์ง์ ๋๋ Vanishing Gradient Problem์ ๊ฐ์ ํ ๋ชจ๋ธ๋ก, ๋๋ถ๋ถ์ ๊ฒฝ์ฐ์์ RNN๋ณด๋ค ์ข์ ์ฑ๋ฅ์ ๋ณด์ด๋ฏ๋ก ์ฑํ
โ ํ์ต๋ฐ์ดํฐ reshape
print("train data shape")
print(x_train.shape)
print(x_test.shape)
#x_train=x_train.reshape(2176,40,1)
x_train = np.reshape(x_train, (len(x_train), len(x_train[0]), -1))
x_test = np.reshape(x_test, (len(x_test), len(x_test[0]), -1))
#print(y_train.shape)
#print(y_test.shape)
print("\ntrain data reshape ๊ฒฐ๊ณผ")
print(x_train.shape)
print(x_test.shape)
โก ๋ชจ๋ธ ๊ตฌํ
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, Conv2D, MaxPooling2D, GlobalAveragePooling2D
from keras.layers import GRU, LSTM, Embedding # RNN
from keras.optimizers import Adam
from keras.utils import np_utils
from sklearn import metrics
num_labels = y_train.shape[1]
#LSTM ๋ชจ๋ธ ๊ตฌํ
model = Sequential()
model.add(LSTM(256,input_shape=(40,1),return_sequences=False))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
#model.add(TimeDistributed(Dense(vocabulary)))
model.add(Dense(num_labels, activation='softmax'))
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
# Display model architecture summary
model.summary()
- ๋ชจ๋ธ ์ค๋ช
- LSTM ๋ชจ๋ธ์ ์์ ์ฐ๊ฒฐ๊ณ์ธต 5๊ฐ ์ฐ๊ฒฐ
- ๊ฐ ๊ณ์ธต์์ ReLUํจ์, ์ถ๋ ฅ๊ณ์ธต์์ softmaxํจ์๋ฅผ ์ฌ์ฉ
- 5๊ฐ์ Dense
- drop out 0.2
- ๋ค์๊ณผ ๊ฐ์ด ํ์ต ์งํ
- Batch 256
- epoch๋ 100, 150,,,,, 1000 ๊น์ง ๋ค์ํ๊ฒ ์งํํด๋ด
- ํน์ด์ฌํญ
- LSTM๋ชจ๋ธ์ ์์ฐ์ด ์ฒ๋ฆฌ์ ์ฌ์ฉ์, ์ธํ๋ฐ์ดํฐ๋ฅผ ์ซ์ ํํ๋ก ๋ณํํ๊ธฐ์ํด ์ฃผ๋ก ์-ํซ์ธ์ฝ๋ฉ์ ์ ์ฉํ๋ค.
- ์์ MLP๋ชจ๋ธ์์ ์ ์ํ ์ ์ฒ๋ฆฌํจ์ (Extract_feature) ์์ MFCC์ ์ฉ์ ํตํด ์ธํ๋ฐ์ดํฐ๋ฅผ ์ซ์๋ก ๋ณํํ์๊ธฐ์ ๋ณ๋์ ์ธ์ฝ๋ฉ์ ์งํํ์ง ์์๋ค. ๋ค๋ง, ๋ฐ์ดํฐ์ shape๋ง ์ด์ง ๋ฐ๊พธ์ด ์ฃผ์๋ค.
2.2.7 ๋ชจ๋ธ ์ ํ๋ ๋น๊ต ๋ฐ ๋ชจ๋ธ ์ ํ
MLP, CNN, LSTM ๊ฐ๊ฐ epoch 300, eopch 300, eopch 600์์ accuracy ๊ฐ ๊ฐ์ฅ ๋๊ฒ ๋ํ๋ฌ๋ค. ์ ํ๋๋ CNN > MLP > LSTM ์์ผ๋ก ๋์๊ณ , ํ์ต ์๊ฐ์ MLP, LSTM, CNN ์์ผ๋ก ์งง์๋ค. LSTM์ ์ ํ๋๊ฐ 85% ๋ฏธ๋ง์ด๊ณ , ํ์ต์๊ฐ์ MLP ๋๋น ๊ธธ๊ธฐ ๋๋ฌธ์ ๋ชจ๋ธ ์ฑํ์์ ์ ์ธํ๊ณ , ์ฑ๋ฅ์ด ์ข์ง๋ง ์๊ฐ์ด ์ค๋๊ฑธ๋ฆฌ๋ CNN๊ณผ ์ฑ๋ฅ์ด ๋ค์ ๋จ์ด์ง์ง๋ง ํ์ต์๊ฐ์ด ์งง์ MLP ์ค์ ๋ชจ๋ธ์ ์ ํํ๊ธฐ๋ก ํ๋ค.
2.2.7.1 MFCC ๋ณ๊ฒฝ
๊ต์๋๊ป์ ์ธํ ๋ฐ์ดํฐ์ ๊ธธ์ด๊ฐ ๊ธด ๊ฒฝ์ฐ์ ์งง์ ๊ฒฝ์ฐ์ ๊ฒ์ค ์ด๋ ๊ฒ์ด ๋ ์ ํ๋๊ฐ ๋์์ง์ ๋ํ ์ถ๊ฐ ์ฐ๊ตฌ๊ฐ ํ์ํ ๊ฒ์ด๋ผ๋ ์๊ฒฌ์ ์ฃผ์ ง๋ค. ๋ฐ๋ผ์ MFCC ์ ํ๋ ์ ๊ธธ์ด๋ฅผ ๋ณ๊ฒฝํด์ ๋ชจ๋ธ ํ์ต์ ์งํํด๋ณด๊ธฐ๋ก ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก MFCC์์๋ ์ด ํ๋ ์์ ๊ธธ์ด๊ฐ 20~40ms ์ ๋์ด๋ค. ํ๋ ์์ ๊ธธ์ด๊ฐ ๋๋ฌด ๊ธธ๋ฉด ์ฃผํ์ ๋ถ์์์ ์ ๋ขฐ๋๊ฐ ๋จ์ด์ง๋ค. ๋ํ ํ๋ ์์ ๊ธธ์ด๊ฐ ๋๋ฌด ์งง์ผ๋ฉด ํ ํ๋ ์ ๋ด ์ ํธ ๋ณํ๊ฐ ์ปค์ง๊ธฐ ๋๋ฌธ์ ์ข์ง ์์๋ค. ๊ฐ์ฅ ์ข์ ๋ชจ๋ธ MLP ์ CNN ๋ชจ๋ธ ์ค, MFCC ๊ธธ์ด์ ๊ฐ์ ๋ณ๊ฒฝํด์ ๋ ํ์ต์ ์งํดํด ๋ณด์๋ค. MFCC=20์ผ๋์ MFCC=40์ผ๋์ ๋ชจ๋ธ์ ๋น๊ตํ์ฌ ์ต์ข ๋ชจ๋ธ์ ์ ํํ ๊ฒ์ด๋ค.
๋ชจ๋ธ ํ์ต ๊ฒฐ๊ณผ, ์ฐ๋ฆฌ ํ์ ์ต์ข ๋ชจ๋ธ์ MFCC = 40 ์ผ๋, CNN๋ชจ๋ธ์ ์ฌ์ฉํ๊ธฐ๋ก ํ๋ค.
2.2.8 ๊ฒฐ๊ณผ ์์
์ต์ข ์ ํ๋ ๋ชจ๋ธ๋ก ์๋ฆฌ๋ฅผ ๋ถ๋ฅํด ๋ณด๊ฒ ๋ค.
def print_prediction(file_name):
prediction_feature = extract_feature(file_name)
predicted_vector = model.predict_classes(prediction_feature)
predicted_class = le.inverse_transform(predicted_vector)
print("The predicted class is:", predicted_class[0], '\n')
predicted_proba_vector = model.predict_proba(prediction_feature)
predicted_proba = predicted_proba_vector[0]
for i in range(len(predicted_proba)):
category = le.inverse_transform(np.array([i]))
print(category[0], "\t\t : ", format(predicted_proba[i], '.32f') )
filename = 'UrbanSound Dataset sample/audio/100648-1-0-0.wav'
print_prediction(filename)
์๋์ฐจ ์๋ฆฌ๋ฅผ ๋ฌด์ฌํ ์๋์ฐจ ์๋ฆฌ๋ผ๊ณ ๋ถ๋ฅํ ์ ์์๋ค!!
filename = '../Evaluation audio/siren_1.wav'
print_prediction(filename)
๋ค๋ฅธ ๋ฐ์ดํฐ์
์ ์ฌ์ฉํด๋ ๋ฌด์ฌํ ์ฌ์ด๋ ์๋ฆฌ๋ฅผ ์ฌ์ด๋ ์๋ฆฌ๋ก ๊ตฌ๋ณํ ์์์๋ค.
์ฐ๋ฆฌํ์ ์ผ์ ์๋ฆฌ์ผ
2.2.9 ํ๋กํ ํ์ ์ ์
์ฐ๋ฆฌ์ ์ฃผ์ ๋ ์ ์ด์ '์ดํ๋ฆฌ์ผ์ด์ '์ด์ง๋ง, ์ ํ ์๊ฐ ์ด๋ด๋ก ์๋๋ก์ด๋์ Java๋ฅผ ์๋ จ์์ผ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ค์ ๋ก ์ ์ํ๊ธฐ์ ๋ฌด๋ฆฌ๊ฐ ์์๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ ํ์ ์ดํ๋ฆฌ์ผ์ด์ ์ผ๋ก ๋ณด์ผ ์ ์๋ exe ํ์ผ์ ์ ์ํ์ฌ ํ๋กํ ํ์ ์ ์ ์ํ๋ก ํ๊ณ ํ๋ก์ ํธ๋ฅผ ์งํํ์๋ค. python์ผ๋ก ๊ตฌํํ ๋ชจ๋ธ๊ณผ PyQt๋ฅผ ์ฐ๋์์ผ ํ๋กํ ํ์ ์ ์ ์ํ ์ ์์๋ค.
์๋ ๋ฐฉ๋ฒ์ผ๋ก ํ๋กํ ํ์ ์ ์์ ์งํํ๋ค.
ํด๋น ๋ง์ง๋ง ๊ณผ์ ์ ๋ด๊ฐ ์ฐธ์ฌํ ๊ฒ์ด ์๋ ํ์์ ์ํ์ด๊ธฐ์ ์์ธํ ์ฝ๋๋ ์ฒจ๋ถํ์ง ์๊ณ , ์ต์ข ๊ฒฐ๊ณผ๋ฌผ์ ์ ๋ก๋ ํด๋ณด๊ฒ ๋ค.
์ง์ง ์ดํ๋ฆฌ์ผ์ด์ ์ ์๋๋๋ผ๋ ์ด๋ ๊ฒ ํ๋กํ ํ์ ์ผ๋ก ์ ์ํ์ฌ ์ค์ํ์์ ์ด๋ป๊ฒ ์ฌ์ฉ๋ ์ง ์ง์ ๊ตฌํํ์ฌ ๋ฐํํ ์ ์ด ํ์ ๋ํ ๊ธ์ ์์์ ๊ฐ์ฅ ํฐ ์ํฅ์ ๋ผ์น ๊ฒ์ด ์๋๊น ์๊ฐํ๋ค. ๋ณดํต ์ฝ๋๋ฅผ ํตํด ์๋ฆฌ๋ฅผ inputํด์, out๋๋ ๊ฒฐ๊ณผ๊ฐ์ ๋ณด์ฌ์ฃผ๋ ๋ถ๋ฅ์ ๊ฐ๋ฅ์ฑ์ ๋ณด์ฌ์ฃผ์๋๋ฐ, ์ฐ๋ฆฌ ํ์ ์ค์ ๋ก ์๋ฆฌ๋ฅผ ๋ค๋ ค์ฃผ๊ณ , ์ด๋ฅผ ๋ถ๋ฅํ๋ ๊ณผ์ ๊น์ง ๋์์์ ํตํด ๋ณด์ฌ์ฃผ๋ฉด์ ๋ง์ ์ฌ๋๋ค์๊ฒ ์ธ์ ๋ฐ์ ์ ์์๋ ๊ฒ ๊ฐ๋ค.
์ฌ์ฉ์๊ฐ ์๋ฆฌ๋ฅผ ์ ํํ๊ณ , ํด๋น ์๋ฆฌ์ ์ํ๋ ์ง๋ํจํด์ ์ ํํ ์ ์๋๋ก ๋ง๋ค์๋ค. ๋ํ ์ฒญ๊ฐ์ฅ์ ์ธ์ด ์ด๊ฐ์ผ๋ก ์๋ฆฌ๋ฅผ ๋๋ ์ ์๋๋ก ์ง๋์ผ๋ก ๊ตฌํํ๊ณ ์ ํ์ง๋ง, ๋ฐํ๋ผ๋ ํน์ฑ์ ํ๋กํ ํ์ ์ ์ฒญ๊ฐ ๋ฐ ์๊ฐ์ ์ธ ํจ๊ณผ๋ฅผ ์ํด ์--- ์๋ฆฌ๋ฅผ ์ด์ฉํด์ ๊ตฌํํด ๋ณด์๋ค.
3. ๊ธฐ๋ํจ๊ณผ ๋ฐ ์ถํ ์ฐ๊ตฌ ๋ฐฉํฅ
- ๊ธฐ๋ํจ๊ณผ
- ๋ฒ์ฃ ๋ฐ์๋ฅ ์ด ๋์ ์ง์ญ์ ๊ธฐ๊ธฐ๋ฅผ ์ค์นํ์ฌ ๋ฐฉ๋ฒ์ฉ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅ
- ์ด์ดํฐ ์ฐฉ์ฉ์ค์๋ ์ฐจ ๊ฒฝ์ ๋ฐ ์์ง์๋ฆฌ๋ฅผ ๊ฐ์งํ๋ ์๋ฆผ์ ์ฃผ๋ ์ดํ๋ฆฌ์ผ์ด์ ์ผ๋ก ๋ฐ์ ๊ฐ๋ฅ
- ์ฒญ๊ฐ์ฅ์ ์ธ์ ์ํ ์์ค ๋น์ฉ์ ์ ๊ฐํ ์ ์์
- ์๋ฆฌ๋ฅผ ๋ฃ์ง ๋ชปํด์ ์๊ธฐ๋ ์ํ์ ๋ฐฉ์งํ ์ ์์.
- ๋ง์ถคํ ์๋ฆฌ ๋ถ๋ฅ ์์คํ ์ผ๋ก ์ถ์ ์ง ํฅ์ ๊ฐ๋ฅ
- ์ ์กฐ ์ฐ์ ์์์ ์ํ ์ฌ๊ณ ๋ฐ์ ๊ฐ์ง, ๊ฒ์ ์ฐ์ ์์์ ์์ฑ์ธ์, ott ๋ฑ ๋ฏธ๋์ด ์ฐ์ ์์์ ์์ฑ ์ธ์, ๊ธ์ต์ ์์์ ์ฑ๋ด ๋ฑ ๋ค์ํ ์ฐ์ ์์์ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ๋ฌดํํ ์กด์ฌํจ
- ํ๊ณ ๋ฐ ์ถํ ์ฐ๊ตฌ ๋ฐฉํฅ
- ์๋ฆฌ ๋ถ๋ฅ์ ์ ํ๋๋ ์ฃผ๋ณ ์ํฉ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์๊ธฐ์ ๋ ธ์ด์ฆ ๊ด๋ จ ์ฐ๊ตฌ๊ฐ ์ถ๊ฐ๋ก ์งํ์ด ํ์ํ๋ค.
- ์๋ฆฌ๋ฅผ ํ์งํ๋ ๋ง์ดํฌ์ ์ฑ๋ฅ๋ ์ค์ํ๊ฒ ์์ฉํ๋ค.
- ๊ฐ์งํด์ผํ ์๋ฆฌ๊ฐ ๋์๋ค๋ฐ์ ์ผ๋ก ๋ฐ์ํ๋ฉด, ๋ชจ๋ ์๋ฆฌ๋ฅผ ์ธ์ํ๊ธฐ ํ๋ค๋ค๋ ํ๊ณ๊ฐ ์กด์ฌํ๋ค.
- ๋ฐ๋ผ์ ๋์๋ค๋ฐ์ ์ผ๋ก ๋ฐ์ํ๋ ์๋ฆฌ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ชจ๋ธ ์ฑ๋ฅ ๊ฐ์ ์ด ํ์ํ๋ค.
- ์๋ฆฌ์ ์ข ๋ฅ๋ฅผ ๋๋ ค์ ์ ์กฐ, ๊ณต์ , ๋์งํธ ํฌ์ค์ผ์ด, ๊ธ์ต, ๊ฒ์ ๋ฑ ๋ค์ํ ์ฐ์ ์์ ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก ์ฐ๊ตฌ๊ฐ ํ์ํ๋ค.
๋ง์น๋ฉฐ ... :)
๊ธธ๊ณ ๊ธด ํฌ์คํ ์ด ๋๋ฌ๋ค. ๋ง์ง๋ง์ ์ดํ๋ฆฌ์ผ์ด์ ์ ์๋ฒฝํ๊ฒ ๊ตฌํํ์ง๋ชปํ์ง๋ง, ์ด๋ ๊ฒ๋ผ๋ AI๊ฐ ์ฐ์ ์ ์ด๋ป๊ฒ ์ ์ฉ๋์ด ์ฌ์ฉ๋๊ณ , ์ดํ๋ฆฌ์ผ์ด์ ์ ์ด๋ค ๊ธฐ๋ฅ์ผ๋ก ์ ์ฉ๋๋์ง์ ๋ํด์ ๊ณต๋ถํด๋ณผ ์ ์์๋ค. PyQt ํด๋ ์ ์ ํ๊ณ , ์ด๋ฅผ ํตํด ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ ๊ตฌํํ ์ ์๋ค๋ ์ ๋ ์ ์ ํ๋ค.
๋ง์ง๋ง์ผ๋ก,,, ์ง์ง ์ฝ 3๊ฐ์๊ฐ์ ๊ณ ์๋์ ๋ชจ๋ ์ ๋ฐฐ๋ค, ๋ชจ๋ ํ๋ค์ ์ ์น๊ณ ์์ํ ์์ฅ ์ฌ์ง์ ๋ง์ง๋ง์ผ๋ก ํฌ์คํ ๋ง๋ฌด๋ฆฌ์ง๊ฒ๋ค!!!!!!!!!!! ํ๋ณตํ๋ฐ!!!!!!!!!!
๋ ธ๋ ฅ์ ๋ฐฐ์ ํ์ง ์๋๋ค :)