BP神经网络单独预测正常,引入交叉验证预测值为一固定值,语言为python

这是在网上找的别人的代码改过来的,下面我粘贴的代码之前是别人BP神经网络 python程序

下面是BP神经网络相关代码

def clc_accuracy(y_true, y_predict):

    from  sklearn.metrics import r2_score
    score = r2_score(y_true, y_predict)
    return score

def sigmoid(Z):


    """
    Compute the sigmoid of x
    Arguments:
    x -- A scalar or numpy array of any size.
    Return:
    s -- sigmoid(x)
    """
    A = 1.0/(1.0+np.exp(-Z))
    return A

def sigmoid_backward(dA, cache):

    Z = cache
    s = 1.0 / (1.0 + np.exp(-Z))
    dZ = dA * s * (1 - s)
    assert (dZ.shape == Z.shape)
    return dZ

def relu(Z):

    A = np.maximum(0, Z)
    assert (A.shape == Z.shape) #用于判断一个表达式,在表达式条件为 false 的时候触发异常。
    return A

def relu_backward(dA, cache):

    Z = cache
    dZ = np.array(dA, copy=True)  # just converting dz to a correct object. 把dz转换成一个正确的对象。
    # When z <= 0, you should set dz to 0 as well.
    dZ[Z <= 0] = 0
    assert (dZ.shape == Z.shape)  
    return dZ

def layer_sizes(X, Y):
    n_x = X.shape[0]  # size of input layer, number of features ?
    n_h = 4
    n_y = Y.shape[0]  # size of output layer
    return (n_x, n_h, n_y)


def initialize_parameters(n_x, n_h, n_y):

    np.random.seed(2)  # we set up a seed so that your output matches ours although the initialization is random.

    W1 = np.random.randn(n_h, n_x) * 0.01  #以给定的形状创建一个数组,数组元素来符合标准正态分布N(0,1)
    b1 = np.zeros((n_h, 1))
    W2 = np.random.randn(n_y, n_h) * 0.01
    b2 = np.zeros((n_y, 1))

    assert (W1.shape == (n_h, n_x))
    assert (b1.shape == (n_h, 1))
    assert (W2.shape == (n_y, n_h))
    assert (b2.shape == (n_y, 1))

    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}
    return parameters


def forward_propagation(X, parameters):

    # Retrieve each parameter from the dictionary "parameters"
    W1 = parameters["W1"]  #
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]

    # Implement Forward Propagation to calculate A2 (probabilities)
    Z1 = np.dot(W1, X) + b1
    #A1 = np.tanh(Z1)
    A1 = sigmoid(Z1)
    Z2 = np.dot(W2, A1) + b2
    #A2 = sigmoid(Z2)
    A2 = Z2

    assert (A2.shape == (1, X.shape[1]))

    cache = {"Z1": Z1,
             "A1": A1,
             "Z2": Z2,
             "A2": A2}
    return A2, cache


def compute_cost(A2, Y, parameters):

    m = Y.shape[1]  # number of example

    # Compute the cross-entropy cost
    #logprobs = np.multiply(np.log(A2), Y) + np.multiply(np.log(1 - A2), 1 - Y)
    logprobs = - 0.5 * np.multiply(A2-Y, A2-Y)

    cost = - 1.0 / m * np.sum(logprobs)
    cost = np.squeeze(cost)  # makes sure cost is the dimension we expect.
    # squeeze 函数:从数组的形状中删除单维度条目,即把shape中为1的维度去掉
    assert (isinstance(cost, float))
    #isinstance() 函数来判断一个对象是否是一个已知的类型
    return cost


def backward_propagation(parameters, cache, X, Y):
 
    m = X.shape[1]

    # First, retrieve W1 and W2 from the dictionary "parameters".
    W1 = parameters["W1"]
    W2 = parameters["W2"]

    # Retrieve also A1 and A2 from dictionary "cache".
    A1 = cache["A1"]
    A2 = cache["A2"]
    Z1 = cache["Z1"]

    # Backward propagation: calculate dW1, db1, dW2, db2.
    dZ2 = A2 - Y
    dW2 = 1.0/m * np.dot(dZ2, A1.T)
    db2 = 1.0/m * np.sum(dZ2, axis=1, keepdims=True)   #add each row, keep as 2D array
    dA1 = np.dot(W2.T, dZ2)

    #dZ1 = np.dot(W2.T, dZ2) * (1 - np.power(A1, 2))
    dZ1 = sigmoid_backward(dA1, Z1)

    dW1 = 1.0/m * np.dot(dZ1, X.T)
    db1 = 1.0/m * np.sum(dZ1, axis=1, keepdims=True)

    grads = {"dW1": dW1,
             "db1": db1,
             "dW2": dW2,
             "db2": db2}
    return grads


def update_parameters(parameters, grads, learning_rate=1.2):

    # Retrieve each parameter from the dictionary "parameters"
    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]

    # Retrieve each gradient from the dictionary "grads"
    dW1 = grads["dW1"]
    db1 = grads["db1"]
    dW2 = grads["dW2"]
    db2 = grads["db2"]

    # Update rule for each parameter
    W1 = W1 - learning_rate * dW1
    b1 = b1 - learning_rate * db1
    W2 = W2 - learning_rate * dW2
    b2 = b2 - learning_rate * db2

    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}

    return parameters


def nn_model(X, Y, n_h, num_iterations=10000, print_cost=False):

    np.random.seed(3)
    n_x = layer_sizes(X, Y)[0]  # (n_x, n_h, n_y) = layer_sizes(X, Y)
    n_y = layer_sizes(X, Y)[2]

    # Initialize parameters, then retrieve W1, b1, W2, b2. Inputs: "n_x, n_h, n_y". Outputs = "W1, b1, W2, b2, parameters".
    parameters = initialize_parameters(n_x, n_h, n_y)
    W1 = np.random.randn(n_h, n_x) * 0.01
    b1 = np.zeros((n_h, 1))
    W2 = np.random.randn(n_y, n_h) * 0.01
    b2 = np.zeros((n_y, 1))

    # Loop (gradient descent)
    for i in range(0, num_iterations):
        # Forward propagation. Inputs: "X, parameters". Outputs: "A2, cache".
        A2, cache = forward_propagation(X, parameters)

        # Cost function. Inputs: "A2, Y, parameters". Outputs: "cost".
        cost = compute_cost(A2, Y, parameters)

        #print ("A2 = " + str(A2))

        # Backpropagation. Inputs: "parameters, cache, X, Y". Outputs: "grads".
        grads = backward_propagation(parameters, cache, X, Y)

        # Gradient descent parameter update. Inputs: "parameters, grads". Outputs: "parameters".
        parameters = update_parameters(parameters, grads, learning_rate=0.1)

#         # Print the cost every 1000 iterations
#         if print_cost and i % 100 == 0:
#         #if i < 60:
#             print ("Cost after iteration %i: %f" % (i, cost))
    return parameters


def predict(parameters, X):


    # Computes probabilities using forward propagation, and classifies to 0/1 using 0.5 as the threshold.
    A2, cache = forward_propagation(X, parameters)  # cache -- a dictionary containing "Z1", "A1", "Z2" and "A2"

    return A2 


问题不确定是否出在这里

    file = "G:\\Study\\2020-12-16汇报\\收集数据.xlsx"
    data = pd.read_excel(file,sheet_name='Sheet3',header=0)
    Target_features = data[['Tx']]
    Y = Target_features.values
    Base_features = data.drop(['Composition (at. %)','Tx_','Tx','RAND'],axis=1)
    X = Base_features.values


kfold = KFold(n_splits=10)
for train_index, test_index in kfold.split(X, Y):
 # train_index 就是分类的训练集的下标,test_index 就是分配的验证集的下标
    #  this_train_x, this_train_y = X[train_index], Y[train_index]  # 本组训练集
    #  this_test_x, this_test_y = X[test_index], Y[test_index]  # 本组验证集
    X_train, Y_train = X[train_index].T, Y[train_index].T
    X_test, Y_test = X[test_index].T, Y[test_index].T

    shape_X = X_train.shape
    shape_XX = X_test.shape
    shape_Y = Y_train.shape
    m = X_train.shape[1]  # training set size
    n = X_test.shape[1] 
    print ('The shape of X train is: ' + str(shape_X))
    print ('The shape of X test is: ' + str(shape_XX))
    print ('The shape of Y train is: ' + str(shape_Y))
    print ('I have m = %d training examples!' % (m))
    print ('I have n = %d training examples!' % (n))
       

    # Build a model with a n_h-dimensional hidden layer
    parameters = nn_model(X_train, Y_train, n_h = 4, num_iterations = 10000, print_cost=True)

    pred_train = predict(parameters, X_train)

    pred_test = predict(parameters, X_test)   

    pred_err1 = Y_train - pred_train
    pred_err = Y_test - pred_test
  

    error = []
    berror = []
    squaredError = []
    absError = []
        
        
    target =np.mat(Y_test)
    prediction=np.mat(pred_test)       
        
    for i in range(len(target)):
        error.append(target[i] - prediction[i])
        berror.append((target[i] - prediction[i])/(target[i]))
            
    for val in error:
        n=val.shape[0]
        m=val.shape[1]    
        val_t=val.reshape(m,n)
        squaredError.append(val * val_t) #target-prediction之差平方 
        absError.append(abs(val))  #误差绝对值
            
       #数据格式转换
    Y_train = Y_train.tolist()
    pred_train = pred_train.tolist()
    Y_test = Y_test.tolist()
    pred_test = pred_test.tolist()
        
        

    Y_train = list(zip(*Y_train))
    Y_test = list(zip(*Y_test))    #zip(*)解压,返回多维矩阵式


    pred_train = list(zip(*pred_train))
    pred_test = list(zip(*pred_test))
  

    Y_train = np.array(Y_train)
    Y_test  = np.array(Y_test)
    pred_train = np.array(pred_train)
        
    SStot_0=np.sum((Y_train-np.mean(Y_train))**2)
    SSres_0=np.sum((Y_train-pred_train)**2)        
    
    SStot_1=np.sum((Y_test-np.mean(Y_test))**2)
    SSres_1=np.sum((Y_test-pred_test)**2)
        
    r2_score_0 = 1-SSres_0/SStot_0
    r2_score_1 = 1-SSres_1/SStot_1
        
        
    mae=np.sum(absError) / len(absError)                  #平均绝对误差(Mean Absolute Error)
    mse=np.sum(squaredError) / len(squaredError)          #平均均方误差(Mean Squared Error)
    mape=np.sum(np.abs(berror)) / len(Y_test)   #平均绝对百分误差(Mean Absolute Percentage Error)
    rmse=sqrt(sum(squaredError) / len(squaredError))   #均方根误差(Root Mean Squared Error)

        
    print("测试集平均绝对误差(Mean Absolute Error)是:%f" % mae)        
    print("测试集均方误差(Mean Squared Error)是:%f" % mse)
    print("测试集平均绝对百分误差(Mean Absolute Percentage Error)是:%f" % mape)
    print("测试集均方根误差(Root Mean Squared Error)是:%f" % rmse)
    print("BP_nn_model has R^2 score {:,.2f} on train data".format(r2_score_0))
    print("BP_nn_model has R^2 score {:,.2f} on test data".format(r2_score_1))
        
    xn = range(0, len(Y_test))
    plt.figure(1)
    plt.scatter(xn, Y_test)
    plt.scatter(xn, pred_test, c='black')
    plt.scatter(xn, pred_err, c='red')
    plt.show()
    end = time.perf_counter()
    print('Running time: %s Seconds'%(end-start))
    print("****************************")


运行结果及报错内容

预测值我print出来,Y_test全是一个值,不知道错在哪里。一直转圈圈

The shape of X train is: (32, 213)
The shape of X test is: (32, 24)
The shape of Y train is: (1, 213)
I have m = 213 training examples!
I have n = 24 training examples!
测试集平均绝对误差(Mean Absolute Error)是:4.217821
测试集均方误差(Mean Squared Error)是:1.048306
测试集平均绝对百分误差(Mean Absolute Percentage Error)是:0.420938
测试集均方根误差(Root Mean Squared Error)是:1.023868
BP_nn_model has R^2 score 0.00 on train data
BP_nn_model has R^2 score -0.25 on test data
我的解答思路和尝试过的方法
尝试把训练集 X_train转置,也print出X_train具体数值,和在未引入交叉验证时是同类的数据。
没有引入交叉验证,预测R2d分数就很正常,预测值不是固定不变的。

我想要达到的结果
想要在BP神经网络中引入交叉验证,或者是交叉验证时,采用BP神经网络正确预测回归。麻烦帮忙看一下。

你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。


因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。