- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 TensorFlow 训练 DNN。我了解到 Batch Normalization 对 DNN 非常有帮助,所以我在 DNN 中使用了它。
我使用“tf.layers.batch_normalization”并按照API文档的说明构建网络:training时,设置其参数“training=True” ,并在验证时设置“training=False”。并添加 tf.get_collection(tf.GraphKeys.UPDATE_OPS)。
这是我的代码:
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
input_node_num=257*7
output_node_num=257
tf_X = tf.placeholder(tf.float32,[None,input_node_num])
tf_Y = tf.placeholder(tf.float32,[None,output_node_num])
dropout_rate=tf.placeholder(tf.float32)
flag_training=tf.placeholder(tf.bool)
hid_node_num=2048
h1=tf.contrib.layers.fully_connected(tf_X, hid_node_num, activation_fn=None)
h1_2=tf.nn.relu(tf.layers.batch_normalization(h1,training=flag_training))
h1_3=tf.nn.dropout(h1_2,dropout_rate)
h2=tf.contrib.layers.fully_connected(h1_3, hid_node_num, activation_fn=None)
h2_2=tf.nn.relu(tf.layers.batch_normalization(h2,training=flag_training))
h2_3=tf.nn.dropout(h2_2,dropout_rate)
h3=tf.contrib.layers.fully_connected(h2_3, hid_node_num, activation_fn=None)
h3_2=tf.nn.relu(tf.layers.batch_normalization(h3,training=flag_training))
h3_3=tf.nn.dropout(h3_2,dropout_rate)
tf_Y_pre=tf.contrib.layers.fully_connected(h3_3, output_node_num, activation_fn=None)
loss=tf.reduce_mean(tf.square(tf_Y-tf_Y_pre))
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i1 in range(3000*num_batch):
train_feature=... # Some processing
train_label=... # Some processing
sess.run(train_step,feed_dict={tf_X:train_feature,tf_Y:train_label,flag_training:True,dropout_rate:1}) # when train , set "training=True" , when validate ,set "training=False" , get a bad result . However when train , set "training=False" ,when validate ,set "training=False" , get a better result .
if((i1+1)%277200==0):# print validate loss every 0.1 epoch
validate_feature=... # Some processing
validate_label=... # Some processing
validate_loss = sess.run(loss,feed_dict={tf_X:validate_feature,tf_Y:validate_label,flag_training:False,dropout_rate:1})
print(validate_loss)
我的代码有什么错误吗?如果我的代码是正确的,我想我会得到一个奇怪的结果:
当训练时,我设置“training = True”,当验证时,设置“training = False ”,结果不好。我每 0.1 个时期打印一次验证损失,第 1 到第 3 个时期的验证损失是
0.929624
0.992692
0.814033
0.858562
1.042705
0.665418
0.753507
0.700503
0.508338
0.761886
0.787044
0.817034
0.726586
0.901634
0.633383
0.783920
0.528140
0.847496
0.804937
0.828761
0.802314
0.855557
0.702335
0.764318
0.776465
0.719034
0.678497
0.596230
0.739280
0.970555
但是,当我更改代码“sess.run(train_step,feed_dict={tf_X:train_feature,tf_Y:train_label,flag_training:True,dropout_rate:1})”时,即:设置“training=False”在training时,设置“training=False”在validate时。结果很好。第一个 epoch 的验证损失为
0.474313
0.391002
0.369357
0.366732
0.383477
0.346027
0.336518
0.368153
0.330749
0.322070
0.335551
为什么会出现这个结果?是否需要在训练时设置“training=True”,在验证时设置“training=False”?
最佳答案
TL;DR:使用小于默认动量的标准化层,如下所示:
tf.layers.batch_normalization( h1, momentum = 0.9, training=flag_training )
TS;WM:
当您设置 training = False
时,这意味着批归一化层将使用其内部存储的均值和方差的平均值来归一化批处理,而不是批处理本身的均值和方差。当 training = False
时,这些内部变量也不会更新。由于它们被初始化为 mean = 0
和 variance = 1
这意味着批量归一化实际上被关闭了 - 该层减去零并将结果除以 1。
因此,如果您使用 training = False
进行训练并像那样进行评估,那仅意味着您正在训练您的网络,而没有任何批量归一化。它仍然会产生合理的结果,因为嘿,批归一化之前还有生命,尽管不可否认不是那么迷人......
如果您使用 training = True
打开批归一化,这将开始对批处理本身进行归一化,并收集每个批处理的均值和方差的移动平均值。现在这是棘手的部分。移动平均线是指数移动平均线,tf.layers.batch_normalization()
的默认动量为0.99 .均值从 0 开始,方差再次从 1 开始。但由于每次更新都应用了 ( 1 - momentum ) 的权重,它将逐渐达到无穷大的实际均值和方差。例如,在 100 步中,它将达到实际值的大约 73.4%,因为 0.99100 是 0.366。如果您的数值很大,则差异可能会很大。
因此,如果您处理的批处理数量相对较少,那么在您运行测试时,内部存储的均值和方差仍可能有很大差异。然后,您的网络将在正确规范化的数据上进行训练,并在错误规范化的数据上进行测试。
为了加快内部批量归一化值的收敛,您可以应用较小的动量,例如 0.9:
tf.layers.batch_normalization( h1, momentum = 0.9, training=flag_training )
(对所有批量归一化层重复。)但是请注意,这有一个缺点。数据中的随机波动会“拖拽”你存储的均值和方差,像这样的小动量会更大,结果值(稍后用于推理)可能会受到你确切停止训练的位置的很大影响,这显然不是最佳的。拥有尽可能大的动量是有用的。根据训练步数的不同,我们一般使用0.9、0.99、0.999 100、1,000、10,000分别训练步骤。超过 0.999 没有意义。
另一个重要的事情是训练数据的适当随机化。如果您首先使用整个数据集的较小数值进行训练,那么规范化会收敛得更慢。最好完全随机化训练数据的顺序,并确保使用至少 14 的批量大小(经验法则)。
旁注:众所周知,零偏差值可以显着加快收敛速度,ExponentialMovingAverage class有这个功能。但是批归一化层没有这个功能,除了tf.slim
。的 batch_norm ,如果您愿意为 slim 重构您的代码。
关于python - 训练时设置 "training=False"of "tf.layers.batch_normalization"会得到更好的验证结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50047653/
在 C# 及其同类语言中,我们总是使用 public string SomeString { get; set;} 但是你也可以使用(我最近才发现这个,而且是在和编译器闲逛的时候发现的) public
我已经为 Controller 中的函数编写了 Swagger 注释,但在生成 swagger-ui 代码时出现错误。以下是我的注释代码 /*** End of Annotation For dele
我正在 PHP 中开发一项服务,该服务使用 exec 函数调用 jar 文件,如下所示: $text = "string with accents á, ó, ú or العربية"; exec(
我正在尝试了解有关在程序中利用/防止缓冲区溢出的方法的更多信息。我知道如果大小是恒定的,下面的代码很容易受到攻击,但是如果大小每次都是随机的怎么办?是否还有办法从堆栈中获取它并以某种方式动态改变溢出字
对于一项学校作业,我应该制作一个可以以小时、分钟和秒为单位存储时间的时间类。一切正常,但仅声明 get 时属性总是返回 0;并设置; private int seconds, minutes, hou
我正在遍历一些测验对象并将结果存储到json变量中。出现"ReferenceError is not defined"错误,不确定原因。 JS代码 // This function will send
使用 Nifi 的 PutDatabaseRecord 处理器在 MySQL 中插入阿拉伯字符(非拉丁语)时,字符被“??????”替换 插入后,阿拉伯字符串被替换为??????。我已经使用 utf8
谁能告诉我为什么 gets(abc) 使用 char[] 而不是使用 int? int abc; char name[] = "lolrofl"; printf("Hello %s.\n",na
为什么在使用 as.POSIXct 转换下面的时间戳时得到所有 NA? > head(tmp$timestamp_utc) [1] Fri Jul 03 00:15:00 EDT 2015 Fri J
def get_submultiples(n): # Get all submultiples of n if n == 1: return [1] i = 2
有没有办法访问基本模型的实际 child ,意思是:继续使用 django Docs 中的示例,让我们假设我正在建模不同的外卖餐厅,它们只是有共同点 姓名 都有deliver方法 至此: class
我正在寻找一个范围的总和,但我总是得到“未定义”。我相信有些东西出现在错误的位置,但我不确定它是什么。 第 1 部分:“编写一个范围函数,它接受两个参数(start 和 end),并返回一个包含从 s
我已将 spring 版本从 4.2.3 更新到 5.0.2,并将安全性从 5.0.1 更新到 5.0.10 并使用 spring -flex版本1.6.0.RC1。 像这样使用 BlazeDS 依赖
我可以输入但在输出中,我得到的结果为零。我使用两门类(class),一门是主要的,是日志,另一门是成绩计算。在成绩计算器中,我编写了方法和构造函数,在日志中,类通过构造函数调用这些方法。 import
我在使用 go 时遇到了构建问题。我想知道这是编译器中的错误还是代码的问题。 // removed the error handling for sake of clarity file, _ :=
我的角色在与盒子互动时出现问题。我有一个 GameObject Player 附加了一个脚本来与游戏中的盒子交互,脚本是: using UnityEngine; using System.Collec
有谁知道为什么我不能在下面生成百分比 codeIshere (第 97-117 行)? var format=d3.format(".1%"); var percent = format(functi
我正在尝试编写图像识别代码,以针对不同动物图像训练系统,这就是代码。我使用 anaconda 作为解释器,使用pycharm作为环境。 import tensorflow as tf import o
我正在尝试在 Java 中初始化 Matcher,但无论字符串是否已初始化且不为 null,都会继续获取 NPE。 这是代码: pattern.compile("\\s"); System.out.p
所以我有这段代码: ; (function (g) { var d = document, i, am = d.createElement('script'), h = d.head || d.g
我是一名优秀的程序员,十分优秀!