gpt4 book ai didi

python-3.x - 随机梯度下降是 hell

转载 作者:行者123 更新时间:2023-11-30 09:16:39 24 4
gpt4 key购买 nike

我正在使用多元线性回归并使用随机梯度下降来优化。

处理此数据集 http://archive.ics.uci.edu/ml/machine-learning-databases/abalone/

对于每次运行,所有 hyperParameters 和所有剩余的内容都是相同的,epochs=200 和 alpha=0.1

当我第一次运行时,我得到了final_cost=0.0591,当我再次运行程序时,保持一切相同,我得到了final_cost=1.0056,再次运行,保持一切相同,我得到 Final_cost=0.8214,再次运行final_cost=15.9591,再次运行final_cost=2.3162等等......

正如你所看到的,保持一切相同并运行,一次又一次,每次最终成本都会发生很大的变化,有时会很大,比如从 0.8 到直接 15.9,从 0.05 到直接 1.00,不仅如此,最终成本的图表与批量 GD 不同,在同一次运行中的每个 epoch 之后都是锯齿形,在批量 GD 中,成本图平滑下降。

我不明白为什么 SGD 的行为如此奇怪,不同的运行结果不同。

我对批量 GD 进行了相同的尝试,一切都按照预期完美且顺利。在批量 GD 的情况下,无论我运行相同的代码多少次,结果每次都完全相同。

但是对于 SGD,我真的哭了,

class Abalone : 
def __init__(self,df,epochs=200,miniBatchSize=250,alpha=0.1) :

self.df = df.dropna()
self.epochs = epochs
self.miniBatchSize = miniBatchSize
self.alpha = alpha

print("abalone created")
self.modelTheData()


def modelTheData(self) :

self.TOTAL_ATTR = len(self.df.columns) - 1
self.TOTAL_DATA_LENGTH = len(self.df.index)

self.df_trainingData =
df.drop(df.index[int(self.TOTAL_DATA_LENGTH * 0.6):])

self.TRAINING_DATA_SIZE = len(self.df_trainingData)

self.df_testingData =
df.drop(df.index[:int(self.TOTAL_DATA_LENGTH * 0.6)])

self.TESTING_DATA_SIZE = len(self.df_testingData)

self.miniBatchSize = int(self.TRAINING_DATA_SIZE / 10)

self.thetaVect = np.zeros((self.TOTAL_ATTR+1,1),dtype=float)

self.stochasticGradientDescent()


def stochasticGradientDescent(self) :

self.finalCostArr = np.array([])

startTime = time.time()

for i in range(self.epochs) :

self.df_trainingData =
self.df_trainingData.sample(frac=1).reset_index(drop=True)

miniBatches=[self.df_trainingData.loc[x:x+self.miniBatchSize-
((x+self.miniBatchSize)/(self.TRAINING_DATA_SIZE-1)),:]
for x in range(0,self.TRAINING_DATA_SIZE,self.miniBatchSize)]

self.epochCostArr = np.array([])

for j in miniBatches :

tempMat = j.values
self.actualValVect = tempMat[ : , self.TOTAL_ATTR:]
tempMat = tempMat[ : , :self.TOTAL_ATTR]
self.desMat = np.append(
np.ones((len(j.index),1),dtype=float) , tempMat , 1 )
del tempMat

self.trainData()

currCost = self.costEvaluation()
self.epochCostArr = np.append(self.epochCostArr,currCost)

self.finalCostArr = np.append(self.finalCostArr,
self.epochCostArr[len(miniBatches)-1])

endTime = time.time()
print(f"execution time : {endTime-startTime}")
self.graphEvaluation()
print(f"final cost :
{self.finalCostArr[len(self.finalCostArr)-1]}")
print(self.thetaVect)


def trainData(self) :

self.predictedValVect = self.predictResult()
diffVect = self.predictedValVect - self.actualValVect
partialDerivativeVect = np.matmul(self.desMat.T , diffVect)
self.thetaVect -=
(self.alpha/len(self.desMat))*partialDerivativeVect


def predictResult(self) :

return np.matmul(self.desMat,self.thetaVect)


def costEvaluation(self) :

cost = sum((self.predictedValVect - self.actualValVect)**2)
return cost / (2*len(self.actualValVect))


def graphEvaluation(self) :

plt.title("cost at end of all epochs")
x = range(len(self.epochCostArr))
y = self.epochCostArr
plt.plot(x,y)
plt.xlabel("iterations")
plt.ylabel("cost")
plt.show()

我在所有运行中都保留 epochs=200 和 alpha=0.1,但每次运行都得到完全不同的结果。

下面提到的向量是 theta 向量,其中第一个条目是偏差,其余是权重

RUN 1 =>>

[[ 5.26020144]
[ -0.48787333]
[ 4.36479114]
[ 4.56848299]
[ 2.90299436]
[ 3.85349625]
[-10.61906207]
[ -0.93178027]
[ 8.79943389]]

final cost : 0.05917831328836957


RUN 2 =>>

[[ 5.18355814]
[ -0.56072668]
[ 4.32621647]
[ 4.58803884]
[ 2.89157598]
[ 3.7465471 ]
[-10.75751065]
[ -1.03302031]
[ 8.87559247]]

final cost: 1.0056239103948563


RUN 3 =>>

[[ 5.12836056]
[ -0.43672936]
[ 4.25664898]
[ 4.53397465]
[ 2.87847224]
[ 3.74693215]
[-10.73960775]
[ -1.00461585]
[ 8.85225402]]

final cost : 0.8214901206702101


RUN 4 =>>

[[ 5.38794798]
[ 0.23695412]
[ 4.43522951]
[ 4.66093372]
[ 2.9460605 ]
[ 4.13390252]
[-10.60071883]
[ -0.9230675 ]
[ 8.87229324]]

final cost: 15.959132174895712


RUN 5 =>>

[[ 5.19643132]
[ -0.76882106]
[ 4.35445135]
[ 4.58782119]
[ 2.8908931 ]
[ 3.63693031]
[-10.83291949]
[ -1.05709616]
[ 8.865904 ]]

final cost: 2.3162151072779804

我无法弄清楚出了什么问题。 SGD 的行为是否像这样,或者我在将代码从批处理 GD 转换为 SGD 时做了一些愚蠢的事情。如果 SGD 的行为像这样,那么我如何知道我必须重新运行多少次,因为我不太幸运,每次在第一次运行时我都会得到如此小的成本,例如 0.05,有时第一次运行的成本约为 10.5 0.6,也许重新运行很多次,我的成本甚至小于 0.05。

当我使用完全相同的代码和 hyperParameters 解决完全相同的问题时,只需用普通批量 GD 替换 SGD 函数,我得到了预期的结果,即,在相同数据的每次迭代之后,我的成本正在平滑下降,即单调递减函数无论我重新运行同一个程序多少次,我都会得到完全相同的结果,因为这是非常明显的。

“保持一切相同,但对 epochs=20000 和 alpha=0.1 使用批量 GD我得到 Final_cost=2.7474"

def BatchGradientDescent(self) :

self.costArr = np.array([])

startTime = time.time()

for i in range(self.epochs) :

tempMat = self.df_trainingData.values
self.actualValVect = tempMat[ : , self.TOTAL_ATTR:]
tempMat = tempMat[ : , :self.TOTAL_ATTR]
self.desMat = np.append( np.ones((self.TRAINING_DATA_SIZE,1),dtype=float) , tempMat , 1 )
del tempMat

self.trainData()

if i%100 == 0 :

currCost = self.costEvaluation()
self.costArr = np.append(self.costArr,currCost)

endTime = time.time()

print(f"execution time : {endTime - startTime} seconds")
self.graphEvaluation()
print(self.thetaVect)
print(f"final cost : {self.costArr[len(self.costArr)-1]}")

有人帮我弄清楚到底发生了什么。在这个新领域,每个意见/解决方案对我来说都是巨大的收入:)

最佳答案

您错过了 GD(“梯度下降”)和 SGD(“随机梯度下降”)之间最重要且唯一的区别。

随机性 - 字面意思是“缺乏任何可预测的顺序或计划的质量”。意思是随机性。

这意味着在 GD 算法中,每个 epoch 中的样本顺序保持不变,而在 SGD 中,顺序在每个 epoch 开始时随机打乱。因此,每次运行具有相同初始化和超参数的 GD 都会产生完全相同的结果,而 SGD 则绝对不会(正如您所经历的那样)。

使用随机性的原因是为了防止模型记住训练样本(这会导致过拟合,训练集上的准确率很高,但在未见过的样本上准确率会很差) .

现在,关于您的案例中运行之间最终成本值的巨大差异,我的猜测是您的学习率太高了。您可以使用较低的常数值,或者更好的是,使用衰减的学习率(随着纪元的增加而降低)。

关于python-3.x - 随机梯度下降是 hell ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54362188/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com