众所周知,神经网络可以在围棋上打败柯洁,比医生更会看x光,甚至在文本翻译上超越人类…事实上,在编写代码方面,神经网络一点也不落下风…用Linux源代码训练2个小时,一个递归神经网络就可以重写自己的代码了。这比程序员还快吗?
为了让你一窥究竟,AI100(ID:rgznai100)整理了开发者Thibault Neveu的这篇文章,教你如何制作这样的神经网络。
作者|蒂博·奈芙
我觉得这很疯狂。开发者教会神经网络自己编程重写自己的代码!好吧,我们试试。
准备条件
tensor flow+基础深度学习技能
这个项目的Github代码库——//github . com/thibo 73800/deep _ generation/tree/master/c _ code。
在本文中,我将简要回顾一下递归神经网络。但是,如果你对这个学科了解不多,相信以下两个资源可以帮助你了解递归神经网络:
视频-//www.youtube.com/watch?v = iX5V1WpxxkY & ampt = 2652s秒
文章-//colah . github . io/posts/2015-08-了解-LSTMs/
这个项目的所有环节我就不在本文详细解释了。但我会详细阐述基本要点,让你了解整个项目。花时间运行下面给出的每段代码,并理解其中的逻辑。这个很重要,毕竟实践出真知。
接下来是题目,我们开始吧!
数据库
像其他监督训练一样,我们需要为神经网络提供一个数据集。这里我们用C语言(如果用太简单的语言就不好玩了)。我们直接使用Linux github代码库中的C脚本作为训练数据。我已经提取了。c代码,我们将在这个项目中使用。
代码地址-//github . com/thibo 73800/deep _ generation/tree/master/c _ code/dataset。
第一个问题:如何表示数据?
神经网络只能用来处理数字。对于其他形式的数据,则无能为力。因此,数据集中的每个字符都需要翻译成这种形式(每个数字一个字符)。
示例:将字符转换为整数(int)
例如,字符“=”在这里由数字7表示。为了在反向传播过程中获得更好的收敛性,我们稍后将在一次热编码中表示每个数字。
#列出数据集目录中的所有文件
all_file = os.listdir(“dataset “)
# Filter:仅选择c文件
all _ file _ name = NP . array([f for f in all _ file if f . find(“。c”)!= -1])
内容= ” “
对于所有文件名中的名称:
以open(os.path.join(“dataset “,name),” r “)为f:
content += f.read() + “\n “
#将字符串转换成整数列表
vocab =集合(内容)
vocab_to_int = {c: i for i,c in enumerate(vocab)}
int _ to _ vocab = dict(enumerate(vocab))
encoded = NP . array([vocab _ to _ int[c]for c in content],dtype=np.int32)
这里,需要记住的三个重要变量是:vocab_to_int、int_to_vocab和encoded。前两个变量允许我们随意在字符和整数之间转换。最后一个变量是以编码器的形式表示所有数据。(均已转换为数字)
第一批函数
首先,创建一个简单的批处理:它由两个输入序列组成,每个序列有10个数字。下面将以该批次为例进行字符处理。
批次= {
” x” : [
编码[:10],
编码[20:30]
],
” y” : [
编码[1:11],
编码[21:31]
]
}
批量输入:
[20 6 58 27 6 27 97 86 56 49]
[ 36 32 32 37 27 12 94 60 89 101]
批处理目标:
[ 6 58 27 6 27 97 86 56 49 57]
[ 32 32 37 27 12 94 60 89 101 77]
这就是批处理函数处理的内容,转换成如下字符:
[‘/’,’ * ‘,\n ‘,’ ‘,’ * ‘,’ C ‘,’ o ‘,’ p ‘,’ y’]
[‘2 ‘,’ 0 ‘,’ 0 ‘,’ 4 ‘,’ ‘,’ E ‘,’ v ‘,’ g ‘,’ E ‘,’ n’]
现在,我们需要处理一些数值。我们希望当最后一个字符“n”已知时,神经网络可以预测下一个字符。而且,不仅仅是最后一个角色。如果我告诉神经网络最后一个字符是“e”,那么下一个字符空的可能性会非常大。但如果我能告诉神经网络,前几个字符是“W”、“H”、“I”、“L”和“E”,那么下一个要输入的字符显然是“(”。
因此,我们必须建立一个可以考虑字符时间间隔的神经网络。这是递归神经网络。
递归神经网络?
为了说明上面的例子,我们使用一个典型的分类器(上图左侧)来处理最后一个字符;在它被传递出蓝色隐藏层之后,分类器可以推断出结果。递归神经网络的结构不同。每个红色隐藏层“单元格”不仅与输入相连,还与前一个“单元格”(instant-1)相连。为了解决这个问题,我们的“细胞”使用长期和短期记忆(LSTM)网络。
请花点时间了解递归神经网络的原理,以便充分理解下面的代码。
建立一个模型!
张量板图
接下来,我们将详细介绍这个神经网络的五个部分。占位符在这里用作模型的入口。初始化后,LSTM神经元用于生成递归神经网络。
连接输出层以测量模型的误差。最后,我们将定义培训内容。
1)图形输入
with TF . name _ scope(” graph _ inputs “):
inputs = tf.placeholder(tf.int32,[2,10],name=’placeholder_inputs ‘)
targets = TF . placeholder(TF . int 32,[2,10],name=’placeholder_targets ‘)
keep _ prob = TF . placeholder(TF . float 32,name=’placeholder_keep_prob ‘)
这个批次由两个大小为10的输入序列组成,所以输入的期望特征是[2,10],批次的每个条目都与单个输出相关联,目标的特征定义是相同的。最后,我们定义一个占位符作为概率值来表示辍学率。
2)LSTM
with tf.name_scope(“LSTM “):
def create_cell()。
lstm = TF . contrib . rnn . basiclstmcell(4)
drop = TF . contrib . rnn . drop out wrapper(lstm,output_keep_prob=keep_prob)
回降
cell = TF . contrib . rnn . multirnncell([create _ cell()for _ in range(3)])
initial _ state = cell . zero _ state(2,tf.float32)
io_size = len(vocab)
x_one_hot = tf.one_hot(输入,io_size)
cell_outputs,final _ state = TF . nn . dynamic _ rnn(cell,x_one_hot,initial _ state =初始状态)
让我们来学习这段代码的每一部分:
Create_cell()用于生成由四个隐藏神经元组成的LSTM神经元。在返回结果之前,该函数还会向单元格输出添加一个退出项。
Tf.contrib.rnn.MultiRNNCell用于实例化递归神经网络。我们把给定的create_cell()数组作为参数,是因为我们想得到一个多层网络组成的递归神经网络。在这种情况下,有三层。
Initial_state:已知递归神经网络的每个神经元依赖于前一个状态,所以我们必须实例化一个全零的初始状态,它将是第一批条目的输入。
X_one_hot将批处理转换为唯一的热代码。
Cell_outputs给出递归神经网络的每个单元的输出。在这个例子中,每个输出包含四个值(隐藏神经元的数量)。
Final_state返回最后一个单元格的状态,在训练时可以作为下一批的最新初始状态(假设下一批是上一批的逻辑延续)。
3)图形输出
with TF . name _ scope(” graph _ outputs “):
seq _ output _ shape = TF . shape(cell _ outputs,[-1,4],name = ” reshape _ x “)
with TF . name _ scope(‘ output _ layer ‘):
w = tf。变量(tf.truncated_normal((4,io_size),stddev=0.1),name=”weights “)
b = tf。变量(tf.zeros(io_size),name=”bias “)
logits = TF . add(TF . mat mul(seq _ output _ shape,w),b,name= “logits “)
softmax = tf.nn.softmax(logits,name=’predictions ‘)
细胞的输出值存储在三维特征表[序列号,序列大小,神经元数目],或[2,10,4]中。我们不需要按顺序分离输出。然后,将输出值的维数更改为存储在seq _ out _ reshape的数组[20,4]中。
最后,使用一个简单的线性操作:tf.matmul(..)+b .最后为了用概率形式表示输出,以softmax结尾。
4)损失
with tf.name_scope(“Loss “):
y_one_hot = tf.one_hot(targets,io_size,name=”y_to_one_hot “)
y _ reshaped = TF . shape(y _ one _ hot,logits.get_shape(),name = ” reshape _ one _ hot “)
loss = TF . nn . soft max _ cross _ entropy _ with _ logits(logits = logits,labels=y_reshaped)
loss = tf.reduce_mean(loss)
为了执行错误操作,我们的批处理目标必须用与模型输出值相同的方法和维度来表示。使用与输入相同的编码,我们使用tf.one_hot来表示输出值。然后重写数组tf.reshape()的维数,使其与tf.matmul的线性输出相同(..)+b .然后,我们可以用这个函数来计算模型的误差。
5)培训
with tf.name_scope(“train “):
Adam = TF . train . adamoptimizer(0.0001)
optimizer = adam.minimize(损失)
我们简单地使用AdamOptimize来最小化误差。
结果!
这是最著名的部分:训练结果。我使用的参数如下:
序列大小:100
批量:200个
每个细胞的神经元数量:512
递归神经网络深度:2
学习速度:0.0005
退学率:0.5
在我的GPU(GeForce GTX 1060)上训练了大概两个小时,结果如下图所示:
我们先来观察误差的变化:
最后,让我们来阅读模型生成的代码:
static int super _ fold(struct mddev * mddev,void __user * *rd)
{
struct md _ rdev * rdev
如果(!tryet & ampgcov_ntreef(*stint)) {
if(GC _ th-& gt;最大扇区数)
如果(任务)
转到next _ start
如果(!list _ empty(amp;mddev-& gt;磁盘){
if(mddev-& gt;dev _ sectors = = 0 | |
mddev-& gt;chunk_sectors == 0。& ampmddev-& gt;未成年人_版本!=
mddev-& gt;最大磁盘数。& ampmddev-& gt;发展部门
rde v2->;rescan_recovnr!= 0)
rdev-& gt;recovery _ offset = MD dev-& gt;curr _ resync _ completed
}
}
}
从结果来看,模型清楚地了解了程序的大致结构,非常酷:一个函数,参数,变量的初始化条件等等。
我们注意到,在使用的数据集中,绝对没有名为“super_fold”的函数。所以我很难理解这个功能的具体作用。更合理的解释是模型比我聪明…哦,我的天啊!!
原始地址:
//becoming human . ai/how-to-train-a-neural-network-to-code-by-self-a 432 E8 a 120 df
看完这篇文章,你对机器自动编程有龙腾棋牌官网 看法?程序员会被裁员吗?还是说机器只能写简单的代码,不能代替程序员?欢迎发表意见
gdhaoji.com kzxmf.com 52jitapu.com mjwl135.com 88wwn.com jjgav4.com laf889.com 027ab.com fqle3.com