我试图创建一个多层前馈-反向传播神经网络来识别手写数字,但我遇到了一个问题,即输出层中的激活都趋向于相同的值。
我正在使用手写数字数据集的光学识别,训练数据看起来像
<代码>0,1,6,15,12,1,0,0,0,7,16,6,6,10,0,0,0,8,16,2,0,11,2,0,0,5,16,3,0,5,0,0,7,13,3,0,8,7,0,0,4,12,0,1,13,5,0,0,14,9,0,0,0,0,0,6,14,7,1,0,0,0
它表示一个8x8矩阵,其中64个整数中的每一个都对应于子4x4矩阵中的暗像素数,最后一个整数是分类。
我在输入层中使用了64个节点,对应于64个整数,在一些隐藏层中使用了一些隐藏节点,在输出层中使用了10个节点,对应于0-9。
我的权重在此初始化,并为输入层和隐藏层添加了偏差
self.weights = []
for i in xrange(1, len(layers) - 1):
self.weights.append(
np.random.uniform(low=-0.2,
high=0.2,
size=(layers[i-1] + 1, layers[i] + 1)))
# Output weights
self.weights.append(
np.random.uniform(low=-0.2,
high=0.2,
size=(layers[-2] + 1, layers[-1])))
其中list
包含每层中的节点数,例如。
<代码>层=[64、30、10]
我使用逻辑函数作为激活函数
def logistic(self, z):
return sp.expit(z)
及其衍生物
def derivative(self, z):
return sp.expit(z) * (1 - sp.expit(z))
我的反向传播算法是从这里大量借用的;我之前的尝试失败了,所以我想尝试另一条路线。
def back_prop_learning(self, X, y):
# add biases to inputs with value of 1
biases = np.atleast_2d(np.ones(X.shape[0]))
X = np.concatenate((biases.T, X), axis=1)
# Iterate over training set
for epoch in xrange(self.epochs):
# for each weight w[i][j] in network assign random tiny values
# handled in __init__
''' PROPAGATE THE INPUTS FORWARD TO COMPUTE THE OUTPUTS '''
for example in zip(X, y):
# for each node i in the input layer
# set input layer outputs equal to input vector outputs
activations = [example[0]]
# for layer = 1 (first hidden) to output layer
for layer in xrange(len(self.weights)):
# for each node j in layer
weighted_sum = np.dot(activations[layer], self.weights[layer])
# assert number of outputs == number of weights in each layer
assert(len(activations[layer]) == len(self.weights[layer]))
# compute activation of weighted sum of node j
activation = self.logistic(weighted_sum)
# append vector of activations
activations.append(activation)
''' PROPAGATE DELTAS BACKWARDS FROM OUTPUT LAYER TO INPUT LAYER '''
# for each node j in the output layer
# compute error of target - output
errors = example[1] - activations[-1]
# multiply by derivative
deltas = [errors * self.derivative(activations[-1])]
# for layer = last hidden layer down to first hidden layer
for layer in xrange(len(activations)-2, 0, -1):
deltas.append(deltas[-1].dot(self.weights[layer].T) * self.derivative(activations[layer]))
''' UPDATE EVERY WEIGHT IN NETWORK USING DELTAS '''
deltas.reverse()
# for each weight w[i][j] in network
for i in xrange(len(self.weights)):
layer = np.atleast_2d(activations[i])
delta = np.atleast_2d(deltas[i])
self.weights[i] += self.alpha * layer.T.dot(delta)
运行测试数据后的输出都类似
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 9.0
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 4.0
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 6.0
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 6.0
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 7.0
无论我选择的学习速度、隐藏节点数或隐藏层数是多少,所有内容似乎都趋向于1。这让我想知道,我是否在正确地处理和设置问题,用64个输入到10个输出,或者我是否正确地选择/实现了我的sigmoid函数,或者我的反向传播算法的实现是否失败。我已经用同样的结果重复了两到三次以上的程序,这让我相信我从根本上误解了问题,没有正确地表达它。
我想我已经回答了我的问题。
我认为问题在于我是如何计算输出层中的错误的。我一直将其计算为示例[1]-激活[-1],它创建了一个错误数组,这些错误是从目标值中减去我的输出层激活而产生的。
我改变了这一点,所以我的目标值是一个0-9的向量,所以我的目标值的索引是1.0。
y = int(example[1])
errors_v = np.zeros(shape=(10,), dtype=float)
errors_v[y] = 1.0
errors = errors_v - activations[-1]
我还将激活函数更改为tanh函数。
这大大增加了我的输出层中激活的差异,到目前为止,我在有限的测试中能够达到50%-75%的准确率。希望这能帮助其他人。
卷积神经网络其实是神经网络特征学习的一个典型例子。传统的机器学习算法其实需要人工的提取特征,比如很厉害的SVM。而卷积神经网络利用模板算子的参数也用以学习这个特点,把特征也学习出来了。其实不同的模板算子本质上就是抽象了图像的不同方面的特征。比如提取边缘,提取梯度的算子。用很多卷积核去提取,那就是 提取了很多的特征。一旦把参数w,b训练出来,意味着特征和目标之间的函数就被确定。今天分享下CNN的关键
训练发散 理想的分类器应当是除了真实标签的概率为1,其余标签概率均为 0,这样计算得到其损失函数为 -ln(1) = 0 损失函数越大,说明该分类器在真实标签上分类概率越小,性能也就越差。一个非常差的分类器,可能在真实标签上的匪类概率接近于0,那么损失函数就接近于正无穷,我们成为训练发散,需要调小学习速率。 6.9 高原反应 在 ImageNet-1000 分类问题中,初始状态为均匀分布,每个类别
1 正向传播(Forward propagation) 回忆一下,给出一个输入特征$x$的时候,我们定义了$a^{[0]}=x$。然后对于层(layer)$l=1,2,3,\dots,N$,其中的$N$是网络中的层数,则有: $z^{[l]}=W^{[l]}a^{[l-1]}+b^{[l]}$ $a^{[l]}=g^{[l]}(z^{[l]})$ 在讲义中都是假设了非线性特征$g^{[l]}$对除
在使用relu激活功能时,我在实现backprop时遇到问题。我的模型有两个隐藏层,两个隐藏层中都有10个节点,输出层中有一个节点(因此有3个权重,3个偏差)。我的模型不适用于这个断开的backward\u prop函数。但是,该函数使用sigmoid激活函数(作为注释包含在函数中)与backprop一起工作。因此,我认为我把relu推导搞砸了。 谁能把我推向正确的方向?
前面几节里我们使用了小批量随机梯度下降的优化算法来训练模型。在实现中,我们只提供了模型的正向传播(forward propagation)的计算,即对输入计算模型输出,然后通过autograd模块来调用系统自动生成的backward函数计算梯度。基于反向传播(back-propagation)算法的自动求梯度极大简化了深度学习模型训练算法的实现。本节我们将使用数学和计算图(computationa
我正在尝试用RELU实现神经网络。 输入层- 以上是我的神经网络结构。我对这个relu的反向传播感到困惑。对于RELU的导数,如果x 有人能解释一下我的神经网络架构的反向传播“一步一步”吗?