import fgm tables


In [ ]:
!pip install gdown
!mkdir ./data
import gdown

def data_import():
  ids = {
      "tables_of_fgm.h5":"1XHPF7hUqT-zp__qkGwHg8noRazRnPqb0"
  }

  url = 'https://drive.google.com/uc?id='

  for title, g_id in ids.items(): 
    try:
      output_file = open("/content/data/" + title, 'wb')
      gdown.download(url + g_id, output_file, quiet=False)
    except IOError as e:
      print(e)
    finally:
      output_file.close()
      
data_import()


Requirement already satisfied: gdown in /usr/local/lib/python3.6/dist-packages (3.6.0)
Requirement already satisfied: requests in /usr/local/lib/python3.6/dist-packages (from gdown) (2.18.4)
Requirement already satisfied: six in /usr/local/lib/python3.6/dist-packages (from gdown) (1.11.0)
Requirement already satisfied: tqdm in /usr/local/lib/python3.6/dist-packages (from gdown) (4.28.1)
Requirement already satisfied: idna<2.7,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests->gdown) (2.6)
Requirement already satisfied: urllib3<1.23,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests->gdown) (1.22)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests->gdown) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests->gdown) (2018.11.29)
Downloading...
From: https://drive.google.com/uc?id=1XHPF7hUqT-zp__qkGwHg8noRazRnPqb0
To: <_io.BufferedWriter name='/content/tables_of_fgm.h5'>
982MB [00:06, 153MB/s]

Function libaries

ResBlock

res_block is the backbone of the resnet structure. The resblock has multi branch, bottle neck layer and skip connection build in. This modularized design has made create deep neural network easy.


In [110]:
import tensorflow as tf
import keras
from keras.layers import Dense, Activation, Input, BatchNormalization, Dropout, concatenate
from keras import layers

def res_branch(bi, conv_name_base, bn_name_base, scale, input_tensor, n_neuron, stage, block, bn=False):
    x_1 = Dense(scale * n_neuron, name=conv_name_base + '2a_'+str(bi))(input_tensor)
    if bn:
        x_1 = BatchNormalization(axis=-1, name=bn_name_base + '2a_'+str(bi))(x_1)
    x_1 = Activation('relu')(x_1)
#     x_1 = Dropout(0.)(x_1)
    return x_1

def res_block(input_tensor,scale, n_neuron, stage, block, bn=False,branches=0):
    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

#     scale = 2
    x = Dense(scale * n_neuron, name=conv_name_base + '2a')(input_tensor)
    if bn:
        x = BatchNormalization(axis=-1, name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)
    dp1=0.0
    if dp1 >0:
        x = Droout(0.)(x)
    
    branch_list=[x]
    for i in range(branches-1):
        branch_list.append(res_branch(i,conv_name_base, bn_name_base, scale,input_tensor,n_neuron,stage,block,bn))
    if branches-1 > 0:
        x = Dense(n_neuron, name=conv_name_base + '2b')(concatenate(branch_list,axis=-1))
#         x = Dense(n_neuron, name=conv_name_base + '2b')(layers.add(branch_list))
    else:
        x = Dense(n_neuron, name=conv_name_base + '2b')(x)
    
    if bn:
        x = BatchNormalization(axis=-1, name=bn_name_base + '2b')(x)
    x = layers.add([x, input_tensor])
    x = Activation('relu')(x)
    if dp1 >0:
        x = Droout(0.)(x)

    return x

data_reader

The read_h5_data function read the table from the hdf5 file.

In the FGM case we chose not to scale the input features, since they all falls between 0 and 1. There are a great variety in the output features. In the reaction region close to stoichiometry the gradient in the output properties are great. A good example is the source term for progress variable, which rises from 0 to 1e5. So the output features are first transformed to logrithmic scale and then rearranged between 0 and 1. The outputs are normalised by its variance. This way the output value will be large where the gradient is great. So during training more focus would be put. The same 'focus design' has been put on the loss function selection as well. mse is selected over mae for that the squared error put more weights on the data samples that shows great changes.


In [199]:
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler, StandardScaler


class data_scaler(object):
    def __init__(self):
        self.norm = None
        self.norm_1 = None
        self.std = None
        self.case = None
        self.scale = 1
        self.bias = 1e-20
#         self.bias = 1


        self.switcher = {
            'min_std': 'min_std',
            'std2': 'std2',
            'std_min':'std_min',
            'min': 'min',
            'no':'no',
            'log': 'log',
            'log_min':'log_min',
            'log2': 'log2',
            'tan': 'tan'
        }

    def fit_transform(self, input_data, case):
        self.case = case
        if self.switcher.get(self.case) == 'min_std':
            self.norm = MinMaxScaler()
            self.std = StandardScaler()
            out = self.norm.fit_transform(input_data)
            out = self.std.fit_transform(out)

        if self.switcher.get(self.case) == 'std2':
            self.std = StandardScaler()
            out = self.std.fit_transform(input_data)

        if self.switcher.get(self.case) == 'std_min':
            self.norm = MinMaxScaler()
            self.std = StandardScaler()
            out = self.std.fit_transform(input_data)
            out = self.norm.fit_transform(out)

        if self.switcher.get(self.case) == 'min':
            self.norm = MinMaxScaler()
            out = self.norm.fit_transform(input_data)

        if self.switcher.get(self.case) == 'no':
            self.norm = MinMaxScaler()
            self.std = StandardScaler()
            out = input_data

        if self.switcher.get(self.case) == 'log':
            out = - np.log(np.asarray(input_data / self.scale) + self.bias)
            self.std = StandardScaler()
            out = self.std.fit_transform(out)

        if self.switcher.get(self.case) == 'log_min':
            out = - np.log(np.asarray(input_data / self.scale) + self.bias)
            self.norm = MinMaxScaler()
            out = self.norm.fit_transform(out)

        if self.switcher.get(self.case) == 'log2':
            self.norm = MinMaxScaler()
            self.norm_1 = MinMaxScaler()
            out = self.norm.fit_transform(input_data)
            out = np.log(np.asarray(out) + self.bias)
            out = self.norm_1.fit_transform(out)

        if self.switcher.get(self.case) == 'tan':
            self.norm = MaxAbsScaler()
            self.std = StandardScaler()
            out = self.std.fit_transform(input_data)
            out = self.norm.fit_transform(out)
            out = np.tan(out / (2 * np.pi + self.bias))

        return out

    def transform(self, input_data):
        if self.switcher.get(self.case) == 'min_std':
            out = self.norm.transform(input_data)
            out = self.std.transform(out)

        if self.switcher.get(self.case) == 'std2':
            out = self.std.transform(input_data)

        if self.switcher.get(self.case) == 'std_min':
            out = self.std.transform(input_data)
            out = self.norm.transform(out)

        if self.switcher.get(self.case) == 'min':
            out = self.norm.transform(input_data)

        if self.switcher.get(self.case) == 'no':
            out = input_data

        if self.switcher.get(self.case) == 'log':
            out = - np.log(np.asarray(input_data / self.scale) + self.bias)
            out = self.std.transform(out)

        if self.switcher.get(self.case) == 'log_min':
            out = - np.log(np.asarray(input_data / self.scale) + self.bias)
            out = self.norm.transform(out)

        if self.switcher.get(self.case) == 'log2':
            out = self.norm.transform(input_data)
            out = np.log(np.asarray(out) + self.bias)
            out = self.norm_1.transform(out)

        if self.switcher.get(self.case) == 'tan':
            out = self.std.transform(input_data)
            out = self.norm.transform(out)
            out = np.tan(out / (2 * np.pi + self.bias))

        return out

    def inverse_transform(self, input_data):

        if self.switcher.get(self.case) == 'min_std':
            out = self.std.inverse_transform(input_data)
            out = self.norm.inverse_transform(out)

        if self.switcher.get(self.case) == 'std2':
            out = self.std.inverse_transform(input_data)

        if self.switcher.get(self.case) == 'std_min':
            out = self.norm.inverse_transform(input_data)
            out = self.std.inverse_transform(out)

        if self.switcher.get(self.case) == 'min':
            out = self.norm.inverse_transform(input_data)

        if self.switcher.get(self.case) == 'no':
            out = input_data

        if self.switcher.get(self.case) == 'log':
            out = self.std.inverse_transform(input_data)
            out = (np.exp(-out) - self.bias) * self.scale

        if self.switcher.get(self.case) == 'log_min':
            out = self.norm.inverse_transform(input_data)
            out = (np.exp(-out) - self.bias) * self.scale

        if self.switcher.get(self.case) == 'log2':
            out = self.norm_1.inverse_transform(input_data)
            out = np.exp(out) - self.bias
            out = self.norm.inverse_transform(out)

        if self.switcher.get(self.case) == 'tan':
            out = (2 * np.pi + self.bias) * np.arctan(input_data)
            out = self.norm.inverse_transform(out)
            out = self.std.inverse_transform(out)

        return out
      

def read_h5_data(fileName, input_features, labels):
    df = pd.read_hdf(fileName)
    df = df[df['f']<0.45]
    
    input_df=df[input_features]
    in_scaler = data_scaler()
    input_np = in_scaler.fit_transform(input_df.values,'no')

    label_df=df[labels].clip(0)
#     if 'PVs' in labels:
#       label_df['PVs']=np.log(label_df['PVs']+1)
    out_scaler = data_scaler()
    label_np = out_scaler.fit_transform(label_df.values,'std2')

    return input_np, label_np, df, in_scaler, out_scaler

model

load data


In [200]:
%matplotlib inline
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt


# define the labels
col_labels=['C2H3', 'C2H6', 'CH2', 'H2CN', 'C2H4', 'H2O2', 'C2H', 'CN',
       'heatRelease', 'NCO', 'NNH', 'N2', 'AR', 'psi', 'CO', 'CH4', 'HNCO',
       'CH2OH', 'HCCO', 'CH2CO', 'CH', 'mu', 'C2H2', 'C2H5', 'H2', 'T', 'PVs',
       'O', 'O2', 'N2O', 'C', 'C3H7', 'CH2(S)', 'NH3', 'HO2', 'NO', 'HCO',
       'NO2', 'OH', 'HCNO', 'CH3CHO', 'CH3', 'NH', 'alpha', 'CH3O', 'CO2',
       'CH3OH', 'CH2CHO', 'CH2O', 'C3H8', 'HNO', 'NH2', 'HCN', 'H', 'N', 'H2O',
       'HCCOH', 'HCNN']

# labels = ['T','PVs']
labels = ['T','CH4','O2','CO2','CO','H2O','H2','OH','psi']
# labels = ['CH2OH','HNCO','CH3OH', 'CH2CHO', 'CH2O', 'C3H8', 'HNO', 'NH2', 'HCN']

# labels = np.random.choice(col_labels,9,replace=False).tolist()
labels.append('PVs')

# labels = col_labels

print(labels)

input_features=['f','pv','zeta']

# read in the data
x_input, y_label, df, in_scaler, out_scaler = read_h5_data('./data/tables_of_fgm.h5',input_features=input_features, labels = labels)


['C2H3', 'C2H6', 'CH2', 'H2CN', 'C2H4', 'H2O2', 'C2H', 'CN', 'heatRelease', 'NCO', 'NNH', 'N2', 'AR', 'psi', 'CO', 'CH4', 'HNCO', 'CH2OH', 'HCCO', 'CH2CO', 'CH', 'mu', 'C2H2', 'C2H5', 'H2', 'T', 'PVs', 'O', 'O2', 'N2O', 'C', 'C3H7', 'CH2(S)', 'NH3', 'HO2', 'NO', 'HCO', 'NO2', 'OH', 'HCNO', 'CH3CHO', 'CH3', 'NH', 'alpha', 'CH3O', 'CO2', 'CH3OH', 'CH2CHO', 'CH2O', 'C3H8', 'HNO', 'NH2', 'HCN', 'H', 'N', 'H2O', 'HCCOH', 'HCNN']

build neural network model


In [248]:
from sklearn.model_selection import train_test_split

import tensorflow as tf
from keras.models import Model
from keras.layers import Dense, Input
from keras.callbacks import ModelCheckpoint

# split into train and test data
x_train, x_test, y_train, y_test = train_test_split(x_input,y_label, test_size=0.01)

n_neuron = 10
scale=3
branches=5
# %%
print('set up ANN')
# ANN parameters
dim_input = x_train.shape[1]
dim_label = y_train.shape[1]

batch_norm = False

# This returns a tensor
inputs = Input(shape=(dim_input,),name='input_1')

# a layer instance is callable on a tensor, and returns a tensor
x = Dense(n_neuron, activation='relu')(inputs)

# less then 2 res_block, there will be variance
x = res_block(x, scale, n_neuron, stage=1, block='a', bn=batch_norm,branches=branches)
x = res_block(x, scale, n_neuron, stage=1, block='b', bn=batch_norm,branches=branches)
# x = res_block(x, scale, n_neuron, stage=1, block='c', bn=batch_norm,branches=branches)

x = Dense(500, activation='relu')(x)
predictions = Dense(dim_label, activation='linear', name='output_1')(x)

model = Model(inputs=inputs, outputs=predictions)
model.summary()


set up ANN
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 3)            0                                            
__________________________________________________________________________________________________
dense_104 (Dense)               (None, 10)           40          input_1[0][0]                    
__________________________________________________________________________________________________
res1a_branch2a (Dense)          (None, 30)           330         dense_104[0][0]                  
__________________________________________________________________________________________________
res1a_branch2a_0 (Dense)        (None, 30)           330         dense_104[0][0]                  
__________________________________________________________________________________________________
res1a_branch2a_1 (Dense)        (None, 30)           330         dense_104[0][0]                  
__________________________________________________________________________________________________
res1a_branch2a_2 (Dense)        (None, 30)           330         dense_104[0][0]                  
__________________________________________________________________________________________________
res1a_branch2a_3 (Dense)        (None, 30)           330         dense_104[0][0]                  
__________________________________________________________________________________________________
activation_353 (Activation)     (None, 30)           0           res1a_branch2a[0][0]             
__________________________________________________________________________________________________
activation_354 (Activation)     (None, 30)           0           res1a_branch2a_0[0][0]           
__________________________________________________________________________________________________
activation_355 (Activation)     (None, 30)           0           res1a_branch2a_1[0][0]           
__________________________________________________________________________________________________
activation_356 (Activation)     (None, 30)           0           res1a_branch2a_2[0][0]           
__________________________________________________________________________________________________
activation_357 (Activation)     (None, 30)           0           res1a_branch2a_3[0][0]           
__________________________________________________________________________________________________
concatenate_43 (Concatenate)    (None, 150)          0           activation_353[0][0]             
                                                                 activation_354[0][0]             
                                                                 activation_355[0][0]             
                                                                 activation_356[0][0]             
                                                                 activation_357[0][0]             
__________________________________________________________________________________________________
res1a_branch2b (Dense)          (None, 10)           1510        concatenate_43[0][0]             
__________________________________________________________________________________________________
add_140 (Add)                   (None, 10)           0           res1a_branch2b[0][0]             
                                                                 dense_104[0][0]                  
__________________________________________________________________________________________________
activation_358 (Activation)     (None, 10)           0           add_140[0][0]                    
__________________________________________________________________________________________________
res1b_branch2a (Dense)          (None, 30)           330         activation_358[0][0]             
__________________________________________________________________________________________________
res1b_branch2a_0 (Dense)        (None, 30)           330         activation_358[0][0]             
__________________________________________________________________________________________________
res1b_branch2a_1 (Dense)        (None, 30)           330         activation_358[0][0]             
__________________________________________________________________________________________________
res1b_branch2a_2 (Dense)        (None, 30)           330         activation_358[0][0]             
__________________________________________________________________________________________________
res1b_branch2a_3 (Dense)        (None, 30)           330         activation_358[0][0]             
__________________________________________________________________________________________________
activation_359 (Activation)     (None, 30)           0           res1b_branch2a[0][0]             
__________________________________________________________________________________________________
activation_360 (Activation)     (None, 30)           0           res1b_branch2a_0[0][0]           
__________________________________________________________________________________________________
activation_361 (Activation)     (None, 30)           0           res1b_branch2a_1[0][0]           
__________________________________________________________________________________________________
activation_362 (Activation)     (None, 30)           0           res1b_branch2a_2[0][0]           
__________________________________________________________________________________________________
activation_363 (Activation)     (None, 30)           0           res1b_branch2a_3[0][0]           
__________________________________________________________________________________________________
concatenate_44 (Concatenate)    (None, 150)          0           activation_359[0][0]             
                                                                 activation_360[0][0]             
                                                                 activation_361[0][0]             
                                                                 activation_362[0][0]             
                                                                 activation_363[0][0]             
__________________________________________________________________________________________________
res1b_branch2b (Dense)          (None, 10)           1510        concatenate_44[0][0]             
__________________________________________________________________________________________________
add_141 (Add)                   (None, 10)           0           res1b_branch2b[0][0]             
                                                                 activation_358[0][0]             
__________________________________________________________________________________________________
activation_364 (Activation)     (None, 10)           0           add_141[0][0]                    
__________________________________________________________________________________________________
dense_105 (Dense)               (None, 500)          5500        activation_364[0][0]             
__________________________________________________________________________________________________
output_1 (Dense)                (None, 58)           29058       dense_105[0][0]                  
==================================================================================================
Total params: 40,918
Trainable params: 40,918
Non-trainable params: 0
__________________________________________________________________________________________________

model training

gpu training


In [72]:
import keras.backend as K


def cubic_loss(y_true, y_pred):
    return K.mean(K.square(y_true - y_pred)*K.abs(y_true - y_pred), axis=-1)

def coeff_r2(y_true, y_pred):
    from keras import backend as K
    SS_res =  K.sum(K.square( y_true-y_pred ))
    SS_tot = K.sum(K.square( y_true - K.mean(y_true) ) )
    return ( 1 - SS_res/(SS_tot + K.epsilon()) )

In [247]:
from keras import optimizers

batch_size = 1024*32
epochs = 200
vsplit = 0.1

loss_type='mse'

adam_op = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999,epsilon=1e-8, decay=0.0, amsgrad=True)

model.compile(loss=loss_type, optimizer=adam_op, metrics=[coeff_r2])
# model.compile(loss=cubic_loss, optimizer=adam_op, metrics=['accuracy'])

# checkpoint (save the best model based validate loss)
!mkdir ./tmp
filepath = "./tmp/weights.best.cntk.hdf5"

checkpoint = ModelCheckpoint(filepath,
                             monitor='val_loss',
                             verbose=1,
                             save_best_only=True,
                             mode='min',
                             period=20)

callbacks_list = [checkpoint]

# fit the model
history = model.fit(
    x_train, y_train,
    epochs=epochs,
    batch_size=batch_size,
    validation_split=vsplit,
    verbose=2,
    callbacks=callbacks_list,
    shuffle=True)

model.save('trained_fgm_nn.h5')


mkdir: cannot create directory ‘./tmp’: File exists
Train on 1004379 samples, validate on 111598 samples
Epoch 1/200
 - 12s - loss: 0.0226 - coeff_r2: 0.9769 - val_loss: 0.0215 - val_coeff_r2: 0.9779
Epoch 2/200
 - 1s - loss: 0.0219 - coeff_r2: 0.9777 - val_loss: 0.0215 - val_coeff_r2: 0.9779
Epoch 3/200
 - 1s - loss: 0.0219 - coeff_r2: 0.9778 - val_loss: 0.0212 - val_coeff_r2: 0.9782
Epoch 4/200
 - 1s - loss: 0.0219 - coeff_r2: 0.9778 - val_loss: 0.0213 - val_coeff_r2: 0.9781
Epoch 5/200
 - 1s - loss: 0.0219 - coeff_r2: 0.9777 - val_loss: 0.0215 - val_coeff_r2: 0.9779
Epoch 6/200
 - 1s - loss: 0.0219 - coeff_r2: 0.9776 - val_loss: 0.0212 - val_coeff_r2: 0.9782
Epoch 7/200
 - 1s - loss: 0.0219 - coeff_r2: 0.9777 - val_loss: 0.0215 - val_coeff_r2: 0.9779
Epoch 8/200
 - 1s - loss: 0.0220 - coeff_r2: 0.9776 - val_loss: 0.0212 - val_coeff_r2: 0.9781
Epoch 9/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9779 - val_loss: 0.0211 - val_coeff_r2: 0.9783
Epoch 10/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9780 - val_loss: 0.0212 - val_coeff_r2: 0.9781
Epoch 11/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9779 - val_loss: 0.0213 - val_coeff_r2: 0.9781
Epoch 12/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9780 - val_loss: 0.0214 - val_coeff_r2: 0.9780
Epoch 13/200
 - 1s - loss: 0.0218 - coeff_r2: 0.9778 - val_loss: 0.0214 - val_coeff_r2: 0.9779
Epoch 14/200
 - 1s - loss: 0.0218 - coeff_r2: 0.9779 - val_loss: 0.0211 - val_coeff_r2: 0.9783
Epoch 15/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9780 - val_loss: 0.0212 - val_coeff_r2: 0.9781
Epoch 16/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9779 - val_loss: 0.0213 - val_coeff_r2: 0.9781
Epoch 17/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9779 - val_loss: 0.0211 - val_coeff_r2: 0.9782
Epoch 18/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9779 - val_loss: 0.0211 - val_coeff_r2: 0.9783
Epoch 19/200
 - 1s - loss: 0.0219 - coeff_r2: 0.9778 - val_loss: 0.0210 - val_coeff_r2: 0.9784
Epoch 20/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9779 - val_loss: 0.0211 - val_coeff_r2: 0.9783

Epoch 00020: val_loss improved from inf to 0.02110, saving model to ./tmp/weights.best.cntk.hdf5
Epoch 21/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9779 - val_loss: 0.0211 - val_coeff_r2: 0.9783
Epoch 22/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9780 - val_loss: 0.0210 - val_coeff_r2: 0.9784
Epoch 23/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9780 - val_loss: 0.0213 - val_coeff_r2: 0.9780
Epoch 24/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9781 - val_loss: 0.0213 - val_coeff_r2: 0.9781
Epoch 25/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9781 - val_loss: 0.0211 - val_coeff_r2: 0.9783
Epoch 26/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9779 - val_loss: 0.0211 - val_coeff_r2: 0.9782
Epoch 27/200
 - 1s - loss: 0.0218 - coeff_r2: 0.9779 - val_loss: 0.0218 - val_coeff_r2: 0.9776
Epoch 28/200
 - 1s - loss: 0.0217 - coeff_r2: 0.9780 - val_loss: 0.0212 - val_coeff_r2: 0.9781
Epoch 29/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9780 - val_loss: 0.0210 - val_coeff_r2: 0.9784
Epoch 30/200
 - 1s - loss: 0.0214 - coeff_r2: 0.9782 - val_loss: 0.0209 - val_coeff_r2: 0.9785
Epoch 31/200
 - 1s - loss: 0.0215 - coeff_r2: 0.9782 - val_loss: 0.0211 - val_coeff_r2: 0.9783
Epoch 32/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9781 - val_loss: 0.0212 - val_coeff_r2: 0.9782
Epoch 33/200
 - 1s - loss: 0.0219 - coeff_r2: 0.9778 - val_loss: 0.0210 - val_coeff_r2: 0.9784
Epoch 34/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9779 - val_loss: 0.0211 - val_coeff_r2: 0.9782
Epoch 35/200
 - 1s - loss: 0.0215 - coeff_r2: 0.9781 - val_loss: 0.0213 - val_coeff_r2: 0.9781
Epoch 36/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9781 - val_loss: 0.0210 - val_coeff_r2: 0.9784
Epoch 37/200
 - 1s - loss: 0.0215 - coeff_r2: 0.9781 - val_loss: 0.0211 - val_coeff_r2: 0.9783
Epoch 38/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9780 - val_loss: 0.0211 - val_coeff_r2: 0.9783
Epoch 39/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9781 - val_loss: 0.0209 - val_coeff_r2: 0.9785
Epoch 40/200
 - 1s - loss: 0.0216 - coeff_r2: 0.9781 - val_loss: 0.0212 - val_coeff_r2: 0.9781

Epoch 00040: val_loss did not improve from 0.02110
Epoch 41/200
 - 1s - loss: 0.0218 - coeff_r2: 0.9779 - val_loss: 0.0212 - val_coeff_r2: 0.9782
Epoch 42/200
 - 1s - loss: 0.0215 - coeff_r2: 0.9781 - val_loss: 0.0215 - val_coeff_r2: 0.9779
Epoch 43/200
 - 1s - loss: 0.0218 - coeff_r2: 0.9778 - val_loss: 0.0210 - val_coeff_r2: 0.9784
Epoch 44/200
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-247-c2665536867e> in <module>
     33     verbose=2,
     34     callbacks=callbacks_list,
---> 35     shuffle=True)
     36 
     37 model.save('trained_fgm_nn.h5')

~/anaconda3/envs/my_dev/lib/python3.6/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
   1037                                         initial_epoch=initial_epoch,
   1038                                         steps_per_epoch=steps_per_epoch,
-> 1039                                         validation_steps=validation_steps)
   1040 
   1041     def evaluate(self, x=None, y=None,

~/anaconda3/envs/my_dev/lib/python3.6/site-packages/keras/engine/training_arrays.py in fit_loop(model, f, ins, out_labels, batch_size, epochs, verbose, callbacks, val_f, val_ins, shuffle, callback_metrics, initial_epoch, steps_per_epoch, validation_steps)
    185                             ins[:-1], batch_ids) + [ins[-1]]
    186                     else:
--> 187                         ins_batch = slice_arrays(ins, batch_ids)
    188                 except TypeError:
    189                     raise TypeError('TypeError while preparing batch. '

~/anaconda3/envs/my_dev/lib/python3.6/site-packages/keras/utils/generic_utils.py in slice_arrays(arrays, start, stop)
    524             if hasattr(start, 'shape'):
    525                 start = start.tolist()
--> 526             return [None if x is None else x[start] for x in arrays]
    527         else:
    528             return [None if x is None else x[start:stop] for x in arrays]

~/anaconda3/envs/my_dev/lib/python3.6/site-packages/keras/utils/generic_utils.py in <listcomp>(.0)
    524             if hasattr(start, 'shape'):
    525                 start = start.tolist()
--> 526             return [None if x is None else x[start] for x in arrays]
    527         else:
    528             return [None if x is None else x[start:stop] for x in arrays]

KeyboardInterrupt: 

TPU training


In [ ]:
import os


batch_size = 1024*128
epochs = 100
vsplit = 0.2

tpu_model = tf.contrib.tpu.keras_to_tpu_model(
    model,
    strategy=tf.contrib.tpu.TPUDistributionStrategy(
        tf.contrib.cluster_resolver.TPUClusterResolver(tpu='grpc://' + os.environ['COLAB_TPU_ADDR'])
    )
)

tpu_model.compile(
    optimizer=tf.train.AdamOptimizer(learning_rate=1e-4),
    loss=tf.keras.losses.mae,
    metrics=['accuracy']
)


tpu_model.fit(
    X_train,y_train,
    epochs=epochs,
    batch_size=batch_size,
    validation_split=vsplit
)

Training loss plot


In [243]:
fig = plt.figure()
plt.semilogy(history.history['loss'])
if vsplit:
    plt.semilogy(history.history['val_loss'])
plt.title(loss_type)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper right')
plt.show()


Inference test

prepare frontend for plotting


In [75]:
#@title import plotly
import plotly.plotly as py
import numpy as np
from plotly.offline import init_notebook_mode, iplot
# from plotly.graph_objs import Contours, Histogram2dContour, Marker, Scatter
import plotly.graph_objs as go

def configure_plotly_browser_state():
  import IPython
  display(IPython.core.display.HTML('''
        <script src="/static/components/requirejs/require.js"></script>
        <script>
          requirejs.config({
            paths: {
              base: '/static/base',
              plotly: 'https://cdn.plot.ly/plotly-1.5.1.min.js?noext',
            },
          });
        </script>
        '''))

prepare data for plotting

TPU data prepare


In [25]:
cpu_model = tpu_model.sync_to_cpu()
predict_val=cpu_model.predict(X_test)

X_test_df = pd.DataFrame(in_scaler.inverse_transform(X_test),columns=input_features)
y_test_df = pd.DataFrame(out_scaler.inverse_transform(y_test),columns=labels)

predict_val = model.predict(X_test)
predict_df = pd.DataFrame(out_scaler.inverse_transform(predict_val), columns=labels)

test_data=pd.concat([X_test_df,y_test_df],axis=1)
pred_data=pd.concat([X_test_df,predict_df],axis=1)

test_data.to_hdf('sim_check.H5',key='test')
pred_data.to_hdf('sim_check.H5',key='pred')

df_test=pd.read_hdf('sim_check.H5',key='test')
df_pred=pd.read_hdf('sim_check.H5',key='pred')
zeta_level=list(set(df_test['zeta']))
zeta_level.sort()


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-25-d05c976572f2> in <module>
----> 1 cpu_model = tpu_model.sync_to_cpu()
      2 predict_val=cpu_model.predict(X_test)
      3 
      4 X_test_df = pd.DataFrame(in_scaler.inverse_transform(X_test),columns=input_features)
      5 y_test_df = pd.DataFrame(out_scaler.inverse_transform(y_test),columns=labels)

NameError: name 'tpu_model' is not defined

GPU data prepare


In [222]:
model.load_weights("./tmp/weights.best.cntk.hdf5")

x_test_df = pd.DataFrame(in_scaler.inverse_transform(x_test),columns=input_features)
y_test_df = pd.DataFrame(out_scaler.inverse_transform(y_test),columns=labels)

predict_val = model.predict(x_test,batch_size=1024*8)
predict_df = pd.DataFrame(out_scaler.inverse_transform(predict_val), columns=labels)

test_data=pd.concat([x_test_df,y_test_df],axis=1)
pred_data=pd.concat([x_test_df,predict_df],axis=1)

!rm sim_check.h5
test_data.to_hdf('sim_check.h5',key='test')
pred_data.to_hdf('sim_check.h5',key='pred')

df_test=pd.read_hdf('sim_check.h5',key='test')
df_pred=pd.read_hdf('sim_check.h5',key='pred')

zeta_level=list(set(df_test['zeta']))
zeta_level.sort()

interactive plot


In [227]:
#@title Default title text
# species = 'PVs' #@param {type:"string"}
species = np.random.choice(labels)
# configure_plotly_browser_state()
# init_notebook_mode(connected=False)

from sklearn.metrics import r2_score


df_t=df_test.loc[df_test['zeta']==zeta_level[5]].sample(frac=0.5)
# df_p=df_pred.loc[df_pred['zeta']==zeta_level[1]].sample(frac=0.1)
df_p=df_pred.loc[df_t.index]
error=df_p[species]-df_t[species]
r2=round(r2_score(df_p[species],df_t[species]),4)
fig_db = {
    'data': [       
        {'name':'test data from table',
         'x': df_t['f'],
         'y': df_t['pv'],
         'z': df_t[species],
         'type':'scatter3d', 
        'mode': 'markers',
          'marker':{
              'size':1
          }
        },
        {'name':'prediction from neural networks',
         'x': df_p['f'],
         'y': df_p['pv'],
         'z': df_p[species],
         'type':'scatter3d', 
        'mode': 'markers',
          'marker':{
              'size':1
          },
        },
        {'name':'error in difference',
         'x': df_p['f'],
         'y': df_p['pv'],
         'z': error,
         'type':'scatter3d', 
         'mode': 'markers',
          'marker':{
              'size':1
          },
         }       
    ],
    'layout': {
        'scene':{
            'xaxis': {'title':'mixture fraction'},
            'yaxis': {'title':'progress variable'},
            'zaxis': {'title': species+'_r2:'+str(r2)}
                 }
    }
}
# iplot(fig_db, filename='multiple-scatter')
iplot(fig_db)
print(species,r2)


HCCOH 0.9908

In [225]:
df_p['HNO']


Out[225]:
7439     6.637201e-10
4115     6.110275e-10
5666     4.434435e-10
1360     3.476686e-10
10429    3.929451e-10
1525     2.402853e-10
10161    3.281936e-10
5254     1.965035e-10
4668     4.564958e-10
4814     7.894504e-11
9009     6.995772e-10
4275     2.042588e-09
1846     1.010142e-10
3080     3.708507e-10
7515     3.446403e-10
4626     5.336014e-10
3998     7.704517e-10
10586    8.493684e-10
2469     8.434011e-11
8676     2.274323e-10
210      6.284249e-10
6150     1.970245e-09
7744     1.041587e-09
468      1.511511e-10
2179    -4.123996e-11
5755     3.018803e-10
2216    -6.337348e-11
9680     9.579471e-12
8636     7.560247e-10
2887     1.750237e-10
             ...     
1550     8.563383e-11
6831     2.066853e-09
7699     1.110051e-12
9235     7.832048e-11
5776     4.230535e-10
289      7.532306e-10
10167    6.899540e-10
4500     2.745467e-10
7223     1.184324e-09
10483    5.083916e-11
9339     2.717981e-10
8398    -5.417073e-11
4695     8.368586e-11
6970     1.314812e-09
8512     1.023175e-09
8744     2.828673e-10
5075     4.448311e-10
8240    -5.943196e-12
3311     1.307491e-09
3399     2.234745e-11
8042     8.746897e-10
6453     1.623367e-09
5886     1.168451e-10
5120     2.064057e-10
8058     3.407174e-10
1008     2.455609e-10
8340     7.762123e-10
7522     1.149367e-09
4039     5.209612e-10
4965     1.666638e-09
Name: HNO, Length: 541, dtype: float32

In [138]:
%run -i k2tf.py --input_model='trained_fgm_nn.h5' --output_model='exported/fgm.pb'


---------------------------------------------------------------------------
DuplicateFlagError                        Traceback (most recent call last)
~/repos/combustionML/FPV_ANN/k2tf.py in <module>
     25 FLAGS = flags.FLAGS
     26 
---> 27 flags.DEFINE_string('input_model', None, 'Path to the input model.')
     28 flags.DEFINE_string('input_model_json', None, 'Path to the input model '
     29                                               'architecture in json format.')

~/anaconda3/envs/my_dev/lib/python3.6/site-packages/absl/flags/_defines.py in DEFINE_string(name, default, help, flag_values, **args)
    239   parser = _argument_parser.ArgumentParser()
    240   serializer = _argument_parser.ArgumentSerializer()
--> 241   DEFINE(parser, name, default, help, flag_values, serializer, **args)
    242 
    243 

~/anaconda3/envs/my_dev/lib/python3.6/site-packages/absl/flags/_defines.py in DEFINE(parser, name, default, help, flag_values, serializer, module_name, **args)
     80   """
     81   DEFINE_flag(_flag.Flag(parser, serializer, name, default, help, **args),
---> 82               flag_values, module_name)
     83 
     84 

~/anaconda3/envs/my_dev/lib/python3.6/site-packages/absl/flags/_defines.py in DEFINE_flag(flag, flag_values, module_name)
    102   # Copying the reference to flag_values prevents pychecker warnings.
    103   fv = flag_values
--> 104   fv[flag.name] = flag
    105   # Tell flag_values who's defining the flag.
    106   if module_name:

~/anaconda3/envs/my_dev/lib/python3.6/site-packages/absl/flags/_flagvalues.py in __setitem__(self, name, flag)
    425         # module is simply being imported a subsequent time.
    426         return
--> 427       raise _exceptions.DuplicateFlagError.from_flag(name, self)
    428     short_name = flag.short_name
    429     # If a new flag overrides an old one, we need to cleanup the old flag's

DuplicateFlagError: The flag 'input_model' is defined twice. First from k2tf.py, Second from k2tf.py.  Description from first occurrence: Path to the input model.

In [ ]: