建议使用以下浏览器,以获得最佳体验。 IE 9.0+以上版本 Chrome 31+ 谷歌浏览器 Firefox 30+ 火狐浏览器
请选择 进入手机版 | 继续访问电脑版
设置昵称

在此一键设置昵称,即可参与社区互动!

确定
我再想想
选择版块
直达楼层
标签
您还可以添加5个标签
  • 没有搜索到和“关键字”相关的标签
  • 云产品
  • 解决方案
  • 技术领域
  • 通用技术
  • 平台功能
取消

采纳成功

您已采纳当前回复为最佳回复

角动量

发帖: 218粉丝: 8

发消息 + 关注

发表于2021年03月08日 20:03:10 433 7
直达本楼层的链接
楼主
显示全部楼层
[技术干货] TensorFlow神经网络实现二分类的正确姿势

最近在论文中看到的TensorFlow代码眼花缭乱,TF2.0语法更新很多,现在又出了JAX等改进框架,所以觉得有必要系统的从头学习一下。

下文使用的环境为TensorFlow1.15.0和Python3.7.9。这段程序可以辅助理解

样例程序

image.png
我们可以在Tensorflow Neural Network Playground网站(http://playground.tensorflow.org/)上可视化用于二分类的全连接网络,现在我们使用TF编写一个类似的网络,解决类似的问题。

需要引入的库如下

其中RandomState函数用来生成一个固定种子的随机数生成器,相同种子的随机数序列是固定的,这样重复实验可以得到稳定的结果。image.png

下面模拟数据集

随机生成一些点,这些点如果在指定的圆内,则类别标签为1,就像上图中的蓝色点,否则为0。rand函数生成了一个维度为DATASET_SIZEx2的numpy数组,数值为0到1之间的均匀分布。注意标签的维度为DATASET_SIZEx1,类型为list。我们的分类任务就是给定坐标,预测该点的颜色。这里没有抽取测试集,而是直接在训练过程中展示效果。image.png

image.png

下面定义权重矩阵和偏置变量

使用tf.Variable新建变量,其参数为初始化方法。这里使用标准差为1,均值为0(默认值)的正态分布初始化权重。固定种子为1以重复实验。image.png


定义输入坐标和ground truth标签的占位变量,和数据集的维度一致。这里None表示大小不确定,可以自动适配feed进来的值的维度。image.png


前向传播过程如下

使用sigmoid作为激活函数来归一化结果,因为结果的概率在0~1之间。
image.png

反向传播过程如下

使用交叉熵损失函数,使用TF提供的Adam优化器进行优化。

image.pngimage.png

接下来进行训练

每隔2000步输出一下总的交叉熵。训练完毕后获取所有样本上的预测值。
image.png


我们将预测类别和真实类别可视化一下看看效果

plt.subplot(121)for i, (x1, x2) in enumerate(dataset_X):    plt.scatter(x1, x2, color=["orange", "blue"][int(predict[i][0] > 0.5)])
plt.subplot(122)for i, (x1, x2) in enumerate(dataset_X):    plt.scatter(x1, x2, color=["orange", "blue"][dataset_y[i][0]])plt.show()


实验结果如下

左侧的是预测值,右侧是真实值,可以看出两者非常接近了
image.png

书中的例程实际是不包含偏置值和非线性激活函数的。去掉b1和b2,将学习率修改为0.06,再次实验的效果如下

image.png
可以看出失去了偏置值,神经网络的表征能力明显下降。这相当于在后一层网络对前层的输出线性变换时无法进行平移,而只能简单的加权。在Playground中可视化一下各个神经元的特征图,可以看出具有偏置的神经网络隐藏层的四个节点像是割圆法的四条切线,重叠在一起时大致将圆的轮廓勾勒出来。输入的横纵坐标可以看做是横线和竖线,而隐藏层加权得到斜线,通过偏置值,将斜线平移到合适的位置,最终输出层将四条斜线综合起来。
至于完全不使用激活函数,暂且不提非线性表征能力,光是输出值无法归一化到概率的取值范围,即0到1之间,就是个巨大的问题。这里不给出结果了,因为效果实在太差。但是一个有趣的事实是,如果只添加一层激活函数,在隐藏层和输出层之间归一化的效果要比在输出层之后效果要好,当然其原因也显而易见。
激活函数归一化的说法不太严谨,sigmoid的归一化只是一个副作用。类似ReLU的激活函数并不能对值域进行压缩,真正将输出变为概率分布的其实是最后一步的softmax。这里由于使用的是阈值截断的方式,自然去除激活函数之后效果很差。可以尝试使用softmax,去除sigmoid再次实验。

最后给出完整代码

import tensorflow as tffrom numpy.random import RandomStateimport matplotlib.pyplot as plt
w1 = tf.Variable(tf.random_normal([2, 4], stddev=1, seed=1))b1 = tf.Variable(tf.random_normal([1, 4], stddev=1, seed=1))w2 = tf.Variable(tf.random_normal([4, 1], stddev=1, seed=1))b2 = tf.Variable(tf.random_normal([1], stddev=1, seed=1))
_X = tf.placeholder(tf.float32, shape=(None, 2), name="x_input")_y = tf.placeholder(tf.float32, shape=(None, 1), name="y_input")
a = tf.sigmoid(tf.matmul(_X, w1) + b1)y = tf.sigmoid(tf.matmul( a, w2) + b2)
cross_entropy = -tf.reduce_mean(    _y * tf.log(tf.clip_by_value(y, 1e-10, 1.0)) +    (1 - _y) * tf.log(tf.clip_by_value(1 - y, 1e-10, 1.0)))train_step = tf.train.AdamOptimizer(0.03).minimize(cross_entropy)
BATCH_SIZE, DATASET_SIZE, STEPS = 8, 256, 10000dataset_X = RandomState(1).rand(DATASET_SIZE, 2)dataset_y = [[int((x1-0.5)**2+(x2-0.5)**2 < 0.15)] for x1, x2 in dataset_X]
with tf.Session() as sess:    tf.global_variables_initializer().run()    for i in range(STEPS):        beg = (i * BATCH_SIZE) % DATASET_SIZE        end = min(beg + BATCH_SIZE, DATASET_SIZE)        sess.run(train_step, feed_dict={_X: dataset_X[beg: end], _y: dataset_y[beg: end]})        if i % 2000 == 0:            total_cross_entropy = sess.run(                cross_entropy, feed_dict={_X: dataset_X, _y: dataset_y}            )            print("After {:>5d} training_step(s), loss is {:.4f}".format(i, total_cross_entropy))    predict = sess.run(y, feed_dict={_X: dataset_X})
plt.subplot(121)for i, (x1, x2) in enumerate(dataset_X):    plt.scatter(x1, x2, color=["orange", "blue"][int(predict[i][0] > 0.5)])
plt.subplot(122)for i, (x1, x2) in enumerate(dataset_X):    plt.scatter(x1, x2, color=["orange", "blue"][dataset_y[i][0]])plt.show()


举报
分享

分享文章到朋友圈

分享文章到微博

采纳成功

您已采纳当前回复为最佳回复

运气男孩

发帖: 445粉丝: 54

发消息 + 关注

发表于2021年03月08日 22:56:03
直达本楼层的链接
沙发
显示全部楼层

感谢分享啊

点赞 评论 引用 举报

采纳成功

您已采纳当前回复为最佳回复

yyy7124

发帖: 162粉丝: 3

发消息 + 关注

发表于2021年03月09日 10:35:05
直达本楼层的链接
板凳
显示全部楼层

点赞 评论 引用 举报

采纳成功

您已采纳当前回复为最佳回复
发表于2021年03月09日 10:43:42
直达本楼层的链接
地板
显示全部楼层

感谢分享.

点赞 评论 引用 举报

采纳成功

您已采纳当前回复为最佳回复

望闻问切ice

发帖: 517粉丝: 8

级别 : 版主

发消息 + 关注

发表于2021年03月10日 16:17:28
直达本楼层的链接
5#
显示全部楼层

TensorFlow神经网络实现二分类,好详细呀φ(゜▽゜*)♪ 

点赞 评论 引用 举报

采纳成功

您已采纳当前回复为最佳回复

andyleung

发帖: 1023粉丝: 83

发消息 + 关注

发表于2021年03月20日 16:27:19
直达本楼层的链接
6#
显示全部楼层

感谢分享

点赞 评论 引用 举报

采纳成功

您已采纳当前回复为最佳回复

小强鼓掌

发帖: 168粉丝: 2

发消息 + 关注

发表于2021年03月21日 18:20:33
直达本楼层的链接
7#
显示全部楼层

感谢分享

点赞 评论 引用 举报

采纳成功

您已采纳当前回复为最佳回复

yzq18941596181

发帖: 180粉丝: 4

发消息 + 关注

发表于2021年03月21日 18:20:39
直达本楼层的链接
8#
显示全部楼层

感谢分享

点赞 评论 引用 举报

游客

富文本
Markdown
您需要登录后才可以回帖 登录 | 立即注册

结贴

您对问题的回复是否满意?
满意度
非常满意 满意 一般 不满意
我要反馈
0/200