当前位置:首页 » 编程软件 » 反编译神经网络

反编译神经网络

发布时间: 2022-05-26 12:24:32

㈠ 基于matlab或C#的神经网络编程

1.人工神经元( Artificial Neuron )模型

人工神经元是神经网络的基本元素,其原理可以用下图表示:


若神经元的净激活net为正,称该神经元处于激活状态或兴奋状态(fire),若净激活net为负,则称神经元处于抑制状态。

图1中的这种“阈值加权和”的神经元模型称为M-P模型( McCulloch-Pitts Model ),也称为神经网络的一个处理单元( PE, Processing Element )。

㈡ 需要把MATLAB中的BP神经网络工具箱与自己的一个软件项目结合

这个就是C++与matlab混合编程。但是神经网络工具箱比较特别,它反盗用比较严厉。采用传统的混编方式,可以调用matlab自己的函数,但无法成功调用神经网络工具箱。这一点在mathwork网站上也做了说明。

以C#为例,一般混编有四种方式:
(1)利用Matlab自身编译器,目的是将m文件转换为c或c++的源代码。
(2)利用COM或.NET组件技术。通过MATLAB中的Deploy tool工具将m文件编译成dll,然后在系统中调用。
(3)利用Mideva平台。没尝试过。
(4)利用MATLAB引擎技术。该方法相当于在.NET中运行MATLAB程序,获取其结果。优点是操作简单,过程简易。缺点是需要安装Matlab软件。

如果要调用神经网络工具箱,只有使用第四种方法,即引擎技术,其他方法都不可行。这种混编方式仅仅传递参数,因此不涉及到神经网络工具箱的代码,也就没有了防盗用限制。

㈢ 如何用9行Python代码编写一个简易神经网络

学习人工智能时,我给自己定了一个目标--用Python写一个简单的神经网络。为了确保真得理解它,我要求自己不使用任何神经网络库,从头写起。多亏了Andrew Trask写得一篇精彩的博客,我做到了!下面贴出那九行代码:在这篇文章中,我将解释我是如何做得,以便你可以写出你自己的。我将会提供一个长点的但是更完美的源代码。

首先,神经网络是什么?人脑由几千亿由突触相互连接的细胞(神经元)组成。突触传入足够的兴奋就会引起神经元的兴奋。这个过程被称为“思考”。我们可以在计算机上写一个神经网络来模拟这个过程。不需要在生物分子水平模拟人脑,只需模拟更高层级的规则。我们使用矩阵(二维数据表格)这一数学工具,并且为了简单明了,只模拟一个有3个输入和一个输出的神经元。

我们将训练神经元解决下面的问题。前四个例子被称作训练集。你发现规律了吗?‘?’是0还是1?你可能发现了,输出总是等于输入中最左列的值。所以‘?’应该是1。

训练过程

但是如何使我们的神经元回答正确呢?赋予每个输入一个权重,可以是一个正的或负的数字。拥有较大正(或负)权重的输入将决定神经元的输出。首先设置每个权重的初始值为一个随机数字,然后开始训练过程:

取一个训练样本的输入,使用权重调整它们,通过一个特殊的公式计算神经元的输出。

计算误差,即神经元的输出与训练样本中的期待输出之间的差值。

根据误差略微地调整权重。

重复这个过程1万次。最终权重将会变为符合训练集的一个最优解。如果使用神经元考虑这种规律的一个新情形,它将会给出一个很棒的预测。

这个过程就是back propagation。

计算神经元输出的公式

你可能会想,计算神经元输出的公式是什么?首先,计算神经元输入的加权和,即接着使之规范化,结果在0,1之间。为此使用一个数学函数--Sigmoid函数:Sigmoid函数的图形是一条“S”状的曲线。把第一个方程代入第二个,计算神经元输出的最终公式为:你可能注意到了,为了简单,我们没有引入最低兴奋阈值。

调整权重的公式

我们在训练时不断调整权重。但是怎么调整呢?可以使用“Error Weighted Derivative”公式:为什么使用这个公式?首先,我们想使调整和误差的大小成比例。其次,乘以输入(0或1),如果输入是0,权重就不会调整。最后,乘以Sigmoid曲线的斜率(图4)。为了理解最后一条,考虑这些:

我们使用Sigmoid曲线计算神经元的输出

如果输出是一个大的正(或负)数,这意味着神经元采用这种(或另一种)方式

从图四可以看出,在较大数值处,Sigmoid曲线斜率小

如果神经元认为当前权重是正确的,就不会对它进行很大调整。乘以Sigmoid曲线斜率便可以实现这一点

Sigmoid曲线的斜率可以通过求导得到:把第二个等式代入第一个等式里,得到调整权重的最终公式:当然有其他公式,它们可以使神经元学习得更快,但是这个公式的优点是非常简单。

构造Python代码

虽然我们没有使用神经网络库,但是将导入Python数学库numpy里的4个方法。分别是:

exp--自然指数

array--创建矩阵

dot--进行矩阵乘法

random--产生随机数

比如, 我们可以使用array()方法表示前面展示的训练集:“.T”方法用于矩阵转置(行变列)。所以,计算机这样存储数字:我觉得我们可以开始构建更优美的源代码了。给出这个源代码后,我会做一个总结。

我对每一行源代码都添加了注释来解释所有内容。注意在每次迭代时,我们同时处理所有训练集数据。所以变量都是矩阵(二维数据表格)。下面是一个用Python写地完整的示例代码。

我们做到了!我们用Python构建了一个简单的神经网络!

首先神经网络对自己赋予随机权重,然后使用训练集训练自己。接着,它考虑一种新的情形[1, 0, 0]并且预测了0.99993704。正确答案是1。非常接近!

传统计算机程序通常不会学习。而神经网络却能自己学习,适应并对新情形做出反应,这是多么神奇,就像人类一样。

㈣ matlab神经网络工具箱编译成dll

matlab编译动态连接库需要你有mcc,你的安装序列号必须能包括这个功能,这是前提。
之后,两种方法,一种使用mcc -t myfile.m 可以生成c/c++代码,然后使用其他编译器编译成dll文件。第二种方法,使用mcc -l myfile.m,直接生成dll文件。
然后,这时候你可以看看神经网络工具箱里面都有些什么东西,可以尝试一下直接编译nntool.m,使用mcc -l nntool.m,应该就可以直接编译。
我觉得这样可以。如果不行,那么你可能得把你需要的函数都找出来,复制到一个文件下面,然后再用mcc进行编译。

㈤ 如何用代码编写一个神经网络异或运算器

配置环境、安装合适的库、下载数据集……有时候学习深度学习的前期工作很让人沮丧,如果只是为了试试现在人人都谈的深度学习,做这些麻烦事似乎很不值当。但好在我们也有一些更简单的方法可以体验深度学习。近日,编程学习平台 Scrimba 联合创始人 Per Harald Borgen 在 Medium 上发文介绍了一种仅用30行 JavaScript 代码就创建出了一个神经网络的教程,而且使用的工具也只有 Node.js、Synaptic.js 和浏览器而已。另外,作者还做了一个交互式 Scrimba 教程,也许能帮你理解其中的复杂概念。

Synaptic.js:http://synaptic.juancazala.com

Node.js:http://nodejs.org

Scrimba 教程:http://scrimba.com/casts/cast-1980

Synaptic.js 让你可以使用 Node.js 和浏览器做深度学习。在这篇文章中,我将介绍如何使用 Synaptic.js 创建和训练神经网络。

//创建网络const { Layer, Network }= window.synaptic;var inputLayer = new Layer(2);var hiddenLayer = new Layer(3);var outputLayer = new Layer(1);

inputLayer.project(hiddenLayer);

hiddenLayer.project(outputLayer);var myNetwork = new Network({

input: inputLayer,

hidden:[hiddenLayer],

output: outputLayer

});//训练网络——学习异或运算var learningRate =.3;for (var i =0; i <20000; i++)

{//0,0=>0

myNetwork.activate([0,0]);

myNetwork.propagate(learningRate,[0]);//0,1=>1

myNetwork.activate([0,1]);

myNetwork.propagate(learningRate,[1]);//1,0=>1

myNetwork.activate([1,0]);

myNetwork.propagate(learningRate,[1]);//1,1=>0

myNetwork.activate([1,1]);

myNetwork.propagate(learningRate,[0]);

}//测试网络console.log(myNetwork.activate([0,0]));//[0.0]console.log(myNetwork.activate([0,1]));//[0.]console.log(myNetwork.activate([1,0]));//[0.]console.log(myNetwork.activate([1,1]));//[0.0]

我们将创建一个最简单的神经网络:一个可以执行异或运算的网络。上面就是这个网络的全部代码,但在我们深入解读这些代码之前,首先我们先了解一下神经网络的基础知识。

神经元和突触

神经网络的基本构造模块是神经元。神经元就像是一个函数,有几个输入,然后可以得到一个输出。神经元的种类有很多。我们的网络将使用 sigmoid 神经元,它可以输入任何数字并将其压缩到0 到1 之间。下图就是一个 sigmoid 神经元。它的输入是5,输出是1。箭头被称为突触,可以将该神经元与网络中的其它层连接到一起。

现在训练这个网络:

// train the network - learn XORvar learningRate =.3;for (var i =0; i <20000; i++){ //0,0=>0

myNetwork.activate([0,0]);

myNetwork.propagate(learningRate,[0]);//0,1=>1

myNetwork.activate([0,1]);

myNetwork.propagate(learningRate,[1]);//1,0=>1

myNetwork.activate([1,0]);

myNetwork.propagate(learningRate,[1]);//1,1=>0

myNetwork.activate([1,1]);

myNetwork.propagate(learningRate,[0]);

}

这里我们运行该网络20000次。每一次我们都前向和反向传播4 次,为该网络输入4 组可能的输入:[0,0][0,1][1,0][1,1]。

首先我们执行 myNetwork.activate([0,0]),其中[0,0]是我们发送给该网络的数据点。这是前向传播,也称为激活这个网络。在每次前向传播之后,我们需要执行反向传播,这时候网络会更新自己的权重和偏置。

反向传播是通过这行代码完成的:myNetwork.propagate(learningRate,[0]),其中 learningRate 是一个常数,给出了网络每次应该调整的权重的量。第二个参数0 是给定输入[0,0]对应的正确输出。

然后,该网络将自己的预测与正确的标签进行比较,从而了解自己的正确程度有多少。

然后网络使用这个比较为基础来校正自己的权重和偏置值,这样让自己的下一次猜测更加正确一点。

这个过程如此反复20000次之后,我们可以使用所有四种可能的输入来检查网络的学习情况:

->[0.0]console.log(myNetwork.activate([0,1]));

->[0.]console.log(myNetwork.activate([1,0]));

->[0.]console.log(myNetwork.activate([1,1]));

->[0.0]

如果我们将这些值四舍五入到最近的整数,我们就得到了正确的异或运算结果。

这样就完成了。尽管这仅仅只碰到了神经网络的表皮,但也足以帮助你进一步探索 Synaptic 和继续学习了。http://github.com/cazala/synaptic/wiki 这里还包含了更多好教程。

㈥ 神经网络编程序用什么语言啊

一般用matlab或者scilab来编程,因为输入输出是图像的话,用矩阵计算会更方便。

㈦ 神经网络在训练权值和阈值时先给定初始值,然后根据误差最小进行训练,这类训练代码怎么编写呀

例采用动量梯度下降算法训练BP网络。
训练样本定义如下:
输入矢量为
p =[-1 -2 3 1
-1 1 5 -3]
目标矢量为 t = [-1 -1 1 1]
解:本例的MATLAB程序如下:

close all
clear
echo on
clc
% NEWFF——生成一个新的前向神经网络
% TRAIN——对BP神经网络进行训练
% SIM——对BP神经网络进行仿真
pause
% 敲任意键开始
clc
% 定义训练样本
% P为输入矢量
P=[-1, -2, 3, 1; -1, 1, 5, -3];
% T为目标矢量
T=[-1, -1, 1, 1];
pause;
clc
% 创建一个新的前向神经网络
net=newff(minmax(P),[3,1],{'tansig','purelin'},'traingdm')
% 当前输入层权值和阈值
inputWeights=net.IW{1,1}
inputbias=net.b{1}
% 当前网络层权值和阈值
layerWeights=net.LW{2,1}
layerbias=net.b{2}
pause
clc
% 设置训练参数
net.trainParam.show = 50;
net.trainParam.lr = 0.05;
net.trainParam.mc = 0.9;
net.trainParam.epochs = 1000;
net.trainParam.goal = 1e-3;
pause
clc
% 调用TRAINGDM算法训练BP网络
[net,tr]=train(net,P,T);
pause
clc
% 对BP网络进行仿真
A = sim(net,P)
% 计算仿真误差
E = T - A
MSE=mse(E)
pause
clc
echo off

㈧ 神经网络编程到底有多神奇

神经网络算法,通过一次次地训练来调节神经节点的连接权重,能够有效地进行模式识别。

比如电脑可以快速分辨出

00000000

00000O00

之间内容不同。

但是却很难认为找茬游戏的两张图片是相似图片。

使用神经网络,可以瞬间识别出两张图片的相似程度(需要用其中一张长期训练)。

总而言之,神经网络算法给了程序模式识别的能力。

㈨ 如何用PyTorch实现递归神经网络

从 Siri 到谷歌翻译,深度神经网络已经在机器理解自然语言方面取得了巨大突破。这些模型大多数将语言视为单调的单词或字符序列,并使用一种称为循环神经网络(recurrent neural network/RNN)的模型来处理该序列。但是许多语言学家认为语言最好被理解为具有树形结构的层次化词组,一种被称为递归神经网络(recursive neural network)的深度学习模型考虑到了这种结构,这方面已经有大量的研究。虽然这些模型非常难以实现且效率很低,但是一个全新的深度学习框架 PyTorch 能使它们和其它复杂的自然语言处理模型变得更加容易。

虽然递归神经网络很好地显示了 PyTorch 的灵活性,但它也广泛支持其它的各种深度学习框架,特别的是,它能够对计算机视觉(computer vision)计算提供强大的支撑。PyTorch 是 Facebook AI Research 和其它几个实验室的开发人员的成果,该框架结合了 Torch7 高效灵活的 GPU 加速后端库与直观的 Python 前端,它的特点是快速成形、代码可读和支持最广泛的深度学习模型。

开始 SPINN

链接中的文章(https://github.com/jekbradbury/examples/tree/spinn/snli)详细介绍了一个递归神经网络的 PyTorch 实现,它具有一个循环跟踪器(recurrent tracker)和 TreeLSTM 节点,也称为 SPINN——SPINN 是深度学习模型用于自然语言处理的一个例子,它很难通过许多流行的框架构建。这里的模型实现部分运用了批处理(batch),所以它可以利用 GPU 加速,使得运行速度明显快于不使用批处理的版本。

SPINN 的意思是堆栈增强的解析器-解释器神经网络(Stack-augmented Parser-Interpreter Neural Network),由 Bowman 等人于 2016 年作为解决自然语言推理任务的一种方法引入,该论文中使用了斯坦福大学的 SNLI 数据集。

该任务是将语句对分为三类:假设语句 1 是一幅看不见的图像的准确标题,那么语句 2(a)肯定(b)可能还是(c)绝对不是一个准确的标题?(这些类分别被称为蕴含(entailment)、中立(neutral)和矛盾(contradiction))。例如,假设一句话是“两只狗正跑过一片场地”,蕴含可能会使这个语句对变成“户外的动物”,中立可能会使这个语句对变成“一些小狗正在跑并试图抓住一根棍子”,矛盾能会使这个语句对变成“宠物正坐在沙发上”。

特别地,研究 SPINN 的初始目标是在确定语句的关系之前将每个句子编码(encoding)成固定长度的向量表示(也有其它方式,例如注意模型(attention model)中将每个句子的每个部分用一种柔焦(soft focus)的方法相互比较)。

数据集是用句法解析树(syntactic parse tree)方法由机器生成的,句法解析树将每个句子中的单词分组成具有独立意义的短语和子句,每个短语由两个词或子短语组成。许多语言学家认为,人类通过如上面所说的树的分层方式来组合词意并理解语言,所以用相同的方式尝试构建一个神经网络是值得的。下面的例子是数据集中的一个句子,其解析树由嵌套括号表示:

( ( The church ) ( ( has ( cracks ( in ( the ceiling ) ) ) ) . ) )

这个句子进行编码的一种方式是使用含有解析树的神经网络构建一个神经网络层 Rece,这个神经网络层能够组合词语对(用词嵌入(word embedding)表示,如 GloVe)、 和/或短语,然后递归地应用此层(函数),将最后一个 Rece 产生的结果作为句子的编码:

X = Rece(“the”, “ceiling”)
Y = Rece(“in”, X)
... etc.

但是,如果我希望网络以更类似人类的方式工作,从左到右阅读并保留句子的语境,同时仍然使用解析树组合短语?或者,如果我想训练一个网络来构建自己的解析树,让解析树根据它看到的单词读取句子?这是一个同样的但方式略有不同的解析树的写法:

The church ) has cracks in the ceiling ) ) ) ) . ) )

或者用第 3 种方式表示,如下:

WORDS: The church has cracks in the ceiling .
PARSES: S S R S S S S S R R R R S R R

我所做的只是删除开括号,然后用“S”标记“shift”,并用“R”替换闭括号用于“rece”。但是现在可以从左到右读取信息作为一组指令来操作一个堆栈(stack)和一个类似堆栈的缓冲区(buffer),能得到与上述递归方法完全相同的结果:

1. 将单词放入缓冲区。
2. 从缓冲区的前部弹出“The”,将其推送(push)到堆栈上层,紧接着是“church”。
3. 弹出前 2 个堆栈值,应用于 Rece,然后将结果推送回堆栈。
4. 从缓冲区弹出“has”,然后推送到堆栈,然后是“cracks”,然后是“in”,然后是“the”,然后是“ceiling”。
5. 重复四次:弹出 2 个堆栈值,应用于 Rece,然后推送结果。
6. 从缓冲区弹出“.”,然后推送到堆栈上层。
7. 重复两次:弹出 2 个堆栈值,应用于 Rece,然后推送结果。
8. 弹出剩余的堆栈值,并将其作为句子编码返回。

我还想保留句子的语境,以便在对句子的后半部分应用 Rece 层时考虑系统已经读取的句子部分的信息。所以我将用一个三参数函数替换双参数的 Rece 函数,该函数的输入值为一个左子句、一个右子句和当前句的上下文状态。该状态由神经网络的第二层(称为循环跟踪器(Tracker)的单元)创建。Tracker 在给定当前句子上下文状态、缓冲区中的顶部条目 b 和堆栈中前两个条目 s1\s2 时,在堆栈操作的每个步骤(即,读取每个单词或闭括号)后生成一个新状态:

context[t+1] = Tracker(context[t], b, s1, s2)

容易设想用你最喜欢的编程语言来编写代码做这些事情。对于要处理的每个句子,它将从缓冲区加载下一个单词,运行跟踪器,检查是否将单词推送入堆栈或执行 Rece 函数,执行该操作;然后重复,直到对整个句子完成处理。通过对单个句子的应用,该过程构成了一个大而复杂的深度神经网络,通过堆栈操作的方式一遍又一遍地应用它的两个可训练层。但是,如果你熟悉 TensorFlow 或 Theano 等传统的深度学习框架,就知道它们很难实现这样的动态过程。你值得花点时间回顾一下,探索为什么 PyTorch 能有所不同。

图论

图 1:一个函数的图结构表示

深度神经网络本质上是有大量参数的复杂函数。深度学习的目的是通过计算以损失函数(loss)度量的偏导数(梯度)来优化这些参数。如果函数表示为计算图结构(图 1),则向后遍历该图可实现这些梯度的计算,而无需冗余工作。每个现代深度学习框架都是基于此反向传播(backpropagation)的概念,因此每个框架都需要一个表示计算图的方式。

在许多流行的框架中,包括 TensorFlow、Theano 和 Keras 以及 Torch7 的 nngraph 库,计算图是一个提前构建的静态对象。该图是用像数学表达式的代码定义的,但其变量实际上是尚未保存任何数值的占位符(placeholder)。图中的占位符变量被编译进函数,然后可以在训练集的批处理上重复运行该函数来产生输出和梯度值。

这种静态计算图(static computation graph)方法对于固定结构的卷积神经网络效果很好。但是在许多其它应用中,有用的做法是令神经网络的图结构根据数据而有所不同。在自然语言处理中,研究人员通常希望通过每个时间步骤中输入的单词来展开(确定)循环神经网络。上述 SPINN 模型中的堆栈操作很大程度上依赖于控制流程(如 for 和 if 语句)来定义特定句子的计算图结构。在更复杂的情况下,你可能需要构建结构依赖于模型自身的子网络输出的模型。

这些想法中的一些(虽然不是全部)可以被生搬硬套到静态图系统中,但几乎总是以降低透明度和增加代码的困惑度为代价。该框架必须在其计算图中添加特殊的节点,这些节点代表如循环和条件的编程原语(programming primitive),而用户必须学习和使用这些节点,而不仅仅是编程代码语言中的 for 和 if 语句。这是因为程序员使用的任何控制流程语句将仅运行一次,当构建图时程序员需要硬编码(hard coding)单个计算路径。

例如,通过词向量(从初始状态 h0 开始)运行循环神经网络单元(rnn_unit)需要 TensorFlow 中的特殊控制流节点 tf.while_loop。需要一个额外的特殊节点来获取运行时的词长度,因为在运行代码时它只是一个占位符。

# TensorFlow
# (this code runs once, ring model initialization)
# “words” is not a real list (it’s a placeholder variable) so
# I can’t use “len”
cond = lambda i, h: i < tf.shape(words)[0]
cell = lambda i, h: rnn_unit(words[i], h)
i = 0
_, h = tf.while_loop(cond, cell, (i, h0))

基于动态计算图(dynamic computation graph)的方法与之前的方法有根本性不同,它有几十年的学术研究历史,其中包括了哈佛的 Kayak、自动微分库(autograd)以及以研究为中心的框架 Chainer和 DyNet。在这样的框架(也称为运行时定义(define-by-run))中,计算图在运行时被建立和重建,使用相同的代码为前向通过(forward pass)执行计算,同时也为反向传播(backpropagation)建立所需的数据结构。这种方法能产生更直接的代码,因为控制流程的编写可以使用标准的 for 和 if。它还使调试更容易,因为运行时断点(run-time breakpoint)或堆栈跟踪(stack trace)将追踪到实际编写的代码,而不是执行引擎中的编译函数。可以在动态框架中使用简单的 Python 的 for 循环来实现有相同变量长度的循环神经网络。

# PyTorch (also works in Chainer)
# (this code runs on every forward pass of the model)
# “words” is a Python list with actual values in it
h = h0
for word in words:
h = rnn_unit(word, h)

PyTorch 是第一个 define-by-run 的深度学习框架,它与静态图框架(如 TensorFlow)的功能和性能相匹配,使其能很好地适合从标准卷积神经网络(convolutional network)到最疯狂的强化学习(reinforcement learning)等思想。所以让我们来看看 SPINN 的实现。

代码

在开始构建网络之前,我需要设置一个数据加载器(data loader)。通过深度学习,模型可以通过数据样本的批处理进行操作,通过并行化(parallelism)加快训练,并在每一步都有一个更平滑的梯度变化。我想在这里可以做到这一点(稍后我将解释上述堆栈操作过程如何进行批处理)。以下 Python 代码使用内置于 PyTorch 的文本库的系统来加载数据,它可以通过连接相似长度的数据样本自动生成批处理。运行此代码之后,train_iter、dev_iter 和 test_itercontain 循环遍历训练集、验证集和测试集分块 SNLI 的批处理。

from torchtext import data, datasets
TEXT = datasets.snli.ParsedTextField(lower=True)
TRANSITIONS = datasets.snli.ShiftReceField()
LABELS = data.Field(sequential=False)train, dev, test = datasets.SNLI.splits(
TEXT, TRANSITIONS, LABELS, wv_type='glove.42B')TEXT.build_vocab(train, dev, test)
train_iter, dev_iter, test_iter = data.BucketIterator.splits(
(train, dev, test), batch_size=64)

你可以在 train.py中找到设置训练循环和准确性(accuracy)测量的其余代码。让我们继续。如上所述,SPINN 编码器包含参数化的 Rece 层和可选的循环跟踪器来跟踪句子上下文,以便在每次网络读取单词或应用 Rece 时更新隐藏状态;以下代码代表的是,创建一个 SPINN 只是意味着创建这两个子模块(我们将很快看到它们的代码),并将它们放在一个容器中以供稍后使用。

import torchfrom torch import nn
# subclass the Mole class from PyTorch’s neural network package
class SPINN(nn.Mole):
def __init__(self, config):
super(SPINN, self).__init__()
self.config = config self.rece = Rece(config.d_hidden, config.d_tracker)
if config.d_tracker is not None:
self.tracker = Tracker(config.d_hidden, config.d_tracker)

当创建模型时,SPINN.__init__ 被调用了一次;它分配和初始化参数,但不执行任何神经网络操作或构建任何类型的计算图。在每个新的批处理数据上运行的代码由 SPINN.forward 方法定义,它是用户实现的方法中用于定义模型向前过程的标准 PyTorch 名称。上面描述的是堆栈操作算法的一个有效实现,即在一般 Python 中,在一批缓冲区和堆栈上运行,每一个例子都对应一个缓冲区和堆栈。我使用转移矩阵(transition)包含的“shift”和“rece”操作集合进行迭代,运行 Tracker(如果存在),并遍历批处理中的每个样本来应用“shift”操作(如果请求),或将其添加到需要“rece”操作的样本列表中。然后在该列表中的所有样本上运行 Rece 层,并将结果推送回到它们各自的堆栈。

def forward(self, buffers, transitions):
# The input comes in as a single tensor of word embeddings;
# I need it to be a list of stacks, one for each example in
# the batch, that we can pop from independently. The words in
# each example have already been reversed, so that they can
# be read from left to right by popping from the end of each
# list; they have also been prefixed with a null value.
buffers = [list(torch.split(b.squeeze(1), 1, 0))
for b in torch.split(buffers, 1, 1)]
# we also need two null values at the bottom of each stack,
# so we can from the nulls in the input; these nulls
# are all needed so that the tracker can run even if the
# buffer or stack is empty
stacks = [[buf[0], buf[0]] for buf in buffers]
if hasattr(self, 'tracker'):
self.tracker.reset_state()
for trans_batch in transitions:
if hasattr(self, 'tracker'):
# I described the Tracker earlier as taking 4
# arguments (context_t, b, s1, s2), but here I
# provide the stack contents as a single argument
# while storing the context inside the Tracker
# object itself.
tracker_states, _ = self.tracker(buffers, stacks)
else:
tracker_states = itertools.repeat(None)
lefts, rights, trackings = [], [], []
batch = zip(trans_batch, buffers, stacks, tracker_states)
for transition, buf, stack, tracking in batch:
if transition == SHIFT:
stack.append(buf.pop())
elif transition == REDUCE:
rights.append(stack.pop())
lefts.append(stack.pop())
trackings.append(tracking)
if rights:
reced = iter(self.rece(lefts, rights, trackings))
for transition, stack in zip(trans_batch, stacks):
if transition == REDUCE:
stack.append(next(reced))
return [stack.pop() for stack in stacks]

在调用 self.tracker 或 self.rece 时分别运行 Tracker 或 Rece 子模块的向前方法,该方法需要在样本列表上应用前向操作。在主函数的向前方法中,在不同的样本上进行独立的操作是有意义的,即为批处理中每个样本提供分离的缓冲区和堆栈,因为所有受益于批处理执行的重度使用数学和需要 GPU 加速的操作都在 Tracker 和 Rece 中进行。为了更干净地编写这些函数,我将使用一些 helper(稍后将定义)将这些样本列表转化成批处理张量(tensor),反之亦然。

我希望 Rece 模块自动批处理其参数以加速计算,然后解批处理(unbatch)它们,以便可以单独推送和弹出。用于将每对左、右子短语表达组合成父短语(parent phrase)的实际组合函数是 TreeLSTM,它是普通循环神经网络单元 LSTM 的变型。该组合函数要求每个子短语的状态实际上由两个张量组成,一个隐藏状态 h 和一个存储单元(memory cell)状态 c,而函数是使用在子短语的隐藏状态操作的两个线性层(nn.Linear)和将线性层的结果与子短语的存储单元状态相结合的非线性组合函数 tree_lstm。在 SPINN 中,这种方式通过添加在 Tracker 的隐藏状态下运行的第 3 个线性层进行扩展。

图 2:TreeLSTM 组合函数增加了第 3 个输入(x,在这种情况下为 Tracker 状态)。在下面所示的 PyTorch 实现中,5 组的三种线性变换(由蓝色、黑色和红色箭头的三元组表示)组合为三个 nn.Linear 模块,而 tree_lstm 函数执行位于框内的所有计算。图来自 Chen et al. (2016)。

㈩ 是不是GUI编译成EXE的文件中不能包含神经网络工.....

神经网络工具箱目前只支持将训练好的网络转化为函数之后参与编译:http://cn.mathworks.com/help/nnet/ug/deploy-neural-network-functions-and-objects.html

热点内容
java返回this 发布:2025-10-20 08:28:16 浏览:705
制作脚本网站 发布:2025-10-20 08:17:34 浏览:968
python中的init方法 发布:2025-10-20 08:17:33 浏览:676
图案密码什么意思 发布:2025-10-20 08:16:56 浏览:828
怎么清理微信视频缓存 发布:2025-10-20 08:12:37 浏览:737
c语言编译器怎么看执行过程 发布:2025-10-20 08:00:32 浏览:1076
邮箱如何填写发信服务器 发布:2025-10-20 07:45:27 浏览:308
shell脚本入门案例 发布:2025-10-20 07:44:45 浏览:188
怎么上传照片浏览上传 发布:2025-10-20 07:44:03 浏览:875
python股票数据获取 发布:2025-10-20 07:39:44 浏览:829