我有一个CNN,可以在我创建的数据集中学习得很好。我向该网络添加了“批量归一化”以尝试改善性能。
但是..当我尝试对单个图像进行预测时,我总是会得到相同的结果(无论图像如何)。我认为这是因为我需要批处理才能真正进行批处理规范化。
那么有可能使用BN的CNN对单个图像进行预测吗?我想在网络训练完毕后删除BN图层,这是可行的方法吗?
谢谢 :)
我一直在Tensorflow中跟踪SEGFAULT。可以使用以下代码段重现该问题:
import tensorflow as tf                                                                                                                                                                                                                       
with tf.device('/cpu:0'):
    xin = tf.placeholder(tf.float32, [None, 1, 1], name='input')
    rnn_cell = tf.contrib.rnn.LSTMCell(1)
    out, _ = tf.nn.dynamic_rnn(rnn_cell, xin, dtype=tf.float32)
    out = tf.layers.batch_normalization(out, training=True)
    out = tf.identity(out, name='output')
    optimiser = tf.train.AdamOptimizer(.0001)
    update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
    with tf.control_dependencies(update_ops):
        out = optimiser.minimize(out, global_step=tf.Variable(0, dtype=tf.float32), name='train_op')
config = tf.ConfigProto(allow_soft_placement = False)
sess = tf.Session(config=config)
sess.run(tf.global_variables_initializer())
sample_in = [[[0]]]
sess.run(out, feed_dict={xin: sample_in})
我设法找到了这个问题,并在github上有一个pull-request请求。如果使用我的补丁程序运行此代码,则会收到以下错误消息:
2018-04-03 13:09:24.326950: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1212] Found device 0 with properties:                                                                                                                          
name: TITAN Xp major: 6 minor: …我正在尝试基于流行的苗条实现训练tensorflow模型,mobilenet_v2并且正在观察无法解释与批处理规范化相关的行为(我认为)。
推理模式下的模型性能最初有所提高,但经过很长一段时间后才开始产生琐碎的推理(全部接近零)。当在训练模式下运行时,即使在评估数据集上,也将继续保持良好的性能。批处理归一化衰减/动量速率会影响评估性能。
下面提供了更多详细的实现细节,但是我可能会在文本墙中迷失大多数人,因此,这里有一些图片会让您感兴趣。
下面的曲线来自我bn_decay在训练时调整参数的模型。
0-370k :(bn_decay=0.997默认)
370k-670k: bn_decay=0.9
670k +: bn_decay=0.5
 (橙色)训练(在训练模式下)和(蓝色)评估(在推理模式下)的损失。低是好的。
(橙色)训练(在训练模式下)和(蓝色)评估(在推理模式下)的损失。低是好的。
我试图提供一个最小的例子来说明问题-在MNIST上进行分类-但失败了(即分类效果很好,并且我所遇到的问题没有出现)。对于无法进一步简化工作,我深表歉意。
我的问题是2D姿态估计,目标是将高斯集中在关节位置。它本质上与语义分段相同,除了不使用softmax_cross_entropy_with_logits(labels, logits)I用法tf.losses.l2_loss(sigmoid(logits) - gaussian(label_2d_points))(我使用术语“ logits”来描述我学习的模型的未激活输出,尽管这可能不是最好的术语)。
在对输入进行预处理之后,我的logits函数是对基本mobilenet_v2的作用域调用,其后是单个未激活的卷积层,以使过滤器数量合适。
from slim.nets.mobilenet import mobilenet_v2
def get_logtis(image):
    with mobilenet_v2.training_scope(
            is_training=is_training, bn_decay=bn_decay):
        base, _ = mobilenet_v2.mobilenet(image, base_only=True)
    logits = tf.layers.conv2d(base, n_joints, 1, 1)
    return logits
我已经尝试过tf.contrib.slim.learning.create_train_op,还有自定义培训操作:
def get_train_op(optimizer, loss):
    global_step = tf.train.get_or_create_global_step()
    opt_op = optimizer.minimize(loss, global_step)
    update_ops = set(tf.get_collection(tf.GraphKeys.UPDATE_OPS))
    update_ops.add(opt_op)
    return tf.group(*update_ops)
我使用的是tf.train.AdamOptimizer …
machine-learning deep-learning tensorflow tf-slim batch-normalization
inputs = Input((img_height, img_width, img_ch))
conv1 = Conv2D(n_filters, (k, k), padding=padding)(inputs)
conv1 = BatchNormalization(scale=False, axis=3)(conv1)
conv1 = Activation('relu')(conv1)    
conv1 = Conv2D(n_filters, (k, k),  padding=padding)(conv1)
conv1 = BatchNormalization(scale=False, axis=3)(conv1)
conv1 = Activation('relu')(conv1)    
pool1 = MaxPooling2D(pool_size=(s, s))(conv1)
在BatchNormalization  我阅读了 keras 文档但我不明白它的 (axis =3) 是什么意思,谁能解释一下axis是什么意思?
我正在使用 LSTM 网络进行多元多时间步预测。因此,基本上seq2seq预测是将多个数据n_inputs输入模型以预测n_outputs时间序列的多个数据。
我的问题是如何有意义地应用Dropout,BatchnNormalization因为这似乎是循环网络和 LSTM 网络广泛讨论的主题。为了简单起见,我们坚持使用 Keras 作为框架。
案例 1:普通 LSTM
model = Sequential()
model.add(LSTM(n_blocks, activation=activation, input_shape=(n_inputs, n_features), dropout=dropout_rate))
model.add(Dense(int(n_blocks/2)))
model.add(BatchNormalization())
model.add(Activation(activation))
model.add(Dense(n_outputs))
案例 2:带有 TimeDistributed Layers 的编码器解码器(如 LSTM)
model = Sequential()
model.add(LSTM(n_blocks, activation=activation, input_shape=(n_inputs,n_features), dropout=dropout_rate))
model.add(RepeatVector(n_outputs))
model.add(LSTM(n_blocks, activation=activation, return_sequences=True, dropout=dropout_rate))
model.add(TimeDistributed(Dense(int(n_blocks/2)), use_bias=False))
model.add(TimeDistributed(BatchNormalization()))
model.add(TimeDistributed(Activation(activation)))
model.add(TimeDistributed(Dropout(dropout_rate)))
model.add(TimeDistributed(Dense(1)))
lstm keras recurrent-neural-network batch-normalization dropout
假设我们有一个使用 BatchNormalization 的简单 Keras 模型:
model = tf.keras.Sequential([
                     tf.keras.layers.InputLayer(input_shape=(1,)),
                     tf.keras.layers.BatchNormalization()
])
如何实际使用 GradientTape?以下似乎不起作用,因为它没有更新移动平均线?
# model training... we want the output values to be close to 150
for i in range(1000):
  x = np.random.randint(100, 110, 10).astype(np.float32)
  with tf.GradientTape() as tape:
    y = model(np.expand_dims(x, axis=1))
    loss = tf.reduce_mean(tf.square(y - 150))
  grads = tape.gradient(loss, model.variables)
  opt.apply_gradients(zip(grads, model.variables))
特别是,如果您检查移动平均值,它们将保持不变(检查 model.variables,平均值始终为 0 和 1)。我知道可以使用 .fit() 和 .predict(),但我想使用 GradientTape 并且我不知道如何执行此操作。某些版本的文档建议更新 update_ops,但这似乎在急切模式下不起作用。
特别是,经过上述训练后,以下代码将不会输出任何接近 150 的结果。
x = np.random.randint(200, 210, 100).astype(np.float32)
print(model(np.expand_dims(x, axis=1)))
我使用Tensorflow 1.14.0和Keras 2.2.4。以下代码实现了一个简单的神经网络:
import numpy as np
np.random.seed(1)
import random
random.seed(2)
import tensorflow as tf
tf.set_random_seed(3)
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.layers import Input, Dense, Activation
x_train=np.random.normal(0,1,(100,12))
model = Sequential()
model.add(Dense(8, input_shape=(12,)))
# model.add(tf.keras.layers.BatchNormalization())
model.add(Activation('linear'))
model.add(Dense(12))
model.add(Activation('linear'))
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(x_train, x_train,epochs=20, validation_split=0.1, shuffle=False,verbose=2)
20个纪元后的最终val_loss为0.7751。当我取消注释添加批处理规范化层的唯一注释行时,val_loss更改为1.1230。
我的主要问题是方法更复杂,但同样的事情也会发生。由于激活是线性的,因此在激活之后还是之前将批处理归一化都没关系。
问题:为什么批量规范化无济于事?有什么我可以更改的,以便批量标准化可以在不更改激活功能的情况下改善结果吗?
收到评论后更新:
具有一个隐藏层和线性激活的NN类似于PCA。有大量的论文。对我来说,此设置在隐藏层和输出的所有激活功能组合中提供的MSE最小。
声明线性激活的某些资源表示PCA:
https://arxiv.org/pdf/1702.07800.pdf
https://link.springer.com/article/10.1007/BF00275687
https://www.quora.com/How-can-I-make-a-neural-network-to-work-as-a-PCA
我用较小的数据集训练了以下 CNN 模型,因此它确实过拟合:
model = Sequential()
model.add(Conv2D(32, kernel_size=(3,3), input_shape=(28,28,1), padding='same'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Conv2D(32, kernel_size=(3,3), padding='same'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(512))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
model.compile(loss="categorical_crossentropy", optimizer=Adam(), metrics=['accuracy'])
该模型有很多可训练的参数(超过 300 万个,这就是为什么我想知道我是否应该像下面这样使用额外的 MaxPooling 来减少参数的数量?
Conv - BN - Act - MaxPooling - Conv - BN - Act - MaxPooling - Dropout - Flatten
或者有一个额外的 MaxPooling 和 Dropout,如下所示?
Conv - BN - Act - MaxPooling - Dropout - Conv - BN - Act - MaxPooling - Dropout - Flatten
我试图了解 MaxPooling …
我想知道在 Tensorflow 2 的量化感知训练期间模拟 BatchNorm 折叠的当前可用选项是什么。 Tensorflow 1 具有tf.contrib.quantize.create_training_graph将 FakeQuantization 层插入图中并负责模拟批量归一化折叠的功能(根据本白皮书)。
Tensorflow 2 有一个关于如何在他们最近采用的API 中使用量化的教程tf.keras,但他们没有提到关于批量标准化的任何内容。我使用 BatchNorm 层尝试了以下简单示例:
import tensorflow_model_optimization as tfmo
model = tf.keras.Sequential([
      l.Conv2D(32, 5, padding='same', activation='relu', input_shape=input_shape),
      l.MaxPooling2D((2, 2), (2, 2), padding='same'),
      l.Conv2D(64, 5, padding='same', activation='relu'),
      l.BatchNormalization(),    # BN!
      l.MaxPooling2D((2, 2), (2, 2), padding='same'),
      l.Flatten(),
      l.Dense(1024, activation='relu'),
      l.Dropout(0.4),
      l.Dense(num_classes),
      l.Softmax(),
])
model = tfmo.quantization.keras.quantize_model(model)
然而,它给出了以下例外:
RuntimeError: Layer batch_normalization:<class 'tensorflow.python.keras.layers.normalization.BatchNormalization'> is not supported. You can quantize this layer by passing a `tfmot.quantization.keras.QuantizeConfig` …python tensorflow batch-normalization tensorflow2.0 quantization-aware-training
根据tensorflow官方文档:
关于在`BatchNormalization层上设置layer.trainable = False:
设置layer.trainable = False的含义是冻结该层,即其内部状态在训练期间不会改变:其可训练权重不会在fit()或train_on_batch(),其状态更新将不会运行。
通常,这并不一定意味着该层在推理模式下运行(通常由调用层时可以传递的训练参数控制)。“冻结状态”和“推理模式”是两个独立的概念。
然而,对于 BatchNormalization 层,在该层上设置 trainable = False 意味着该层随后将在推理模式下运行(意味着它将使用移动均值和移动方差来标准化当前批次,而不是使用当前批次的均值和方差)。
此行为已在 TensorFlow 2.0 中引入,以便使 layer.trainable = False 能够在卷积网络微调用例中产生最常见的预期行为。
我不太理解概念中的术语“冻结状态”和“推理模式”。我尝试通过将 设为 False 进行微调trainable,但发现移动均值和移动方差没有更新。
所以我有以下问题:
python ×6
keras ×5
tensorflow ×5
dropout ×2
gradienttape ×1
lstm ×1
max-pooling ×1
quantization-aware-training ×1
rnn ×1
tf-slim ×1
tf.keras ×1