실습에 필요한 2개의 파일을 다운로드 받습니다.
https://cafe.daum.net/oracleoracle/Sl3Y/600
모델 파일
코드 파일
아주 기본적인 구현 코드이고 개선해야할 부분을 직접 개선해서 쓸 수 있도록 만든 코드
테스트 데이터의 정확도가 84% 인 모델을 내려 받습니다.
화면 구현에 필요한 함수 2가지에 대한 설명
내가 직접 구현하는 화면이라는 제목으로 새 노트를 엽니다.
함수 생성 코딩
upload_sound 함수
#1. 필요한 패키지를 전부 임폴트 합니다.
import tkinter as tk
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Image
import numpy as np
from keras.models import load_model
import cv2
import numpy
import glob
import librosa
#2. upload_image 함수 생성
def upload_image():
try:
file_path=filedialog.askopenfilename() # 윈도우 탐색기를 엽니다.
print(file_path)
# show_classify_button(file_path) # 음성 분류를 하는 함수에 음성 파일을 입력
except:
pass # try 와 except 사이에 문제가 생겨도 그냥 무시해라!
upload_image()
#3. upload_image 의 file_path 를 전역변수로 생성합니다.
# C:/data/cats_dogs/cat_1.wav
#1. 필요한 패키지를 전부 임폴트 합니다.
import tkinter as tk
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Image
import numpy as np
from keras.models import load_model
import cv2
import numpy
import glob
import librosa
#2. upload_sound 함수 생성
def upload_sound():
try:
global file_path
file_path=filedialog.askopenfilename() # 윈도우 탐색기를 엽니다.
except:
pass # try 와 except 사이에 문제가 생겨도 그냥 무시해라!
upload_sound()
print(file_path) # 전역 변수이므로 함수 밖에서 사용할 수 있습니다.
# 또는 다른 함수에서도 사용할 수 있습니다.
#3. sound_classify 함수의 역활은 음성---> 모델 ---> 결과를 출력하는 것입니다. 그런데 편하게 sound_classify 함수를 만들기 위해서 다음의 함수를 미리 만듭니다.
model = load_model('d:\\\\\\\\sound2\\\\\\\\model_keras.h5')
모델을 불러오는 코드는 미리 준비합니다.
↑
음성---> 모델 ---> 결과
↑
음성에서 특징을 뽑아는 함수
#4. 음성에 특징을 뽑아내는 함수 생성
# 4. 음성에 특징을 뽑아내는 함수 생성
# 특징은 소리의 주파수 스팩트럼 데이터 40개 + zero_crossing_rate 1개
def extract_features(audio_samples, sample_rate): # 음성의 특징을 추출하는 함수
extracted_features = np.empty((0, 41, )) # (1,41) 은 아니고 그냥 41개의 값을 받을 비어있는 리스트를 할당하겠다는 뜻
if not isinstance(audio_samples, list):# 리스트가 아니라면
audio_samples = [audio_samples] # 리스트화 해라
for sample in audio_samples: # 진폭 데이터 리스트를 하나씩 가져옵니다.
zero_cross_feat = librosa.feature.zero_crossing_rate(sample).mean() # 음성 신호 파형이 중심축(0) 을 통과하는 횟수
mfccs = librosa.feature.mfcc(y=sample, sr=sample_rate, n_mfcc=40) # <https://youdaeng-com.tistory.com/5>
mfccsscaled = np.mean(mfccs.T,axis=0) # 각 주파수별 평균값을 구합니다.
mfccsscaled = np.append(mfccsscaled, zero_cross_feat)
mfccsscaled = mfccsscaled.reshape(1, 41, ) # 41개의 값을 학습 데이터로 구성합니다. [[293,291,293,...392]]
extracted_features = np.vstack((extracted_features, mfccsscaled)) #[[293,291,293,...392]]
# 41개의 변수를 가진 훈련데이터 419개를 vstack으로 쌓아 만듬.
return extracted_features
#5. file_path 에 들어있는 음성 파일을 숫자로 변환한다.
upload_sound() # 음성을 선택해서 파일위치와 이름을 file_path 에 담는 함수를 실행합니다.
print(file_path) # C:/Users/YYS/Downloads/archive/cats_dogs/train/dog/dog_barking_11.wav
x_test = librosa.load(file_path)[0] # 해당 음성을 숫자로 변환해서 x_test 에 담습니다.
print(x_test)
#6. file_path 에 들어있는 음성 파일의 sample rate (주파수 대역) 정보를 추출합니다.
upload_sound()
wave_rate = librosa.load(file_path)[1]
print(wave_rate)
# 22050
#7. 위에서 얻은 두개의 값을 extract_features 함수에 넣어서 모델에 넣을 41개의 데이터를 출력하시오!
upload_sound() # 소리 데이터 선택하게 하는 윈도우 탐색기 열리게 하고
x_test = librosa.load(file_path)[0] # 그 소리의 진폭값들을 x_test 에 담아내고
wave_rate = librosa.load(file_path)[1] # 그 소리의 대표 주파수를 wave_rate 에 담아내고
x_test_features = extract_features( x_test, wave_rate ) # 소리의 특징을 추출 합니다.
print( x_test_features )
#8. 음성을 모델에 넣고 결과를 출력하는 classify 라는 함수를 생성하시오 !
음성---> 모델 ---> 결과 ↑ 음성에서 특징을 뽑아는 함수
model = load_model('c:\\\\data\\\\model_keras.keras')
print(model)
def classify():
upload_sound() # 음성을 선택해서
x_test = librosa.load(file_path)[0] # 숫자로 변환하고
wave_rate = librosa.load(file_path)[1] # 주파수 대역을 추출해서
x_test_features = extract_features( x_test, wave_rate ) # 41개의 학습 데이터를 만든후에
pred = model.predict( x_test_features.reshape( 1, 41, ) ) # 모델에 넣고 예측해라
print(pred)
classify()
# 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 210ms/step
# [[9.9998152e-01 1.8478753e-05]]
#9. 위에서 출력되는 확률 백터 [[0.11749879 0.8825012 ]] 를 cat 또는 dog 로 출력되게 하시오!
# 음성---> 모델 ---> 결과(cat 또는 dog)
def classify():
upload_sound() # 음성을 선택해서
x_test = librosa.load(file_path)[0] # 숫자로 변환하고
wave_rate = librosa.load(file_path)[1] # 주파수 대역을 추출해서
x_test_features = extract_features( x_test, wave_rate ) # 41개의 학습 데이터를 만든후에
pred = model.predict( x_test_features.reshape( 1, 41, ) ) # 모델에 넣고 예측해라
a = np.argmax(pred) # 가장 큰 원소의 인덱스 번호를 추출합니다.
if a == 0:
print('cat')
else:
print('dog')
classify()
# 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step
# dog
#10. 사용자 인터페이스 배경 판을 생성합니다.
top=tk.Tk() # tkinter(사용자 인터페이스 전문 모듈) 를 객체화 시키겠다.
top.geometry('800x600') # 화면 크기를 결정합니다.
top.title('cat and dog sound Classification') # 맨위에 제목을 붙입니다.
top.configure(background='coral') # 판의 바탕 색깔, 구글에서 #CDCDCD 검색
# top.mainloop()
#11. 사운드를 업로드 하는 버튼을 만듭니다.
upload=Button(top,text="Upload an sound",command=upload_sound,padx=10,pady=5)
upload.configure(background='crimson', foreground='white',font=('arial',10,'bold')) #버튼 색깔
upload.pack(side=BOTTOM, pady=50) # 버튼의 위치 , TOP, BOTTOM, LEFT, RIGHT 를 쓸 수 있음
upload.place(relx=0.2, rely=0.8) # <--- 이 부분 추가
# top.mainloop() # 이 코드는 무조건 맨아래에 하나만 있으면 됩니다.
#12. 분류하는 버튼을 판에 올립니다.
#분류 버튼 구현
classify_bt=Button(top,text="classify an sound",command= classify ,padx=10,pady=5)
classify_bt.configure(background='crimson', foreground='white',font=('arial',10,'bold')) #버튼 색깔
classify_bt.pack(side=TOP, pady=50) # 버튼의 위치 , TOP, BOTTOM, LEFT, RIGHT 를 쓸 수 있음
classify_bt.place(relx=0.6, rely=0.8) # <--- 이 부분 추가
# top.mainloop() # 이 코드는 무조건 맨아래에 하나만 있으면 됩니다.
# ※ 위의 작업을 수행할때 classify 함수 안에 upload_image 함수 실행코드를 주석으로 막습니다.
#13. cat 과 dog 가 화면 판에 출력되게 합니다.
# 1. classify 함수에서 cat 과 dog 를 print 하지 말고 변수에 담게 수정합니다.
def classify():
#upload_sound() # 음성을 선택해서
x_test = librosa.load(file_path)[0] # 숫자로 변환하고
wave_rate = librosa.load(file_path)[1] # 주파수 대역을 추출해서
x_test_features = extract_features( x_test, wave_rate ) # 41개의 학습 데이터를 만든후에
pred = model.predict( x_test_features.reshape( 1, 41, ) ) # 모델에 넣고 예측해라
a = np.argmax(pred) # 가장 큰 원소의 인덱스 번호를 추출합니다.
if a == 0:
sign='cat'
else:
sign='dog'
label.configure(foreground='#011638', text= sign) # 판에 자리잡은 영역에 글씨를 붙입니다.
# 2. 아래쪽에서 화면에 글씨를 출력합니다.
# 화면에 출력할 결과 구현
label = Label( top, background='coral' , font =('arial', 48, 'bold') )
label.pack(side=BOTTOM,expand=True)
top.mainloop()