0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一个能帮助神经网络更好地模拟数值信息的新框架

zhKF_jqr_AI 来源:未知 作者:李倩 2018-10-04 10:20 次阅读

编者按:2个月前,DeepMind发表了一篇名为“神经算术逻辑单元(NALU)”的新论文,提出了一个能帮助神经网络更好地模拟数值信息的新框架。这是一篇有趣的论文,解决的问题也很实际,所以今天论智想推荐一篇有关这个框架的文章,它也是被TensorFlow官博力荐的佳作。比起复杂的论文解读,它更简洁直观,也易于理解。

现如今,尽管深度学习已经在许多任务中取得了令人惊艳的成果,诸多AI产品也逐渐在医疗等领域发挥越来越重要的作用,但如何教导神经网络还是它的一个重要问题,说出来可能有人不信,神经网络在简单算术任务上还会出现问题。

在一个实验中,DeepMind的研究人员曾训练了一个精度接近完美的模型,它能从数据中找出范围在-5到5之间的数字,但当输入从未见过的新数据后,模型就无法概括了。

论文针对上述问题提出了两种方法,但这里我们不会搬运原文的详细内容,相反地,下文将简要介绍NAC的工作原理,以及它如何处理加减乘除等操作,相应代码也会在文章中列出,读者可以从中获得更直观的了解。

第一个神经网络(NAC)

论文介绍的第一个神经网络是神经累积器(简称NAC),它能对输入执行线性变换,而用于变换的矩阵是tanh(What)和sigmoid(Mhat)的元素乘积。简而言之,input(x)后,模型输入会乘以变换矩阵W,并产生输出a。

NAC的Python实现:

import tensorflow as tf

# NAC

W_hat = tf.Variable(tf.truncated_normal(shape, stddev=0.02))

M_hat = tf.Variable(tf.truncated_normal(shape, stddev=0.02))

W = tf.tanh(W_hat) * tf.sigmoid(M_hat)

# 前向传播

a = tf.matmul(in_dim, W)

第二个神经网络(NALU)

神经算术逻辑单元(NALU)由两个NAC构成,其中,第一个NAC g是sigmoid(Gx),第二个NAC在一个等于exp(W(log(|x| + epsilon)))的对数空间m中运行。

NALU的Python实现:

import tensorflow as tf

# NALU

G = tf.Variable(tf.truncated_normal(shape, stddev=0.02))

m = tf.exp(tf.matmul(tf.log(tf.abs(in_dim)+ epsilon), W))

g = tf.sigmoid(tf.matmul(in_dim, G))

y = g * a +(1- g)* m

通过加法理解NAC

现在我们来进行测试。首先,把NAC转成函数:

# NAC

def NAC(in_dim, out_dim):

in_features = in_dim.shape[1]

# 定义W_hat和M_hat

W_hat = tf.get_variable(name = 'W_hat', initializer=tf.initializers.random_uniform(minval=-2, maxval=2),shape=[in_features, out_dim], trainable=True)

M_hat = tf.get_variable(name = 'M_hat', initializer=tf.initializers.random_uniform(minval=-2, maxval=2), shape=[in_features, out_dim], trainable=True)

W = tf.nn.tanh(W_hat) * tf.nn.sigmoid(M_hat)

a = tf.matmul(in_dim, W)

return a, W

其次,创建一些数据,把它们分成训练集和测试集。NumPy有一个较numpy.arrange的API,很适合用来创建数据集:

# 生成一系列输入数字X1和X2用于训练

x1 = np.arange(0,10000,5, dtype=np.float32)

x2 = np.arange(5,10005,5, dtype=np.float32)

y_train = x1 + x2

x_train = np.column_stack((x1,x2))

print(x_train.shape)

print(y_train.shape)

# 生成一系列输入数字X1和X2进行测试

x1 = np.arange(1000,2000,8, dtype=np.float32)

x2 = np.arange(1000,1500,4, dtype= np.float32)

x_test = np.column_stack((x1,x2))

y_test = x1 + x2

print()

print(x_test.shape)

print(y_test.shape)

接着,用这些准备好的东西训练模型。我们先定义占位符X和Y以在运行时提供数据,用tf.reduce_sum()计算损失,模型包含两个超参数:学习率alpha和训练几个epochs。在训练开始前,我们还要定义一个优化器,方便用tf.train.AdamOptimizer()降低损失。

# 定义占位符以在运行时提供输入

X = tf.placeholder(dtype=tf.float32, shape =[None , 2]) # Number of samples x Number of features (number of inputs to be added)

Y = tf.placeholder(dtype=tf.float32, shape=[None,])

#定义网络

#这里网络只包含一个NAC(用于测试)

y_pred, W = NAC(in_dim=X, out_dim=1)

y_pred = tf.squeeze(y_pred) # Remove extra dimensions if any

# 均方误差 (MSE)

loss = tf.reduce_mean( (y_pred - Y) **2)

# 训练参数

alpha = 0.05 # learning rate

epochs = 22000

optimize = tf.train.AdamOptimizer(learning_rate=alpha).minimize(loss)

with tf.Session() as sess:

#init = tf.global_variables_initializer()

cost_history = []

sess.run(tf.global_variables_initializer())

# 训练前损失

print("Pre training MSE: ", sess.run (loss, feed_dict={X: x_test, Y:y_test}))

print()

for i in range(epochs):

_, cost = sess.run([optimize, loss ], feed_dict={X:x_train, Y: y_train})

print("epoch: {}, MSE: {}".format( i,cost) )

cost_history.append(cost)

# 列出每次迭代的均方误差

plt.plot(np.arange(epochs),np.log(cost_history)) # Plot MSE on log scale

plt.xlabel("Epoch")

plt.ylabel("MSE")

plt.show()

print()

print(W.eval())

print()

# 训练后损失

print("Post training MSE: ", sess.run(loss, feed_dict={X: x_test, Y: y_test}))

print("Actual sum: ", y_test[0:10])

print()

print("Predicted sum: ", sess.run(y_pred[0:10], feed_dict={X: x_test, Y: y_test}))

训练完成后,我们可以得到这样一幅图损失曲线图:

Actual sum: [2000.2012.2024.2036.2048.2060.2072.2084.2096.2108.]

Predicted sum: [1999.90212011.90152023.90092035.90042047.89972059.89922071.8984

2083.8982095.89752107.8967]

如输出所示,NAC可以处理诸如加减法的操作,但它还做不到处理乘法和除法。为了解决这个问题,我们就要用到NALU。

通过乘法理解NALU

在上文基础上,首先我们再添加一个NAC,组成NALU:

如果说NAC只是对输入做线性变化,那么NALU就是把两个具有权重的NAC组合在一起,用来执行加减(较小的紫色单元)和乘除(较大的紫色单元),计算由门(橙色单元)控制。

# NALU

def NALU(in_dim, out_dim):

shape = (int(in_dim.shape[-1]), out_dim)

epsilon = 1e-7

# NAC

W_hat = tf.Variable(tf.truncated_normal(shape, stddev=0.02))

M_hat = tf.Variable(tf.truncated_normal(shape, stddev=0.02))

G = tf.Variable(tf.truncated_normal(shape, stddev=0.02))

W = tf.tanh(W_hat) * tf.sigmoid(M_hat)

# 前向传播

a = tf.matmul(in_dim, W)

# NALU

m = tf.exp(tf.matmul(tf.log(tf.abs(in_dim) + epsilon), W))

g = tf.sigmoid(tf.matmul(in_dim, G))

y = g * a + (1 - g) * m

return y

这里我们再创建一些数据,但和上次相比,这次要做一些改动:在第8行和第20行,我们把运算符从加改成了乘。

# 通过学习乘法来测试网络

# 生成一系列输入数字X1和X2用于训练

x1 = np.arange(0,10000,5, dtype=np.float32)

x2 = np.arange(5,10005,5, dtype=np.float32)

y_train = x1 * x2

x_train = np.column_stack((x1,x2))

print(x_train.shape)

print(y_train.shape)

# 生成一系列输入数字X1和X2进行测试

x1 = np.arange(1000,2000,8, dtype=np.float32)

x2 = np.arange(1000,1500,4, dtype= np.float32)

x_test = np.column_stack((x1,x2))

y_test = x1 * x2

print()

print(x_test.shape)

print(y_test.shape)

之后是训练模型,需要注意的是,这里我们定义的还是NAC,而不是NALU:

# 定义占位符以在运行时提供值

X = tf.placeholder(dtype=tf.float32, shape =[None , 2]) # Number of samples x Number of features (number of inputs to be added)

Y = tf.placeholder(dtype=tf.float32, shape=[None,])

# 定义网络

# 这里网络只包含一个NAC(用于测试)

y_pred = NALU(in_dim=X, out_dim=1)

y_pred = tf.squeeze(y_pred) # Remove extra dimensions if any

# 均方误差 (MSE)

loss = tf.reduce_mean( (y_pred - Y) **2)

# 训练参数

alpha = 0.05 # 学习率

epochs = 22000

optimize = tf.train.AdamOptimizer(learning_rate=alpha).minimize(loss)

with tf.Session() as sess:

#init = tf.global_variables_initializer()

cost_history = []

sess.run(tf.global_variables_initializer())

# 训练前损失

print("Pre training MSE: ", sess.run (loss, feed_dict={X: x_test, Y: y_test}))

print()

for i in range(epochs):

_, cost = sess.run([optimize, loss ], feed_dict={X: x_train, Y: y_train})

print("epoch: {}, MSE: {}".format( i,cost) )

cost_history.append(cost)

# 列出每次迭代的损失

plt.plot(np.arange(epochs),np.log(cost_history)) # Plot MSE on log scale

plt.xlabel("Epoch")

plt.ylabel("MSE")

plt.show()

# 训练后损失

print("Post training MSE: ", sess.run(loss, feed_dict={X: x_test, Y: y_test}))

print("Actual product: ", y_test[0:10])

print()

print("Predicted product: ", sess.run(y_pred[0:10], feed_dict={X: x_test, Y: y_test}))

Actual product: [1000000.1012032.1024128.1036288.1048512.1060800.1073152.1085568.

1098048.1110592.]

Predicted product: [1000000.21012032. 1024127.561036288.61048512.061060800.8

1073151.61085567.61098047.61110592.8 ]

如果想获取在TensorFlow中实现NALU的完整代码,可以去这个github:github.com/ahylton19/simpleNALU-tf

小结

以上只是NALU在加减乘除任务上具体表现,在论文中,研究人员还测试了平方运算和开根,NALU的表现都优于传统框架。简而言之,DeepMind的这个简单而实用的技术让神经网络掌握了数值推算,它类似传统处理器中的算术逻辑单元,能让网络真正“学会”加减乘除和基于加减乘除的近似估计,更好地把经验外推到其他数值任务上,而不再受训练数据限制。

通过这篇文章,我们希望现在你已经了解了这篇轰动学界的论文到底说了什么,以及它对深度学习的贡献和影响。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 神经网络
    +关注

    关注

    42

    文章

    4572

    浏览量

    98716
  • 数据
    +关注

    关注

    8

    文章

    6511

    浏览量

    87587
  • NAC
    NAC
    +关注

    关注

    0

    文章

    5

    浏览量

    7657

原文标题:TensorFlow推荐:神经算术逻辑单元的直观理解

文章出处:【微信号:jqr_AI,微信公众号:论智】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    神经网络教程(李亚非)

    源程序  4.3 旅行商问题(TSP)的HNN求解  Hopfield模型求解TSP源程序  第5章 随机型神经网络  5.1 模拟退火算法  5.2 Boltzmann机  Boltzmann机模型
    发表于 03-20 11:32

    求助大神关于神经网络的问题

    求助大神 小的现在有难题: 组车重实时数据 对应车重的最终数值
    发表于 07-14 13:35

    labview BP神经网络的实现

    请问:我在用labview做BP神经网络实现故障诊断,在NI官网找到了机器学习工具包(MLT),但是里面没有关于这部分VI的帮助文档,对于”BP神经网络分类“这个范例有很多不懂的地方,比如
    发表于 02-22 16:08

    【PYNQ-Z2试用体验】神经网络基础知识

    思考问题的过程。人脑输入问题,进行思考,然后给出答案。神经网络就是在模拟人的思考这过程。而我们要做的就是以数学的方式,将这
    发表于 03-03 22:10

    容差模拟电路软故障诊断的小波与量子神经网络方法设计

    的成分做为电路故障特征,再输入给量子神经网络。不仅解决了可测试点问题,并提高了辨识故障类别的能力,而且在网络训练之前,利用主元分析降低了网络
    发表于 07-05 08:06

    【案例分享】基于BP算法的前馈神经网络

    `BP神经网络首先给出只包含隐层的BP神经网络模型(两层神经网络): BP神经网络其实由两
    发表于 07-21 04:00

    【案例分享】ART神经网络与SOM神经网络

    今天学习了两神经网络,分别是自适应谐振(ART)神经网络与自组织映射(SOM)神经网络。整体感觉不是很难,只不过些最基础的概念容易理解不
    发表于 07-21 04:30

    人工神经网络实现方法有哪些?

    人工神经网络(Artificial Neural Network,ANN)是种类似生物神经网络信息处理结构,它的提出是为了解决些非线性
    发表于 08-01 08:06

    如何设计BP神经网络图像压缩算法?

    神经网络(Neural Networks)是人工神经网络(Ar-tificial Neural Networks)的简称,是当前的研究热点之。人脑在接受视觉感官传来的大量图像信息后,
    发表于 08-08 06:11

    如何移植CNN神经网络到FPGA中?

    训练神经网络并移植到Lattice FPGA上,通常需要开发人员既要懂软件又要懂数字电路设计,是不容易的事。好在FPGA厂商为我们提供了许多工具和IP,我们可以在这些工具和IP的
    发表于 11-26 07:46

    卷积神经网络的层级结构和常用框架

      卷积神经网络的层级结构  卷积神经网络的常用框架
    发表于 12-29 06:16

    如何构建神经网络

    原文链接:http://tecdat.cn/?p=5725 神经网络种基于现有数据创建预测的计算系统。如何构建神经网络神经网络包括:输入层:根据现有数据获取输入的层隐藏层:使用反
    发表于 07-12 08:02

    如何使用Keras框架搭建小型的神经网络多层感知器

    本文介绍了如何使用Keras框架,搭建小型的神经网络-多层感知器,并通过给定数据进行计算训练,最好将训练得到的模型提取出参数,放在51单片机上进行运行。
    发表于 11-22 07:00

    如何利用卷积神经网络更好地控制巡线智能车呢

    巡线智能车控制中的CNN网络有何应用?嵌入式单片机中的神经网络该怎样去使用?如何利用卷积神经网络更好地控制巡线智能车呢?
    发表于 12-21 07:47

    图像预处理和改进神经网络推理的简要介绍

    为提升识别准确率,采用改进神经网络,通过Mnist数据集进行训练。整体处理过程分为两步:图像预处理和改进神经网络推理。图像预处理主要根据图像的特征,将数据处理成规范的格式,而改进神经网络推理主要用于输出结果。 整个过程分为两
    发表于 12-23 08:07