프로그램
[파이썬] CNN Stacked AutoEncoder 기반의 Time-series Denoising(노이즈 제거)
오디세이99
2023. 7. 18. 10:19
728x90
반응형
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv1D, MaxPooling1D, UpSampling1D
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.callbacks import Callback
# Generate clean sine wave
data_size = 2000 # Increased data size
t = np.linspace(0, 10, data_size)
clean_data = np.sin(t)
# Add uniform noise
noise = np.random.uniform(-0.1, 0.1, data_size)
noisy_data = clean_data + noise
# Normalize data
scaler = MinMaxScaler(feature_range=(0, 1)) # Normalization to [0, 1]
noisy_data = scaler.fit_transform(noisy_data.reshape(-1, 1))
# Reshape the data to a 2D array (necessary for the convolutional autoencoder)
noisy_data = noisy_data.reshape((-1, 1))
# Parameters
input_shape = (None, 1) # Any number of time steps with 1 feature
conv_filters = [32, 16, 8] # three layers with 32, 16, 8 filters
kernel_size = 3 # Size of the convolving kernel
pool_size = 2 # Size of the max pooling windows
# Input
input_layer = Input(shape=input_shape)
# Encoder
x = Conv1D(conv_filters[0], kernel_size, activation='relu', padding='same')(input_layer)
x = MaxPooling1D(pool_size)(x)
x = Conv1D(conv_filters[1], kernel_size, activation='relu', padding='same')(x)
x = MaxPooling1D(pool_size)(x)
x = Conv1D(conv_filters[2], kernel_size, activation='relu', padding='same')(x)
encoded = MaxPooling1D(pool_size)(x)
# Decoder
x = Conv1D(conv_filters[2], kernel_size, activation='relu', padding='same')(encoded)
x = UpSampling1D(pool_size)(x)
x = Conv1D(conv_filters[1], kernel_size, activation='relu', padding='same')(x)
x = UpSampling1D(pool_size)(x)
x = Conv1D(conv_filters[0], kernel_size, activation='relu', padding='same')(x)
x = UpSampling1D(pool_size)(x)
decoded = Conv1D(1, kernel_size, activation='sigmoid', padding='same')(x)
# Autoencoder
autoencoder = Model(input_layer, decoded)
autoencoder.compile(optimizer='adam', loss='mse')
# Print a summary of the model
autoencoder.summary()
class CustomCallback(Callback): # 100 epoch마다 보임
def on_epoch_end(self, epoch, logs=None):
if epoch % 100 == 0: # Check if this is the 100th epoch
print(f"After epoch {epoch}, loss is {logs['loss']}, val_loss is {logs['val_loss']}")
# Split data into train and test sets
train_data, test_data = train_test_split(noisy_data, test_size=0.2, shuffle=False)
# Reshape the data into the format expected by the autoencoder
train_data = train_data.reshape((1, *train_data.shape))
test_data = test_data.reshape((1, *test_data.shape))
# Train the model
history = autoencoder.fit(train_data, train_data, epochs=5000, validation_data=(test_data, test_data), verbose=0, callbacks=[CustomCallback()])
# Predict on the test data
denoised_data = autoencoder.predict(test_data)
# Reshape denoised data to 2D
denoised_data = np.squeeze(denoised_data)
denoised_data = denoised_data.reshape(-1, 1) # Convert to 2D array
# Invert normalization
noisy_data = scaler.inverse_transform(noisy_data)
denoised_data = scaler.inverse_transform(denoised_data)
# Calculate the start and end index of the test data
start_idx = int(0.8 * len(t)) # 80% of the data is used for training
end_idx = start_idx + len(test_data[0]) # The remainder is used for testing
# Plot the original, noisy, and denoised data
plt.figure(figsize=(10, 5))
plt.plot(t, clean_data, label='Original')
plt.plot(t, noisy_data.flatten(), label='Noisy')
plt.plot(t[start_idx:end_idx], denoised_data.flatten(), label='Denoised')
plt.legend()
plt.show()
Model: "model_16"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_17 (InputLayer) [(None, None, 1)] 0
conv1d_112 (Conv1D) (None, None, 32) 128
max_pooling1d_48 (MaxPoolin (None, None, 32) 0
g1D)
conv1d_113 (Conv1D) (None, None, 16) 1552
max_pooling1d_49 (MaxPoolin (None, None, 16) 0
g1D)
conv1d_114 (Conv1D) (None, None, 8) 392
max_pooling1d_50 (MaxPoolin (None, None, 8) 0
g1D)
conv1d_115 (Conv1D) (None, None, 8) 200
up_sampling1d_48 (UpSamplin (None, None, 8) 0
g1D)
conv1d_116 (Conv1D) (None, None, 16) 400
up_sampling1d_49 (UpSamplin (None, None, 16) 0
g1D)
conv1d_117 (Conv1D) (None, None, 32) 1568
up_sampling1d_50 (UpSamplin (None, None, 32) 0
g1D)
conv1d_118 (Conv1D) (None, None, 1) 97
=================================================================
Total params: 4,337
Trainable params: 4,337
Non-trainable params: 0
_________________________________________________________________
After epoch 0, loss is 0.10450702905654907, val_loss is 0.06911314278841019
After epoch 100, loss is 0.003051506821066141, val_loss is 0.0035117107909172773
After epoch 200, loss is 0.0007455113809555769, val_loss is 0.0023853301536291838
After epoch 300, loss is 0.0007021011551842093, val_loss is 0.002051988150924444
After epoch 400, loss is 0.0006892073433846235, val_loss is 0.001874042907729745
After epoch 500, loss is 0.0006814108928665519, val_loss is 0.0017645710613578558
After epoch 600, loss is 0.0006783285061828792, val_loss is 0.0017318697646260262
After epoch 700, loss is 0.0006759861134923995, val_loss is 0.0017360710771754384
After epoch 800, loss is 0.000673560076393187, val_loss is 0.0017452369211241603
After epoch 900, loss is 0.0006985874497331679, val_loss is 0.0017664558254182339
After epoch 1000, loss is 0.0006707648863084614, val_loss is 0.001741617452353239
After epoch 1100, loss is 0.0006916309357620776, val_loss is 0.0017732185078784823
After epoch 1200, loss is 0.0006682073581032455, val_loss is 0.0017409463180229068
After epoch 1300, loss is 0.000674318231176585, val_loss is 0.0017417854396626353
After epoch 1400, loss is 0.0006667553097940981, val_loss is 0.0017520369729027152
After epoch 1500, loss is 0.0006646261899732053, val_loss is 0.0017481767572462559
After epoch 1600, loss is 0.0006694296607747674, val_loss is 0.0017526986775919795
After epoch 1700, loss is 0.0006620572530664504, val_loss is 0.0017598049016669393
After epoch 1800, loss is 0.0006611980497837067, val_loss is 0.0017639095894992352
After epoch 1900, loss is 0.0006602614303119481, val_loss is 0.0017728423699736595
After epoch 2000, loss is 0.0006668126443400979, val_loss is 0.0017951461486518383
After epoch 2100, loss is 0.0006750418106094003, val_loss is 0.0018031119834631681
After epoch 2200, loss is 0.0006573552382178605, val_loss is 0.0017947613960132003
After epoch 2300, loss is 0.0006586895906366408, val_loss is 0.0018061655573546886
After epoch 2400, loss is 0.0006646490073762834, val_loss is 0.0018159964820370078
After epoch 2500, loss is 0.000656965421512723, val_loss is 0.0018387611489742994
After epoch 2600, loss is 0.0006550662219524384, val_loss is 0.00186380953527987
After epoch 2700, loss is 0.0006501793977804482, val_loss is 0.001874843379482627
After epoch 2800, loss is 0.0006549088866449893, val_loss is 0.0018747906433418393
After epoch 2900, loss is 0.0007012670976109803, val_loss is 0.0019860200118273497
After epoch 3000, loss is 0.0006486615748144686, val_loss is 0.0018858775729313493
After epoch 3100, loss is 0.0006473447429016232, val_loss is 0.001890695421025157
After epoch 3200, loss is 0.0006451343651860952, val_loss is 0.0019256609957665205
After epoch 3300, loss is 0.0006439416320063174, val_loss is 0.0019586749840527773
After epoch 3400, loss is 0.0006427128682844341, val_loss is 0.0019668922759592533
After epoch 3500, loss is 0.0006458878633566201, val_loss is 0.0020130136981606483
After epoch 3600, loss is 0.000639669771771878, val_loss is 0.002026270842179656
After epoch 3700, loss is 0.0006386086461134255, val_loss is 0.0020245241466909647
After epoch 3800, loss is 0.0006373562500812113, val_loss is 0.0020193075761198997
After epoch 3900, loss is 0.0006375666125677526, val_loss is 0.002027568407356739
After epoch 4000, loss is 0.0006589865079149604, val_loss is 0.002076950389891863
After epoch 4100, loss is 0.000634072523098439, val_loss is 0.0020566852763295174
After epoch 4200, loss is 0.000635586678981781, val_loss is 0.0020770367700606585
After epoch 4300, loss is 0.0006328367162495852, val_loss is 0.0020998246036469936
After epoch 4400, loss is 0.0006306078284978867, val_loss is 0.0021127136424183846
After epoch 4500, loss is 0.0006279853987507522, val_loss is 0.002122009638696909
After epoch 4600, loss is 0.0006361935520544648, val_loss is 0.002124659949913621
After epoch 4700, loss is 0.0006304665002971888, val_loss is 0.002083962317556143
After epoch 4800, loss is 0.0006321638356894255, val_loss is 0.0021081753075122833
After epoch 4900, loss is 0.0006237715133465827, val_loss is 0.002068204339593649
1/1 [==============================] - 0s 110ms/step
728x90
반응형