22-T67/keras_multi-attention_multi...

7.1 MiB
Raw Permalink Blame History

In [1]:
import os
os.environ['CUDA_DEVICE_ORDER'] = 'PCB_BUS_ID'
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
In [2]:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
#新增加的两行
from pylab import mpl
# 设置显示中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]

mpl.rcParams["axes.unicode_minus"] = False
In [3]:
data = pd.read_csv('./new_train_data.csv', index_col='date')
# data.drop(columns=['wd'], inplace=True) # 风向还没想好怎么处理
data.head()
Out[3]:
24_PM2.5 24_PM10 24_SO2 24_NO2 24_O3 24_CO 23_PM2.5 23_PM10 23_SO2 23_NO2 ... NH3_resdient NH3_agricultural VOC_industrial VOC_transportation VOC_resdient VOC_power PM2.5_industrial PM2.5_transportation PM2.5_resdient PM2.5_power
date
2015-01-03 01:00:00 136.0 214.0 317.0 38.0 8.0 3.71 114.0 176.0 305.0 38.0 ... 0.033910 0.359273 1.177423 1.084925 0.937173 0.037724 0.926851 0.077715 0.827110 0.436028
2015-01-03 02:00:00 114.0 176.0 305.0 38.0 8.0 3.55 97.0 154.0 306.0 37.0 ... 0.033910 0.359273 1.177423 1.134240 0.937173 0.036215 0.926851 0.081248 0.827110 0.418587
2015-01-03 03:00:00 97.0 154.0 306.0 37.0 7.0 3.51 87.0 141.0 316.0 38.0 ... 0.033910 0.327791 1.177423 1.232869 0.937173 0.035712 0.926851 0.088313 0.827110 0.412773
2015-01-03 04:00:00 87.0 141.0 316.0 38.0 7.0 3.55 85.0 139.0 292.0 37.0 ... 0.033910 0.350014 1.177423 1.273965 0.937173 0.036718 0.926851 0.091256 0.827110 0.424400
2015-01-03 05:00:00 85.0 139.0 292.0 37.0 7.0 3.62 106.0 167.0 316.0 37.0 ... 0.071588 0.388904 1.177423 1.290403 1.978475 0.039736 0.926851 0.092434 1.746121 0.459282

5 rows × 187 columns

In [4]:
import seaborn as sns
In [5]:
out_cols = ['PM2.5', 'PM10', 'SO2', 'NO2', 'O3', 'CO']
feature_cols = [x for x in data.columns if x not in out_cols and x != 'date']
feature_cols = feature_cols[144:]
len(feature_cols), len(out_cols)
Out[5]:
(37, 6)
In [6]:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import tensorflow.keras.backend as K
2023-03-30 09:43:47.876739: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
In [7]:
class TransformerBlock(layers.Layer):
    def __init__(self, embed_dim, num_heads, ff_dim, name, rate=0.1):
        super().__init__()
        self.att = layers.MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim, name=name)
        self.ffn = keras.Sequential(
            [layers.Dense(ff_dim, activation="relu"), layers.Dense(embed_dim),]
        )
        self.layernorm1 = layers.LayerNormalization(epsilon=1e-6)
        self.layernorm2 = layers.LayerNormalization(epsilon=1e-6)
        self.dropout1 = layers.Dropout(rate)
        self.dropout2 = layers.Dropout(rate)

    def call(self, inputs, training):
        attn_output = self.att(inputs, inputs)
        attn_output = self.dropout1(attn_output, training=training)
        out1 = self.layernorm1(inputs + attn_output)
        ffn_output = self.ffn(out1)
        ffn_output = self.dropout2(ffn_output, training=training)
        return self.layernorm2(out1 + ffn_output)
In [8]:
from tensorflow.keras import Model
In [9]:
from tensorflow.keras.initializers import Constant
In [10]:
# Custom loss layer
class CustomMultiLossLayer(layers.Layer):
    def __init__(self, nb_outputs=2, **kwargs):
        self.nb_outputs = nb_outputs
        self.is_placeholder = True
        super(CustomMultiLossLayer, self).__init__(**kwargs)
        
    def build(self, input_shape=None):
        # initialise log_vars
        self.log_vars = []
        for i in range(self.nb_outputs):
            self.log_vars += [self.add_weight(name='log_var' + str(i), shape=(1,),
                                              initializer=tf.initializers.he_normal(), trainable=True)]
        super(CustomMultiLossLayer, self).build(input_shape)

    def multi_loss(self, ys_true, ys_pred):
        assert len(ys_true) == self.nb_outputs and len(ys_pred) == self.nb_outputs
        loss = 0
        for y_true, y_pred, log_var in zip(ys_true, ys_pred, self.log_vars):
            mse = (y_true - y_pred) ** 2.
            pre = K.exp(-log_var[0])
            loss += tf.abs(tf.reduce_logsumexp(pre * mse + log_var[0], axis=-1))
        return K.mean(loss)

    def call(self, inputs):
        ys_true = inputs[:self.nb_outputs]
        ys_pred = inputs[self.nb_outputs:]
        loss = self.multi_loss(ys_true, ys_pred)
        self.add_loss(loss, inputs=inputs)
        # We won't actually use the output.
        return K.concatenate(inputs, -1)
In [11]:
num_heads, ff_dim = 3, 16
In [12]:
def get_prediction_model():
    def build_output(out, out_name):
        self_block = TransformerBlock(64, num_heads, ff_dim, name=f'{out_name}_attn')
        out = self_block(out)
        out = layers.GlobalAveragePooling1D()(out)
        out = layers.Dropout(0.1)(out)
        out = layers.Dense(32, activation="relu")(out)
        # out = layers.Dense(1, name=out_name, activation="sigmoid")(out)
        return out
    inputs = layers.Input(shape=(1,len(feature_cols)), name='input')
    x = layers.Conv1D(filters=64, kernel_size=1, activation='relu')(inputs)
    # x = layers.Dropout(rate=0.1)(x)
    lstm_out = layers.Bidirectional(layers.LSTM(units=64, return_sequences=True))(x)
    lstm_out = layers.Dense(128, activation='relu')(lstm_out)
    transformer_block = TransformerBlock(128, num_heads, ff_dim, name='first_attn')
    out = transformer_block(lstm_out)
    out = layers.GlobalAveragePooling1D()(out)
    out = layers.Dropout(0.1)(out)
    out = layers.Dense(64, activation='relu')(out)
    out = K.expand_dims(out, axis=1)

    pm25 = build_output(out, 'pm25')
    pm10 = build_output(out, 'pm10')
    so2 = build_output(out, 'so2')
    no2 = build_output(out, 'no2')
    o3 = build_output(out, 'o3')
    co = build_output(out, 'co')

    merge = layers.Concatenate(axis=1)([pm25, pm10, so2, no2, o3, co])
    merge = K.expand_dims(merge, axis=1)
    merge_attn = TransformerBlock(32*6, 3, 16, name='last_attn')

    out = merge_attn(merge)
    out = layers.GlobalAveragePooling1D()(out)
    out = layers.Dropout(0.1)(out)

    pm25 = layers.Dense(32, activation='relu')(out)
    pm10 = layers.Dense(32, activation='relu')(out)
    so2 = layers.Dense(32, activation='relu')(out)
    no2 = layers.Dense(32, activation='relu')(out)
    o3 = layers.Dense(32, activation='relu')(out)
    co = layers.Dense(32, activation='relu')(out)

    pm25 = layers.Dense(1, activation='sigmoid', name='pm25')(pm25)
    pm10 = layers.Dense(1, activation='sigmoid', name='pm10')(pm10)
    so2 = layers.Dense(1, activation='sigmoid', name='so2')(so2)
    no2 = layers.Dense(1, activation='sigmoid', name='no2')(no2)
    o3 = layers.Dense(1, activation='sigmoid', name='o3')(o3)
    co = layers.Dense(1, activation='sigmoid', name='co')(co)

    model = Model(inputs=[inputs], outputs=[pm25, pm10, so2, no2, o3, co])
    return model

def get_trainable_model(prediction_model):
    inputs = layers.Input(shape=(1,len(feature_cols)), name='input')
    pm25, pm10, so2, no2, o3, co = prediction_model(inputs)
    pm25_real = layers.Input(shape=(1,), name='pm25_real')
    pm10_real = layers.Input(shape=(1,), name='pm10_real')
    so2_real = layers.Input(shape=(1,), name='so2_real')
    no2_real = layers.Input(shape=(1,), name='no2_real')
    o3_real = layers.Input(shape=(1,), name='o3_real')
    co_real = layers.Input(shape=(1,), name='co_real')
    out = CustomMultiLossLayer(nb_outputs=6)([pm25_real, pm10_real, so2_real, no2_real, o3_real, co_real, pm25, pm10, so2, no2, o3, co])
    return Model([inputs, pm25_real, pm10_real, so2_real, no2_real, o3_real, co_real], out)
In [13]:
use_cols = feature_cols + out_cols
use_data = data[use_cols].dropna()
In [14]:
for col in use_cols:
    use_data[col] = use_data[col].astype('float32')
In [15]:
maxs = use_data.max()
mins = use_data.min()
use_cols = use_data.columns
In [16]:
for col in use_cols:
    # use_data[col] = use_data[col].apply(lambda x: 0 if x < 0 else x)
    # use_data[col] = np.log1p(use_data[col])
    use_data[col] = (use_data[col] - mins[col]) / (maxs[col] - mins[col])
In [17]:
train_data, valid = train_test_split(use_data[use_cols], test_size=0.1, random_state=42, shuffle=True)
valid_data, test_data = train_test_split(valid, test_size=0.5, random_state=42, shuffle=True)
In [18]:
prediction_model = get_prediction_model()
trainable_model = get_trainable_model(prediction_model)
2023-03-30 09:43:54.452903: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcuda.so.1
2023-03-30 09:43:54.512341: E tensorflow/stream_executor/cuda/cuda_driver.cc:328] failed call to cuInit: CUDA_ERROR_INVALID_DEVICE: invalid device ordinal
2023-03-30 09:43:54.512378: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: ubuntu-NF5468M6
2023-03-30 09:43:54.512384: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: ubuntu-NF5468M6
2023-03-30 09:43:54.512489: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:200] libcuda reported version is: 510.47.3
2023-03-30 09:43:54.512510: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:204] kernel reported version is: 510.47.3
2023-03-30 09:43:54.512515: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:310] kernel version seems to match DSO: 510.47.3
2023-03-30 09:43:54.512816: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
In [19]:
prediction_model.summary()
Model: "model"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input (InputLayer)              [(None, 1, 37)]      0                                            
__________________________________________________________________________________________________
conv1d (Conv1D)                 (None, 1, 64)        2432        input[0][0]                      
__________________________________________________________________________________________________
bidirectional (Bidirectional)   (None, 1, 128)       66048       conv1d[0][0]                     
__________________________________________________________________________________________________
dense (Dense)                   (None, 1, 128)       16512       bidirectional[0][0]              
__________________________________________________________________________________________________
transformer_block (TransformerB (None, 1, 128)       202640      dense[0][0]                      
__________________________________________________________________________________________________
global_average_pooling1d (Globa (None, 128)          0           transformer_block[0][0]          
__________________________________________________________________________________________________
dropout_2 (Dropout)             (None, 128)          0           global_average_pooling1d[0][0]   
__________________________________________________________________________________________________
dense_3 (Dense)                 (None, 64)           8256        dropout_2[0][0]                  
__________________________________________________________________________________________________
tf.expand_dims (TFOpLambda)     (None, 1, 64)        0           dense_3[0][0]                    
__________________________________________________________________________________________________
transformer_block_1 (Transforme (None, 1, 64)        52176       tf.expand_dims[0][0]             
__________________________________________________________________________________________________
transformer_block_2 (Transforme (None, 1, 64)        52176       tf.expand_dims[0][0]             
__________________________________________________________________________________________________
transformer_block_3 (Transforme (None, 1, 64)        52176       tf.expand_dims[0][0]             
__________________________________________________________________________________________________
transformer_block_4 (Transforme (None, 1, 64)        52176       tf.expand_dims[0][0]             
__________________________________________________________________________________________________
transformer_block_5 (Transforme (None, 1, 64)        52176       tf.expand_dims[0][0]             
__________________________________________________________________________________________________
transformer_block_6 (Transforme (None, 1, 64)        52176       tf.expand_dims[0][0]             
__________________________________________________________________________________________________
global_average_pooling1d_1 (Glo (None, 64)           0           transformer_block_1[0][0]        
__________________________________________________________________________________________________
global_average_pooling1d_2 (Glo (None, 64)           0           transformer_block_2[0][0]        
__________________________________________________________________________________________________
global_average_pooling1d_3 (Glo (None, 64)           0           transformer_block_3[0][0]        
__________________________________________________________________________________________________
global_average_pooling1d_4 (Glo (None, 64)           0           transformer_block_4[0][0]        
__________________________________________________________________________________________________
global_average_pooling1d_5 (Glo (None, 64)           0           transformer_block_5[0][0]        
__________________________________________________________________________________________________
global_average_pooling1d_6 (Glo (None, 64)           0           transformer_block_6[0][0]        
__________________________________________________________________________________________________
dropout_5 (Dropout)             (None, 64)           0           global_average_pooling1d_1[0][0] 
__________________________________________________________________________________________________
dropout_8 (Dropout)             (None, 64)           0           global_average_pooling1d_2[0][0] 
__________________________________________________________________________________________________
dropout_11 (Dropout)            (None, 64)           0           global_average_pooling1d_3[0][0] 
__________________________________________________________________________________________________
dropout_14 (Dropout)            (None, 64)           0           global_average_pooling1d_4[0][0] 
__________________________________________________________________________________________________
dropout_17 (Dropout)            (None, 64)           0           global_average_pooling1d_5[0][0] 
__________________________________________________________________________________________________
dropout_20 (Dropout)            (None, 64)           0           global_average_pooling1d_6[0][0] 
__________________________________________________________________________________________________
dense_6 (Dense)                 (None, 32)           2080        dropout_5[0][0]                  
__________________________________________________________________________________________________
dense_9 (Dense)                 (None, 32)           2080        dropout_8[0][0]                  
__________________________________________________________________________________________________
dense_12 (Dense)                (None, 32)           2080        dropout_11[0][0]                 
__________________________________________________________________________________________________
dense_15 (Dense)                (None, 32)           2080        dropout_14[0][0]                 
__________________________________________________________________________________________________
dense_18 (Dense)                (None, 32)           2080        dropout_17[0][0]                 
__________________________________________________________________________________________________
dense_21 (Dense)                (None, 32)           2080        dropout_20[0][0]                 
__________________________________________________________________________________________________
concatenate (Concatenate)       (None, 192)          0           dense_6[0][0]                    
                                                                 dense_9[0][0]                    
                                                                 dense_12[0][0]                   
                                                                 dense_15[0][0]                   
                                                                 dense_18[0][0]                   
                                                                 dense_21[0][0]                   
__________________________________________________________________________________________________
tf.expand_dims_1 (TFOpLambda)   (None, 1, 192)       0           concatenate[0][0]                
__________________________________________________________________________________________________
transformer_block_7 (Transforme (None, 1, 192)       451408      tf.expand_dims_1[0][0]           
__________________________________________________________________________________________________
global_average_pooling1d_7 (Glo (None, 192)          0           transformer_block_7[0][0]        
__________________________________________________________________________________________________
dropout_23 (Dropout)            (None, 192)          0           global_average_pooling1d_7[0][0] 
__________________________________________________________________________________________________
dense_24 (Dense)                (None, 32)           6176        dropout_23[0][0]                 
__________________________________________________________________________________________________
dense_25 (Dense)                (None, 32)           6176        dropout_23[0][0]                 
__________________________________________________________________________________________________
dense_26 (Dense)                (None, 32)           6176        dropout_23[0][0]                 
__________________________________________________________________________________________________
dense_27 (Dense)                (None, 32)           6176        dropout_23[0][0]                 
__________________________________________________________________________________________________
dense_28 (Dense)                (None, 32)           6176        dropout_23[0][0]                 
__________________________________________________________________________________________________
dense_29 (Dense)                (None, 32)           6176        dropout_23[0][0]                 
__________________________________________________________________________________________________
pm25 (Dense)                    (None, 1)            33          dense_24[0][0]                   
__________________________________________________________________________________________________
pm10 (Dense)                    (None, 1)            33          dense_25[0][0]                   
__________________________________________________________________________________________________
so2 (Dense)                     (None, 1)            33          dense_26[0][0]                   
__________________________________________________________________________________________________
no2 (Dense)                     (None, 1)            33          dense_27[0][0]                   
__________________________________________________________________________________________________
o3 (Dense)                      (None, 1)            33          dense_28[0][0]                   
__________________________________________________________________________________________________
co (Dense)                      (None, 1)            33          dense_29[0][0]                   
==================================================================================================
Total params: 1,110,086
Trainable params: 1,110,086
Non-trainable params: 0
__________________________________________________________________________________________________
In [20]:
from tensorflow.keras import optimizers
In [21]:
trainable_model.compile(optimizer='adam', loss=None)
In [22]:
X = np.expand_dims(train_data[feature_cols].values, axis=1)
Y = [x for x in train_data[out_cols].values.T]
Y_valid = [x for x in valid_data[out_cols].values.T]
In [23]:
from keras.callbacks import ReduceLROnPlateau
reduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=10, mode='auto')
In [24]:
trainable_model.compile(optimizer='adam', loss=None)
hist = trainable_model.fit([X, Y[0], Y[1], Y[2], Y[3], Y[4], Y[5]], epochs=100, batch_size=64, verbose=1, 
                           validation_data=[np.expand_dims(valid_data[feature_cols].values, axis=1), Y_valid[0], Y_valid[1], Y_valid[2], Y_valid[3], Y_valid[4], Y_valid[5]],
                           callbacks=[reduce_lr]
                           )
2023-03-30 09:44:00.730399: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
2023-03-30 09:44:00.750292: I tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2200000000 Hz
Epoch 1/100
690/690 [==============================] - 22s 20ms/step - loss: 2.0729 - val_loss: 1.2554
Epoch 2/100
690/690 [==============================] - 12s 18ms/step - loss: 0.7311 - val_loss: 0.3496
Epoch 3/100
690/690 [==============================] - 12s 18ms/step - loss: 0.1033 - val_loss: 0.0213
Epoch 4/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0228 - val_loss: 0.0188
Epoch 5/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0224 - val_loss: 0.0237
Epoch 6/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0217 - val_loss: 0.0196
Epoch 7/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0210 - val_loss: 0.0249
Epoch 8/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0214 - val_loss: 0.0212
Epoch 9/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0202 - val_loss: 0.0181
Epoch 10/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0197 - val_loss: 0.0221
Epoch 11/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0197 - val_loss: 0.0189
Epoch 12/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0191 - val_loss: 0.0176
Epoch 13/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0188 - val_loss: 0.0180
Epoch 14/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0185 - val_loss: 0.0176
Epoch 15/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0183 - val_loss: 0.0177
Epoch 16/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0181 - val_loss: 0.0167
Epoch 17/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0182 - val_loss: 0.0171
Epoch 18/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0177 - val_loss: 0.0169
Epoch 19/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0180 - val_loss: 0.0164
Epoch 20/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0173 - val_loss: 0.0163
Epoch 21/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0168 - val_loss: 0.0167
Epoch 22/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0172 - val_loss: 0.0167
Epoch 23/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0169 - val_loss: 0.0151
Epoch 24/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0169 - val_loss: 0.0178
Epoch 25/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0166 - val_loss: 0.0156
Epoch 26/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0163 - val_loss: 0.0170
Epoch 27/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0162 - val_loss: 0.0151
Epoch 28/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0167 - val_loss: 0.0147
Epoch 29/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0165 - val_loss: 0.0155
Epoch 30/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0159 - val_loss: 0.0152
Epoch 31/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0156 - val_loss: 0.0149
Epoch 32/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0161 - val_loss: 0.0150
Epoch 33/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0153 - val_loss: 0.0148
Epoch 34/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0156 - val_loss: 0.0160
Epoch 35/100
690/690 [==============================] - 13s 18ms/step - loss: 0.0153 - val_loss: 0.0164
Epoch 36/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0151 - val_loss: 0.0147
Epoch 37/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0152 - val_loss: 0.0146
Epoch 38/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0152 - val_loss: 0.0144
Epoch 39/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0147 - val_loss: 0.0142
Epoch 40/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0149 - val_loss: 0.0141
Epoch 41/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0147 - val_loss: 0.0156
Epoch 42/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0145 - val_loss: 0.0144
Epoch 43/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0146 - val_loss: 0.0135
Epoch 44/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0143 - val_loss: 0.0184
Epoch 45/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0147 - val_loss: 0.0142
Epoch 46/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0144 - val_loss: 0.0136
Epoch 47/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0143 - val_loss: 0.0134
Epoch 48/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0139 - val_loss: 0.0136
Epoch 49/100
690/690 [==============================] - 12s 17ms/step - loss: 0.0143 - val_loss: 0.0151
Epoch 50/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0139 - val_loss: 0.0144
Epoch 51/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0141 - val_loss: 0.0144
Epoch 52/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0135 - val_loss: 0.0136
Epoch 53/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0136 - val_loss: 0.0137
Epoch 54/100
690/690 [==============================] - 13s 18ms/step - loss: 0.0118 - val_loss: 0.0119
Epoch 55/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0115 - val_loss: 0.0118
Epoch 56/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0114 - val_loss: 0.0118
Epoch 57/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0114 - val_loss: 0.0117
Epoch 58/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0113 - val_loss: 0.0118
Epoch 59/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0112 - val_loss: 0.0118
Epoch 60/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0112 - val_loss: 0.0117
Epoch 61/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0112 - val_loss: 0.0118
Epoch 62/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0111 - val_loss: 0.0117
Epoch 63/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0111 - val_loss: 0.0117
Epoch 64/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0111 - val_loss: 0.0116
Epoch 65/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0110 - val_loss: 0.0115
Epoch 66/100
690/690 [==============================] - 13s 18ms/step - loss: 0.0110 - val_loss: 0.0117
Epoch 67/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0110 - val_loss: 0.0116
Epoch 68/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0110 - val_loss: 0.0116
Epoch 69/100
690/690 [==============================] - 13s 18ms/step - loss: 0.0109 - val_loss: 0.0116
Epoch 70/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0110 - val_loss: 0.0114
Epoch 71/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0109 - val_loss: 0.0115
Epoch 72/100
690/690 [==============================] - 13s 18ms/step - loss: 0.0109 - val_loss: 0.0116
Epoch 73/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0108 - val_loss: 0.0115
Epoch 74/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0108 - val_loss: 0.0115
Epoch 75/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0108 - val_loss: 0.0116
Epoch 76/100
690/690 [==============================] - 13s 18ms/step - loss: 0.0108 - val_loss: 0.0114
Epoch 77/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0107 - val_loss: 0.0115
Epoch 78/100
690/690 [==============================] - 13s 18ms/step - loss: 0.0107 - val_loss: 0.0115
Epoch 79/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0107 - val_loss: 0.0115
Epoch 80/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0107 - val_loss: 0.0115
Epoch 81/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0105 - val_loss: 0.0113
Epoch 82/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 83/100
690/690 [==============================] - 14s 20ms/step - loss: 0.0104 - val_loss: 0.0114
Epoch 84/100
690/690 [==============================] - 14s 21ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 85/100
690/690 [==============================] - 13s 19ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 86/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 87/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 88/100
690/690 [==============================] - 13s 18ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 89/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 90/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 91/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 92/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0103 - val_loss: 0.0113
Epoch 93/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0103 - val_loss: 0.0113
Epoch 94/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0104 - val_loss: 0.0113
Epoch 95/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0103 - val_loss: 0.0113
Epoch 96/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0103 - val_loss: 0.0113
Epoch 97/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0103 - val_loss: 0.0113
Epoch 98/100
690/690 [==============================] - 12s 17ms/step - loss: 0.0103 - val_loss: 0.0113
Epoch 99/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0103 - val_loss: 0.0113
Epoch 100/100
690/690 [==============================] - 12s 18ms/step - loss: 0.0104 - val_loss: 0.0113
In [25]:
prediction_model.save(f'./models/uw_loss_looknow/')
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.
2023-03-30 10:05:02.545274: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
WARNING:absl:Found untraced functions such as first_attn_layer_call_fn, first_attn_layer_call_and_return_conditional_losses, layer_normalization_layer_call_fn, layer_normalization_layer_call_and_return_conditional_losses, layer_normalization_1_layer_call_fn while saving (showing 5 of 450). These functions will not be directly callable after loading.
INFO:tensorflow:Assets written to: ./models/uw_loss_looknow/assets
INFO:tensorflow:Assets written to: ./models/uw_loss_looknow/assets
In [26]:
rst = prediction_model.predict(np.expand_dims(test_data[feature_cols], axis=1))
rst
Out[26]:
[array([[0.05530462],
        [0.15461421],
        [0.06984487],
        ...,
        [0.11500913],
        [0.0667375 ],
        [0.2275947 ]], dtype=float32),
 array([[0.04914668],
        [0.10565668],
        [0.0540773 ],
        ...,
        [0.12981808],
        [0.06497446],
        [0.13074341]], dtype=float32),
 array([[0.0275037 ],
        [0.03192595],
        [0.02210939],
        ...,
        [0.04022893],
        [0.02630579],
        [0.04132178]], dtype=float32),
 array([[0.06796426],
        [0.20642754],
        [0.28993258],
        ...,
        [0.4715118 ],
        [0.09288657],
        [0.5116445 ]], dtype=float32),
 array([[0.25186226],
        [0.35088968],
        [0.09913486],
        ...,
        [0.03776854],
        [0.47971994],
        [0.05172443]], dtype=float32),
 array([[0.06528944],
        [0.12970403],
        [0.08967546],
        ...,
        [0.10639769],
        [0.0641529 ],
        [0.18867406]], dtype=float32)]
In [27]:
[np.exp(K.get_value(log_var[0]))**0.5 for log_var in trainable_model.layers[-1].log_vars]
Out[27]:
[0.9995770752172775,
 0.9998096046393907,
 0.9998504109554951,
 0.9992896477643191,
 0.9997416699046467,
 0.9996395653611235]
In [28]:
pred_rst = pd.DataFrame.from_records(np.squeeze(np.asarray(rst), axis=2).T, columns=out_cols)
In [29]:
real_rst = test_data[out_cols].copy()
In [30]:
for col in out_cols:
    pred_rst[col] = pred_rst[col] * (maxs[col] - mins[col]) + mins[col]
    real_rst[col] = real_rst[col] * (maxs[col] - mins[col]) + mins[col]
In [31]:
y_pred_pm25 = pred_rst['PM2.5'].values.reshape(-1,)
y_pred_pm10 = pred_rst['PM10'].values.reshape(-1,)
y_pred_so2 = pred_rst['SO2'].values.reshape(-1,)
y_pred_no2 = pred_rst['NO2'].values.reshape(-1,)
y_pred_o3 = pred_rst['O3'].values.reshape(-1,)
y_pred_co = pred_rst['CO'].values.reshape(-1,)
y_true_pm25 = real_rst['PM2.5'].values.reshape(-1,)
y_true_pm10 = real_rst['PM10'].values.reshape(-1,)
y_true_so2 = real_rst['SO2'].values.reshape(-1,)
y_true_no2 = real_rst['NO2'].values.reshape(-1,)
y_true_o3 = real_rst['O3'].values.reshape(-1,)
y_true_co = real_rst['CO'].values.reshape(-1,)
In [32]:
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score, mean_absolute_percentage_error
In [33]:
def print_eva(y_true, y_pred, tp):
    MSE = mean_squared_error(y_true, y_pred)
    RMSE = np.sqrt(MSE)
    MAE = mean_absolute_error(y_true, y_pred)
    MAPE = mean_absolute_percentage_error(y_true, y_pred)
    R_2 = r2_score(y_true, y_pred)
    print(f"COL: {tp}, MSE: {format(MSE, '.2E')}", end=',')
    print(f'RMSE: {round(RMSE, 4)}', end=',')
    print(f'MAPE: {round(MAPE, 4) * 100} %', end=',')
    print(f'MAE: {round(MAE, 4)}', end=',')
    print(f'R_2: {round(R_2, 4)}')
    return [MSE, RMSE, MAE, MAPE, R_2]
In [34]:
pm25_eva = print_eva(y_true_pm25, y_pred_pm25, tp='pm25')
pm10_eva = print_eva(y_true_pm10, y_pred_pm10, tp='pm10')
so2_eva = print_eva(y_true_so2, y_pred_so2, tp='so2')
nox_eva = print_eva(y_true_no2, y_pred_no2, tp='no2')
o3_eva = print_eva(y_true_o3, y_pred_o3, tp='o3')
co_eva = print_eva(y_true_co, y_pred_co, tp='co')
COL: pm25, MSE: 6.07E+02,RMSE: 24.63920021057129,MAPE: 47.06000089645386 %,MAE: 17.84910011291504,R_2: 0.7534
COL: pm10, MSE: 2.18E+03,RMSE: 46.695701599121094,MAPE: 38.22999894618988 %,MAE: 32.543701171875,R_2: 0.6114
COL: so2, MSE: 6.40E+02,RMSE: 25.30109977722168,MAPE: 69.72000002861023 %,MAE: 15.265700340270996,R_2: 0.7953
COL: no2, MSE: 1.25E+02,RMSE: 11.198399543762207,MAPE: 23.669999837875366 %,MAE: 8.1274995803833,R_2: 0.7998
COL: o3, MSE: 1.39E+02,RMSE: 11.781700134277344,MAPE: 45.170000195503235 %,MAE: 8.724499702453613,R_2: 0.9443
COL: co, MSE: 9.53E-02,RMSE: 0.30869999527931213,MAPE: 21.150000393390656 %,MAE: 0.22669999301433563,R_2: 0.8096
In [35]:
pd.DataFrame.from_records([pm25_eva, pm10_eva, so2_eva, nox_eva, o3_eva,co_eva], columns=['MSE', 'RMSE', 'MAE', 'MAPE', 'R_2'], index=['PM25', 'PM10', 'SO2', 'NO2', 'O3', 'CO'])
Out[35]:
MSE RMSE MAE MAPE R_2
PM25 607.088562 24.639168 17.849148 0.470577 0.753417
PM10 2180.489258 46.695709 32.543747 0.382252 0.611418
SO2 640.143799 25.301064 15.265686 0.697226 0.795343
NO2 125.403076 11.198352 8.127537 0.236683 0.799830
O3 138.808472 11.781701 8.724504 0.451706 0.944349
CO 0.095273 0.308662 0.226732 0.211459 0.809550
In [36]:
plt.figure(figsize=(16, 9))
plt.plot(pred_rst['PM10'].values[50:150], 'o-', label='pred')
plt.plot(real_rst['PM10'].values[50:150], '*-', label='real')
plt.legend(loc='best')
Out[36]:
<matplotlib.legend.Legend at 0x7f9e107bdc90>
WARNING:matplotlib.font_manager:findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: SimHei
No description has been provided for this image
In [38]:
from statistics import mean
import matplotlib.pyplot as plt
from sklearn.metrics import explained_variance_score,r2_score, median_absolute_error, mean_squared_error, mean_absolute_error
from scipy import stats
import numpy as np
from matplotlib import rcParams
config = {"font.size": 32,"mathtext.fontset":'stix'}
rcParams.update(config)
In [39]:
config = {"font.size": 32,"mathtext.fontset":'stix'}
rcParams.update(config)
In [40]:
def scatter_out_1(x, y, label, name): ## x,y为两个需要做对比分析的两个量。
    # ==========计算评价指标==========
    BIAS = mean(x - y)
    MSE = mean_squared_error(x, y)
    RMSE = np.power(MSE, 0.5)
    R2 = r2_score(x, y)
    MAE = mean_absolute_error(x, y)
    EV = explained_variance_score(x, y)
    print('==========算法评价指标==========')
    print('Explained Variance(EV):', '%.3f' % (EV))
    print('Mean Absolute Error(MAE):', '%.3f' % (MAE))
    print('Mean squared error(MSE):', '%.3f' % (MSE))
    print('Root Mean Squard Error(RMSE):', '%.3f' % (RMSE))
    print('R_squared:', '%.3f' % (R2))
    # ===========Calculate the point density==========
    xy = np.vstack([x, y])
    z = stats.gaussian_kde(xy)(xy)
    # ===========Sort the points by density, so that the densest points are plotted last===========
    idx = z.argsort()
    x, y, z = x[idx], y[idx], z[idx]
    def best_fit_slope_and_intercept(xs, ys):
        m = (((mean(xs) * mean(ys)) - mean(xs * ys)) / ((mean(xs) * mean(xs)) - mean(xs * xs)))
        b = mean(ys) - m * mean(xs)
        return m, b
    m, b = best_fit_slope_and_intercept(x, y)
    regression_line = []
    for a in x:
        regression_line.append((m * a) + b)
    fig,ax=plt.subplots(figsize=(12,9),dpi=400)
    scatter=ax.scatter(x,y,marker='o',c=z*100,s=15,label='LST',cmap='Spectral_r')
    cbar=plt.colorbar(scatter,shrink=1,orientation='vertical',extend='both',pad=0.015,aspect=30,label='Frequency')
    min_value = min(min(x), min(y))
    max_value = max(max(x), max(y))

    plt.plot([min_value-5,max_value+5],[min_value-5,max_value+5],'black',lw=1.5)  # 画的1:1线线的颜色为black线宽为0.8
    plt.plot(x,regression_line,'red',lw=1.5)      # 预测与实测数据之间的回归线
    plt.axis([min_value-5,max_value+5,min_value-5,max_value+5])  # 设置线的范围
    plt.xlabel('Measured %s' % label)
    plt.ylabel('Retrived %s' % label)
    # plt.xticks(fontproperties='Times New Roman')
    # plt.yticks(fontproperties='Times New Roman')


    plt.text(min_value-5 + (max_value-min_value) * 0.05, int(max_value * 0.95), '$N=%.f$' % len(y)) # text的位置需要根据x,y的大小范围进行调整。
    plt.text(min_value-5 + (max_value-min_value) * 0.05, int(max_value * 0.88), '$R^2=%.2f$' % R2)
    plt.text(min_value-5 + (max_value-min_value) * 0.05, int(max_value * 0.81), '$RMSE=%.2f$' % RMSE)
    plt.xlim(min_value-5,max_value+5)                                  # 设置x坐标轴的显示范围
    plt.ylim(min_value-5,max_value+5)                                  # 设置y坐标轴的显示范围
    # file_name = name.split('(')[0].strip()
    plt.savefig(f'./figure/looknow/{name}.png',dpi=800,bbox_inches='tight',pad_inches=0)
    plt.show()
In [41]:
scatter_out_1(real_rst['PM10'].values, pred_rst['PM10'].values, label='$PM_{10}\ (\mu g/m^3$)', name='PM10')
==========算法评价指标==========
Explained Variance(EV): 0.611
Mean Absolute Error(MAE): 32.544
Mean squared error(MSE): 2180.489
Root Mean Squard Error(RMSE): 46.696
R_squared: 0.611
WARNING:matplotlib.font_manager:findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: SimHei
No description has been provided for this image
In [42]:
scatter_out_1(real_rst['PM2.5'].values, pred_rst['PM2.5'].values, label='$PM_{2.5} (\mu g/m^3$)', name='PM25')
==========算法评价指标==========
Explained Variance(EV): 0.754
Mean Absolute Error(MAE): 17.849
Mean squared error(MSE): 607.089
Root Mean Squard Error(RMSE): 24.639
R_squared: 0.753
No description has been provided for this image
In [43]:
scatter_out_1(real_rst['SO2'].values, pred_rst['SO2'].values, label='$SO_2\ (\mu g/m^3)$', name='SO2')
==========算法评价指标==========
Explained Variance(EV): 0.797
Mean Absolute Error(MAE): 15.266
Mean squared error(MSE): 640.144
Root Mean Squard Error(RMSE): 25.301
R_squared: 0.795
No description has been provided for this image
In [44]:
scatter_out_1(real_rst['NO2'].values, pred_rst['NO2'].values, label='$NO_2\ (\mu g/m^3)$', name='NO2')
==========算法评价指标==========
Explained Variance(EV): 0.800
Mean Absolute Error(MAE): 8.128
Mean squared error(MSE): 125.403
Root Mean Squard Error(RMSE): 11.198
R_squared: 0.800
No description has been provided for this image
In [45]:
scatter_out_1(real_rst['O3'], pred_rst['O3'], label='$O_3 \ (\mu g/m^3)$', name='O3')
==========算法评价指标==========
Explained Variance(EV): 0.944
Mean Absolute Error(MAE): 8.725
Mean squared error(MSE): 138.808
Root Mean Squard Error(RMSE): 11.782
R_squared: 0.944
No description has been provided for this image
In [46]:
def scatter_out_2(x, y, name): ## x,y为两个需要做对比分析的两个量。
    # ==========计算评价指标==========
    BIAS = mean(x - y)
    MSE = mean_squared_error(x, y)
    RMSE = np.power(MSE, 0.5)
    R2 = r2_score(x, y)
    MAE = mean_absolute_error(x, y)
    EV = explained_variance_score(x, y)
    print('==========算法评价指标==========')
    print('Explained Variance(EV):', '%.3f' % (EV))
    print('Mean Absolute Error(MAE):', '%.3f' % (MAE))
    print('Mean squared error(MSE):', '%.3f' % (MSE))
    print('Root Mean Squard Error(RMSE):', '%.3f' % (RMSE))
    print('R_squared:', '%.3f' % (R2))
    # ===========Calculate the point density==========
    xy = np.vstack([x, y])
    z = stats.gaussian_kde(xy)(xy)
    # ===========Sort the points by density, so that the densest points are plotted last===========
    idx = z.argsort()
    x, y, z = x[idx], y[idx], z[idx]
    def best_fit_slope_and_intercept(xs, ys):
        m = (((mean(xs) * mean(ys)) - mean(xs * ys)) / ((mean(xs) * mean(xs)) - mean(xs * xs)))
        b = mean(ys) - m * mean(xs)
        return m, b
    m, b = best_fit_slope_and_intercept(x, y)
    regression_line = []
    for a in x:
        regression_line.append((m * a) + b)
    fig,ax=plt.subplots(figsize=(12,9),dpi=400)
    scatter=ax.scatter(x,y,marker='o',c=z*100,s=15,label='LST',cmap='Spectral_r')
    cbar=plt.colorbar(scatter,shrink=1,orientation='vertical',extend='both',pad=0.015,aspect=30,label='frequency')

    plt.plot([0, 6], [0, 6],'black',lw=1.5)  # 画的1:1线线的颜色为black线宽为0.8
    plt.plot(x,regression_line,'red',lw=1.5)      # 预测与实测数据之间的回归线
    plt.axis([0,6,0,6])  # 设置线的范围
    plt.xlabel(f'Measured {name}')
    plt.ylabel(f'Retrived {name}')
    # plt.xticks(fontproperties='Times New Roman')
    # plt.yticks(fontproperties='Times New Roman')


    plt.text(0.3, 5.5, '$N=%.f$' % len(y)) # text的位置需要根据x,y的大小范围进行调整。
    plt.text(0.3, 5.0, '$R^2=%.2f$' % R2)
    plt.text(0.3, 4.5, '$RMSE=%.2f$' % RMSE)
    plt.xlim(0, 6)                                  # 设置x坐标轴的显示范围
    plt.ylim(0, 6)                                  # 设置y坐标轴的显示范围
    file_name = name.split('(')[0].strip()
    plt.savefig(f'./figure/looknow/CO.png',dpi=800,bbox_inches='tight',pad_inches=0)
    plt.show()
In [47]:
scatter_out_2(real_rst['CO'].values, pred_rst['CO'].values, name='$CO \ (mg/m^3)$')
==========算法评价指标==========
Explained Variance(EV): 0.810
Mean Absolute Error(MAE): 0.227
Mean squared error(MSE): 0.095
Root Mean Squard Error(RMSE): 0.309
R_squared: 0.810
No description has been provided for this image
In [ ]: