<jupyter_start><jupyter_text>神经元网络 1.BP神经网络见 'MPLClassifier.ipynb' 2.RBF神经网络- RBF神经网络经过这样两层变化: $\left\{\begin{array}{l}R_i(X)=exp(-||X-C_i||^2/2\sigma_i^2),\qquad i=1,\cdots,m\\\hat{y}_k=\sum\limits_{i=1}^{m}\omega_{ik}R_i(X),\qquad k=1,\cdots,p\end{array}\right.$  这样只有小部分靠近中心的隐藏层神经元被激活($R_i(X)$随着其中范数增大,指数减少)- 确定基函数中心$C_i$. 一般采用K均值聚类法.- 确定基函数宽度$\sigma_i$. 通常令它等于基函数中心与子样本集中样本模式之间的平均距离- 确定权值$\omega_{ik}$. 采用最小均方误差测度.<jupyter_code># RBF神经网络(based on tensorflow): https://github.com/shiluqiang/RBF_NN_tensorflow/blob/master/RBF_tensorflow.py
# 由于数据量小, 本人的不熟悉等原因, 预测结果并不理想.

import tensorflow as tf
import numpy as np
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from sklearn.cluster import KMeans
import pandas as pd
from sklearn import preprocessing

class RBF_NN():
    def __init__(self, hidden_nodes, input_data_trainX, input_data_trainY):
        self.hidden_nodes = hidden_nodes #隐含层节点数
        self.input_data_trainX = input_data_trainX #训练样本的特征
        self.input_data_trainY = input_data_trainY #训练样本的标签
    
    def fit(self):
        '''模型训练
        '''
        tf.compat.v1.disable_eager_execution()
        # 1.声明输入输出的占位符
        n = 19
        n_input = (self.input_data_trainX).shape[1]
        n_output = (self.input_data_trainY).shape[0]
        X = tf.compat.v1.placeholder('float', [None, n_input],name = 'X')
        Y = tf.compat.v1.placeholder('float', [None, 1],name = 'Y')
        
        # 2.参数设置
        ## RBF函数参数
        ### K-means求中心
        random_state = 170
        kms = KMeans(n_clusters=self.hidden_nodes, random_state=None)
        pred = kms.fit_predict(trainX)
        
        # c = tf.Variable(tf.random_normal(shape=(self.hidden_nodes, n_input)),name = 'c')
        # c = tf.concat((tf.cast(tf.Variable(kms.cluster_centers_), tf.float32), c), axis=0)
        c = tf.cast(tf.Variable(kms.cluster_centers_), tf.float32)
        delta = tf.Variable(tf.compat.v1.random_normal(shape=(1,self.hidden_nodes)), name='delta')
        ## 隐含层到输出层权重和偏置
        W = tf.Variable(tf.compat.v1.random_normal(shape=(self.hidden_nodes, 1)), name='W')
        b = tf.Variable(tf.compat.v1.random_normal(shape=(1, 1)), name='b')
        
        # 3.构造前向传播计算图
        ## 隐含层输出
        ### 特征样本与RBF均值的距离
        dist = tf.reduce_sum(tf.square(tf.subtract(tf.tile(X,[self.hidden_nodes, 1]),c)), axis=1)
        dist = tf.multiply(1.0,tf.transpose(dist))
        ### RBF方差的平方
        delta_2 = tf.square(delta)
        ### 隐含层输出
        RBF_OUT = tf.exp(tf.multiply(-1.0,tf.divide(dist,tf.multiply(2.0,delta_2))))
        ## 输出层输入
        output_in = tf.matmul(RBF_OUT, W) + b
        
        # 4.声明代价函数优化算法
        loss = tf.reduce_mean(tf.pow(Y - output_in,2)) #损失函数为均方误差
        train_op = tf.compat.v1.train.AdamOptimizer(0.1).minimize(loss) #优化算法为梯度下降法
    
        # 5.反向传播求参数
        trX = self.input_data_trainX[:n]
        trY = self.input_data_trainY[:n]
        
        with tf.compat.v1.Session() as sess:
            ## 初始化所有参数
            tf.compat.v1.global_variables_initializer().run()
            for epoch in range(200):
                for i in range(trX.shape[0]):
                    feed = {X:trX[i][:,None].T, Y:[[trY[i]]]}
                    sess.run(train_op,feed_dict=feed)
                if epoch % 20. == 0 :
                    total_loss = 0.0
                    for j in range(trX.shape[0]):
                        total_loss += sess.run(loss, feed_dict={X:trX[i][:,None].T, Y:[[trY[i]]]})
                    print('Loss function at step %d is %s'%(epoch, total_loss / trX.shape[0]))
                    
            print('Training complete!')

            W = W.eval()
            b = b.eval()
            c = c.eval()
            delta = delta.eval()
            pred_trX = np.mat(np.zeros((len(trX),n_output)))
            
            ## 训练准确率
            correct_tr = 0.0
            pred = []
            for i in range(self.input_data_trainX.shape[0]):
                pred_tr = sess.run(output_in, feed_dict={X:self.input_data_trainX[i][:,None].T})
                pred.append(pred_tr[0][0])
            df_columns = ['Input', 'Pred Out', 'Raw Out', 'Error', 'Relative Error']
            pred = np.array(pred)
            df = pd.DataFrame(np.c_[[x.__str__() for x in self.input_data_trainX],
                                    pred,
                                    self.input_data_trainY,
                                    np.subtract(pred, self.input_data_trainY),
                                    np.array(np.divide(np.subtract(pred, self.input_data_trainY), self.input_data_trainY), dtype=np.float)
                                   ], columns=df_columns)
            print('Relative Error Sum: {:.4%}'.format(df['Relative Error'].astype(float).abs().sum()))
            df['Pred Out'] = df['Pred Out'].apply(lambda x: format(float(x), '.4f'))
            df['Raw Out'] = df['Raw Out'].apply(lambda x: format(float(x), '.1f'))
            df['Error'] = df['Error'].apply(lambda x: format(float(x), '.4f'))
            df['Relative Error'] = df['Relative Error'].apply(lambda x: format(float(x), '.4%'))
            print(df)

data = np.loadtxt('15.D 水库年径流与因子特征.txt')
# data = preprocessing.scale(data)

trainX = data[:, :-1]
trainY = data[:, -1]
input_data_trainX = trainX
input_data_trainY = trainY
rbf = RBF_NN(10, input_data_trainX, input_data_trainY)
rbf.fit()
# BP神经网络(based on keras)

import pandas as pd
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation
from tensorflow.keras.callbacks import LambdaCallback

data = np.loadtxt('15.D 水库年径流与因子特征.txt')
X = data[:, :-1]
Y = data[:, -1]
n = 5
trainX = X[n:]
trainY = Y[n:]

model = Sequential()  #层次模型
model.add(Dense(12, input_dim=4)) #输入层，Dense表示BP层
model.add(Activation('relu'))
model.add(Dense(5, input_dim=12))
model.add(Activation('relu'))
model.add(Dense(1, input_dim=5))  #输出层
model.compile(loss='mean_squared_error', optimizer='Adam') #编译模型


def eposh_callback(epoch, logs):
    if epoch % 200 == 0:
        print('At the end of epoch: {}, with loss: {}'.format(epoch, logs['loss']))
        
        
batch_print_callback = LambdaCallback(on_epoch_end=eposh_callback)
model.fit(trainX, trainY, epochs = 1000, batch_size = 5, verbose=0, callbacks=[batch_print_callback]) #训练模型1000次

pred = np.array(model.predict(X)).flatten()
df_columns = ['Input', 'Pred Out', 'Raw Out', 'Error', 'Relative Error']
df = pd.DataFrame(np.c_[[x.__str__() for x in X],
                    pred,
                    Y,
                    np.subtract(pred, Y),
                    np.array(np.divide(np.subtract(pred, Y), Y), dtype=np.float)
                   ], columns=df_columns)
print('Relative Error Sum: {:.4%}'.format(df['Relative Error'].astype(float).abs().sum()))
df['Pred Out'] = df['Pred Out'].apply(lambda x: format(float(x), '.4f'))
df['Raw Out'] = df['Raw Out'].apply(lambda x: format(float(x), '.1f'))
df['Error'] = df['Error'].apply(lambda x: format(float(x), '.4f'))
df['Relative Error'] = df['Relative Error'].apply(lambda x: format(float(x), '.4%'))
print(df)<jupyter_output>At the end of epoch: 0, with loss: 1282.6154378255208
At the end of epoch: 200, with loss: 46.1252498626709
At the end of epoch: 400, with loss: 28.372927983601887
At the end of epoch: 600, with loss: 17.97803243001302
At the end of epoch: 800, with loss: 10.040056864420572
Relative Error Sum: 973.1400%
                    Input Pred Out Raw Out    Error Relative Error
0   [15.6  5.6  3.5 25.5]  36.6835    22.9  13.7835       60.1899%
1   [27.8  4.3  1.   7.7]  22.5843    23.4  -0.8157       -3.4860%
2   [35.2  3.  38.1  3.7]  54.3693    36.8  17.5693       47.7428%
3   [10.2  3.4  3.5  7.4]  12.0602    22.0  -9.9398      -45.1808%
4   [29.1 33.2  1.6 24. ]  52.4762     6.4  46.0762      719.9399%
5   [10.2 11.6  2.2 26.7]  31.6173    29.4   2.2173        7.5419%
6   [35.4  4.1  1.3  7. ]  26.2944    26.2   0.0944        0.3604%
7       [8.7 3.5 7.5 5. ]  19.0089    20.9  -1.8911       -9.0485%
8   [25.4  0.7 22.2 35.4]  26.5318    26.5   0.0318        0.1199%
9   [15.3  6.   2.  17.5][...]
{'fraction_non_alphanumeric': 0.15584734323229843, 'fraction_numerical': 0.06062093508405939, 'mean_word_length': 2.39300582847627, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '583937', 'license': 'MIT', 'n_tokens_mistral': 3483, 'n_tokens_neox': 3351, 'n_words': 585, 'path': '.ipynb_checkpoints/15.7 神经元网络-checkpoint.ipynb', 'repo_name': 'ZDDWLIG/math-model', 'size': '8149'}