Audio Tampering Detection
1. Audio authentication in forensic examination (절차 정의, 하는 이유)
- 오디오 위변조 탐지는 증거로 제출된 오디오에 수행되는 표준 절차
- 오디오 인증은 편집되거나 다시 녹음된 오디오의 흔적을 정확하게 감지하기 위한 절차로, 오디오가 원본인지 변경된 것인지 결정하는 과정
2. Forensic anallyst's task
- 녹음이 조작되었는지 확인하고, 조작 유형(복사 이동, 스플라이싱, 삽입) 및 원본 오디오에서의 조작 위치 식별
- 오디오가 녹음된 환경 또는 녹음 장치 식별
3. Tampering attacks on audio
- 원본 오디오 파일에 스플라이싱, 복사-이동, 삽입 및 삭제 등의 조작이 가해질 수 있음
- 스플라이싱: 하나의 오디오의 짧은 클립이 동일한 오디오의 다른 위치에 복붙되는 것. 다른 환경의 오디오를 교체
4. Focus
- 스플라이싱 위조 탐지에 중점을 두고 있음
- MFCC 및 DRD 특성 추출
- DRD 특성은 시간 및 주파수 대역에서의 에너지 decay 속도에 따라 오디오 신호를 나누어 추출되고, 속도 분포에 대한 기본 통계가 적용됨
5. Machine learning models
- MFCC 및 DRD 특성을 추출하여 KNN, SVM, Decision Tree 및 Random Forest 사용하여 위조 오디오 분류
- 정확도 높이기 위해 ANN, CNN, LSTM과 같은 딥러닝 모델로 train
ANN
# 데이터 전처리 및 모델 구축
from keras import Sequential
from keras.layers import Dense, Dropout
model = Sequential()
# ANN Model
model.add(Dense(units=256, activation='relu', input_dim=1025))
model.add(Dropout(0.4))
model.add(Dense(units=256, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(units=256, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(units=2, activation='softmax'))
# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 모델 학습
model.fit(x_train, y_train, epochs=50, validation_data=(x_test, y_test), batch_size=500)
# 모델 평가
train_loss_score = model.evaluate(x_train, y_train)
test_loss_score = model.evaluate(x_test, y_test)
print(train_loss_score)
print(test_loss_score)
# 모델 예측
y_predicted = model.predict(x_test)
# 혼동 행렬 생성
import tensorflow as tf
y_predicted_labels = [np.argmax(i) for i in y_predicted]
cm = tf.math.confusion_matrix(labels=y_test, predictions=y_predicted_labels)
cm
# 혼동 행렬 시각화
import seaborn as sn
plt.figure(figsize=(10, 7))
sn.heatmap(cm, annot=True, fmt='d')
plt.xlabel('Predicted')
plt.ylabel('Truth')
CNN
# 데이터 전처리
from keras.utils.np_utils import to_categorical
y_train = to_categorical(y_train, num_classes=2)
y_test = to_categorical(y_test, num_classes=2)
# 모델 구축
from keras import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense
model = Sequential()
# CNN Model
model.add(Conv2D(64, kernel_size=5, strides=1, padding="Same", activation="relu", input_shape=(200, 1, 1)))
model.add(MaxPooling2D(padding="same"))
model.add(Conv2D(128, kernel_size=5, strides=1, padding="same", activation="relu"))
model.add(MaxPooling2D(padding="same"))
model.add(Dropout(0.3))
model.add(Flatten())
model.add(Dense(256, activation="relu"))
model.add(Dropout(0.3))
model.add(Dense(512, activation="relu"))
model.add(Dropout(0.3))
model.add(Dense(2, activation="softmax"))
# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 모델 학습
model.fit(x_train, y_train, epochs=50, validation_data=(x_test, y_test), batch_size=500)
# 모델 평가
train_loss_score = model.evaluate(x_train, y_train)
test_loss_score = model.evaluate(x_test, y_test)
print(train_loss_score)
print(test_loss_score)
# 모델 예측
y_predicted = model.predict(x_test)
# 혼동 행렬 생성
import tensorflow as tf
y_predicted_labels = [np.argmax(i) for i in y_predicted]
cm = tf.math.confusion_matrix(labels=y_test, predictions=y_predicted_labels)
cm
# 혼동 행렬 시각화
import seaborn as sn
plt.figure(figsize=(10, 7))
sn.heatmap(cm, annot=True, fmt='d')
plt.xlabel('Predicted')
plt.ylabel('Truth')
LSTM
# Data reshaping for LSTM(3D)
x_train = np.reshape(x_train, (x_train.shape[0], 1, 200, 1))
x_test = np.reshape(x_test, (x_test.shape[0], 1, 200, 1))
x_train.shape, x_test.shape, y_train.shape, y_test.shape
# test data size same for all models
from keras.utils import to_categorical
y_train = to_categorical(y_train, num_classes=2)
y_test = to_categorical(y_test, num_classes=2)
y_train.shape, y_test.shape
# model building
from keras import Sequential
from keras.layers import LSTM, Dense
model = Sequential()
# LSTM Model
model.add(LSTM(200, activation='relu', return_sequences=True, input_shape=(200,1)))
model.add(LSTM(100, activation='relu', return_sequences=True))
model.add(LSTM(50, activation='relu', return_sequences=True))
model.add(LSTM(25, activation='relu'))
model.add(Dense(20, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(2))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=50, validation_data=(x_test, y_test), batch_size=500)
train_loss_score = model.evaluate(x_train, y_train)
test_loss_score = model.evaluate(x_test, y_test)
print(train_loss_score)
print(test_loss_score)
# predict first 50 audios in the test set
y_predicted = model.predict(x_test[50])
import tensorflow as tf
y_predicted_labels = [np.argmax(i) for i in y_predicted]
cm = tf.math.confusion_matrix(labels=y_test, predictions=y_predicted_labels)
cm
import seaborn as sn
plt.figure(figsize=(10, 7))
sn.heatmap(cm, annot=True, fmt='d')
plt.xlabel('Predicted')
plt.ylabel('Truth')
<feature_tatble_DRD>
WAV 파일에서 추출한 특징들을 변수에 저장하고, 나중에 분석 및 시각화를 위해 사용할 수 있도록 테이블 형태로 정리
import os
import numpy as np
from scipy.stats import skew, kurtosis
from scipy.io import wavfile
def feature_table_DRD(directory):
files = [f for f in os.listdir(directory) if f.endswith('.wav')]
num_files = len(files)
xdata_m_t = np.zeros((num_files, 32))
xdata_me_an = np.zeros((num_files, 1))
xdata_st_d = np.zeros((num_files, 1))
xdata_var_an = np.zeros((num_files, 1))
xdata_skew_ness = np.zeros((num_files, 1))
xdata_ku_r = np.zeros((num_files, 1))
for k, file_name in enumerate(files):
full_file_path = os.path.join(directory, file_name)
print(f'Now reading {full_file_path}')
Fs, rec = wavfile.read(full_file_path)
M_t, mb, sd, variance, sb, kur = featurefun_DRD(rec, Fs)
xdata_m_t[k, :] = M_t
xdata_me_an[k, :] = mb
xdata_st_d[k, :] = sd
xdata_var_an[k, :] = variance
xdata_skew_ness[k, :] = sb
xdata_ku_r[k, :] = kur
return xdata_m_t, xdata_me_an, xdata_st_d, xdata_var_an, xdata_skew_ness, xdata_ku_r
def featurefun_DRD(rec, Fs):
# 이 함수는 실제로 정의되어 있지 않아서 주어진 내용만으로는 세부 내용을 알 수 없습니다.
# featurefun_DRD 함수가 정의되어 있다면, 해당 부분을 적절히 채워넣어야 합니다.
# 아래는 임시적으로 구현한 것으로 실제 함수 내용과는 무관합니다.
M_t = np.mean(rec)
mb = np.mean(rec)
sd = np.std(rec)
variance = np.var(rec)
sb = skew(rec)
kur = kurtosis(rec)
return M_t, mb, sd, variance, sb, kur
# 사용 예시
directory_path = '/path/to/your/directory'
xdata_m_t, xdata_me_an, xdata_st_d, xdata_var_an, xdata_skew_ness, xdata_ku_r = feature_table_DRD(directory_path)
<feature_table_MFCC>
MFCC 특성 추출하여 특성 테이블 생성하는 코드(원래 MATLAB 코드였는데 파이썬으로 변환함)
import os
import numpy as np
from python_speech_features import mfcc
from scipy.io import wavfile
def feature_table_mfcc(directory):
files = [f for f in os.listdir(directory) if f.endswith('.wav')]
num_files = len(files)
xdata_mfcc_mb = np.zeros((num_files, 13))
xdata_mfcc_sd = np.zeros((num_files, 13))
xdata_mfcc_kur = np.zeros((num_files, 13))
xdata_mfcc_sb = np.zeros((num_files, 13))
for k, file_name in enumerate(files):
full_file_path = os.path.join(directory, file_name)
print(f'Now reading {full_file_path}')
Fs, rec = wavfile.read(full_file_path)
rec = rec[:, 0]
mfcc_mb, mfcc_sd, mfcc_kur, mfcc_sb = featurefun_MFCC(rec, Fs)
xdata_mfcc_mb[k, :] = mfcc_mb
xdata_mfcc_sd[k, :] = mfcc_sd
xdata_mfcc_kur[k, :] = mfcc_kur
xdata_mfcc_sb[k, :] = mfcc_sb
return xdata_mfcc_mb, xdata_mfcc_sd, xdata_mfcc_kur, xdata_mfcc_sb
def featurefun_MFCC(rec, Fs):
# 이 함수는 실제로 정의되어 있지 않아서 주어진 내용만으로는 세부 내용을 알 수 없습니다.
# featurefun_MFCC 함수가 정의되어 있다면, 해당 부분을 적절히 채워넣어야 합니다.
# 아래는 임시적으로 구현한 것으로 실제 함수 내용과는 무관합니다.
mfcc_feat = mfcc(rec, Fs)
mfcc_mb = np.mean(mfcc_feat, axis=0)
mfcc_sd = np.std(mfcc_feat, axis=0)
mfcc_kur = np.kurtosis(mfcc_feat, axis=0)
mfcc_sb = np.mean(np.abs(mfcc_feat - np.mean(mfcc_feat, axis=0))**3, axis=0) / np.std(mfcc_feat, axis=0)**3
return mfcc_mb, mfcc_sd, mfcc_kur, mfcc_sb
# 사용 예시
directory_path = '/path/to/your/directory'
xdata_mfcc_mb, xdata_mfcc_sd, xdata_mfcc_kur, xdata_mfcc_sb = feature_table_mfcc(directory_path)
DRD 특성 추출하는 MATLAB 함수 ➡️ 파이썬으로 바꿈
- STFT 계산
- Magnitude Spectrum 계산
- magnitude spectrum ➡️ perceptual scale로 변환
- Energy Envelope 추정
- 로컬 피크 검출
- 로컬 피크 중 유효한 decay 시작 및 종료지점 선택
- 최소 제곱법으로 선형 피팅(→DRD 특성 얻음)
- DRD Feature Vector 계산 (DRD 특성 계산하고, 함수 이용하여 평균, 표준편차, 분산, 왜도, 첨도 계산함)
- 최종적으로 features_test1에 DRD 특성 담은 벡터 반환
📌목적: 입력 오디오 신호에서 DRD 특성 추출하고, 이거 통해서 오디오의 decay 속도와 관련된 특성 파악
▸DRD: Decay Rate Distribution
음향 신호의 decay 속도 분포를 나타내는 특징. 주파수별로 음향 신호가 얼마나 빨리 감되는지 분석.
DRD 특징 추출하는 과정에서 음향 신호를 주파수 영역으로 변환한 후, 각 주파수 대역에서의 decay 속도를 계산하여 분포를 나타냄.
import numpy as np
from scipy.signal import spectrogram
from scipy.stats import skew, kurtosis
def featurefun_DRD(rec, Fs):
siglen = len(rec)
wlen = 1024
hop = wlen // 4
fftpt = 1024
win = np.hamming(wlen)
r = int(np.ceil((1 + fftpt) / 2) - 1)
c = int(1 + np.floor((siglen - wlen) / hop))
stft = np.zeros((r, c))
indx = 0
for i in range(c):
rec_win = rec[indx:indx + wlen] * win
R = np.fft.fft(rec_win, fftpt)
stft[:, i] = R[:r]
indx += hop
timevec = np.arange(wlen / 2, wlen / 2 + (c - 1) * hop, hop) / Fs
freqvec = np.arange(0, r) * Fs / fftpt
magSpec = np.abs(stft)
logMagSpec = 10 * np.log10(np.maximum(magSpec, 0.00001))
# ... (이어지는 부분은 그대로 사용)
# 최소 제곱법으로 선형 피팅
p = np.zeros((r4, 2))
f = np.zeros((r4, len(x1[i])))
for i in range(r4):
p[i, :] = np.polyfit(x1[i], y1[i], 1)
f[i, :] = np.polyval(p[i, :], x1[i])
# DRD Feature Vector 계산
Nb = r1
D = np.zeros((Nb, r4))
count2 = 0
for k in range(r4):
for j in range(Nb):
if loc_final[k, 0] == j + 1:
count2 += 1
D[j, count2] = p[k, 0]
# Mean vector m_t
m_t = np.zeros(Nb)
for i in range(Nb):
Np_i = np.count_nonzero(D[i, :])
if Np_i > 0:
m_t[i] = np.sum(D[i, :]) / Np_i
M_t = m_t
# Statistical functions on M_t
mb = np.mean(M_t)
sd = np.std(M_t)
variance = np.var(M_t)
sb = skew(M_t)
kur = kurtosis(M_t)
# DRD feature vector
features_test1 = np.concatenate((M_t, [mb, sd, variance, sb, kur]))
return features_test1
음향 신호(rec) 기반으로 MFCC 특징 추출하는 함수
- STFT: 음향 신호를 STFT 사용하여 주파수 영역으로 변환함. 윈도우 함수(hamming) 사용함. 윈도우 겹치는 방식으로 STFT 계산함
- MelSpectrogram 계산: 주파수 영역에서 Mel 스케일로 변환된 스펙트로그램 계산함. Mel 필터 및 로그 변환 사용함
- MFCC 계산: DCT 사용하여 MFCC 계산함. 13개의 계수 추출함
- MFCC 계수에 대해 평균(md), 표준편차(sd), 점도(kur), 비대칭도(sb) 계산하여 통계적 특징 벡터 얻음
📌MFCC 활용하여 음향 신호의 주파수 특성을 추출하고, 각 계수에 대한 통계적 특징 계산하는 코
import numpy as np
from scipy.fftpack import fft
from scipy.signal import spectrogram
from scipy.stats import skew, kurtosis
def featurefun_mfcc(rec, Fs):
wlen = 1024
hop = wlen // 4
fftpt = 4096
win = np.hamming(wlen)
# Short Time Fourier Transform
_, _, stft = spectrogram(rec, fs=Fs, window=win, nperseg=wlen, noverlap=hop)
# Log of magnitude of spectrum
mag_spec = np.abs(stft)
mag_spec[mag_spec == 0] = 0.00001
log_mag_spec = 10 * np.log10(mag_spec)
# Conversion to perceptual scale
filter_bank = melbank(Fs, fftpt)
mel_spec = np.dot(filter_bank, log_mag_spec)
# MFCC Calculation
log_mel = np.log10(mel_spec)
mel_ceps = dct(log_mel, axis=0)
mfccs = np.abs(mel_ceps[1:14, :])
# Statistical functions on MFCCs
mb = np.mean(mfccs, axis=1)
sd = np.std(mfccs, axis=1)
kur = kurtosis(mfccs, axis=1)
sb = skew(mfccs, axis=1)
return mb, sd, kur, sb
# 임의로 Mel 필터를 생성하는 함수
def melbank(fs, nfft, num_channels=20):
fmin = 0
fmax = fs / 2
mel_points = np.linspace(freq_to_mel(fmin), freq_to_mel(fmax), num_channels + 2)
hz_points = mel_to_freq(mel_points)
bin_points = np.floor((nfft + 1) * hz_points / fs).astype(int)
filter_bank = np.zeros((num_channels, nfft))
for m in range(1, num_channels + 1):
filter_bank[m - 1, bin_points[m - 1]:bin_points[m]] = (bin_points[m] - mel_points[m - 1]) / (bin_points[m] - bin_points[m - 1])
filter_bank[m - 1, bin_points[m]:bin_points[m + 1]] = (mel_points[m + 1] - bin_points[m]) / (bin_points[m + 1] - bin_points[m])
return filter_bank
def freq_to_mel(freq):
return 2595 * np.log10(1 + freq / 700)
def mel_to_freq(mel):
return 700 * (10 ** (mel / 2595) - 1)
# 예시 음향 신호와 샘플링 주파수
example_rec = np.random.rand(44100) # 임의의 음향 신호 (44100Hz 샘플링)
example_fs = 44100
# 특징 추출
example_mb, example_sd, example_kur, example_sb = featurefun_mfcc(example_rec, example_fs)
print("Mean of MFCCs:", example_mb)
print("Standard Deviation of MFCCs:", example_sd)
print("Kurtosis of MFCCs:", example_kur)
print("Skewness of MFCCs:", example_sb)
여기까지는 음성 파일 자체가 조작된거 탐지하는 방법
⬇️화자가 연기를 하고 있는지 알아내는 방법
1. 목표: 음향 정보만을 활용하여 거짓말을 감지하는 머신 러닝 모델 훈련.
2. 특징 추출: MFCC, 에너지 엔벨롭, 및 피치 컨투어를 사용하여 음성 특징을 추출.
3. 모델 훈련
- Gradient Boosting Classifier (GBC)
- Support Vector Machine (SVM)
- Stochastic Gradient Descent (SGD)
4. 학습 분류기: GBC, SVM, SGD로 구성된 다수결 앙상블 학습 분류기 생성
# LieDetection
# GOAL : True/Lie Detection Using Sequences from Video
Create Lie Detection Model using Deep Learning RNN (Final Yr USJP Research Project)
Steps:
01. Extract Keypoints from video using mediapipe fashmesh
02. Train an RNN LSTM DL Model
03. Make real time predictions using sequences
# How it Works
01. Extract Keypoints from mediapipe fashmesh
2. Train a deep neural network with LSTM layers for sequences
3. Perform real time True/ Lie Detection using OpenCV
# Contents of our notebook:
01. Import and Install Dependencies
02. Using Mediapipe (Google's open-source framework)
- Given the original image and obtaining the values through the model.
- Storing the keypoints values in the mediapipe into a variable.
- Calculating blink rate (Euclidean distance).
03. Extract Position Landmarks (Keypoints Values)
04. Setup Folder for Collection
05. Collect Keypoints Values for Training and Testing
06. Preprocess Data and Create Labels and Features
07. Build and Train LSTM Neural Network
08. Make Predictions
09. Save Weights
10. Evaluation using Confusion Matrix and Accuracy
11. Test in Real Time
# Full code details of the video:
[![Watch Here]()](https://www.youtube.com/watch?v=PSu1qiPmiRw)