Esempio n. 1
0
def solve_Multiscale_PDE(R):
    log_out_path = R['FolderName']  # 将路径从字典 R 中提取出来
    if not os.path.exists(log_out_path):  # 判断路径是否已经存在
        os.mkdir(log_out_path)  # 无 log_out_path 路径,创建一个 log_out_path 路径

    outfile_name1 = '%s%s.txt' % ('log2', 'train')
    log_fileout_NN = open(os.path.join(log_out_path, outfile_name1),
                          'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件
    dictionary_out2file(R,
                        log_fileout_NN,
                        actName2normal=R['act_name2NN1'],
                        actName2scale=R['act_name2NN2'])

    # laplace 问题需要的设置
    batchsize_it = R['batch_size2interior']
    batchsize_bd = R['batch_size2boundary']
    bd_penalty_init = R[
        'init_boundary_penalty']  # Regularization parameter for boundary conditions
    lr_decay = R['learning_rate_decay']
    learning_rate = R['learning_rate']
    init_penalty2powU = R['balance2solus']
    hidden2normal = R['hidden2normal']
    hidden2scale = R['hidden2scale']
    wb_regular = R[
        'regular_weight_biases']  # Regularization parameter for weights and biases

    # ------- set the problem ---------
    input_dim = R['input_dim']
    out_dim = R['output_dim']

    act_func1 = R['act_name2NN1']
    act_func2 = R['act_name2NN2']

    region_l = 0.0
    region_r = 1.0
    if R['PDE_type'] == 'general_laplace':
        # -laplace u = f
        region_l = 0.0
        region_r = 1.0
        f, u_true, u_left, u_right = laplace_eqs1d.get_laplace_infos(
            input_dim=input_dim,
            out_dim=out_dim,
            left_bottom=region_l,
            right_top=region_r,
            laplace_name=R['equa_name'])
    elif R['PDE_type'] == 'p_laplace':
        # 求解如下方程, A_eps(x) 震荡的比较厉害,具有多个尺度
        #       d      ****         d         ****
        #   -  ----   |  A_eps(x)* ---- u_eps(x) |  =f(x), x \in R^n
        #       dx     ****         dx        ****
        # 问题区域,每个方向设置为一样的长度。等网格划分,对于二维是方形区域
        p_index = R['order2laplace']
        epsilon = R['epsilon']
        if 2 == p_index:
            region_l = 0.0
            region_r = 1.0
            u_true, f, A_eps, u_left, u_right = pLaplace_eqs1d.get_infos_2laplace(
                in_dim=input_dim,
                out_dim=out_dim,
                region_a=region_l,
                region_b=region_r,
                p=p_index,
                eps=epsilon)
        elif 3 == p_index:
            region_l = 0.0
            region_r = 1.0
            u_true, f, A_eps, u_left, u_right = pLaplace_eqs1d.get_infos_3laplace(
                in_dim=input_dim,
                out_dim=out_dim,
                region_a=region_l,
                region_b=region_r,
                p=p_index,
                eps=epsilon)
        elif 5 == p_index:
            region_l = 0.0
            region_r = 1.0
            u_true, f, A_eps, u_left, u_right = pLaplace_eqs1d.get_infos_5laplace(
                in_dim=input_dim,
                out_dim=out_dim,
                region_a=region_l,
                region_b=region_r,
                p=p_index,
                eps=epsilon)
        elif 8 == p_index:
            region_l = 0.0
            region_r = 1.0
            u_true, f, A_eps, u_left, u_right = pLaplace_eqs1d.get_infos_8laplace(
                in_dim=input_dim,
                out_dim=out_dim,
                region_a=region_l,
                region_b=region_r,
                p=p_index,
                eps=epsilon)
        else:
            region_l = 0.0
            region_r = 1.0
            u_true, f, A_eps, u_left, u_right = pLaplace_eqs1d.get_infos_pLaplace(
                in_dim=input_dim,
                out_dim=out_dim,
                region_a=region_l,
                region_b=region_r,
                p=p_index,
                eps=epsilon,
                eqs_name=R['equa_name'])

    # 初始化权重和和偏置的模式
    if R['weight_biases_model'] == 'general_model':
        flag_normal = 'WB_NN2normal'
        flag_scale = 'WB_NN2scale'
        # Weights, Biases = PDE_DNN_base.Initial_DNN2different_hidden(input_dim, out_dim, hidden_layers, flag)
        # Weights, Biases = laplace_DNN1d_base.initialize_NN_xavier(input_dim, out_dim, hidden_layers, flag1)
        # Weights, Biases = laplace_DNN1d_base.initialize_NN_random_normal(input_dim, out_dim, hidden_layers, flag1)
        if R['model2normal'] == 'PDE_DNN_Cos_C_Sin_Base' or R[
                'model2normal'] == 'DNN_adaptCosSin_Base':
            W2NN_Normal, B2NN_Normal = DNN_base.initialize_NN_random_normal2_CS(
                input_dim, out_dim, hidden2normal, flag_normal)
        else:
            W2NN_Normal, B2NN_Normal = DNN_base.initialize_NN_random_normal2(
                input_dim, out_dim, hidden2normal, flag_normal)

        if R['model2scale'] == 'PDE_DNN_Cos_C_Sin_Base' or R[
                'model2scale'] == 'DNN_adaptCosSin_Base':
            W2NN_freqs, B2NN_freqs = DNN_base.initialize_NN_random_normal2_CS(
                input_dim, out_dim, hidden2scale, flag_scale)
        else:
            W2NN_freqs, B2NN_freqs = DNN_base.initialize_NN_random_normal2(
                input_dim, out_dim, hidden2scale, flag_scale)

    global_steps = tf.Variable(0, trainable=False)
    with tf.device('/gpu:%s' % (R['gpuNo'])):
        with tf.variable_scope('vscope', reuse=tf.AUTO_REUSE):
            X_it = tf.placeholder(tf.float32,
                                  name='X_it',
                                  shape=[None, input_dim])  # * 行 1 列
            X_left_bd = tf.placeholder(tf.float32,
                                       name='X_left_bd',
                                       shape=[None, input_dim])  # * 行 1 列
            X_right_bd = tf.placeholder(tf.float32,
                                        name='X_right_bd',
                                        shape=[None, input_dim])  # * 行 1 列
            bd_penalty = tf.placeholder_with_default(input=1e3,
                                                     shape=[],
                                                     name='bd_p')
            penalty2powU = tf.placeholder_with_default(input=1.0,
                                                       shape=[],
                                                       name='p_powU')
            in_learning_rate = tf.placeholder_with_default(input=1e-5,
                                                           shape=[],
                                                           name='lr')
            train_opt = tf.placeholder_with_default(input=True,
                                                    shape=[],
                                                    name='train_opt')

            if R['model2normal'] == 'PDE_DNN':
                U_NN_Normal = DNN_base.PDE_DNN(X_it,
                                               W2NN_Normal,
                                               B2NN_Normal,
                                               hidden2normal,
                                               activate_name=act_func1)
                ULeft_NN_Normal = DNN_base.PDE_DNN(X_left_bd,
                                                   W2NN_Normal,
                                                   B2NN_Normal,
                                                   hidden2normal,
                                                   activate_name=act_func1)
                URight_NN_Normal = DNN_base.PDE_DNN(X_right_bd,
                                                    W2NN_Normal,
                                                    B2NN_Normal,
                                                    hidden2normal,
                                                    activate_name=act_func1)
            elif R['model2normal'] == 'PDE_DNN_Cos_C_Sin_Base':
                freq = [1]
                U_NN_Normal = DNN_base.PDE_DNN_Cos_C_Sin_Base(
                    X_it,
                    W2NN_Normal,
                    B2NN_Normal,
                    hidden2normal,
                    freq,
                    activate_name=act_func1)
                ULeft_NN_Normal = DNN_base.PDE_DNN_Cos_C_Sin_Base(
                    X_left_bd,
                    W2NN_Normal,
                    B2NN_Normal,
                    hidden2normal,
                    freq,
                    activate_name=act_func1)
                URight_NN_Normal = DNN_base.PDE_DNN_Cos_C_Sin_Base(
                    X_right_bd,
                    W2NN_Normal,
                    B2NN_Normal,
                    hidden2normal,
                    freq,
                    activate_name=act_func1)
            elif R['model2normal'] == 'DNN_adaptCosSin_Base':
                freq = [1]
                U_NN_Normal = DNN_base.DNN_adaptCosSin_Base(
                    X_it,
                    W2NN_Normal,
                    B2NN_Normal,
                    hidden2normal,
                    freq,
                    activate_name=act_func1)
                ULeft_NN_Normal = DNN_base.DNN_adaptCosSin_Base(
                    X_left_bd,
                    W2NN_Normal,
                    B2NN_Normal,
                    hidden2normal,
                    freq,
                    activate_name=act_func1)
                URight_NN_Normal = DNN_base.DNN_adaptCosSin_Base(
                    X_right_bd,
                    W2NN_Normal,
                    B2NN_Normal,
                    hidden2normal,
                    freq,
                    activate_name=act_func1)

            freqs = R['freqs']
            if R['model2scale'] == 'PDE_DNN_scale':
                U_NN_freqs = DNN_base.PDE_DNN_scale(X_it,
                                                    W2NN_freqs,
                                                    B2NN_freqs,
                                                    hidden2scale,
                                                    freqs,
                                                    activate_name=act_func2)
                ULeft_NN_freqs = DNN_base.PDE_DNN_scale(
                    X_left_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                URight_NN_freqs = DNN_base.PDE_DNN_scale(
                    X_right_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
            elif R['model2scale'] == 'PDE_DNN_adapt_scale':
                U_NN_freqs = DNN_base.PDE_DNN_adapt_scale(
                    X_it,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                ULeft_NN_freqs = DNN_base.PDE_DNN_adapt_scale(
                    X_left_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                URight_NN_freqs = DNN_base.PDE_DNN_adapt_scale(
                    X_right_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
            elif R['model2scale'] == 'PDE_DNN_FourierBase':
                U_NN_freqs = DNN_base.PDE_DNN_FourierBase(
                    X_it,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                ULeft_NN_freqs = DNN_base.PDE_DNN_FourierBase(
                    X_left_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                URight_NN_freqs = DNN_base.PDE_DNN_FourierBase(
                    X_right_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
            elif R['model2scale'] == 'PDE_DNN_Cos_C_Sin_Base':
                U_NN_freqs = DNN_base.PDE_DNN_Cos_C_Sin_Base(
                    X_it,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                ULeft_NN_freqs = DNN_base.PDE_DNN_Cos_C_Sin_Base(
                    X_left_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                URight_NN_freqs = DNN_base.PDE_DNN_Cos_C_Sin_Base(
                    X_right_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
            elif R['model2scale'] == 'DNN_adaptCosSin_Base':
                U_NN_freqs = DNN_base.DNN_adaptCosSin_Base(
                    X_it,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                ULeft_NN_freqs = DNN_base.DNN_adaptCosSin_Base(
                    X_left_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)
                URight_NN_freqs = DNN_base.DNN_adaptCosSin_Base(
                    X_right_bd,
                    W2NN_freqs,
                    B2NN_freqs,
                    hidden2scale,
                    freqs,
                    activate_name=act_func2)

            U_NN = U_NN_Normal + U_NN_freqs

            # 变分形式的loss of interior,训练得到的 U_NN1 是 * 行 1 列, 因为 一个点对(x,y) 得到一个 u 值
            dU_NN_Normal = tf.gradients(U_NN_Normal, X_it)[0]  # * 行 2 列
            dU_NN_freqs = tf.gradients(U_NN_freqs, X_it)[0]  # * 行 2 列
            if R['variational_loss'] == 1:
                dU_NN = tf.add(dU_NN_Normal, dU_NN_freqs)
                if R['PDE_type'] == 'general_laplace':
                    laplace_norm2NN = tf.reduce_sum(tf.square(dU_NN), axis=-1)
                    loss_it_NN = (1.0 / 2) * tf.reshape(laplace_norm2NN, shape=[-1, 1]) - \
                                           tf.multiply(tf.reshape(f(X_it), shape=[-1, 1]), U_NN)
                elif R['PDE_type'] == 'p_laplace':
                    # a_eps = A_eps(X_it)                          # * 行 1 列
                    a_eps = 1 / (2 + tf.cos(2 * np.pi * X_it / epsilon))
                    laplace_p_pow2NN = tf.reduce_sum(
                        a_eps * tf.pow(tf.abs(dU_NN), p_index), axis=-1)
                    loss_it_NN = (1.0 / p_index) * tf.reshape(laplace_p_pow2NN, shape=[-1, 1]) - \
                                           tf.multiply(tf.reshape(f(X_it), shape=[-1, 1]), U_NN)
                Loss_it2NN = tf.reduce_mean(loss_it_NN) * (region_r - region_l)

                if R['wavelet'] == 1:
                    # |Uc*Uf|^2-->0
                    norm2UdU = tf.square(tf.multiply(U_NN_Normal, U_NN_freqs))
                    UNN_dot_UNN = tf.reduce_mean(norm2UdU, axis=0)
                elif R['wavelet'] == 2:
                    # |a(x)*(grad Uc)*(grad Uf)|^2-->0
                    dU_dot_dU = tf.multiply(dU_NN_Normal, dU_NN_freqs)
                    sum2dUdU = tf.reshape(tf.reduce_sum(dU_dot_dU, axis=-1),
                                          shape=[-1, 1])
                    norm2AdUdU = tf.square(tf.multiply(a_eps, sum2dUdU))
                    # norm2AdUdU = tf.square(sum2dUdU)
                    UNN_dot_UNN = tf.reduce_mean(norm2AdUdU, axis=0)
                else:
                    U_dot_U = tf.reduce_mean(tf.square(
                        tf.multiply(U_NN_Normal, U_NN_freqs)),
                                             axis=0)
                    dU_dot_dU = tf.multiply(dU_NN_Normal, dU_NN_freqs)
                    sum2dUdU = tf.reshape(tf.reduce_sum(dU_dot_dU, axis=-1),
                                          shape=[-1, 1])
                    norm2AdUdU = tf.square(tf.multiply(a_eps, sum2dUdU))
                    UNN_dot_UNN = tf.reduce_mean(norm2AdUdU, axis=0) + U_dot_U
            elif R['variational_loss'] == 2:
                dU_NN = tf.add(dU_NN_Normal, dU_NN_freqs)
                if R['PDE_type'] == 'general_laplace':
                    laplace_norm2NN = tf.reduce_sum(tf.square(dU_NN), axis=-1)
                    loss_it_NN = (1.0 / 2) * tf.reshape(laplace_norm2NN, shape=[-1, 1]) - \
                                           tf.multiply(tf.reshape(f(X_it), shape=[-1, 1]), U_NN)
                elif R['PDE_type'] == 'p_laplace':
                    # a_eps = A_eps(X_it)                          # * 行 1 列
                    a_eps = 1 / (2 + tf.cos(2 * np.pi * X_it / epsilon))
                    laplace_p_pow2NN = tf.reduce_sum(
                        a_eps * tf.pow(tf.abs(dU_NN), p_index), axis=-1)
                    loss_it_NN = (1.0 / p_index) * tf.reshape(laplace_p_pow2NN, shape=[-1, 1]) - \
                                           tf.multiply(tf.reshape(f(X_it), shape=[-1, 1]), U_NN)
                Loss_it2NN = tf.reduce_mean(loss_it_NN) * (region_r - region_l)
                if R['wavelet'] == 1:
                    norm2UdU = tf.square(tf.multiply(U_NN_Normal, U_NN_freqs))
                    UNN_dot_UNN = tf.reduce_mean(norm2UdU, axis=0)
                else:
                    UNN_dot_UNN = tf.constant(0.0)

            Loss2UNN_dot_UNN = penalty2powU * UNN_dot_UNN

            U_left = tf.reshape(u_left(X_left_bd), shape=[-1, 1])
            U_right = tf.reshape(u_right(X_right_bd), shape=[-1, 1])
            loss_bd_Normal = tf.square(ULeft_NN_Normal -
                                       U_left) + tf.square(URight_NN_Normal -
                                                           U_right)
            loss_bd_Freqs = tf.square(ULeft_NN_freqs -
                                      U_left) + tf.square(URight_NN_freqs -
                                                          U_right)
            Loss_bd2NN = tf.reduce_mean(loss_bd_Normal) + tf.reduce_mean(
                loss_bd_Freqs)

            if R['regular_weight_model'] == 'L1':
                regular_WB_Normal = DNN_base.regular_weights_biases_L1(
                    W2NN_Normal, B2NN_Normal)  # 正则化权重和偏置 L1正则化
                regular_WB_Scale = DNN_base.regular_weights_biases_L1(
                    W2NN_freqs, B2NN_freqs)  # 正则化权重和偏置 L1正则化
            elif R['regular_weight_model'] == 'L2':
                regular_WB_Normal = DNN_base.regular_weights_biases_L2(
                    W2NN_Normal, B2NN_Normal)  # 正则化权重和偏置 L2正则化
                regular_WB_Scale = DNN_base.regular_weights_biases_L2(
                    W2NN_freqs, B2NN_freqs)  # 正则化权重和偏置 L2正则化
            else:
                regular_WB_Normal = tf.constant(0.0)  # 无正则化权重参数
                regular_WB_Scale = tf.constant(0.0)

            penalty_Weigth_Bias = wb_regular * (regular_WB_Normal +
                                                regular_WB_Scale)

            Loss2NN = Loss_it2NN + bd_penalty * Loss_bd2NN + Loss2UNN_dot_UNN + penalty_Weigth_Bias

            my_optimizer = tf.train.AdamOptimizer(in_learning_rate)
            if R['variational_loss'] == 1:
                if R['train_group'] == 1:
                    train_op1 = my_optimizer.minimize(Loss_it2NN,
                                                      global_step=global_steps)
                    train_op2 = my_optimizer.minimize(Loss_bd2NN,
                                                      global_step=global_steps)
                    train_op3 = my_optimizer.minimize(Loss2UNN_dot_UNN,
                                                      global_step=global_steps)
                    train_op4 = my_optimizer.minimize(Loss2NN,
                                                      global_step=global_steps)
                    train_Loss2NN = tf.group(train_op1, train_op2, train_op3,
                                             train_op4)
                elif R['train_group'] == 2:
                    train_op1 = my_optimizer.minimize(Loss2NN,
                                                      global_step=global_steps)
                    train_op2 = my_optimizer.minimize(Loss_bd2NN,
                                                      global_step=global_steps)
                    train_op3 = my_optimizer.minimize(Loss2UNN_dot_UNN,
                                                      global_step=global_steps)
                    train_Loss2NN = tf.group(train_op1, train_op2, train_op3)
                else:
                    train_Loss2NN = my_optimizer.minimize(
                        Loss2NN, global_step=global_steps)
            elif R['variational_loss'] == 2:
                if R['train_group'] == 1:
                    train_op1 = my_optimizer.minimize(Loss_it2NN,
                                                      global_step=global_steps)
                    train_op2 = my_optimizer.minimize(Loss_bd2NN,
                                                      global_step=global_steps)
                    train_op3 = my_optimizer.minimize(Loss2NN,
                                                      global_step=global_steps)
                    train_Loss2NN = tf.group(train_op1, train_op2, train_op3)
                elif R['train_group'] == 2:
                    train_op1 = my_optimizer.minimize(Loss2NN,
                                                      global_step=global_steps)
                    train_op2 = my_optimizer.minimize(Loss_bd2NN,
                                                      global_step=global_steps)
                    train_Loss2NN = tf.group(train_op1, train_op2)
                else:
                    train_Loss2NN = my_optimizer.minimize(
                        Loss2NN, global_step=global_steps)

            # 训练上的真解值和训练结果的误差
            U_true = u_true(X_it)
            train_mse_NN = tf.reduce_mean(tf.square(U_true - U_NN))
            train_rel_NN = train_mse_NN / tf.reduce_mean(tf.square(U_true))

    t0 = time.time()
    # 空列表, 使用 append() 添加元素
    lossIt_all2NN, lossBD_all2NN, loss_all2NN, UDU_NN, train_mse_all2NN, train_rel_all2NN = [], [], [], [], [], []
    test_mse_all2NN, test_rel_all2NN = [], []
    test_epoch = []

    test_batch_size = 1000
    test_x_bach = np.reshape(
        np.linspace(region_l, region_r, num=test_batch_size), [-1, 1])
    saveData.save_testData_or_solus2mat(test_x_bach,
                                        dataName='testx',
                                        outPath=R['FolderName'])

    # ConfigProto 加上allow_soft_placement=True就可以使用 gpu 了
    config = tf.ConfigProto(allow_soft_placement=True)  # 创建sess的时候对sess进行参数配置
    config.gpu_options.allow_growth = True  # True是让TensorFlow在运行过程中动态申请显存,避免过多的显存占用。
    config.allow_soft_placement = True  # 当指定的设备不存在时,允许选择一个存在的设备运行。比如gpu不存在,自动降到cpu上运行
    with tf.Session(config=config) as sess:
        sess.run(tf.global_variables_initializer())
        tmp_lr = learning_rate

        for i_epoch in range(R['max_epoch'] + 1):
            x_it_batch = DNN_data.rand_it(batchsize_it,
                                          input_dim,
                                          region_a=region_l,
                                          region_b=region_r)
            xl_bd_batch, xr_bd_batch = DNN_data.rand_bd_1D(batchsize_bd,
                                                           input_dim,
                                                           region_a=region_l,
                                                           region_b=region_r)
            tmp_lr = tmp_lr * (1 - lr_decay)
            if R['activate_penalty2bd_increase'] == 1:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_bd = bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_bd = 10 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_bd = 50 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_bd = 100 * bd_penalty_init
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_bd = 200 * bd_penalty_init
                else:
                    temp_penalty_bd = 500 * bd_penalty_init
            elif R['activate_penalty2bd_increase'] == 2:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_bd = 5 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_bd = 1 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_bd = 0.5 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_bd = 0.1 * bd_penalty_init
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_bd = 0.05 * bd_penalty_init
                else:
                    temp_penalty_bd = 0.02 * bd_penalty_init
            else:
                temp_penalty_bd = bd_penalty_init

            if R['activate_powSolus_increase'] == 1:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_powU = init_penalty2powU
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_powU = 10 * init_penalty2powU
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_powU = 50 * init_penalty2powU
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_powU = 100 * init_penalty2powU
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_powU = 200 * init_penalty2powU
                else:
                    temp_penalty_powU = 500 * init_penalty2powU
            elif R['activate_powSolus_increase'] == 2:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_powU = 5 * init_penalty2powU
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_powU = 1 * init_penalty2powU
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_powU = 0.5 * init_penalty2powU
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_powU = 0.1 * init_penalty2powU
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_powU = 0.05 * init_penalty2powU
                else:
                    temp_penalty_powU = 0.02 * init_penalty2powU
            else:
                temp_penalty_powU = init_penalty2powU

            p_WB = 0.0
            _, loss_it_nn, loss_bd_nn, loss_nn, udu_nn, train_mse_nn, train_rel_nn = sess.run(
                [
                    train_Loss2NN, Loss_it2NN, Loss_bd2NN, Loss2NN,
                    UNN_dot_UNN, train_mse_NN, train_rel_NN
                ],
                feed_dict={
                    X_it: x_it_batch,
                    X_left_bd: xl_bd_batch,
                    X_right_bd: xr_bd_batch,
                    in_learning_rate: tmp_lr,
                    bd_penalty: temp_penalty_bd,
                    penalty2powU: temp_penalty_powU
                })
            lossIt_all2NN.append(loss_it_nn)
            lossBD_all2NN.append(loss_bd_nn)
            loss_all2NN.append(loss_nn)
            UDU_NN.append(udu_nn)
            train_mse_all2NN.append(train_mse_nn)
            train_rel_all2NN.append(train_rel_nn)

            if i_epoch % 1000 == 0:
                run_times = time.time() - t0
                DNN_tools.print_and_log_train_one_epoch(i_epoch,
                                                        run_times,
                                                        tmp_lr,
                                                        temp_penalty_bd,
                                                        temp_penalty_powU,
                                                        p_WB,
                                                        loss_it_nn,
                                                        loss_bd_nn,
                                                        loss_nn,
                                                        udu_nn,
                                                        train_mse_nn,
                                                        train_rel_nn,
                                                        log_out=log_fileout_NN)

                # ---------------------------   test network ----------------------------------------------
                test_epoch.append(i_epoch / 1000)
                train_option = False
                u_true2test, utest_nn, u_nn_normal, u_nn_scale = sess.run(
                    [U_true, U_NN, U_NN_Normal, U_NN_freqs],
                    feed_dict={
                        X_it: test_x_bach,
                        train_opt: train_option
                    })
                test_mse2nn = np.mean(np.square(u_true2test - utest_nn))
                test_mse_all2NN.append(test_mse2nn)
                test_rel2nn = test_mse2nn / np.mean(np.square(u_true2test))
                test_rel_all2NN.append(test_rel2nn)

                DNN_tools.print_and_log_test_one_epoch(test_mse2nn,
                                                       test_rel2nn,
                                                       log_out=log_fileout_NN)

        # -----------------------  save training results to mat files, then plot them ---------------------------------
        saveData.save_trainLoss2mat_1actFunc(lossIt_all2NN,
                                             lossBD_all2NN,
                                             loss_all2NN,
                                             actName=act_func1,
                                             outPath=R['FolderName'])

        saveData.save_train_MSE_REL2mat(train_mse_all2NN,
                                        train_rel_all2NN,
                                        actName=act_func1,
                                        outPath=R['FolderName'])

        plotData.plotTrain_loss_1act_func(lossIt_all2NN,
                                          lossType='loss_it',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'])
        plotData.plotTrain_loss_1act_func(lossBD_all2NN,
                                          lossType='loss_bd',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'],
                                          yaxis_scale=True)
        plotData.plotTrain_loss_1act_func(loss_all2NN,
                                          lossType='loss',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'])

        plotData.plotTrain_MSE_REL_1act_func(train_mse_all2NN,
                                             train_rel_all2NN,
                                             actName=act_func2,
                                             seedNo=R['seed'],
                                             outPath=R['FolderName'],
                                             yaxis_scale=True)

        # ----------------------  save testing results to mat files, then plot them --------------------------------
        saveData.save_testData_or_solus2mat(u_true2test,
                                            dataName='Utrue',
                                            outPath=R['FolderName'])
        saveData.save_testData_or_solus2mat(utest_nn,
                                            dataName=act_func1,
                                            outPath=R['FolderName'])
        saveData.save_testData_or_solus2mat(u_nn_normal,
                                            dataName='normal',
                                            outPath=R['FolderName'])
        saveData.save_testData_or_solus2mat(u_nn_scale,
                                            dataName='scale',
                                            outPath=R['FolderName'])

        saveData.save_testMSE_REL2mat(test_mse_all2NN,
                                      test_rel_all2NN,
                                      actName=act_func2,
                                      outPath=R['FolderName'])
        plotData.plotTest_MSE_REL(test_mse_all2NN,
                                  test_rel_all2NN,
                                  test_epoch,
                                  actName=act_func2,
                                  seedNo=R['seed'],
                                  outPath=R['FolderName'],
                                  yaxis_scale=True)
Esempio n. 2
0
def solve_Multiscale_PDE(R):
    log_out_path = R['FolderName']  # 将路径从字典 R 中提取出来
    if not os.path.exists(log_out_path):  # 判断路径是否已经存在
        os.mkdir(log_out_path)  # 无 log_out_path 路径,创建一个 log_out_path 路径
    logfile_name = '%s%s.txt' % ('log2', R['name2act_hidden'])
    log_fileout = open(os.path.join(log_out_path, logfile_name),
                       'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件
    DNN_Log_Print.dictionary_out2file(R, log_fileout)

    # 一般 laplace 问题需要的设置
    batchsize_it = R['batch_size2interior']
    batchsize_bd = R['batch_size2boundary']

    bd_penalty_init = R[
        'init_boundary_penalty']  # Regularization parameter for boundary conditions
    penalty2WB = R[
        'penalty2weight_biases']  # Regularization parameter for weights and biases
    lr_decay = R['learning_rate_decay']
    learning_rate = R['learning_rate']
    hidden_layers = R['hidden_layers']

    input_dim = R['input_dim']
    out_dim = R['output_dim']
    act_func = R['name2act_hidden']

    # p laplace 问题需要的额外设置, 先预设一下
    p_index = R['order2pLaplace_operator']
    mesh_number = 2

    region_lb = 0.0
    region_rt = 1.0
    if R['PDE_type'] == 'general_Laplace':
        # -laplace u = f
        region_lb = 0.0
        region_rt = 1.0
        f, u_true, u00, u01, u10, u11, u20, u21, u30, u31, u40, u41 = General_Laplace.get_infos2Laplace_5D(
            input_dim=input_dim,
            out_dim=out_dim,
            intervalL=region_lb,
            intervalR=region_rt,
            equa_name=R['equa_name'])
    elif R['PDE_type'] == 'pLaplace':
        region_lb = 0.0
        region_rt = 1.0
        u_true, f, A_eps, u00, u01, u10, u11, u20, u21, u30, u31, u40, u41 = MS_LaplaceEqs.get_infos2pLaplace_5D(
            input_dim=input_dim,
            out_dim=out_dim,
            intervalL=0.0,
            intervalR=1.0,
            equa_name=R['equa_name'])
    elif R['PDE_type'] == 'Possion_Boltzmann':
        region_lb = 0.0
        region_rt = 1.0
        u_true, f, A_eps, kappa, u00, u01, u10, u11, u20, u21, u30, u31, u40, u41 = MS_BoltzmannEqs.get_infos2Boltzmann_5D(
            input_dim=input_dim,
            out_dim=out_dim,
            intervalL=0.0,
            intervalR=1.0,
            equa_name=R['equa_name'])

    flag = 'WB2NN'
    if R['model2NN'] == 'DNN_FourierBase':
        W2NN, B2NN = DNN_base.Xavier_init_NN_Fourier(input_dim, out_dim,
                                                     hidden_layers, flag)
    else:
        W2NN, B2NN = DNN_base.Xavier_init_NN(input_dim, out_dim, hidden_layers,
                                             flag)

    global_steps = tf.compat.v1.Variable(0, trainable=False)
    with tf.device('/gpu:%s' % (R['gpuNo'])):
        with tf.compat.v1.variable_scope('vscope',
                                         reuse=tf.compat.v1.AUTO_REUSE):
            XYZST_it = tf.compat.v1.placeholder(tf.float32,
                                                name='XYZST_it',
                                                shape=[None, input_dim])
            XYZST00 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST00',
                                               shape=[None, input_dim])
            XYZST01 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST01',
                                               shape=[None, input_dim])
            XYZST10 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST10',
                                               shape=[None, input_dim])
            XYZST11 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST11',
                                               shape=[None, input_dim])
            XYZST20 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST20',
                                               shape=[None, input_dim])
            XYZST21 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST21',
                                               shape=[None, input_dim])
            XYZST30 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST30',
                                               shape=[None, input_dim])
            XYZST31 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST31',
                                               shape=[None, input_dim])
            XYZST40 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST40',
                                               shape=[None, input_dim])
            XYZST41 = tf.compat.v1.placeholder(tf.float32,
                                               name='XYZST41',
                                               shape=[None, input_dim])
            boundary_penalty = tf.compat.v1.placeholder_with_default(
                input=1e3, shape=[], name='bd_p')
            in_learning_rate = tf.compat.v1.placeholder_with_default(
                input=1e-5, shape=[], name='lr')

            # 供选择的网络模式
            if R['model2NN'] == 'DNN':
                UNN = DNN_base.DNN(XYZST_it,
                                   W2NN,
                                   B2NN,
                                   hidden_layers,
                                   activateIn_name=R['name2act_in'],
                                   activate_name=R['name2act_hidden'])
                U00_NN = DNN_base.DNN(XYZST00,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U01_NN = DNN_base.DNN(XYZST01,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U10_NN = DNN_base.DNN(XYZST10,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U11_NN = DNN_base.DNN(XYZST11,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U20_NN = DNN_base.DNN(XYZST20,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U21_NN = DNN_base.DNN(XYZST21,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U30_NN = DNN_base.DNN(XYZST30,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U31_NN = DNN_base.DNN(XYZST31,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U40_NN = DNN_base.DNN(XYZST40,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
                U41_NN = DNN_base.DNN(XYZST41,
                                      W2NN,
                                      B2NN,
                                      hidden_layers,
                                      activateIn_name=R['name2act_in'],
                                      activate_name=R['name2act_hidden'])
            elif R['model2NN'] == 'DNN_scale':
                UNN = DNN_base.DNN_scale(XYZST_it,
                                         W2NN,
                                         B2NN,
                                         hidden_layers,
                                         R['freq'],
                                         activateIn_name=R['name2act_in'],
                                         activate_name=R['name2act_hidden'])
                U00_NN = DNN_base.DNN_scale(XYZST00,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U01_NN = DNN_base.DNN_scale(XYZST01,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U10_NN = DNN_base.DNN_scale(XYZST10,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U11_NN = DNN_base.DNN_scale(XYZST11,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U20_NN = DNN_base.DNN_scale(XYZST20,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U21_NN = DNN_base.DNN_scale(XYZST21,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U30_NN = DNN_base.DNN_scale(XYZST30,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U31_NN = DNN_base.DNN_scale(XYZST31,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U40_NN = DNN_base.DNN_scale(XYZST40,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
                U41_NN = DNN_base.DNN_scale(XYZST41,
                                            W2NN,
                                            B2NN,
                                            hidden_layers,
                                            R['freq'],
                                            activateIn_name=R['name2act_in'],
                                            activate_name=R['name2act_hidden'])
            elif R['model2NN'] == 'DNN_adapt_scale':
                UNN = DNN_base.DNN_adapt_scale(
                    XYZST_it,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U00_NN = DNN_base.DNN_adapt_scale(
                    XYZST00,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U01_NN = DNN_base.DNN_adapt_scale(
                    XYZST01,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U10_NN = DNN_base.DNN_adapt_scale(
                    XYZST10,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U11_NN = DNN_base.DNN_adapt_scale(
                    XYZST11,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U20_NN = DNN_base.DNN_adapt_scale(
                    XYZST20,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U21_NN = DNN_base.DNN_adapt_scale(
                    XYZST21,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U30_NN = DNN_base.DNN_adapt_scale(
                    XYZST30,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U31_NN = DNN_base.DNN_adapt_scale(
                    XYZST31,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U40_NN = DNN_base.DNN_adapt_scale(
                    XYZST40,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
                U41_NN = DNN_base.DNN_adapt_scale(
                    XYZST41,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activateIn_name=R['name2act_in'],
                    activate_name=R['name2act_hidden'])
            elif R['model2NN'] == 'DNN_FourierBase':
                UNN = DNN_base.DNN_FourierBase(
                    XYZST_it,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U00_NN = DNN_base.DNN_FourierBase(
                    XYZST00,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U01_NN = DNN_base.DNN_FourierBase(
                    XYZST01,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U10_NN = DNN_base.DNN_FourierBase(
                    XYZST10,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U11_NN = DNN_base.DNN_FourierBase(
                    XYZST11,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U20_NN = DNN_base.DNN_FourierBase(
                    XYZST20,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U21_NN = DNN_base.DNN_FourierBase(
                    XYZST21,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U30_NN = DNN_base.DNN_FourierBase(
                    XYZST30,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U31_NN = DNN_base.DNN_FourierBase(
                    XYZST31,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U40_NN = DNN_base.DNN_FourierBase(
                    XYZST40,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])
                U41_NN = DNN_base.DNN_FourierBase(
                    XYZST41,
                    W2NN,
                    B2NN,
                    hidden_layers,
                    R['freq'],
                    activate_name=R['name2act_hidden'],
                    sFourier=R['sfourier'])

            X_it = tf.reshape(XYZST_it[:, 0], shape=[-1, 1])
            Y_it = tf.reshape(XYZST_it[:, 1], shape=[-1, 1])
            Z_it = tf.reshape(XYZST_it[:, 2], shape=[-1, 1])
            S_it = tf.reshape(XYZST_it[:, 3], shape=[-1, 1])
            T_it = tf.reshape(XYZST_it[:, 4], shape=[-1, 1])

            dUNN = tf.gradients(UNN, XYZST_it)[0]  # * 行 2 列

            # 变分形式的loss of interior,训练得到的 UNN 是 * 行 1 列, 因为 一个点对(x,y) 得到一个 u 值
            if R['loss_type'] == 'variational_loss':
                dUNN_Norm = tf.reshape(tf.sqrt(
                    tf.reduce_sum(tf.square(dUNN), axis=-1)),
                                       shape=[-1, 1])  # 按行求和
                if R['PDE_type'] == 'general_Laplace':
                    dUNN_2Norm = tf.square(dUNN_Norm)
                    loss_it_variational = (1.0 / 2) * dUNN_2Norm - tf.multiply(
                        f(X_it, Y_it, Z_it, S_it, T_it), UNN)
                elif R['PDE_type'] == 'pLaplace':
                    a_eps = A_eps(X_it, Y_it, Z_it, S_it, T_it)  # * 行 1 列
                    AdUNN_pNorm = a_eps * tf.pow(dUNN_Norm, p_index)
                    if R['equa_name'] == 'multi_scale5D_4' or R['equa_name'] == 'multi_scale5D_5' or \
                            R['equa_name'] == 'multi_scale5D_6' or R['equa_name'] == 'multi_scale5D_7':
                        fxyzst = MS_LaplaceEqs.get_forceSide2pLaplace5D(
                            x=X_it,
                            y=Y_it,
                            z=Z_it,
                            s=S_it,
                            t=T_it,
                            equa_name=R['equa_name'])
                        loss_it_variational = (
                            1.0 / p_index) * AdUNN_pNorm - tf.multiply(
                                tf.reshape(fxyzst, shape=[-1, 1]), UNN)
                    else:
                        loss_it_variational = (
                            1.0 / p_index) * AdUNN_pNorm - tf.multiply(
                                f(X_it, Y_it, Z_it, S_it, T_it), UNN)
                elif R['PDE_type'] == 'Possion_Boltzmann':
                    a_eps = A_eps(X_it, Y_it, Z_it, S_it, T_it)  # * 行 1 列
                    AdUNN_pNorm = a_eps * tf.pow(dUNN_Norm, p_index)
                    Kappa = np.pi * np.pi
                    # Kappa = kappa(X_it, Y_it, Z_it, S_it, T_it)
                    if R['equa_name'] == 'multi_scale5D_4' or R['equa_name'] == 'multi_scale5D_5' or \
                            R['equa_name'] == 'multi_scale5D_6' or R['equa_name'] == 'multi_scale5D_7':
                        fxyzst = MS_BoltzmannEqs.get_forceSide2Boltzmann_5D(
                            x=X_it,
                            y=Y_it,
                            z=Z_it,
                            s=S_it,
                            t=T_it,
                            equa_name=R['equa_name'])
                        loss_it_variational = (1.0 / p_index) * (
                            AdUNN_pNorm + Kappa * UNN * UNN) - tf.multiply(
                                fxyzst, UNN)
                    else:
                        loss_it_variational = (1.0 / p_index) * (AdUNN_pNorm + Kappa*UNN*UNN) - \
                                              tf.multiply(f(X_it, Y_it, Z_it, S_it, T_it), UNN)
                loss_it = tf.reduce_mean(loss_it_variational)

            U_00 = tf.constant(0.0)
            U_01 = tf.constant(0.0)
            U_10 = tf.constant(0.0)
            U_11 = tf.constant(0.0)
            U_20 = tf.constant(0.0)
            U_21 = tf.constant(0.0)
            U_30 = tf.constant(0.0)
            U_31 = tf.constant(0.0)
            U_40 = tf.constant(0.0)
            U_41 = tf.constant(0.0)

            loss_bd_square2NN = tf.square(U00_NN - U_00) + tf.square(U01_NN - U_01) + tf.square(U10_NN - U_10) + \
                                tf.square(U11_NN - U_11) + tf.square(U20_NN - U_20) + tf.square(U21_NN - U_21) + \
                                tf.square(U30_NN - U_30) + tf.square(U31_NN - U_31) + tf.square(U40_NN - U_40) + \
                                tf.square(U41_NN - U_41)
            loss_bd = tf.reduce_mean(loss_bd_square2NN)

            if R['regular_wb_model'] == 'L1':
                regularSum2WB = DNN_base.regular_weights_biases_L1(
                    W2NN, B2NN)  # 正则化权重和偏置 L1正则化
            elif R['regular_wb_model'] == 'L2':
                regularSum2WB = DNN_base.regular_weights_biases_L2(
                    W2NN, B2NN)  # 正则化权重和偏置 L2正则化
            else:
                regularSum2WB = tf.constant(0.0)  # 无正则化权重参数

            PWB = penalty2WB * regularSum2WB
            loss = loss_it + boundary_penalty * loss_bd + PWB  # 要优化的loss function

            my_optimizer = tf.train.AdamOptimizer(in_learning_rate)
            if R['train_model'] == 'group3_training':
                train_op1 = my_optimizer.minimize(loss_it,
                                                  global_step=global_steps)
                train_op2 = my_optimizer.minimize(loss_bd,
                                                  global_step=global_steps)
                train_op3 = my_optimizer.minimize(loss,
                                                  global_step=global_steps)
                train_my_loss = tf.group(train_op1, train_op2, train_op3)
            elif R['train_model'] == 'group2_training':
                train_op2bd = my_optimizer.minimize(loss_bd,
                                                    global_step=global_steps)
                train_op2union = my_optimizer.minimize(
                    loss, global_step=global_steps)
                train_my_loss = tf.group(train_op2union, train_op2bd)
            elif R['train_model'] == 'union_training':
                train_my_loss = my_optimizer.minimize(loss,
                                                      global_step=global_steps)

            if R['PDE_type'] == 'general_Laplace' or R[
                    'PDE_type'] == 'pLaplace' or R[
                        'PDE_type'] == 'Possion_Boltzmann':
                # 训练上的真解值和训练结果的误差
                U_true = u_true(X_it, Y_it, Z_it, S_it, T_it)
                train_mse = tf.reduce_mean(tf.square(U_true - UNN))
                train_rel = train_mse / tf.reduce_mean(tf.square(U_true))
            else:
                train_mse = tf.constant(0.0)
                train_rel = tf.constant(0.0)

    t0 = time.time()
    loss_it_all, loss_bd_all, loss_all, train_mse_all, train_rel_all = [], [], [], [], []  # 空列表, 使用 append() 添加元素
    test_mse_all, test_rel_all = [], []
    test_epoch = []

    # 画网格解图
    if R['testData_model'] == 'random_generate':
        # 生成测试数据,用于测试训练后的网络
        # test_bach_size = 400
        # size2test = 20
        # test_bach_size = 900
        # size2test = 30
        test_bach_size = 1600
        size2test = 40
        # test_bach_size = 4900
        # size2test = 70
        # test_bach_size = 10000
        # size2test = 100
        test_xyzst_bach = DNN_data.rand_it(test_bach_size, input_dim,
                                           region_lb, region_rt)
        saveData.save_testData_or_solus2mat(test_xyzst_bach,
                                            dataName='testXYZST',
                                            outPath=R['FolderName'])
    elif R['testData_model'] == 'loadData':
        test_bach_size = 1600
        size2test = 40
        mat_data_path = 'dataMat_highDim'
        test_xyzst_bach = Load_data2Mat.get_randomData2mat(
            dim=input_dim, data_path=mat_data_path)
        saveData.save_testData_or_solus2mat(test_xyzst_bach,
                                            dataName='testXYZST',
                                            outPath=R['FolderName'])

    # ConfigProto 加上allow_soft_placement=True就可以使用 gpu 了
    config = tf.ConfigProto(allow_soft_placement=True)  # 创建sess的时候对sess进行参数配置
    config.gpu_options.allow_growth = True  # True是让TensorFlow在运行过程中动态申请显存,避免过多的显存占用。
    config.allow_soft_placement = True  # 当指定的设备不存在时,允许选择一个存在的设备运行。比如gpu不存在,自动降到cpu上运行
    with tf.Session(config=config) as sess:
        sess.run(tf.global_variables_initializer())
        tmp_lr = learning_rate

        for i_epoch in range(R['max_epoch'] + 1):
            xyzst_it_batch = DNN_data.rand_it(batchsize_it,
                                              input_dim,
                                              region_a=region_lb,
                                              region_b=region_rt)
            xyzst00_batch, xyzst01_batch, xyzst10_batch, xyzst11_batch, xyzst20_batch, xyzst21_batch, xyzst30_batch, \
            xyzst31_batch, xyzst40_batch, xyzst41_batch = DNN_data.rand_bd_5D(batchsize_bd, input_dim,
                                                                              region_a=region_lb, region_b=region_rt)
            tmp_lr = tmp_lr * (1 - lr_decay)
            if R['activate_penalty2bd_increase'] == 1:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_bd = bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_bd = 10 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_bd = 50 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_bd = 100 * bd_penalty_init
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_bd = 200 * bd_penalty_init
                else:
                    temp_penalty_bd = 500 * bd_penalty_init
            elif R['activate_penalty2bd_increase'] == 2:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_bd = 5 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_bd = 1 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_bd = 0.5 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_bd = 0.1 * bd_penalty_init
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_bd = 0.05 * bd_penalty_init
                else:
                    temp_penalty_bd = 0.02 * bd_penalty_init
            else:
                temp_penalty_bd = bd_penalty_init

            _, loss_it_tmp, loss_bd_tmp, loss_tmp, train_mse_tmp, train_rel_tmp, pwb = sess.run(
                [
                    train_my_loss, loss_it, loss_bd, loss, train_mse,
                    train_rel, PWB
                ],
                feed_dict={
                    XYZST_it: xyzst_it_batch,
                    XYZST00: xyzst00_batch,
                    XYZST01: xyzst01_batch,
                    XYZST10: xyzst10_batch,
                    XYZST11: xyzst11_batch,
                    XYZST20: xyzst20_batch,
                    XYZST21: xyzst21_batch,
                    XYZST30: xyzst30_batch,
                    XYZST31: xyzst31_batch,
                    XYZST40: xyzst40_batch,
                    XYZST41: xyzst41_batch,
                    in_learning_rate: tmp_lr,
                    boundary_penalty: temp_penalty_bd
                })

            loss_it_all.append(loss_it_tmp)
            loss_bd_all.append(loss_bd_tmp)
            loss_all.append(loss_tmp)
            train_mse_all.append(train_mse_tmp)
            train_rel_all.append(train_rel_tmp)

            if i_epoch % 1000 == 0:
                run_times = time.time() - t0
                DNN_Log_Print.print_and_log_train_one_epoch(
                    i_epoch,
                    run_times,
                    tmp_lr,
                    temp_penalty_bd,
                    pwb,
                    loss_it_tmp,
                    loss_bd_tmp,
                    loss_tmp,
                    train_mse_tmp,
                    train_rel_tmp,
                    log_out=log_fileout)

                # ---------------------------   test network ----------------------------------------------
                test_epoch.append(i_epoch / 1000)
                train_option = False
                if R['PDE_type'] == 'general_laplace' or R[
                        'PDE_type'] == 'pLaplace' or R[
                            'PDE_type'] == 'Possion_Boltzmann':
                    u_true2test, u_nn2test = sess.run(
                        [U_true, UNN], feed_dict={XYZST_it: test_xyzst_bach})
                else:
                    u_true2test = u_true
                    u_nn2test = sess.run(UNN,
                                         feed_dict={XYZST_it: test_xyzst_bach})

                point_square_error = np.square(u_true2test - u_nn2test)
                mse2test = np.mean(point_square_error)
                test_mse_all.append(mse2test)
                res2test = mse2test / np.mean(np.square(u_true2test))
                test_rel_all.append(res2test)

                DNN_Log_Print.print_and_log_test_one_epoch(mse2test,
                                                           res2test,
                                                           log_out=log_fileout)

        # ------------------- save the testing results into mat file and plot them -------------------------
        saveData.save_trainLoss2mat_1actFunc(loss_it_all,
                                             loss_bd_all,
                                             loss_all,
                                             actName=act_func,
                                             outPath=R['FolderName'])
        saveData.save_train_MSE_REL2mat(train_mse_all,
                                        train_rel_all,
                                        actName=act_func,
                                        outPath=R['FolderName'])

        plotData.plotTrain_loss_1act_func(loss_it_all,
                                          lossType='loss_it',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'])
        plotData.plotTrain_loss_1act_func(loss_bd_all,
                                          lossType='loss_bd',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'],
                                          yaxis_scale=True)
        plotData.plotTrain_loss_1act_func(loss_all,
                                          lossType='loss',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'])

        saveData.save_train_MSE_REL2mat(train_mse_all,
                                        train_rel_all,
                                        actName=act_func,
                                        outPath=R['FolderName'])
        plotData.plotTrain_MSE_REL_1act_func(train_mse_all,
                                             train_rel_all,
                                             actName=act_func,
                                             seedNo=R['seed'],
                                             outPath=R['FolderName'],
                                             yaxis_scale=True)

        # ----------------------  save testing results to mat files, then plot them --------------------------------
        saveData.save_2testSolus2mat(u_true2test,
                                     u_nn2test,
                                     actName='utrue',
                                     actName1=act_func,
                                     outPath=R['FolderName'])

        # 绘制解的热力图(真解和DNN解)
        plotData.plot_Hot_solution2test(u_true2test,
                                        size_vec2mat=size2test,
                                        actName='Utrue',
                                        seedNo=R['seed'],
                                        outPath=R['FolderName'])
        plotData.plot_Hot_solution2test(u_nn2test,
                                        size_vec2mat=size2test,
                                        actName=act_func,
                                        seedNo=R['seed'],
                                        outPath=R['FolderName'])

        saveData.save_testMSE_REL2mat(test_mse_all,
                                      test_rel_all,
                                      actName=act_func,
                                      outPath=R['FolderName'])
        plotData.plotTest_MSE_REL(test_mse_all,
                                  test_rel_all,
                                  test_epoch,
                                  actName=act_func,
                                  seedNo=R['seed'],
                                  outPath=R['FolderName'],
                                  yaxis_scale=True)

        saveData.save_test_point_wise_err2mat(point_square_error,
                                              actName=act_func,
                                              outPath=R['FolderName'])

        plotData.plot_Hot_point_wise_err(point_square_error,
                                         size_vec2mat=size2test,
                                         actName=act_func,
                                         seedNo=R['seed'],
                                         outPath=R['FolderName'])
Esempio n. 3
0
def solve_SIR2COVID(R):
    log_out_path = R['FolderName']  # 将路径从字典 R 中提取出来
    if not os.path.exists(log_out_path):  # 判断路径是否已经存在
        os.mkdir(log_out_path)  # 无 log_out_path 路径,创建一个 log_out_path 路径
    log_fileout = open(os.path.join(log_out_path, 'log_train.txt'),
                       'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件
    DNN_LogPrint.dictionary_out2file(R, log_fileout)

    log2trianSolus = open(os.path.join(log_out_path, 'train_Solus.txt'),
                          'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件
    log2testSolus = open(os.path.join(log_out_path, 'test_Solus.txt'),
                         'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件
    log2testSolus2 = open(os.path.join(log_out_path, 'test_Solus_temp.txt'),
                          'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件

    log2testParas = open(os.path.join(log_out_path, 'test_Paras.txt'),
                         'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件

    trainSet_szie = R['size2train']
    batchSize_train = R['batch_size2train']
    batchSize_test = R['batch_size2test']
    pt_penalty_init = R[
        'init_penalty2predict_true']  # Regularization parameter for difference of predict and true
    wb_penalty = R['regular_weight']  # Regularization parameter for weights
    lr_decay = R['lr_decay']
    learning_rate = R['learning_rate']

    act_func2SIR = R['act2sir']
    act_func2paras = R['act2paras']

    input_dim = R['input_dim']
    out_dim = R['output_dim']

    flag2S = 'WB2S'
    flag2I = 'WB2I'
    flag2R = 'WB2R'
    flag2beta = 'WB2beta'
    flag2gamma = 'WB2gamma'
    hidden_sir = R['hidden2SIR']
    hidden_para = R['hidden2para']

    Weight2S, Bias2S = DNN.init_DNN(size2in=input_dim,
                                    size2out=out_dim,
                                    hiddens=hidden_sir,
                                    scope=flag2S,
                                    opt2Init=R['SIR_opt2init_NN'])
    Weight2I, Bias2I = DNN.init_DNN(size2in=input_dim,
                                    size2out=out_dim,
                                    hiddens=hidden_sir,
                                    scope=flag2I,
                                    opt2Init=R['SIR_opt2init_NN'])
    Weight2R, Bias2R = DNN.init_DNN(size2in=input_dim,
                                    size2out=out_dim,
                                    hiddens=hidden_sir,
                                    scope=flag2R,
                                    opt2Init=R['SIR_opt2init_NN'])

    Weight2beta, Bias2beta = DNN.init_DNN(size2in=input_dim,
                                          size2out=out_dim,
                                          hiddens=hidden_para,
                                          scope=flag2beta,
                                          opt2Init=R['Para_opt2init_NN'])
    Weight2gamma, Bias2gamma = DNN.init_DNN(size2in=input_dim,
                                            size2out=out_dim,
                                            hiddens=hidden_para,
                                            scope=flag2gamma,
                                            opt2Init=R['Para_opt2init_NN'])

    global_steps = tf.Variable(0, trainable=False)
    with tf.device('/gpu:%s' % (R['gpuNo'])):
        with tf.variable_scope('vscope', reuse=tf.AUTO_REUSE):
            T_it = tf.placeholder(tf.float32,
                                  name='T_it',
                                  shape=[None, input_dim])
            I_observe = tf.placeholder(tf.float32,
                                       name='I_observe',
                                       shape=[None, input_dim])
            N_observe = tf.placeholder(tf.float32,
                                       name='N_observe',
                                       shape=[None, input_dim])
            predict_true_penalty = tf.placeholder_with_default(input=1e3,
                                                               shape=[],
                                                               name='bd_p')
            in_learning_rate = tf.placeholder_with_default(input=1e-5,
                                                           shape=[],
                                                           name='lr')
            train_opt = tf.placeholder_with_default(input=True,
                                                    shape=[],
                                                    name='train_opt')

            SNN_temp = DNN.PDE_DNN(x=T_it,
                                   hiddenLayer=hidden_sir,
                                   Weigths=Weight2S,
                                   Biases=Bias2S,
                                   DNNmodel=R['model2sir'],
                                   activation=act_func2SIR,
                                   freqs=R['freqs'])
            INN_temp = DNN.PDE_DNN(x=T_it,
                                   hiddenLayer=hidden_sir,
                                   Weigths=Weight2I,
                                   Biases=Bias2I,
                                   DNNmodel=R['model2sir'],
                                   activation=act_func2SIR,
                                   freqs=R['freqs'])
            RNN_temp = DNN.PDE_DNN(x=T_it,
                                   hiddenLayer=hidden_sir,
                                   Weigths=Weight2R,
                                   Biases=Bias2R,
                                   DNNmodel=R['model2sir'],
                                   activation=act_func2SIR,
                                   freqs=R['freqs'])
            in_beta = DNN.PDE_DNN(x=T_it,
                                  hiddenLayer=hidden_para,
                                  Weigths=Weight2beta,
                                  Biases=Bias2beta,
                                  DNNmodel=R['model2paras'],
                                  activation=act_func2paras,
                                  freqs=R['freqs'])
            in_gamma = DNN.PDE_DNN(x=T_it,
                                   hiddenLayer=hidden_para,
                                   Weigths=Weight2gamma,
                                   Biases=Bias2gamma,
                                   DNNmodel=R['model2paras'],
                                   activation=act_func2paras,
                                   freqs=R['freqs'])

            # Remark: beta, gamma,S_NN.I_NN,R_NN都应该是正的. beta.1--15之间,gamma在(0,1)使用归一化的话S_NN.I_NN,R_NN都在[0,1)范围内
            if (R['total_population']
                    == R['scale_population']) and R['scale_population'] != 1:
                beta = in_beta
                gamma = in_gamma
                # SNN = SNN_temp
                # INN = INN_temp
                # RNN = RNN_temp

                # SNN = tf.nn.relu(SNN_temp)
                # INN = tf.nn.relu(INN_temp)
                # RNN = tf.nn.relu(RNN_temp)

                # SNN = tf.abs(SNN_temp)
                # INN = tf.abs(INN_temp)
                # RNN = tf.abs(RNN_temp)

                # SNN = DNN_base.gauss(SNN_temp)
                # INN = tf.square(INN_temp)
                # RNN = tf.square(RNN_temp)

                # SNN = DNN_base.gauss(SNN_temp)
                # INN = tf.square(INN_temp)
                # RNN = tf.nn.sigmoid(RNN_temp)

                # SNN = DNN_base.gauss(SNN_temp)
                # INN = tf.nn.sigmoid(INN_temp)
                # RNN = tf.square(RNN_temp)

                # SNN = tf.sqrt(tf.square(SNN_temp))
                # INN = tf.sqrt(tf.square(INN_temp))
                # RNN = tf.sqrt(tf.square(RNN_temp))

                SNN = tf.nn.sigmoid(SNN_temp)
                INN = tf.nn.sigmoid(INN_temp)
                RNN = tf.nn.sigmoid(RNN_temp)

            else:
                beta = in_beta
                gamma = in_gamma

                # SNN = SNN_temp
                # INN = INN_temp
                # RNN = RNN_temp

                # SNN = tf.nn.relu(SNN_temp)
                # INN = tf.nn.relu(INN_temp)
                # RNN = tf.nn.relu(RNN_temp)

                SNN = tf.nn.sigmoid(SNN_temp)
                INN = tf.nn.sigmoid(INN_temp)
                RNN = tf.nn.sigmoid(RNN_temp)

            N_NN = SNN + INN + RNN

            dSNN2t = tf.gradients(SNN, T_it)[0]
            dINN2t = tf.gradients(INN, T_it)[0]
            dRNN2t = tf.gradients(RNN, T_it)[0]
            dN_NN2t = tf.gradients(N_NN, T_it)[0]

            temp_snn2t = -beta * SNN * INN
            temp_inn2t = beta * SNN * INN - gamma * INN
            temp_rnn2t = gamma * INN

            if str.lower(
                    R['loss_function']) == 'l2_loss' and R['scale_up'] == 0:
                # LossS_Net_obs = tf.reduce_mean(tf.square(SNN - S_observe))
                LossI_Net_obs = tf.reduce_mean(tf.square(INN - I_observe))
                # LossR_Net_obs = tf.reduce_mean(tf.square(RNN - R_observe))
                LossN_Net_obs = tf.reduce_mean(tf.square(N_NN - N_observe))

                Loss2dS = tf.reduce_mean(tf.square(dSNN2t - temp_snn2t))
                Loss2dI = tf.reduce_mean(tf.square(dINN2t - temp_inn2t))
                Loss2dR = tf.reduce_mean(tf.square(dRNN2t - temp_rnn2t))
                Loss2dN = tf.reduce_mean(tf.square(dN_NN2t))
            elif str.lower(
                    R['loss_function']) == 'l2_loss' and R['scale_up'] == 1:
                scale_up = R['scale_factor']
                # LossS_Net_obs = tf.reduce_mean(tf.square(scale_up*SNN - scale_up*S_observe))
                LossI_Net_obs = tf.reduce_mean(
                    tf.square(scale_up * INN - scale_up * I_observe))
                # LossR_Net_obs = tf.reduce_mean(tf.square(scale_up*RNN - scale_up*R_observe))
                LossN_Net_obs = tf.reduce_mean(
                    tf.square(scale_up * N_NN - scale_up * N_observe))

                Loss2dS = tf.reduce_mean(
                    tf.square(scale_up * dSNN2t - scale_up * temp_snn2t))
                Loss2dI = tf.reduce_mean(
                    tf.square(scale_up * dINN2t - scale_up * temp_inn2t))
                Loss2dR = tf.reduce_mean(
                    tf.square(scale_up * dRNN2t - scale_up * temp_rnn2t))
                Loss2dN = tf.reduce_mean(tf.square(scale_up * dN_NN2t))
            elif str.lower(R['loss_function']) == 'lncosh_loss':
                # LossS_Net_obs = tf.reduce_mean(tf.ln(tf.cosh(SNN - S_observe)))
                LossI_Net_obs = tf.reduce_mean(tf.log(tf.cosh(INN -
                                                              I_observe)))
                # LossR_Net_obs = tf.reduce_mean(tf.log(tf.cosh(RNN - R_observe)))
                LossN_Net_obs = tf.reduce_mean(
                    tf.log(tf.cosh(N_NN - N_observe)))

                Loss2dS = tf.reduce_mean(tf.log(tf.cosh(dSNN2t - temp_snn2t)))
                Loss2dI = tf.reduce_mean(tf.log(tf.cosh(dINN2t - temp_inn2t)))
                Loss2dR = tf.reduce_mean(tf.log(tf.cosh(dRNN2t - temp_rnn2t)))
                Loss2dN = tf.reduce_mean(tf.log(tf.cosh(dN_NN2t)))

            if R['regular_weight_model'] == 'L1':
                regular_WB2S = DNN_base.regular_weights_biases_L1(
                    Weight2S, Bias2S)
                regular_WB2I = DNN_base.regular_weights_biases_L1(
                    Weight2I, Bias2I)
                regular_WB2R = DNN_base.regular_weights_biases_L1(
                    Weight2R, Bias2R)
                regular_WB2Beta = DNN_base.regular_weights_biases_L1(
                    Weight2beta, Bias2beta)
                regular_WB2Gamma = DNN_base.regular_weights_biases_L1(
                    Weight2gamma, Bias2gamma)
            elif R['regular_weight_model'] == 'L2':
                regular_WB2S = DNN_base.regular_weights_biases_L2(
                    Weight2S, Bias2S)
                regular_WB2I = DNN_base.regular_weights_biases_L2(
                    Weight2I, Bias2I)
                regular_WB2R = DNN_base.regular_weights_biases_L2(
                    Weight2R, Bias2R)
                regular_WB2Beta = DNN_base.regular_weights_biases_L2(
                    Weight2beta, Bias2beta)
                regular_WB2Gamma = DNN_base.regular_weights_biases_L2(
                    Weight2gamma, Bias2gamma)
            else:
                regular_WB2S = tf.constant(0.0)
                regular_WB2I = tf.constant(0.0)
                regular_WB2R = tf.constant(0.0)
                regular_WB2Beta = tf.constant(0.0)
                regular_WB2Gamma = tf.constant(0.0)

            PWB2S = wb_penalty * regular_WB2S
            PWB2I = wb_penalty * regular_WB2I
            PWB2R = wb_penalty * regular_WB2R
            PWB2Beta = wb_penalty * regular_WB2Beta
            PWB2Gamma = wb_penalty * regular_WB2Gamma

            Loss2S = Loss2dS + PWB2S
            Loss2I = predict_true_penalty * LossI_Net_obs + Loss2dI + PWB2I
            Loss2R = Loss2dR + PWB2R
            Loss2N = predict_true_penalty * LossN_Net_obs + Loss2dN
            Loss = Loss2S + Loss2I + Loss2R + Loss2N + PWB2Beta + PWB2Gamma

            my_optimizer = tf.train.AdamOptimizer(in_learning_rate)
            if R['train_model'] == 'train_group':
                train_Loss2S = my_optimizer.minimize(Loss2S,
                                                     global_step=global_steps)
                train_Loss2I = my_optimizer.minimize(Loss2I,
                                                     global_step=global_steps)
                train_Loss2R = my_optimizer.minimize(Loss2R,
                                                     global_step=global_steps)
                train_Loss2N = my_optimizer.minimize(Loss2N,
                                                     global_step=global_steps)
                train_Loss = my_optimizer.minimize(Loss,
                                                   global_step=global_steps)
                train_Losses = tf.group(train_Loss2S, train_Loss2I,
                                        train_Loss2R, train_Loss2N, train_Loss)
            elif R['train_model'] == 'train_union_loss':
                train_Losses = my_optimizer.minimize(Loss,
                                                     global_step=global_steps)

    t0 = time.time()
    loss_s_all, loss_i_all, loss_r_all, loss_n_all, loss_all = [], [], [], [], []
    test_epoch = []
    test_mse2I_all, test_rel2I_all = [], []

    # filename = 'data2csv/Wuhan.csv'
    # filename = 'data2csv/Italia_data.csv'
    filename = 'data2csv/Korea_data.csv'
    date, data = DNN_data.load_csvData(filename)

    assert (trainSet_szie + batchSize_test <= len(data))
    train_date, train_data2i, test_date, test_data2i = \
        DNN_data.split_csvData2train_test(date, data, size2train=trainSet_szie, normalFactor=R['scale_population'])

    if R['scale_population'] == 1:
        nbatch2train = np.ones(batchSize_train, dtype=np.float32) * float(
            R['total_population'])
    elif (R['total_population'] !=
          R['scale_population']) and R['scale_population'] != 1:
        nbatch2train = np.ones(batchSize_train, dtype=np.float32) * (
            float(R['total_population']) / float(R['scale_population']))
    elif (R['total_population']
          == R['scale_population']) and R['scale_population'] != 1:
        nbatch2train = np.ones(batchSize_train, dtype=np.float32)

    # 对于时间数据来说,验证模型的合理性,要用连续的时间数据验证
    test_t_bach = DNN_data.sample_testDays_serially(test_date, batchSize_test)
    i_obs_test = DNN_data.sample_testData_serially(test_data2i,
                                                   batchSize_test,
                                                   normalFactor=1.0)
    print('The test data about i:\n', str(np.transpose(i_obs_test)))
    print('\n')
    DNN_tools.log_string(
        'The test data about i:\n%s\n' % str(np.transpose(i_obs_test)),
        log_fileout)

    # ConfigProto 加上allow_soft_placement=True就可以使用 gpu 了
    config = tf.ConfigProto(allow_soft_placement=True)  # 创建sess的时候对sess进行参数配置
    config.gpu_options.allow_growth = True  # True是让TensorFlow在运行过程中动态申请显存,避免过多的显存占用。
    config.allow_soft_placement = True  # 当指定的设备不存在时,允许选择一个存在的设备运行。比如gpu不存在,自动降到cpu上运行
    with tf.Session(config=config) as sess:
        sess.run(tf.global_variables_initializer())
        tmp_lr = learning_rate
        for i_epoch in range(R['max_epoch'] + 1):
            t_batch, i_obs = \
                DNN_data.randSample_Normalize_existData(train_date, train_data2i, batchsize=batchSize_train,
                                                        normalFactor=1.0, sampling_opt=R['opt2sample'])
            n_obs = nbatch2train.reshape(batchSize_train, 1)
            tmp_lr = tmp_lr * (1 - lr_decay)
            train_option = True
            if R['activate_stage_penalty'] == 1:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_pt = pt_penalty_init
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_pt = 10 * pt_penalty_init
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_pt = 50 * pt_penalty_init
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_pt = 100 * pt_penalty_init
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_pt = 200 * pt_penalty_init
                else:
                    temp_penalty_pt = 500 * pt_penalty_init
            elif R['activate_stage_penalty'] == 2:
                if i_epoch < int(R['max_epoch'] / 3):
                    temp_penalty_pt = pt_penalty_init
                elif i_epoch < 2 * int(R['max_epoch'] / 3):
                    temp_penalty_pt = 10 * pt_penalty_init
                else:
                    temp_penalty_pt = 50 * pt_penalty_init
            else:
                temp_penalty_pt = pt_penalty_init

            _, loss_s, loss_i, loss_r, loss_n, loss, pwb2s, pwb2i, pwb2r = sess.run(
                [
                    train_Losses, Loss2S, Loss2I, Loss2R, Loss2N, Loss, PWB2S,
                    PWB2I, PWB2R
                ],
                feed_dict={
                    T_it: t_batch,
                    I_observe: i_obs,
                    N_observe: n_obs,
                    in_learning_rate: tmp_lr,
                    train_opt: train_option,
                    predict_true_penalty: temp_penalty_pt
                })

            loss_s_all.append(loss_s)
            loss_i_all.append(loss_i)
            loss_r_all.append(loss_r)
            loss_n_all.append(loss_n)
            loss_all.append(loss)

            if i_epoch % 1000 == 0:
                # 以下代码为输出训练过程中 S_NN, I_NN, R_NN, beta, gamma 的训练结果
                DNN_LogPrint.print_and_log2train(i_epoch,
                                                 time.time() - t0,
                                                 tmp_lr,
                                                 temp_penalty_pt,
                                                 pwb2s,
                                                 pwb2i,
                                                 pwb2r,
                                                 loss_s,
                                                 loss_i,
                                                 loss_r,
                                                 loss_n,
                                                 loss,
                                                 log_out=log_fileout)

                s_nn2train, i_nn2train, r_nn2train = sess.run(
                    [SNN, INN, RNN],
                    feed_dict={T_it: np.reshape(train_date, [-1, 1])})

                # 以下代码为输出训练过程中 S_NN, I_NN, R_NN, beta, gamma 的测试结果
                test_epoch.append(i_epoch / 1000)
                train_option = False
                s_nn2test, i_nn2test, r_nn2test, beta_test, gamma_test = sess.run(
                    [SNN, INN, RNN, beta, gamma],
                    feed_dict={
                        T_it: test_t_bach,
                        train_opt: train_option
                    })
                point_ERR2I = np.square(i_nn2test - i_obs_test)
                test_mse2I = np.mean(point_ERR2I)
                test_mse2I_all.append(test_mse2I)
                test_rel2I = test_mse2I / np.mean(np.square(i_obs_test))
                test_rel2I_all.append(test_rel2I)

                DNN_tools.print_and_log_test_one_epoch(test_mse2I,
                                                       test_rel2I,
                                                       log_out=log_fileout)
                DNN_tools.log_string(
                    '------------------The epoch----------------------: %s\n' %
                    str(i_epoch), log2testSolus)
                DNN_tools.log_string(
                    'The test result for s:\n%s\n' %
                    str(np.transpose(s_nn2test)), log2testSolus)
                DNN_tools.log_string(
                    'The test result for i:\n%s\n' %
                    str(np.transpose(i_nn2test)), log2testSolus)
                DNN_tools.log_string(
                    'The test result for r:\n%s\n\n' %
                    str(np.transpose(r_nn2test)), log2testSolus)

                # --------以下代码为输出训练过程中 S_NN_temp, I_NN_temp, R_NN_temp, in_beta, in_gamma 的测试结果-------------
                s_nn_temp2test, i_nn_temp2test, r_nn_temp2test, in_beta_test, in_gamma_test = sess.run(
                    [SNN_temp, INN_temp, RNN_temp, in_beta, in_gamma],
                    feed_dict={
                        T_it: test_t_bach,
                        train_opt: train_option
                    })

                DNN_tools.log_string(
                    '------------------The epoch----------------------: %s\n' %
                    str(i_epoch), log2testSolus2)
                DNN_tools.log_string(
                    'The test result for s_temp:\n%s\n' %
                    str(np.transpose(s_nn_temp2test)), log2testSolus2)
                DNN_tools.log_string(
                    'The test result for i_temp:\n%s\n' %
                    str(np.transpose(i_nn_temp2test)), log2testSolus2)
                DNN_tools.log_string(
                    'The test result for r_temp:\n%s\n\n' %
                    str(np.transpose(r_nn_temp2test)), log2testSolus2)

                DNN_tools.log_string(
                    '------------------The epoch----------------------: %s\n' %
                    str(i_epoch), log2testParas)
                DNN_tools.log_string(
                    'The test result for in_beta:\n%s\n' %
                    str(np.transpose(in_beta_test)), log2testParas)
                DNN_tools.log_string(
                    'The test result for in_gamma:\n%s\n' %
                    str(np.transpose(in_gamma_test)), log2testParas)

        DNN_tools.log_string(
            'The train result for S:\n%s\n' % str(np.transpose(s_nn2train)),
            log2trianSolus)
        DNN_tools.log_string(
            'The train result for I:\n%s\n' % str(np.transpose(i_nn2train)),
            log2trianSolus)
        DNN_tools.log_string(
            'The train result for R:\n%s\n\n' % str(np.transpose(r_nn2train)),
            log2trianSolus)

        saveData.true_value2convid(train_data2i,
                                   name2Array='itrue2train',
                                   outPath=R['FolderName'])
        saveData.save_Solu2mat_Covid(s_nn2train,
                                     name2solus='s2train',
                                     outPath=R['FolderName'])
        saveData.save_Solu2mat_Covid(i_nn2train,
                                     name2solus='i2train',
                                     outPath=R['FolderName'])
        saveData.save_Solu2mat_Covid(r_nn2train,
                                     name2solus='r2train',
                                     outPath=R['FolderName'])

        saveData.save_SIR_trainLoss2mat_Covid(loss_s_all,
                                              loss_i_all,
                                              loss_r_all,
                                              loss_n_all,
                                              actName=act_func2SIR,
                                              outPath=R['FolderName'])

        plotData.plotTrain_loss_1act_func(loss_s_all,
                                          lossType='loss2s',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'],
                                          yaxis_scale=True)
        plotData.plotTrain_loss_1act_func(loss_i_all,
                                          lossType='loss2i',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'],
                                          yaxis_scale=True)
        plotData.plotTrain_loss_1act_func(loss_r_all,
                                          lossType='loss2r',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'],
                                          yaxis_scale=True)
        plotData.plotTrain_loss_1act_func(loss_n_all,
                                          lossType='loss2n',
                                          seedNo=R['seed'],
                                          outPath=R['FolderName'],
                                          yaxis_scale=True)

        saveData.true_value2convid(i_obs_test,
                                   name2Array='i_true2test',
                                   outPath=R['FolderName'])
        saveData.save_testMSE_REL2mat(test_mse2I_all,
                                      test_rel2I_all,
                                      actName='Infected',
                                      outPath=R['FolderName'])
        plotData.plotTest_MSE_REL(test_mse2I_all,
                                  test_rel2I_all,
                                  test_epoch,
                                  actName='Infected',
                                  seedNo=R['seed'],
                                  outPath=R['FolderName'],
                                  yaxis_scale=True)
        saveData.save_SIR_testSolus2mat_Covid(s_nn2test,
                                              i_nn2test,
                                              r_nn2test,
                                              name2solus1='snn2test',
                                              name2solus2='inn2test',
                                              name2solus3='rnn2test',
                                              outPath=R['FolderName'])
        saveData.save_SIR_testParas2mat_Covid(beta_test,
                                              gamma_test,
                                              name2para1='beta2test',
                                              name2para2='gamma2test',
                                              outPath=R['FolderName'])

        plotData.plot_testSolu2convid(i_obs_test,
                                      name2solu='i_true',
                                      coord_points2test=test_t_bach,
                                      outPath=R['FolderName'])
        plotData.plot_testSolu2convid(s_nn2test,
                                      name2solu='s_test',
                                      coord_points2test=test_t_bach,
                                      outPath=R['FolderName'])
        plotData.plot_testSolu2convid(i_nn2test,
                                      name2solu='i_test',
                                      coord_points2test=test_t_bach,
                                      outPath=R['FolderName'])
        plotData.plot_testSolu2convid(r_nn2test,
                                      name2solu='r_test',
                                      coord_points2test=test_t_bach,
                                      outPath=R['FolderName'])

        plotData.plot_testSolus2convid(i_obs_test,
                                       i_nn2test,
                                       name2solu1='i_true',
                                       name2solu2='i_test',
                                       coord_points2test=test_t_bach,
                                       seedNo=R['seed'],
                                       outPath=R['FolderName'])

        plotData.plot_testSolu2convid(beta_test,
                                      name2solu='beta_test',
                                      coord_points2test=test_t_bach,
                                      outPath=R['FolderName'])
        plotData.plot_testSolu2convid(gamma_test,
                                      name2solu='gamma_test',
                                      coord_points2test=test_t_bach,
                                      outPath=R['FolderName'])
def solve_Multiscale_PDE(R):
    log_out_path = R['FolderName']        # 将路径从字典 R 中提取出来
    if not os.path.exists(log_out_path):  # 判断路径是否已经存在
        os.mkdir(log_out_path)            # 无 log_out_path 路径,创建一个 log_out_path 路径
    logfile_name = '%s_%s.txt' % ('log2train', R['name2act_hidden'])
    log_fileout = open(os.path.join(log_out_path, logfile_name), 'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件
    DNN_Log_Print.dictionary_out2file(R, log_fileout)

    # 问题需要的设置
    batchsize_it = R['batch_size2interior']
    batchsize_bd = R['batch_size2boundary']

    bd_penalty_init = R['init_boundary_penalty']           # Regularization parameter for boundary conditions
    penalty2WB = R['penalty2weight_biases']                # Regularization parameter for weights and biases
    lr_decay = R['learning_rate_decay']
    learning_rate = R['learning_rate']
    hidden_layers = R['hidden_layers']
    actIn_func = R['name2act_in']
    act_func = R['name2act_hidden']
    actOut_func = R['name2act_out']

    input_dim = R['input_dim']
    out_dim = R['output_dim']

    lambda2lncosh = R['lambda2lncosh']

    # pLaplace 算子需要的额外设置, 先预设一下
    p_index = 2
    epsilon = 0.1
    mesh_number = 2
    region_lb = 0.0
    region_rt = 1.0

    if R['PDE_type'] == 'general_Laplace':
        # -laplace u = f
        region_lb = 0.0
        region_rt = 1.0
        f, u_true, u_left, u_right, u_bottom, u_top = General_Laplace.get_infos2Laplace_2D(
            input_dim=input_dim, out_dim=out_dim, left_bottom=region_lb, right_top=region_rt, equa_name=R['equa_name'])
    elif R['PDE_type'] == 'pLaplace_implicit':
        p_index = R['order2pLaplace_operator']
        epsilon = R['epsilon']
        mesh_number = R['mesh_number']
        if R['equa_name'] == 'multi_scale2D_5':
            region_lb = 0.0
            region_rt = 1.0
        else:
            region_lb = -1.0
            region_rt = 1.0
        u_true, f, A_eps, u_left, u_right, u_bottom, u_top = MS_LaplaceEqs.get_infos2pLaplace_2D(
            input_dim=input_dim, out_dim=out_dim, mesh_number=R['mesh_number'], intervalL=0.0, intervalR=1.0,
            equa_name=R['equa_name'])
    elif R['PDE_type'] == 'pLaplace_explicit':
        p_index = R['order2pLaplace_operator']
        epsilon = R['epsilon']
        mesh_number = R['mesh_number']
        if R['equa_name'] == 'multi_scale2D_7':
            region_lb = 0.0
            region_rt = 1.0
            u_true = MS_LaplaceEqs.true_solution2E7(input_dim, out_dim, eps=epsilon)
            u_left, u_right, u_bottom, u_top = MS_LaplaceEqs.boundary2E7(
                input_dim, out_dim, region_lb, region_rt, eps=epsilon)
            A_eps = MS_LaplaceEqs.elliptic_coef2E7(input_dim, out_dim, eps=epsilon)
    elif R['PDE_type'] == 'Possion_Boltzmann':
        # 求解如下方程, A_eps(x) 震荡的比较厉害,具有多个尺度
        #       d      ****         d         ****
        #   -  ----   |  A_eps(x)* ---- u_eps(x) | + Ku_eps =f(x), x \in R^n
        #       dx     ****         dx        ****
        # region_lb = -1.0
        region_lb = 0.0
        region_rt = 1.0
        p_index = R['order2pLaplace_operator']
        epsilon = R['epsilon']
        mesh_number = R['mesh_number']
        A_eps, kappa, u_true, u_left, u_right, u_top, u_bottom, f = MS_BoltzmannEqs.get_infos2Boltzmann_2D(
            equa_name=R['equa_name'], intervalL=region_lb, intervalR=region_rt)
    elif R['PDE_type'] == 'Convection_diffusion':
        region_lb = -1.0
        region_rt = 1.0
        p_index = R['order2pLaplace_operator']
        epsilon = R['epsilon']
        mesh_number = R['mesh_number']
        A_eps, Bx, By, u_true, u_left, u_right, u_top, u_bottom, f = MS_ConvectionEqs.get_infos2Convection_2D(
            equa_name=R['equa_name'], eps=epsilon, region_lb=0.0, region_rt=1.0)

    # 初始化权重和和偏置
    flag1 = 'WB'
    if R['model2NN'] == 'DNN_FourierBase':
        W2NN, B2NN = DNN_base.Xavier_init_NN_Fourier(input_dim, out_dim, hidden_layers, flag1)
    else:
        W2NN, B2NN = DNN_base.Xavier_init_NN(input_dim, out_dim, hidden_layers, flag1)

    global_steps = tf.compat.v1.Variable(0, trainable=False)
    with tf.device('/gpu:%s' % (R['gpuNo'])):
        with tf.compat.v1.variable_scope('vscope', reuse=tf.compat.v1.AUTO_REUSE):
            XY_it = tf.compat.v1.placeholder(tf.float32, name='X_it', shape=[None, input_dim])                # * 行 2 列
            XY_left = tf.compat.v1.placeholder(tf.float32, name='X_left_bd', shape=[None, input_dim])      # * 行 2 列
            XY_right = tf.compat.v1.placeholder(tf.float32, name='X_right_bd', shape=[None, input_dim])    # * 行 2 列
            XY_bottom = tf.compat.v1.placeholder(tf.float32, name='Y_bottom_bd', shape=[None, input_dim])  # * 行 2 列
            XY_top = tf.compat.v1.placeholder(tf.float32, name='Y_top_bd', shape=[None, input_dim])        # * 行 2 列
            boundary_penalty = tf.compat.v1.placeholder_with_default(input=1e3, shape=[], name='bd_p')
            in_learning_rate = tf.compat.v1.placeholder_with_default(input=1e-5, shape=[], name='lr')

            # 供选择的网络模式
            if R['model2NN'] == 'DNN':
                UNN = DNN_base.DNN(XY_it, W2NN, B2NN, hidden_layers, activateIn_name=actIn_func, activate_name=act_func,
                                   activateOut_name=actOut_func)
                UNN_left = DNN_base.DNN(XY_left, W2NN, B2NN, hidden_layers, activateIn_name=actIn_func,
                                        activate_name=act_func, activateOut_name=actOut_func)
                UNN_right = DNN_base.DNN(XY_right, W2NN, B2NN, hidden_layers, activateIn_name=actIn_func,
                                         activate_name=act_func, activateOut_name=actOut_func)
                UNN_bottom = DNN_base.DNN(XY_bottom, W2NN, B2NN, hidden_layers, activateIn_name=actIn_func,
                                          activate_name=act_func, activateOut_name=actOut_func)
                UNN_top = DNN_base.DNN(XY_top, W2NN, B2NN, hidden_layers, activateIn_name=actIn_func,
                                       activate_name=act_func, activateOut_name=actOut_func)
            elif R['model2NN'] == 'DNN_scale':
                freq = R['freq']
                UNN = DNN_base.DNN_scale(XY_it, W2NN, B2NN, hidden_layers, freq, activateIn_name=actIn_func,
                                         activate_name=act_func, activateOut_name=actOut_func)
                UNN_left = DNN_base.DNN_scale(XY_left, W2NN, B2NN, hidden_layers, freq, activateIn_name=actIn_func,
                                              activate_name=act_func, activateOut_name=actOut_func)
                UNN_right = DNN_base.DNN_scale(XY_right, W2NN, B2NN, hidden_layers, freq, activateIn_name=actIn_func,
                                               activate_name=act_func, activateOut_name=actOut_func)
                UNN_bottom = DNN_base.DNN_scale(XY_bottom, W2NN, B2NN, hidden_layers, freq, activateIn_name=actIn_func,
                                                activate_name=act_func, activateOut_name=actOut_func)
                UNN_top = DNN_base.DNN_scale(XY_top, W2NN, B2NN, hidden_layers, freq, activateIn_name=actIn_func,
                                             activate_name=act_func, activateOut_name=actOut_func)
            elif R['model2NN'] == 'DNN_adapt_scale':
                freqs = R['freq']
                UNN = DNN_base.DNN_adapt_scale(XY_it, W2NN, B2NN, hidden_layers, freqs, activateIn_name=actIn_func,
                                               activate_name=act_func, activateOut_name=actOut_func)
                UNN_left = DNN_base.DNN_adapt_scale(XY_left, W2NN, B2NN, hidden_layers, freqs, activateIn_name=actIn_func,
                                                    activate_name=act_func, activateOut_name=actOut_func)
                UNN_right = DNN_base.DNN_adapt_scale(XY_right, W2NN, B2NN, hidden_layers, freqs, activateIn_name=actIn_func,
                                                     activate_name=act_func, activateOut_name=actOut_func)
                UNN_bottom = DNN_base.DNN_adapt_scale(XY_bottom, W2NN, B2NN, hidden_layers, freqs, activateIn_name=actIn_func,
                                                      activate_name=act_func, activateOut_name=actOut_func)
                UNN_top = DNN_base.DNN_adapt_scale(XY_top, W2NN, B2NN, hidden_layers, freqs, activateIn_name=actIn_func,
                                                   activate_name=act_func, activateOut_name=actOut_func)
            elif R['model2NN'] == 'DNN_FourierBase':
                freqs = R['freq']
                UNN = DNN_base.DNN_FourierBase(XY_it, W2NN, B2NN, hidden_layers, freqs, activate_name=act_func,
                                               activateOut_name=actOut_func, sFourier=R['sfourier'])
                UNN_left = DNN_base.DNN_FourierBase(XY_left, W2NN, B2NN, hidden_layers, freqs, activate_name=act_func,
                                                    activateOut_name=actOut_func, sFourier=R['sfourier'])
                UNN_right = DNN_base.DNN_FourierBase(XY_right, W2NN, B2NN, hidden_layers, freqs, activate_name=act_func,
                                                     activateOut_name=actOut_func, sFourier=R['sfourier'])
                UNN_bottom = DNN_base.DNN_FourierBase(XY_bottom, W2NN, B2NN, hidden_layers, freqs, activate_name=act_func,
                                                      activateOut_name=actOut_func, sFourier=R['sfourier'])
                UNN_top = DNN_base.DNN_FourierBase(XY_top, W2NN, B2NN, hidden_layers, freqs, activate_name=act_func,
                                                   activateOut_name=actOut_func, sFourier=R['sfourier'])

            X_it = tf.reshape(XY_it[:, 0], shape=[-1, 1])
            Y_it = tf.reshape(XY_it[:, 1], shape=[-1, 1])
            # 变分形式的loss of interior,训练得到的 UNN 是 * 行 1 列
            if R['loss_type'] == 'variational_loss':
                dUNN = tf.gradients(UNN, XY_it)[0]                                                       # * 行 2 列
                dUNN_Norm = tf.reshape(tf.sqrt(tf.reduce_sum(tf.square(dUNN), axis=-1)), shape=[-1, 1])  # 按行求和
                if R['PDE_type'] == 'general_Laplace':
                    dUNN_2Norm = tf.square(dUNN_Norm)
                    loss_it_variational = (1.0 / 2) * dUNN_2Norm - \
                                          tf.multiply(tf.reshape(f(X_it, Y_it), shape=[-1, 1]), UNN)
                elif R['PDE_type'] == 'pLaplace_explicit' or R['PDE_type'] == 'pLaplace_implicit':
                    a_eps = A_eps(X_it, Y_it)                                     # * 行 1 列
                    AdUNN_pNorm = tf.multiply(a_eps, tf.pow(dUNN_Norm, p_index))
                    if R['equa_name'] == 'multi_scale2D_7':
                        fxy = MS_LaplaceEqs.get_force_side2MS_E7(x=X_it, y=Y_it)
                        loss_it_variational = (1.0 / p_index) * AdUNN_pNorm - \
                                              tf.multiply(tf.reshape(fxy, shape=[-1, 1]), UNN)
                    else:
                        loss_it_variational = (1.0 / p_index) * AdUNN_pNorm - \
                                              tf.multiply(tf.reshape(f(X_it, Y_it), shape=[-1, 1]), UNN)
                elif R['PDE_type'] == 'Possion_Boltzmann':
                    a_eps = A_eps(X_it, Y_it)                          # * 行 1 列
                    Kappa = kappa(X_it, Y_it)                          # * 行 1 列
                    AdUNN_pNorm = a_eps * tf.pow(dUNN_Norm, p_index)   # * 行 1 列
                    if R['equa_name'] == 'Boltzmann3' or R['equa_name'] == 'Boltzmann4' or\
                            R['equa_name'] == 'Boltzmann5' or R['equa_name'] == 'Boltzmann6':
                        fxy = MS_BoltzmannEqs.get_foreside2Boltzmann2D(x=X_it, y=Y_it)
                        loss_it_variational = (1.0 / p_index) * (AdUNN_pNorm + Kappa*UNN*UNN) - \
                                          tf.multiply(tf.reshape(fxy, shape=[-1, 1]), UNN)
                    else:
                        loss_it_variational = (1.0 / p_index) * (AdUNN_pNorm + Kappa * UNN * UNN) - \
                                              tf.multiply(tf.reshape(f(X_it, Y_it), shape=[-1, 1]), UNN)
                loss_it = tf.reduce_mean(loss_it_variational)
            elif R['loss_type'] == 'lncosh_loss2Ritz':
                dUNN = tf.gradients(UNN, XY_it)[0]  # * 行 2 列
                dUNN_Norm = tf.reshape(tf.sqrt(tf.reduce_sum(tf.square(dUNN), axis=-1)), shape=[-1, 1])  # 按行求和
                if R['PDE_type'] == 'general_Laplace':
                    dUNN_2Norm = tf.square(dUNN_Norm)
                    loss_it_variational = (1.0 / 2) * dUNN_2Norm - \
                                          tf.multiply(tf.reshape(f(X_it, Y_it), shape=[-1, 1]), UNN)
                    cosh_loss_it = tf.cosh(lambda2lncosh * loss_it_variational)
                    loss_lncosh_it = (1.0 / lambda2lncosh)*tf.log(cosh_loss_it)
                elif R['PDE_type'] == 'pLaplace_explicit' or R['PDE_type'] == 'pLaplace_implicit':
                    a_eps = A_eps(X_it, Y_it)  # * 行 1 列
                    AdUNN_pNorm = tf.multiply(a_eps, tf.pow(dUNN_Norm, p_index))
                    if R['equa_name'] == 'multi_scale2D_7':
                        fxy = MS_LaplaceEqs.get_force_side2MS_E7(x=X_it, y=Y_it)
                        loss_it_variational = (1.0 / p_index) * AdUNN_pNorm - \
                                              tf.multiply(tf.reshape(fxy, shape=[-1, 1]), UNN)
                    else:
                        loss_it_variational = (1.0 / p_index) * AdUNN_pNorm - \
                                              tf.multiply(tf.reshape(f(X_it, Y_it), shape=[-1, 1]), UNN)
                    cosh_loss_it = tf.cosh(lambda2lncosh * loss_it_variational)
                    loss_lncosh_it = (1.0 / lambda2lncosh)*tf.log(cosh_loss_it)
                elif R['PDE_type'] == 'Possion_Boltzmann':
                    a_eps = A_eps(X_it, Y_it)  # * 行 1 列
                    Kappa = kappa(X_it, Y_it)  # * 行 1 列
                    AdUNN_pNorm = a_eps * tf.pow(dUNN_Norm, p_index)  # * 行 1 列
                    if R['equa_name'] == 'Boltzmann3' or R['equa_name'] == 'Boltzmann4' or \
                            R['equa_name'] == 'Boltzmann5' or R['equa_name'] == 'Boltzmann6':
                        fxy = MS_BoltzmannEqs.get_foreside2Boltzmann2D(x=X_it, y=Y_it)
                        loss_it_variational = (1.0 / p_index) * (AdUNN_pNorm + Kappa * UNN * UNN) - \
                                              tf.multiply(tf.reshape(fxy, shape=[-1, 1]), UNN)
                    else:
                        loss_it_variational = (1.0 / p_index) * (AdUNN_pNorm + Kappa * UNN * UNN) - \
                                              tf.multiply(tf.reshape(f(X_it, Y_it), shape=[-1, 1]), UNN)
                    cosh_loss_it = tf.cosh(lambda2lncosh * loss_it_variational)
                    loss_lncosh_it = (1.0 / lambda2lncosh)*tf.log(cosh_loss_it)
                loss_it = tf.reduce_mean(loss_lncosh_it)
            elif R['loss_type'] == 'L2_loss':
                dUNN = tf.gradients(UNN, XY_it)[0]  # * 行 2 列
                if R['PDE_type'] == 'general_Laplace':
                    dUNNx = tf.gather(dUNN, [0], axis=-1)
                    dUNNy = tf.gather(dUNN, [1], axis=-1)
                    dUNNxxy = tf.gradients(dUNNx, XY_it)[0]
                    dUNNyxy = tf.gradients(dUNNy, XY_it)[0]
                    dUNNxx = tf.gather(dUNNxxy, [0], axis=-1)
                    dUNNyy = tf.gather(dUNNyxy, [1], axis=-1)
                    # -Laplace U=f --> -Laplace U - f --> -(Laplace U + f)
                    loss_it_L2 = tf.add(dUNNxx, dUNNyy) + tf.reshape(f(X_it, Y_it), shape=[-1, 1])
                    square_loss_it = tf.square(loss_it_L2)
                elif R['PDE_type'] == 'Convection_diffusion':
                    a_eps = A_eps(X_it, Y_it)  # * 行 1 列
                    bx = Bx(X_it, Y_it)
                    by = By(X_it, Y_it)
                    dUNNx = tf.gather(dUNN, [0], axis=-1)
                    dUNNy = tf.gather(dUNN, [1], axis=-1)

                    dUNNxxy = tf.gradients(dUNNx, XY_it)[0]
                    dUNNyxy = tf.gradients(dUNNy, XY_it)[0]
                    dUNNxx = tf.gather(dUNNxxy, [0], axis=-1)
                    dUNNyy = tf.gather(dUNNyxy, [1], axis=-1)
                    ddUNN = tf.add(dUNNxx, dUNNyy)
                    bdUNN = bx * dUNNx + by * dUNNy
                    loss_it_L2 = -a_eps*ddUNN + bdUNN - f(X_it, Y_it)
                    square_loss_it = tf.square(loss_it_L2)
                elif R['PDE_type'] == 'pLaplace_explicit' or R['PDE_type'] == 'pLaplace_implicit':
                    a_eps = A_eps(X_it, Y_it)
                    dUNNxy_norm = tf.reshape(tf.sqrt(tf.reduce_sum(tf.square(dUNN), axis=-1)), shape=[-1, 1])  # 按行求和
                    dUNNx = tf.gather(dUNN, [0], axis=-1)
                    dUNNy = tf.gather(dUNN, [1], axis=-1)
                    if p_index == 2:
                        dUxdUnorm = dUNNx
                        dUydUnorm = dUNNy
                    else:
                        dUxdUnorm = tf.multiply(tf.pow(dUNNxy_norm, p_index - 2), dUNNx)
                        dUydUnorm = tf.multiply(tf.pow(dUNNxy_norm, p_index - 2), dUNNy)

                    AdUxdUnorm = tf.multiply(a_eps, dUxdUnorm)
                    AdUydUnorm = tf.multiply(a_eps, dUydUnorm)

                    dAdUxdUnorm_xy = tf.gradients(AdUxdUnorm, XY_it)[0]
                    dAdUydUnorm_xy = tf.gradients(AdUydUnorm, XY_it)[0]

                    dAdUxdUnorm_x = tf.gather(dAdUxdUnorm_xy, [0], axis=-1)
                    dAdUydUnorm_y = tf.gather(dAdUydUnorm_xy, [1], axis=-1)

                    div_AdUdUnorm = tf.add(dAdUxdUnorm_x, dAdUydUnorm_y)
                    loss_it_L2 = -div_AdUdUnorm - f(X_it, Y_it)
                    square_loss_it = tf.square(loss_it_L2)
                elif R['PDE_type'] == 'Possion_Boltzmann':
                    a_eps = A_eps(X_it, Y_it)
                    Kappa = kappa(X_it, Y_it)  # * 行 1 列
                    dUNNxy_norm = tf.reshape(tf.sqrt(tf.reduce_sum(tf.square(dUNN), axis=-1)), shape=[-1, 1])  # 按行求和
                    dUNNx = tf.gather(dUNN, [0], axis=-1)
                    dUNNy = tf.gather(dUNN, [1], axis=-1)
                    if p_index == 2:
                        dUxdUnorm = dUNNx
                        dUydUnorm = dUNNy
                    else:
                        dUxdUnorm = tf.multiply(tf.pow(dUNNxy_norm, p_index - 2), dUNNx)
                        dUydUnorm = tf.multiply(tf.pow(dUNNxy_norm, p_index - 2), dUNNy)

                    AdUxdUnorm = tf.multiply(a_eps, dUxdUnorm)
                    AdUydUnorm = tf.multiply(a_eps, dUydUnorm)

                    dAdUxdUnorm_xy = tf.gradients(AdUxdUnorm, XY_it)[0]
                    dAdUydUnorm_xy = tf.gradients(AdUydUnorm, XY_it)[0]

                    dAdUxdUnorm_x = tf.gather(dAdUxdUnorm_xy, [0], axis=-1)
                    dAdUydUnorm_y = tf.gather(dAdUydUnorm_xy, [1], axis=-1)

                    div_AdUdUnorm = tf.add(dAdUxdUnorm_x, dAdUydUnorm_y)
                    KU = tf.multiply(Kappa, UNN)
                    loss_it_L2 = -div_AdUdUnorm + KU - f(X_it, Y_it)
                    square_loss_it = tf.square(loss_it_L2)
                # loss_it = tf.reduce_mean(square_loss_it) * (region_rt - region_lb) * (region_rt - region_lb)
                loss_it = tf.reduce_mean(square_loss_it)

            U_left = u_left(tf.reshape(XY_left[:, 0], shape=[-1, 1]), tf.reshape(XY_left[:, 1], shape=[-1, 1]))
            U_right = u_right(tf.reshape(XY_right[:, 0], shape=[-1, 1]), tf.reshape(XY_right[:, 1], shape=[-1, 1]))
            U_bottom = u_bottom(tf.reshape(XY_bottom[:, 0], shape=[-1, 1]), tf.reshape(XY_bottom[:, 1], shape=[-1, 1]))
            U_top = u_top(tf.reshape(XY_top[:, 0], shape=[-1, 1]), tf.reshape(XY_top[:, 1], shape=[-1, 1]))
            if R['loss_type'] == 'lncosh_loss2Ritz':
                cosh_bd = tf.cosh(lambda2lncosh*(UNN_left-U_left))+tf.cosh(lambda2lncosh*(UNN_right-U_right)) + \
                          tf.cosh(lambda2lncosh * (UNN_bottom - U_bottom)) + tf.cosh(lambda2lncosh * (UNN_top - U_top))
                loss_cosh_bd = (1.0 / lambda2lncosh) * tf.log(cosh_bd)
                loss_bd = tf.reduce_mean(loss_cosh_bd)
            else:
                loss_bd_square = tf.square(UNN_left - U_left) + tf.square(UNN_right - U_right) + \
                                 tf.square(UNN_bottom - U_bottom) + tf.square(UNN_top - U_top)
                loss_bd = tf.reduce_mean(loss_bd_square)

            if R['regular_wb_model'] == 'L1':
                regularSum2WB = DNN_base.regular_weights_biases_L1(W2NN, B2NN)    # 正则化权重和偏置 L1正则化
            elif R['regular_wb_model'] == 'L2':
                regularSum2WB = DNN_base.regular_weights_biases_L2(W2NN, B2NN)    # 正则化权重和偏置 L2正则化
            else:
                regularSum2WB = tf.constant(0.0)                                  # 无正则化权重参数

            PWB = penalty2WB * regularSum2WB
            loss = loss_it + boundary_penalty * loss_bd + PWB                     # 要优化的loss function

            my_optimizer = tf.compat.v1.train.AdamOptimizer(in_learning_rate)
            if R['train_model'] == 'group3_training':
                train_op1 = my_optimizer.minimize(loss_it, global_step=global_steps)
                train_op2 = my_optimizer.minimize(loss_bd, global_step=global_steps)
                train_op3 = my_optimizer.minimize(loss, global_step=global_steps)
                train_my_loss = tf.group(train_op1, train_op2, train_op3)
            elif R['train_model'] == 'group2_training':
                train_op2bd = my_optimizer.minimize(loss_bd, global_step=global_steps)
                train_op2union = my_optimizer.minimize(loss, global_step=global_steps)
                train_my_loss = tf.group(train_op2bd, train_op2union)
            elif R['train_model'] == 'union_training':
                train_my_loss = my_optimizer.minimize(loss, global_step=global_steps)

            # 训练上的真解值和训练结果的误差
            if R['PDE_type'] == 'general_Laplace' or R['PDE_type'] == 'pLaplace_explicit' \
                        or R['PDE_type'] == 'Possion_Boltzmann' or R['PDE_type'] == 'Convection_diffusion':
                U_true = u_true(X_it, Y_it)
                train_mse = tf.reduce_mean(tf.square(U_true - UNN))
                train_rel = train_mse / tf.reduce_mean(tf.square(U_true))
            else:
                train_mse = tf.constant(0.0)
                train_rel = tf.constant(0.0)

    t0 = time.time()
    loss_it_all, loss_bd_all, loss_all, train_mse_all, train_rel_all = [], [], [], [], []  # 空列表, 使用 append() 添加元素
    test_mse_all, test_rel_all = [], []
    test_epoch = []

    if R['testData_model'] == 'random_generate':
        # 生成测试数据,用于测试训练后的网络
        test_bach_size = 1600
        size2test = 40
        # test_bach_size = 4900
        # size2test = 70
        # test_bach_size = 10000
        # size2test = 100
        # test_bach_size = 40000
        # size2test = 200
        test_xy_bach = DNN_data.rand_it(test_bach_size, input_dim, region_lb, region_rt)
        saveData.save_testData_or_solus2mat(test_xy_bach, dataName='testXY', outPath=R['FolderName'])
    else:
        if R['PDE_type'] == 'pLaplace_implicit' or R['PDE_type'] == 'pLaplace_explicit':
            test_xy_bach = Load_data2Mat.get_data2pLaplace(equation_name=R['equa_name'], mesh_number=mesh_number)
            size2batch = np.shape(test_xy_bach)[0]
            size2test = int(np.sqrt(size2batch))
            saveData.save_meshData2mat(test_xy_bach, dataName='meshXY', mesh_number=mesh_number, outPath=R['FolderName'])
        elif R['PDE_type'] == 'Possion_Boltzmann':
            if region_lb == (-1.0) and region_rt == 1.0:
                name2data_file = '11'
            else:
                name2data_file = '01'
            test_xy_bach = Load_data2Mat.get_meshData2Boltzmann(domain_lr=name2data_file, mesh_number=mesh_number)
            size2batch = np.shape(test_xy_bach)[0]
            size2test = int(np.sqrt(size2batch))
            saveData.save_meshData2mat(test_xy_bach, dataName='meshXY', mesh_number=mesh_number,
                                       outPath=R['FolderName'])
        elif R['PDE_type'] == 'Convection_diffusion':
            if region_lb == (-1.0) and region_rt == 1.0:
                name2data_file = '11'
            else:
                name2data_file = '01'
            test_xy_bach = Load_data2Mat.get_meshData2Boltzmann(domain_lr=name2data_file, mesh_number=mesh_number)
            size2batch = np.shape(test_xy_bach)[0]
            size2test = int(np.sqrt(size2batch))
            saveData.save_meshData2mat(test_xy_bach, dataName='meshXY', mesh_number=mesh_number,
                                       outPath=R['FolderName'])
        else:
            test_xy_bach = Load_data2Mat.get_randomData2mat(dim=input_dim, data_path='dataMat_highDim')
            size2batch = np.shape(test_xy_bach)[0]
            size2test = int(np.sqrt(size2batch))

    # ConfigProto 加上allow_soft_placement=True就可以使用 gpu 了
    config = tf.compat.v1.ConfigProto(allow_soft_placement=True)  # 创建sess的时候对sess进行参数配置
    config.gpu_options.allow_growth = True              # True是让TensorFlow在运行过程中动态申请显存,避免过多的显存占用。
    config.allow_soft_placement = True                  # 当指定的设备不存在时,允许选择一个存在的设备运行。比如gpu不存在,自动降到cpu上运行
    with tf.compat.v1.Session(config=config) as sess:
        sess.run(tf.compat.v1.global_variables_initializer())
        tmp_lr = learning_rate
        for i_epoch in range(R['max_epoch'] + 1):
            xy_it_batch = DNN_data.rand_it(batchsize_it, input_dim, region_a=region_lb, region_b=region_rt)
            xl_bd_batch, xr_bd_batch, yb_bd_batch, yt_bd_batch = DNN_data.rand_bd_2D(
                batchsize_bd, input_dim, region_a=region_lb, region_b=region_rt)
            tmp_lr = tmp_lr * (1 - lr_decay)
            if R['activate_penalty2bd_increase'] == 1:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_bd = bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_bd = 10 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_bd = 50 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_bd = 100 * bd_penalty_init
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_bd = 200 * bd_penalty_init
                else:
                    temp_penalty_bd = 500 * bd_penalty_init
            else:
                temp_penalty_bd = bd_penalty_init

            _, loss_it_tmp, loss_bd_tmp, loss_tmp, train_mse_tmp, train_rel_tmp, pwb = sess.run(
                [train_my_loss, loss_it, loss_bd, loss, train_mse, train_rel, PWB],
                feed_dict={XY_it: xy_it_batch, XY_left: xl_bd_batch, XY_right: xr_bd_batch,
                           XY_bottom: yb_bd_batch, XY_top: yt_bd_batch, in_learning_rate: tmp_lr,
                           boundary_penalty: temp_penalty_bd})

            loss_it_all.append(loss_it_tmp)
            loss_bd_all.append(loss_bd_tmp)
            loss_all.append(loss_tmp)
            train_mse_all.append(train_mse_tmp)
            train_rel_all.append(train_rel_tmp)

            if i_epoch % 1000 == 0:
                run_times = time.time() - t0
                DNN_Log_Print.print_and_log_train_one_epoch(
                    i_epoch, run_times, tmp_lr, temp_penalty_bd, pwb, loss_it_tmp, loss_bd_tmp, loss_tmp, train_mse_tmp,
                    train_rel_tmp, log_out=log_fileout)

                # ---------------------------   test network ----------------------------------------------
                test_epoch.append(i_epoch / 1000)
                if R['PDE_type'] == 'general_Laplace' or R['PDE_type'] == 'pLaplace_explicit' or \
                        R['PDE_type'] == 'Possion_Boltzmann' or R['PDE_type'] == 'Convection_diffusion':
                    u_true2test, unn2test = sess.run([U_true, UNN], feed_dict={XY_it: test_xy_bach})
                else:
                    u_true2test = u_true
                    unn2test = sess.run(UNN,  feed_dict={XY_it: test_xy_bach})

                point_square_error = np.square(u_true2test - unn2test)
                mse2test = np.mean(point_square_error)
                test_mse_all.append(mse2test)
                res2test = mse2test / np.mean(np.square(u_true2test))
                test_rel_all.append(res2test)

                DNN_Log_Print.print_and_log_test_one_epoch(mse2test, res2test, log_out=log_fileout)

    # ------------------- save the testing results into mat file and plot them -------------------------
    saveData.save_trainLoss2mat_1actFunc(loss_it_all, loss_bd_all, loss_all, actName=act_func,
                                         outPath=R['FolderName'])
    saveData.save_train_MSE_REL2mat(train_mse_all, train_rel_all, actName=act_func, outPath=R['FolderName'])

    plotData.plotTrain_loss_1act_func(loss_it_all, lossType='loss_it', seedNo=R['seed'], outPath=R['FolderName'])
    plotData.plotTrain_loss_1act_func(loss_bd_all, lossType='loss_bd', seedNo=R['seed'], outPath=R['FolderName'],
                                      yaxis_scale=True)
    plotData.plotTrain_loss_1act_func(loss_all, lossType='loss', seedNo=R['seed'], outPath=R['FolderName'])

    saveData.save_train_MSE_REL2mat(train_mse_all, train_rel_all, actName=act_func, outPath=R['FolderName'])
    plotData.plotTrain_MSE_REL_1act_func(train_mse_all, train_rel_all, actName=act_func, seedNo=R['seed'],
                                         outPath=R['FolderName'], yaxis_scale=True)

    # ----------------------  save testing results to mat files, then plot them --------------------------------
    saveData.save_2testSolus2mat(u_true2test, unn2test, actName='utrue', actName1=act_func,
                                 outPath=R['FolderName'])

    plotData.plot_Hot_solution2test(u_true2test, size_vec2mat=size2test, actName='Utrue', seedNo=R['seed'],
                                    outPath=R['FolderName'])
    plotData.plot_Hot_solution2test(unn2test, size_vec2mat=size2test, actName=act_func, seedNo=R['seed'],
                                    outPath=R['FolderName'])

    saveData.save_testMSE_REL2mat(test_mse_all, test_rel_all, actName=act_func, outPath=R['FolderName'])
    plotData.plotTest_MSE_REL(test_mse_all, test_rel_all, test_epoch, actName=act_func,
                              seedNo=R['seed'], outPath=R['FolderName'], yaxis_scale=True)

    saveData.save_test_point_wise_err2mat(point_square_error, actName=act_func, outPath=R['FolderName'])

    plotData.plot_Hot_point_wise_err(point_square_error, size_vec2mat=size2test, actName=act_func,
                                     seedNo=R['seed'], outPath=R['FolderName'])
Esempio n. 5
0
def solve_Multiscale_PDE(R):
    log_out_path = R['FolderName']                                     # 将路径从字典 R 中提取出来
    if not os.path.exists(log_out_path):                               # 判断路径是否已经存在
        os.mkdir(log_out_path)                                         # 无 log_out_path 路径,创建一个 log_out_path 路径
    logfile_name = '%s_%s.txt' % ('logTrain', R['name2act_hidden'])
    log_fileout = open(os.path.join(log_out_path, logfile_name), 'w')  # 在这个路径下创建并打开一个可写的 log_train.txt文件
    DNN_Log_Print.dictionary_out2file(R, log_fileout)

    # 一般 laplace 问题需要的设置
    batchsize_it = R['batch_size2interior']
    batchsize_bd = R['batch_size2boundary']

    bd_penalty_init = R['init_boundary_penalty']                # Regularization parameter for boundary conditions
    penalty2WB = R['penalty2weight_biases']                     # Regularization parameter for weights and biases
    lr_decay = R['learning_rate_decay']
    learning_rate = R['learning_rate']
    hidden_layers = R['hidden_layers']
    act_func = R['name2act_hidden']

    # ------- set the problem ---------
    input_dim = R['input_dim']
    out_dim = R['output_dim']

    region_l = 0.0
    region_r = 1.0
    if R['PDE_type'] == 'general_Laplace':
        # -laplace u = f
        region_l = 0.0
        region_r = 1.0
        f, u_true, u_left, u_right = General_Laplace.get_infos2Laplace_1D(
            input_dim=input_dim, out_dim=out_dim, intervalL=region_l, intervalR=region_r, equa_name=R['equa_name'])
    elif R['PDE_type'] == 'pLaplace':
        # 求解如下方程, A_eps(x) 震荡的比较厉害,具有多个尺度
        #       d      ****         d         ****
        #   -  ----   |  A_eps(x)* ---- u_eps(x) |  =f(x), x \in R^n
        #       dx     ****         dx        ****
        # 问题区域,每个方向设置为一样的长度。等网格划分,对于二维是方形区域
        p_index = R['order2pLaplace_operator']
        epsilon = R['epsilon']
        region_l = 0.0
        region_r = 1.0
        if R['equa_name'] == 'multi_scale':
            u_true, f, A_eps, u_left, u_right = MS_LaplaceEqs.get_infos2pLaplace_1D(
                in_dim=input_dim, out_dim=out_dim, intervalL=region_l, intervalR=region_r, index2p=p_index, eps=epsilon)
        elif R['equa_name'] == '3scale2':
            epsilon2 = 0.01
            u_true, A_eps, u_left, u_right = MS_LaplaceEqs.get_infos2pLaplace_1D_3scale2(
                in_dim=input_dim, out_dim=out_dim, intervalL=region_l, intervalR=region_r, index2p=p_index, eps1=epsilon,
                eps2=epsilon2)
        elif R['equa_name'] == 'rand_ceof':
            num2sun_term = 2
            Alpha = 1.2
            Xi1 = [-0.25, 0.25]
            Xi2 = [-0.3, 0.3]
            # Xi1 = np.random.uniform(-0.5, 0.5, num2sun_term)
            print('Xi1:', Xi1)
            print('\n')
            # Xi2 = np.random.uniform(-0.5, 0.5, num2sun_term)
            print('Xi2:', Xi2)
            print('\n')
            u_left, u_right = random2pLaplace.random_boundary()
        elif R['equa_name'] == 'rand_sin_ceof':
            Xi1=-0.25
            Xi2=0.25
            u_true, f, A_eps = random2pLaplace.random_equa2()
    elif R['PDE_type'] == 'Possion_Boltzmann':
        # 求解如下方程, A_eps(x) 震荡的比较厉害,具有多个尺度
        #       d      ****         d         ****
        #   -  ----   |  A_eps(x)* ---- u_eps(x) | + K(x)u_eps(x) =f(x), x \in R^n
        #       dx     ****         dx        ****
        p_index = R['order2pLaplace_operator']
        epsilon = R['epsilon']
        region_l = 0.0
        region_r = 1.0
        A_eps, kappa, u_true, u_left, u_right, f = MS_BoltzmannEqs.get_infos2Boltzmann_1D(
            in_dim=input_dim, out_dim=out_dim, region_a=region_l, region_b=region_r, index2p=p_index, eps=epsilon,
            eqs_name=R['equa_name'])

    # 初始化权重和和偏置
    flag1 = 'WB'
    if R['model2NN'] == 'DNN_FourierBase':
        Weights, Biases = DNN_base.Xavier_init_NN_Fourier(input_dim, out_dim, hidden_layers, flag1)
    else:
        Weights, Biases = DNN_base.Xavier_init_NN(input_dim, out_dim, hidden_layers, flag1)

    global_steps = tf.compat.v1.Variable(0, trainable=False)
    with tf.device('/gpu:%s' % (R['gpuNo'])):
        with tf.compat.v1.variable_scope('vscope', reuse=tf.compat.v1.AUTO_REUSE):
            X_it = tf.compat.v1.placeholder(tf.float32, name='X_it', shape=[None, input_dim])          # * 行 1 列
            X_left = tf.compat.v1.placeholder(tf.float32, name='X_left', shape=[None, input_dim])      # * 行 1 列
            X_right = tf.compat.v1.placeholder(tf.float32, name='X_right', shape=[None, input_dim])    # * 行 1 列
            bd_penalty = tf.compat.v1.placeholder_with_default(input=1e3, shape=[], name='bd_p')
            in_learning_rate = tf.compat.v1.placeholder_with_default(input=1e-5, shape=[], name='lr')

            # 供选择的网络模式
            if R['model2NN'] == 'DNN':
                UNN = DNN_base.DNN(X_it, Weights, Biases, hidden_layers, activateIn_name=R['name2act_in'],
                                   activate_name=R['name2act_hidden'], activateOut_name=R['activateOut_func'])
                UNN_left = DNN_base.DNN(X_left, Weights, Biases, hidden_layers, activateIn_name=R['name2act_in'],
                                        activate_name=R['name2act_hidden'], activateOut_name=R['name2act_out'])
                UNN_right = DNN_base.DNN(X_right, Weights, Biases, hidden_layers, activateIn_name=R['name2act_in'],
                                         activate_name=R['name2act_hidden'], activateOut_name=R['name2act_out'])
            elif R['model2NN'] == 'DNN_scale':
                freqs = R['freq']
                UNN = DNN_base.DNN_scale(X_it, Weights, Biases, hidden_layers, freqs, activateIn_name=R['name2act_in'],
                                         activate_name=act_func, activateOut_name=R['name2act_out'])
                UNN_left = DNN_base.DNN_scale(X_left, Weights, Biases, hidden_layers, freqs,
                                              activateIn_name=R['name2act_in'], activate_name=R['name2act_hidden'],
                                              activateOut_name=R['name2act_out'])
                UNN_right = DNN_base.DNN_scale(X_right, Weights, Biases, hidden_layers, freqs,
                                               activateIn_name=R['name2act_in'], activate_name=R['name2act_hidden'],
                                               activateOut_name=R['name2act_out'])
            elif R['model2NN'] == 'DNN_FourierBase':
                freqs = R['freq']
                UNN = DNN_base.DNN_FourierBase(X_it, Weights, Biases, hidden_layers, freqs,
                                               activate_name=act_func, activateOut_name=R['name2act_out'],
                                               sFourier=R['sfourier'])
                UNN_left = DNN_base.DNN_FourierBase(X_left, Weights, Biases, hidden_layers, freqs,
                                                    activate_name=act_func, activateOut_name=R['name2act_out'],
                                                    sFourier=R['sfourier'])
                UNN_right = DNN_base.DNN_FourierBase(X_right, Weights, Biases, hidden_layers, freqs,
                                                     activate_name=act_func, activateOut_name=R['name2act_out'],
                                                     sFourier=R['sfourier'])

            # 变分形式的loss of interior,训练得到的 UNN 是 * 行 1 列
            if R['loss_type'] == 'variational_loss':
                dUNN = tf.gradients(UNN, X_it)
                if R['PDE_type'] == 'general_Laplace':
                    dUNN_Norm = tf.reduce_sum(tf.square(dUNN), axis=-1)
                    loss_it_variational = (1.0 / 2) * tf.reshape(dUNN_Norm, shape=[-1, 1]) - \
                                           tf.multiply(tf.reshape(f(X_it), shape=[-1, 1]), UNN)
                elif R['PDE_type'] == 'pLaplace':
                    if R['equa_name'] == '3scale2':
                        a_eps = A_eps(X_it)                          # * 行 1 列
                        AdUNN_pNorm = tf.reduce_sum(a_eps * tf.pow(tf.abs(dUNN), p_index), axis=-1)
                        fx = MS_LaplaceEqs.force_sice_3scale2(X_it, eps1=R['epsilon'], eps2=0.01)
                        loss_it_variational = (1.0 / p_index) * tf.reshape(AdUNN_pNorm, shape=[-1, 1]) - \
                                              tf.multiply(tf.reshape(fx, shape=[-1, 1]), UNN)
                    elif R['equa_name'] == 'rand_ceof':
                        a_eps = random2pLaplace.rangdom_ceof(x=X_it, xi1=Xi1, xi2=Xi2, K=num2sun_term, alpha=Alpha)
                        # fx = random2pLaplace.rangdom_force(x=X_it, xi1=Xi1, xi2=Xi2, K=num2sun_term, alpha=Alpha)
                        # duf = tf.gradients(force_side, X_it)
                        fx = random2pLaplace.rangdom_diff_force2x(x=X_it, xi1=Xi1, xi2=Xi2, K=num2sun_term, alpha=Alpha)
                        AdUNN_pNorm = tf.reduce_sum(a_eps * tf.pow(tf.abs(dUNN), p_index), axis=-1)
                        loss_it_variational = (1.0 / p_index) * tf.reshape(AdUNN_pNorm, shape=[-1, 1]) - \
                                              tf.multiply(tf.reshape(fx, shape=[-1, 1]), UNN)
                    elif R['equa_name'] == 'rand_sin_ceof':
                        a_eps = 1.0
                        fx = random2pLaplace.random_sin_f(x=X_it, xi1=Xi1, xi2=Xi2, K=2, alpha=1.0)
                        AdUNN_pNorm = tf.reduce_sum(a_eps * tf.pow(tf.abs(dUNN), p_index), axis=-1)
                        loss_it_variational = (1.0 / p_index) * tf.reshape(AdUNN_pNorm, shape=[-1, 1]) - \
                                              tf.multiply(tf.reshape(fx, shape=[-1, 1]), UNN)
                    else:
                        # a_eps = A_eps(X_it)                          # * 行 1 列
                        a_eps = 1 / (2 + tf.cos(2 * np.pi * X_it / epsilon))
                        AdUNN_pNorm = tf.reduce_sum(a_eps * tf.pow(tf.abs(dUNN), p_index), axis=-1)
                        loss_it_variational = (1.0 / p_index) * tf.reshape(AdUNN_pNorm, shape=[-1, 1]) - \
                                               tf.multiply(tf.reshape(f(X_it), shape=[-1, 1]), UNN)
                elif R['PDE_type'] == 'Possion_Boltzmann':
                    # a_eps = A_eps(X_it)                          # * 行 1 列
                    a_eps = 1 / (2 + tf.cos(2 * np.pi * X_it / epsilon))
                    Kappa = kappa(X_it)
                    AdUNN_pNorm = tf.reduce_sum(a_eps * tf.pow(tf.abs(dUNN), p_index), axis=-1)
                    if R['equa_name'] == 'Boltzmann2':
                        fside = MS_BoltzmannEqs.get_force_side2Boltzmann_1D(X_it, index2p=p_index, eps=epsilon)
                    else:
                        fside = tf.reshape(f(X_it), shape=[-1, 1])
                    if p_index == 1:
                        loss_it_variational = (1.0 / 2) * (tf.reshape(AdUNN_pNorm, shape=[-1, 1]) +
                                               Kappa*UNN*UNN) - tf.multiply(fside, UNN)
                    elif p_index == 2:
                        loss_it_variational = (1.0 / 2) * (tf.reshape(AdUNN_pNorm, shape=[-1, 1]) +
                                               Kappa*UNN*UNN*UNN) - tf.multiply(fside, UNN)

                loss_it = tf.reduce_mean(loss_it_variational)
            elif R['loss_type'] == 'L2_loss':
                dUNN = tf.gradients(UNN, X_it)
                if R['PDE_type'] == 'general_Laplace':
                    ddUNN = tf.gradients(dUNN, X_it)
                    loss_it_L2 = -1.0*ddUNN - tf.reshape(f(X_it), shape=[-1, 1])
                    square_loss_it = tf.square(loss_it_L2)
                elif R['PDE_type'] == 'pLaplace':
                    a_eps = A_eps(X_it)
                    # a_eps = 1 / (2 + tf.cos(2 * np.pi * X_it / epsilon))
                    if p_index == 2.0:
                        AdUNNpNorm = 1.0*a_eps
                    elif p_index == 3.0:
                        dUNNp_2Nrom = tf.abs(dUNN)
                        AdUNNpNorm = tf.multiply(a_eps, dUNNp_2Nrom)
                    else:
                        dUNNp_2Nrom = tf.pow(tf.abs(dUNN), p_index-2.0)
                        AdUNNpNorm = tf.multiply(a_eps, dUNNp_2Nrom)
                    AdUNNpNorm_dUNN = tf.multiply(AdUNNpNorm, dUNN)
                    dAdUNNpNorm_dUNN = tf.gradients(AdUNNpNorm_dUNN, X_it)
                    if R['equa_name'] == '3scale2':
                        fx = MS_LaplaceEqs.force_sice_3scale2(X_it, eps1=R['epsilon'], eps2=0.01)
                        loss_it_L2 = dAdUNNpNorm_dUNN + tf.reshape(fx, shape=[-1, 1])
                    else:
                        loss_it_L2 = dAdUNNpNorm_dUNN + tf.reshape(f(X_it), shape=[-1, 1])
                    square_loss_it = tf.square(loss_it_L2)
                elif R['PDE_type'] == 'Possion_Boltzmann':
                    a_eps = A_eps(X_it)
                    # a_eps = 1 / (2 + tf.cos(2 * np.pi * X_it / epsilon))
                    Kappa = kappa(X_it)
                    if p_index == 2.0:
                        AdUNNpNorm = 1.0*a_eps
                    elif p_index == 3.0:
                        dUNNp_2Nrom = tf.abs(dUNN)
                        AdUNNpNorm = tf.multiply(a_eps, dUNNp_2Nrom)
                    else:
                        dUNNp_2Nrom = tf.pow(tf.abs(dUNN), p_index-2.0)
                        AdUNNpNorm = tf.multiply(a_eps, dUNNp_2Nrom)
                    AdUNNpNorm_dUNN = tf.multiply(AdUNNpNorm, dUNN)
                    dAdUNNpNorm_dUNN = tf.gradients(AdUNNpNorm_dUNN, X_it)
                    loss_it_L2 = -1.0*dAdUNNpNorm_dUNN + Kappa*UNN - tf.reshape(f(X_it), shape=[-1, 1])

                    square_loss_it = tf.square(loss_it_L2)

                # loss_it = tf.reduce_mean(loss_it_L2)*(region_r-region_l)
                loss_it = tf.reduce_mean(square_loss_it)

            U_left = u_left(X_left)
            U_right = u_right(X_right)
            loss_bd_square = tf.square(UNN_left - U_left) + tf.square(UNN_right - U_right)
            loss_bd = tf.reduce_mean(loss_bd_square)

            if R['regular_wb_model'] == 'L1':
                regularSum2WB = DNN_base.regular_weights_biases_L1(Weights, Biases)    # 正则化权重和偏置 L1正则化
            elif R['regular_wb_model'] == 'L2':
                regularSum2WB = DNN_base.regular_weights_biases_L2(Weights, Biases)    # 正则化权重和偏置 L2正则化
            else:
                regularSum2WB = tf.constant(0.0)                                       # 无正则化权重参数

            PWB = penalty2WB * regularSum2WB
            loss = loss_it + bd_penalty * loss_bd + PWB         # 要优化的loss function

            my_optimizer = tf.compat.v1.train.AdamOptimizer(in_learning_rate)
            if R['train_model'] == 'group3_training':
                train_op1 = my_optimizer.minimize(loss_it, global_step=global_steps)
                train_op2 = my_optimizer.minimize(loss_bd, global_step=global_steps)
                train_op3 = my_optimizer.minimize(loss, global_step=global_steps)
                train_my_loss = tf.group(train_op1, train_op2, train_op3)
            elif R['train_model'] == 'group2_training':
                train_op2 = my_optimizer.minimize(loss_bd, global_step=global_steps)
                train_op3 = my_optimizer.minimize(loss, global_step=global_steps)
                train_my_loss = tf.group(train_op2, train_op3)
            elif R['train_model'] == 'union_training':
                train_my_loss = my_optimizer.minimize(loss, global_step=global_steps)

            # 训练上的真解值和训练结果的误差
            if R['equa_name'] == 'rand_ceof':
                U_true = random2pLaplace.rangdom_exact_solution_1(x=X_it, xi1=Xi1, xi2=Xi2, K=num2sun_term, alpha=Alpha)
                mean_square_error = tf.reduce_mean(tf.square(U_true - dUNN))
                residual_error = mean_square_error / tf.reduce_mean(tf.square(U_true))
            else:
                U_true = u_true(X_it)
                mean_square_error = tf.reduce_mean(tf.square(U_true - UNN))
                residual_error = mean_square_error / tf.reduce_mean(tf.square(U_true))

    t0 = time.time()
    loss_it_all, loss_bd_all, loss_all, train_mse_all, train_rel_all = [], [], [], [], []  # 空列表, 使用 append() 添加元素
    test_mse_all, test_rel_all = [], []
    testing_epoch = []

    test_batch_size = 1000
    test_x_bach = np.reshape(np.linspace(region_l, region_r, num=test_batch_size), [-1, 1])

    # ConfigProto 加上allow_soft_placement=True就可以使用 gpu 了
    config = tf.compat.v1.ConfigProto(allow_soft_placement=True)  # 创建sess的时候对sess进行参数配置
    config.gpu_options.allow_growth = True              # True是让TensorFlow在运行过程中动态申请显存,避免过多的显存占用。
    config.allow_soft_placement = True                  # 当指定的设备不存在时,允许选择一个存在的设备运行。比如gpu不存在,自动降到cpu上运行
    with tf.compat.v1.Session(config=config) as sess:
        sess.run(tf.compat.v1.global_variables_initializer())
        tmp_lr = learning_rate

        for i_epoch in range(R['max_epoch'] + 1):
            x_it_batch = DNN_data.rand_it(batchsize_it, input_dim, region_a=region_l, region_b=region_r)
            xl_bd_batch, xr_bd_batch = DNN_data.rand_bd_1D(batchsize_bd, input_dim, region_a=region_l, region_b=region_r)
            tmp_lr = tmp_lr * (1 - lr_decay)
            if R['activate_penalty2bd_increase'] == 1:
                if i_epoch < int(R['max_epoch'] / 10):
                    temp_penalty_bd = bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 5):
                    temp_penalty_bd = 10 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 4):
                    temp_penalty_bd = 50 * bd_penalty_init
                elif i_epoch < int(R['max_epoch'] / 2):
                    temp_penalty_bd = 100 * bd_penalty_init
                elif i_epoch < int(3 * R['max_epoch'] / 4):
                    temp_penalty_bd = 200 * bd_penalty_init
                else:
                    temp_penalty_bd = 500 * bd_penalty_init
            else:
                temp_penalty_bd = bd_penalty_init

            _, loss_it_tmp, loss_bd_tmp, loss_tmp, train_mse_tmp, train_res_tmp, pwb = sess.run(
                [train_my_loss, loss_it, loss_bd, loss, mean_square_error, residual_error, PWB],
                feed_dict={X_it: x_it_batch, X_left: xl_bd_batch, X_right: xr_bd_batch,
                           in_learning_rate: tmp_lr, bd_penalty: temp_penalty_bd})

            loss_it_all.append(loss_it_tmp)
            loss_bd_all.append(loss_bd_tmp)
            loss_all.append(loss_tmp)
            train_mse_all.append(train_mse_tmp)
            train_rel_all.append(train_res_tmp)
            if i_epoch % 1000 == 0:
                run_times = time.time() - t0
                DNN_Log_Print.print_and_log_train_one_epoch(
                    i_epoch, run_times, tmp_lr, temp_penalty_bd, pwb, loss_it_tmp, loss_bd_tmp, loss_tmp, train_mse_tmp,
                    train_res_tmp, log_out=log_fileout)

                # ---------------------------   test network ----------------------------------------------
                testing_epoch.append(i_epoch / 1000)
                if R['equa_name'] == 'rand_ceof':
                    u_true2test, unn2test = sess.run([U_true, dUNN], feed_dict={X_it: test_x_bach})
                else:
                    u_true2test, unn2test = sess.run([U_true, UNN], feed_dict={X_it: test_x_bach})
                mse2test = np.mean(np.square(u_true2test - unn2test))
                test_mse_all.append(mse2test)
                res2test = mse2test / np.mean(np.square(u_true2test))
                test_rel_all.append(res2test)

                DNN_Log_Print.print_and_log_test_one_epoch(mse2test, res2test, log_out=log_fileout)

    # -----------------------  save training results to mat files, then plot them ---------------------------------
    saveData.save_trainLoss2mat_1actFunc(loss_it_all, loss_bd_all, loss_all, actName=act_func, outPath=R['FolderName'])
    plotData.plotTrain_loss_1act_func(loss_it_all, lossType='loss_it', seedNo=R['seed'], outPath=R['FolderName'])
    plotData.plotTrain_loss_1act_func(loss_bd_all, lossType='loss_bd', seedNo=R['seed'], outPath=R['FolderName'],
                                      yaxis_scale=True)
    plotData.plotTrain_loss_1act_func(loss_all, lossType='loss', seedNo=R['seed'], outPath=R['FolderName'])

    saveData.save_train_MSE_REL2mat(train_mse_all, train_rel_all, actName=act_func, outPath=R['FolderName'])
    plotData.plotTrain_MSE_REL_1act_func(train_mse_all, train_rel_all, actName=act_func, seedNo=R['seed'],
                                         outPath=R['FolderName'], yaxis_scale=True)

    # ----------------------  save testing results to mat files, then plot them --------------------------------
    saveData.save_2testSolus2mat(u_true2test, unn2test, actName='utrue', actName1=act_func, outPath=R['FolderName'])
    plotData.plot_2solutions2test(u_true2test, unn2test, coord_points2test=test_x_bach,
                                  batch_size2test=test_batch_size, seedNo=R['seed'], outPath=R['FolderName'],
                                  subfig_type=R['subfig_type'])

    saveData.save_testMSE_REL2mat(test_mse_all, test_rel_all, actName=act_func, outPath=R['FolderName'])
    plotData.plotTest_MSE_REL(test_mse_all, test_rel_all, testing_epoch, actName=act_func,
                              seedNo=R['seed'], outPath=R['FolderName'], yaxis_scale=True)