神经网络优化失败(使用 Scipy fmin_cg)
Neural net optimization failing (using Scipy fmin_cg)
只是一点上下文:我正在尝试实现一个 3 层神经网络(1 个隐藏层)用于 Cifar-10 数据集上的图像分类。我已经实现了反向传播,最初尝试简单地使用梯度下降训练网络,但我的成本稳定在 40 左右(这有效地以相同的随机猜测速率对新图像进行分类;几乎毫无意义)。
然后我尝试使用 scipy.optimize.fmin_cg
函数训练网络。我将展开的权重传递给函数,我的反向传播函数 returns 具有相同大小的梯度向量,满足函数的输入要求。
我的函数实现如下所示:
scipy.optimize.fmin_cg(cost, iw, fprime=fit_slim)
其中 fit
和 fit_slim
函数如下:
def fit(X, Y, w, l, predict=False, x=None):
w_grad = ([np.mat(np.zeros(np.shape(w[i])))
for i in range(len(w))])
for i in range(len(X)):
x = x if predict else X[i]
y = Y[i]
# forward propagate
a = x
a_s = []
for j in range(len(w)):
a = np.mat(np.append(1, a)).T
a_s.append(a)
z = w[j] * a
a = sigmoid(z)
if predict: return a
# backpropagate
delta = a - y.T
w_grad[-1] += delta * a_s[-1].T
for j in reversed(range(1, len(w))):
delta = delta[1:] if j != len(w)-1 else delta
delta = np.multiply(w[j].T*delta, s_prime(a_s[j]))
w_grad[j-1] += (delta[1:] * a_s[j-1].T)
# regularization
for i in range(len(w)):
w_grad[i] /= len(X)
w_grad[i][:,1:] += (l/len(X)) * w[i][:,1:]
return flatten(w_grad).T
def fit_slim(iw):
iw = shape_back(iw)
return fit(X, Y, iw, l)
而 cost
函数是:
def cost(iw):
J = 0
m = len(X)
iw = shape_back(iw)
for i in range(m):
h = fit(X, Y, iw, l, True, X[i])
J += ((1.0/m)*(np.sum((np.multiply(-Y[i],np.log(h))-
np.multiply((1-Y[i]),np.log(1-h))).flatten())))
for i in range(len(w)):
J += np.sum(((l/(2.0*m))*np.power(w[i],2)).flatten())
return J
iw
变量是展开的权重到一个长向量中,shape_back
函数只是将 iw
重塑回其原始矩阵形状以用于 fit
和 cost
函数。
我面临的第一个问题是我的 fit
函数永远需要 运行 一次迭代。永远,我的意思是大约一分钟,这似乎很慢。尽管如此,我已经让它 运行 直到成本稳定在 40 左右,正如我提到的,这仍然是一个非常高的成本。也就是说,实施替代优化技术对我来说似乎是合理的,我解决了 fmin_cg 功能。
当我 运行 它时,我收到以下错误:
File "image_net.py", line 143, in <module>
print scipy.optimize.fmin_cg(cost, iw, fprime=fit_slim, maxiter=2, callback=callback)
File "/Users/samgriesemer/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 1092, in fmin_cg
res = _minimize_cg(f, x0, args, fprime, callback=callback, **opts)
File "/Users/samgriesemer/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 1156, in _minimize_cg
deltak = numpy.dot(gfk, gfk)
ValueError: shapes (616610,1) and (616610,1) not aligned: 1 (dim 1) != 616610 (dim 0)
在我看来,该函数试图取同一个向量的点积,这对我来说没有任何意义。
所以回顾一下我的问题,我有两个问题。
1) 我可以做些什么来更好地优化我的 fit
功能?我的数据集有10000个例子,所以我理解循环遍历所有样本需要时间,但不明白为什么,即使经过多次迭代,我的成本仍然很高。
2) 为什么我在 运行 调用 fmin_cg
函数时收到错误消息?我传递给函数的参数是相同大小的向量。我不明白为什么它会尝试在函数内取相同大小向量的点积。
非常感谢任何可以阐明这些问题的人 issues/misunderstandings。
It seems to me that the function is attempting to take the dot product of the same vector, which doesn't make any sense to me.
这不是 numpy.dot
的工作方式。问题正是错误消息所说的:它尝试执行矩阵乘法但由于维度不匹配而失败。
请注意,对于可以认为是 "one-dimensional" 的数组,numpy 区分形状 (n,)
、(n, 1)
和 (1, n)
:只有第一个是 one-dimensional for numpy,它not 解释为行或列向量。
>>> a = np.ones(3) # a 1D array
>>> np.dot(a, a)
3.0
>>> b = a.reshape(-1, 1) # a column vector
>>> b
array([[ 1.],
[ 1.],
[ 1.]])
>>> np.dot(b, b) # column times column, fails
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: shapes (3,1) and (3,1) not aligned: 1 (dim 1) != 3 (dim 0)
>>> np.dot(b, b.T) # column times row, i.e. an outer product
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
>>> np.dot(b.T, b) # row times column, but notice the dimensions
array([[ 3.]])
只是一点上下文:我正在尝试实现一个 3 层神经网络(1 个隐藏层)用于 Cifar-10 数据集上的图像分类。我已经实现了反向传播,最初尝试简单地使用梯度下降训练网络,但我的成本稳定在 40 左右(这有效地以相同的随机猜测速率对新图像进行分类;几乎毫无意义)。
然后我尝试使用 scipy.optimize.fmin_cg
函数训练网络。我将展开的权重传递给函数,我的反向传播函数 returns 具有相同大小的梯度向量,满足函数的输入要求。
我的函数实现如下所示:
scipy.optimize.fmin_cg(cost, iw, fprime=fit_slim)
其中 fit
和 fit_slim
函数如下:
def fit(X, Y, w, l, predict=False, x=None):
w_grad = ([np.mat(np.zeros(np.shape(w[i])))
for i in range(len(w))])
for i in range(len(X)):
x = x if predict else X[i]
y = Y[i]
# forward propagate
a = x
a_s = []
for j in range(len(w)):
a = np.mat(np.append(1, a)).T
a_s.append(a)
z = w[j] * a
a = sigmoid(z)
if predict: return a
# backpropagate
delta = a - y.T
w_grad[-1] += delta * a_s[-1].T
for j in reversed(range(1, len(w))):
delta = delta[1:] if j != len(w)-1 else delta
delta = np.multiply(w[j].T*delta, s_prime(a_s[j]))
w_grad[j-1] += (delta[1:] * a_s[j-1].T)
# regularization
for i in range(len(w)):
w_grad[i] /= len(X)
w_grad[i][:,1:] += (l/len(X)) * w[i][:,1:]
return flatten(w_grad).T
def fit_slim(iw):
iw = shape_back(iw)
return fit(X, Y, iw, l)
而 cost
函数是:
def cost(iw):
J = 0
m = len(X)
iw = shape_back(iw)
for i in range(m):
h = fit(X, Y, iw, l, True, X[i])
J += ((1.0/m)*(np.sum((np.multiply(-Y[i],np.log(h))-
np.multiply((1-Y[i]),np.log(1-h))).flatten())))
for i in range(len(w)):
J += np.sum(((l/(2.0*m))*np.power(w[i],2)).flatten())
return J
iw
变量是展开的权重到一个长向量中,shape_back
函数只是将 iw
重塑回其原始矩阵形状以用于 fit
和 cost
函数。
我面临的第一个问题是我的 fit
函数永远需要 运行 一次迭代。永远,我的意思是大约一分钟,这似乎很慢。尽管如此,我已经让它 运行 直到成本稳定在 40 左右,正如我提到的,这仍然是一个非常高的成本。也就是说,实施替代优化技术对我来说似乎是合理的,我解决了 fmin_cg 功能。
当我 运行 它时,我收到以下错误:
File "image_net.py", line 143, in <module>
print scipy.optimize.fmin_cg(cost, iw, fprime=fit_slim, maxiter=2, callback=callback)
File "/Users/samgriesemer/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 1092, in fmin_cg
res = _minimize_cg(f, x0, args, fprime, callback=callback, **opts)
File "/Users/samgriesemer/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 1156, in _minimize_cg
deltak = numpy.dot(gfk, gfk)
ValueError: shapes (616610,1) and (616610,1) not aligned: 1 (dim 1) != 616610 (dim 0)
在我看来,该函数试图取同一个向量的点积,这对我来说没有任何意义。
所以回顾一下我的问题,我有两个问题。
1) 我可以做些什么来更好地优化我的 fit
功能?我的数据集有10000个例子,所以我理解循环遍历所有样本需要时间,但不明白为什么,即使经过多次迭代,我的成本仍然很高。
2) 为什么我在 运行 调用 fmin_cg
函数时收到错误消息?我传递给函数的参数是相同大小的向量。我不明白为什么它会尝试在函数内取相同大小向量的点积。
非常感谢任何可以阐明这些问题的人 issues/misunderstandings。
It seems to me that the function is attempting to take the dot product of the same vector, which doesn't make any sense to me.
这不是 numpy.dot
的工作方式。问题正是错误消息所说的:它尝试执行矩阵乘法但由于维度不匹配而失败。
请注意,对于可以认为是 "one-dimensional" 的数组,numpy 区分形状 (n,)
、(n, 1)
和 (1, n)
:只有第一个是 one-dimensional for numpy,它not 解释为行或列向量。
>>> a = np.ones(3) # a 1D array
>>> np.dot(a, a)
3.0
>>> b = a.reshape(-1, 1) # a column vector
>>> b
array([[ 1.],
[ 1.],
[ 1.]])
>>> np.dot(b, b) # column times column, fails
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: shapes (3,1) and (3,1) not aligned: 1 (dim 1) != 3 (dim 0)
>>> np.dot(b, b.T) # column times row, i.e. an outer product
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
>>> np.dot(b.T, b) # row times column, but notice the dimensions
array([[ 3.]])