본문 바로가기
프로그램

[파이썬] CNN Stacked AutoEncoder 기반의 Time-series Denoising(노이즈 제거)

by 오디세이99 2023. 7. 18.
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
반응형

댓글