Numpy 神经网络成本计算:首次运行后结果变化

在 Python 3.7 中,我的神经网络成本计算出现了问题。
当我第一次运行 compute_cost_nn 时,我得到了正确的成本 0.28762916516131887,但在所有后续运行中,成本变为 0.3262751145707298,这相当令人烦恼。
看起来问题出在我的 params 上;如果我在计算成本之前每次都重新加载它们,运行效果很好。但我无法在不重新运行整个脚本的情况下,使用不同的参数重新运行函数并获得正确的成本。

该神经网络有 400 个输入单元,一个包含 25 个单元的隐藏层,以及 10 个输出单元。

以下是输入数据:

data = loadmat("ex4data1.mat")y = data['y']X = data['X']X = np.c_[np.ones((X.shape[0], 1)), X]weights = loadmat("ex4weights.mat")Theta1 = weights['Theta1']Theta2 = weights['Theta2']params = np.r_[Theta1.ravel(), Theta2.ravel()]

矩阵形状:

>> X: (5000, 401)>> y: (5000, 1)>> Theta1: (25, 401)>> Theta2: (10, 26)>> params: (10285,)

成本函数如下:

def compute_cost_nn(params,                    input_layer_size,                    hidden_layer_size,                    num_labels,                    X, y, lambda_):    m = len(y)    # 从扁平化的 params 中检索 Theta1 和 Theta2    t1_items = (input_layer_size + 1) * hidden_layer_size    Theta1 = params[0:t1_items].reshape(        hidden_layer_size,         input_layer_size+1        )    Theta2 = params[t1_items:].reshape(        num_labels,         hidden_layer_size+1        )    # 将 y 向量列(5000x1)转换为带有标签的 5000x10 矩阵,包含 0 和 1    y_mat = np.eye(num_labels)[(y-1).ravel(), :]    # 前向传播    a1 = X    z2 = a1 @ Theta1.T    a2 = sigmoid(z2)    a2 = np.c_[np.ones((m,1)), a2]    z3 = a2 @ Theta2.T    a3 = sigmoid(z3)    # 计算成本    func = y_mat.T @ np.log(a3) + (1-y_mat).T @ np.log(1-a3)    cost = func.trace()    t1reg = (Theta1[:,1:].T @ Theta1[:,1:]).trace()    t2reg = (Theta2[:,1:].T @ Theta2[:,1:]).trace()    cost_r = -1/m * cost + lambda_/(2*m) * (t1reg + t2reg)    # 梯度(不包括 Theta0)    d3 = a3 - y_mat    d2 = (d3 @ Theta2[:,1:]) * sigmoid_gradient(z2) #5000*25    Delta1 = d2.T @ a1    Delta2 = d3.T @ a2    Theta1_grad = 1/m * Delta1    Theta2_grad = 1/m * Delta2    # 梯度正则化    Theta1[:,1] = 0    Theta2[:,1] = 0    Theta1_grad = Theta1_grad + lambda_/m * Theta1    Theta2_grad = Theta2_grad + lambda_/m * Theta2    return cost_r, Theta1_grad, Theta2_grad

我通过运行以下代码获取成本:

compute_cost_nn(params, 400, 25, 10, X, y, 0)[0]

首次运行: 0.28762916516131887
然后: 0.3262751145707298

任何建议都将不胜感激 🙂


回答:

我没有用虚拟数据测试你的代码,但从快速浏览来看,你似乎是从 .mat(MATLAB)文件中导入权重。MATLAB 以列优先顺序(也称为 Fortran 风格顺序)存储数组元素,而 Python 是行优先(C 风格顺序)。

因此,当你首次 ravel() 你的权重时,Numpy 会假设 C 风格顺序来扁平化数组。在你的函数中重塑扁平化的权重时也是如此。你可以在任一函数中添加 order 参数,因此:

params = np.r_[Theta1.ravel(order='F'), Theta2.ravel('F')]

应该能解决你的问题。

如果你之前从未遇到过行优先和列优先顺序,建议阅读一下相关内容:https://en.wikipedia.org/wiki/Row-_and_column-major_order

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注