我正在尝试使用反向传播实现神经网络的梯度计算.我无法使用交叉熵误差和纠正线性单位(ReLU)作为激活.
我设法通过sigmoid,tanh和ReLU激活函数使我的实现工作为平方错误.正确计算具有S形激活梯度的交叉熵(CE)误差.但是,当我将激活更改为ReLU时 - 它失败了.(我正在为CE跳过tanh,因为它在(-1,1)范围内抽取值.)
是否因为log函数的行为接近于0(ReLU在归一化输入时约为50%的时间返回)?我试图通过以下方式解决这个问题:
log(max(y,eps))
Run Code Online (Sandbox Code Playgroud)
但它只能帮助将误差和渐变带回实数 - 它们仍然与数值梯度不同.
我使用数值梯度验证结果:
num_grad = (f(W+epsilon) - f(W-epsilon)) / (2*epsilon)
Run Code Online (Sandbox Code Playgroud)
以下matlab代码提供了我的实验中使用的简化和压缩反向传播实现:
function [f, df] = backprop(W, X, Y)
% W - weights
% X - input values
% Y - target values
act_type='relu'; % possible values: sigmoid / tanh / relu
error_type = 'CE'; % possible values: SE / CE
N=size(X,1); n_inp=size(X,2); n_hid=100; n_out=size(Y,2);
w1=reshape(W(1:n_hid*(n_inp+1)),n_hid,n_inp+1);
w2=reshape(W(n_hid*(n_inp+1)+1:end),n_out, n_hid+1);
% feedforward
X=[X ones(N,1)];
z2=X*w1'; a2=act(z2,act_type); a2=[a2 ones(N,1)];
z3=a2*w2'; y=act(z3,act_type);
if strcmp(error_type, 'CE') % cross entropy …Run Code Online (Sandbox Code Playgroud) 我正在按照本教程实现Backpropagation算法.但是,我坚持实施此算法的动力.
没有Momentum,这是权重更新方法的代码:
def update_weights(network, row, l_rate):
for i in range(len(network)):
inputs = row[:-1]
if i != 0:
inputs = [neuron['output'] for neuron in network[i - 1]]
for neuron in network[i]:
for j in range(len(inputs)):
neuron['weights'][j] += l_rate * neuron['delta'] * inputs[j]
neuron['weights'][-1] += l_rate * neuron['delta']
Run Code Online (Sandbox Code Playgroud)
以下是我的实施:
def updateWeights(network, row, l_rate, momentum=0.5):
for i in range(len(network)):
inputs = row[:-1]
if i != 0:
inputs = [neuron['output'] for neuron in network[i-1]]
for neuron in network[i]:
for j in range(len(inputs)): …Run Code Online (Sandbox Code Playgroud) python algorithm backpropagation neural-network gradient-descent
首先我想说我对神经网络真的很陌生,我不太了解它;)
我已经实现了反向传播神经网络的第一个 C# 实现。我已经使用 XOR 对其进行了测试,它看起来很有效。
现在我想更改我的实现以使用弹性反向传播(Rprop - http://en.wikipedia.org/wiki/Rprop)。
定义说:“Rprop 只考虑所有模式的偏导数的符号(而不是幅度),并且独立地作用于每个“权重”。
有人能告诉我所有模式的偏导数是什么吗?我应该如何为隐藏层中的神经元计算这个偏导数。
非常感谢
更新:
我的实现基于此 Java 代码:www_.dia.fi.upm.es/~jamartin/downloads/bpnn.java
我的 backPropagate 方法如下所示:
public double backPropagate(double[] targets)
{
double error, change;
// calculate error terms for output
double[] output_deltas = new double[outputsNumber];
for (int k = 0; k < outputsNumber; k++)
{
error = targets[k] - activationsOutputs[k];
output_deltas[k] = Dsigmoid(activationsOutputs[k]) * error;
}
// calculate error terms for hidden
double[] hidden_deltas = new double[hiddenNumber];
for (int j = 0; j < hiddenNumber; …Run Code Online (Sandbox Code Playgroud) 这是一个后续问题这篇文章.对于给定的神经元,我不清楚如何对其误差的偏导数及其重量的偏导数.
在这个网页上工作,很清楚传播是如何工作的(虽然我正在处理弹性传播).对于前馈神经网络,我们必须1)在通过神经网络向前移动时,触发神经元,2)从输出层神经元,计算总误差.然后3)向后移动,通过神经元中的每个重量传播该错误,然后4)再次前进,更新每个神经元中的权重.
确切地说,这些是我不理解的事情.
A)对于每个神经元,如何计算误差的偏导数(定义)超过权重的偏导数?我的困惑在于,在微积分中,偏导数是根据n变量函数计算的.在这篇文章中,我有点理解ldog和拜耳的答案.我甚至还不知道链条规则.但是,当我认为如何将其应用于ai)线性组合器和ii)S形激活函数的结果时,它不会凝胶化.
B)使用弹性传播方法,您将如何改变给定神经元的偏差?或者使用弹性传播训练在NN中没有偏差或阈值?
C)如果有两个或更多输出神经元,你如何传播总误差?每个输出神经元值是否会发生总误差*神经元重量?
谢谢
algorithm artificial-intelligence backpropagation neural-network
我正在尝试为具有 2 个单元输入层、2 个单元隐藏层和 1 个单元输出层的简单前馈神经网络实现梯度检查。我做的是以下内容:
我不明白的是如何准确地执行反向传播。通常,我将网络的输出与目标数据进行比较(在分类的情况下),然后在整个网络中反向传播误差导数。但是,我认为在这种情况下必须反向传播一些其他值,因为在数值梯度计算的结果中,不依赖于目标数据(而仅依赖于输入),而误差反向传播取决于目标数据。那么,梯度检查的反向传播部分应该使用什么值呢?
我正在从头开始编写一个backprop神经网络迷你库,我需要一些帮助来编写有意义的自动化测试.到目前为止,我已经进行了自动化测试,验证了backprop算法是否正确计算了重量和偏差梯度,但没有测试培训本身是否真正有效.
我到目前为止的代码让我做以下事情:
鉴于所有这些,我可以编写什么样的自动化测试来确保正确实施训练算法.我应该尝试近似什么函数(sin,cos,exp,quadratic等)?我应该在什么范围内以及如何密集地从该函数中采样数据?NN应该采用什么架构?
理想情况下,该函数应该相当简单易学,因此测试不会持续很长时间(1-3秒),但也足够复杂以提供一定程度的确定性,即算法是否正确实现.
我对我的模型的前向传递有信心,我如何控制它的后向传递?
这不是一个关于什么是反向传播的理论问题。这是一个实用的问题,即是否有适合可视化/跟踪/控制反向传播期间发生的情况的工具。
理想情况下,该工具将允许可视化模型的计算图的结构(模型操作的图)、其输入及其可训练参数。
现在,我这样做:
loss.backward()
Run Code Online (Sandbox Code Playgroud)
我想想象一下这一步会发生什么。
我知道可以使用梯度下降训练神经网络,并且我了解它是如何工作的。
最近,我偶然发现了其他训练算法:共轭梯度和拟牛顿算法。我试图了解它们是如何工作的,但我能得到的唯一好的直觉是它们使用了高阶导数。
我的问题如下:我提到的那些替代算法与使用损失函数梯度调整权重的反向传播过程有根本的不同吗?如果没有,是否有一种算法可以训练一个与反向传播机制根本不同的神经网络?
谢谢
我想我不了解多输出网络。
我一直都了解实现的实现方式,并且成功地训练了一个这样的模型,但我不了解如何训练多输出深度学习网络。我的意思是,培训期间网络内部发生了什么?
以keras功能性API指南中的以下网络为例:
您可以看到两个输出(aux_output和main_output)。反向传播如何运作?
我的直觉是该模型进行两次反向传播,每个输出一次。然后,每个反向传播都会更新退出之前的图层的权重。 但这似乎是不正确的:从这里(SO),我得到的信息是,尽管有多个输出,但只有一个反向传播;根据输出对使用的损失进行加权。
但是,我仍然不知道如何训练网络及其辅助分支。由于未直接连接到主输出,辅助分支权重如何更新?网络的辅助分支的根与主输出之间的部分是否受到损失加权的影响?还是权重仅影响连接到辅助输出的网络部分?
另外,我正在寻找有关此主题的好文章。我已经读过GoogLeNet / Inception文章(v1,v2-v3),因为该网络正在使用辅助分支。
backpropagation neural-network multipleoutputs deep-learning keras
当我在GPU设备上训练我的 pytorch 模型时,我的 python 脚本突然被杀死。深入研究操作系统日志文件,我发现脚本被 OOM Killer 杀死,因为我的CPU内存不足。It\xe2\x80\x99s 非常奇怪的是,我在GPU设备上训练了模型,但CPU内存用完了。\n OOM 杀手日志文件的快照\n
为了调试这个问题,我安装了 python 内存分析器。从内存分析器查看日志文件,我发现当发生列-=操作时,我的 CPU 内存逐渐增加,直到 OOM Killer 杀死我的\n程序。\n Python 内存分析器的快照\n
\n这\xe2\x80\x99s很奇怪,我尝试了很多方法来解决这个问题。最后,我发现在赋值操作之前,我先分离Tensor。神奇的是,它解决了这个问题。但我不明白\xe2\x80\x99不明白清楚为什么它有效。这是我原来的函数代码。
def GeneralizedNabla(self, image):\n pad_size = 2\n affinity = torch.zeros(image.shape[0], self.window_size**2, self.h, self.w).to(self.device)\n h = self.h+pad_size\n w = self.w+pad_size\n #pad = nn.ZeroPad2d(pad_size)\n image_pad = self.pad(image)\n for i in range(0, self.window_size**2):\n affinity[:, i, :, :] = image[:, :, :].detach() # initialization\n dy = int(i/5)-2\n dx = …Run Code Online (Sandbox Code Playgroud) python memory-leaks memory-profiling backpropagation pytorch
backpropagation ×10
algorithm ×2
python ×2
pytorch ×2
keras ×1
matlab ×1
memory-leaks ×1
unit-testing ×1