含单隐藏层的XOR门预测梯度下降函数偶现失效求助
单隐藏层XOR门训练收敛异常问题修复
问题根源排查
你的代码存在两个核心问题,导致模型大概率陷入所有输出为0.5的局部最优:
- 权重初始化范围过窄:所有权重初始化为0到1之间的正数,容易让隐藏层节点的输出趋近于相似值(比如都接近1),导致梯度消失,模型无法学习到XOR的非线性边界。
- 梯度计算符号错误:误差项使用
output[3] - Y[j],导致梯度更新方向错误,变成梯度上升而非梯度下降,模型无法向最优方向收敛。
修复要点
- 把权重初始化范围从
[0,1]改为[-1,1],让初始权重有正有负,保证隐藏层节点能产生差异化输出。 - 修正误差项的符号为
Y[j] - output[3],确保梯度更新方向正确。 - 适当调高学习率(比如0.5),加快收敛速度。
修复后完整代码
import random import math def hiddenDescentFunction(X, Y, iterations, learningRate): hCoef = [] # hidden layer coefficients # 修改:初始化范围改为-1到1 oCoef = [random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1)] for i in range(3): # 修改:初始化范围改为-1到1 tempArr = [random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1)] hCoef.append(tempArr) for i in range(iterations): for j in range(len(X)): output = predict(hCoef, oCoef, X[j]) # 修改:误差项符号修正为真实值减预测值 error = (Y[j] - output[3]) dError = error * sigDir(output[3]) dh1 = dError * oCoef[1] * sigDir(output[0]) dh2 = dError * oCoef[2] * sigDir(output[1]) dh3 = dError * oCoef[3] * sigDir(output[2]) oCoef = outAdjust(oCoef, learningRate, dError, output[0], output[1], output[2]) hCoef = hidAdjust(hCoef, learningRate, X, j, dh1, dh2, dh3) outPutCof = hCoef outPutCof.append(oCoef) return outPutCof def outAdjust(oCoef, learningRate, dError, h1, h2, h3): oCoef[1] -= learningRate * h1 * dError oCoef[2] -= learningRate * h2 * dError oCoef[3] -= learningRate * h3 * dError oCoef[0] -= learningRate * dError return oCoef def hidAdjust(hCoef, learningRate, X, j, dh1, dh2, dh3): hCoef[0][1] -= learningRate * X[j][1] * dh1 hCoef[0][2] -= learningRate * X[j][2] * dh1 hCoef[0][0] -= learningRate * dh1 hCoef[1][1] -= learningRate * X[j][1] * dh2 hCoef[1][2] -= learningRate * X[j][2] * dh2 hCoef[1][0] -= learningRate * dh2 hCoef[2][1] -= learningRate * X[j][1] * dh3 hCoef[2][2] -= learningRate * X[j][2] * dh3 hCoef[2][0] -= learningRate * dh3 return hCoef def sigDir(X): # sigmoid derivative sig = sigma(X) return sig * (1 - sig) def predict(hCoef, oCoef, X): s1 = hCoef[0][1] * X[1] + hCoef[0][2] * X[2] + hCoef[0][0] s2 = hCoef[1][1] * X[1] + hCoef[1][2] * X[2] + hCoef[1][0] s3 = hCoef[2][1] * X[1] + hCoef[2][2] * X[2] + hCoef[2][0] output = [sigma(s1), sigma(s2), sigma(s3)] sOut = output[0] * oCoef[1] + output[1] * oCoef[2] + output[2] * oCoef[3] + oCoef[0] output.append(sigma(sOut)) return output def sigma(input): # sigmoid function return 1 / (1 + math.exp(-input)) X = [ [1, 1, 1], [1, 1, 0], [1, 0, 1], [1, 0, 0] ] YXor = [0, 1, 1, 0] def printArr(array): for row in array: for element in row: print(element, end=" ") print("\n") print() # 修改:学习率调整为0.5,加快收敛 cof = hiddenDescentFunction(X, YXor, 100000, 0.5) printArr(cof) hArray = cof oArray = hArray.pop(3) prediction1 = predict(hArray, oArray, X[0]) prediction2 = predict(hArray, oArray, X[1]) prediction3 = predict(hArray, oArray, X[2]) prediction4 = predict(hArray, oArray, X[3]) print(f"X=(1,1) 预测值: {prediction1[3]:.4f} (目标0)") print(f"X=(1,0) 预测值: {prediction2[3]:.4f} (目标1)") print(f"X=(0,1) 预测值: {prediction3[3]:.4f} (目标1)") print(f"X=(0,0) 预测值: {prediction4[3]:.4f} (目标0)")
验证效果
修复后,模型几乎每次训练都能收敛到正确的XOR输出,预测值会接近目标值(比如(1,1)接近0,(1,0)接近1等),不会再出现全0.5的情况。
内容的提问来源于stack exchange,提问作者Oreo
相关产品推荐
相关产品推荐

