构建贝叶斯深度学习分类器

原文

介绍

在这篇博客,我会教你如何培养使用贝叶斯深学习分类Kerastensorflow。在深入了解具体的培训示例之前,我将介绍几个重要的高级概念:

  1. 什么是贝叶斯深度学习?
  2. 什么是不确定性?
  3. 为什么不确定性很重要

然后,我将介绍两种在深度学习模型中包含不确定性的技术,并将使用Kerascifar10数据集上通过冻结的ResNet50编码器训练完全连接的层。通过这个例子,我还将讨论探索贝叶斯深度学习分类器的不确定性预测的方法,并提出改进模型的建议。

致谢

这篇文章基于两篇博客文章(这里这里)的材料和一篇关于剑桥大学机器学习小组的贝叶斯深度学习的白皮书。如果您想在阅读本文后了解有关贝叶斯深度学习的更多信息,我建议您查看所有这三种资源。感谢剑桥大学机器学习小组为您提供的精彩博文和论文。

什么是贝叶斯深度学习?

贝叶斯统计是统计学领域的一种理论,其中关于世界真实状态的证据用信念程度来表达。贝叶斯统计学与实践中的深度学习相结合意味着包括深度学习模型预测中的不确定性。早在1991年就提出了在神经网络中包含不确定性的想法。简而言之,贝叶斯深度学习在典型神经网络模型中的每个权重和偏差参数上增加了先验分布。过去,贝叶斯深度学习模型并不经常使用,因为它们需要更多参数进行优化,这可能使模型难以使用。然而,最近,贝叶斯深度学习变得越来越流行,并且正在开发新技术以包括模型中的不确定性,同时使用与传统模型相同数量的参数。

alt图像

可视化贝叶斯深度学习模型。

什么是不确定性

不确定性是指知识有限的状态,无法准确描述现有状态,未来结果或不止一种可能的结果。由于它涉及深度学习和分类,不确定性还包括模糊性; 关于人类定义和概念的不确定性,而不是客观的自然事实。

alt图像

歧义的一个例子。该模型应该预测什么?

不确定性的类型

有几种不同类型的不确定性,我将在本文中仅涵盖两种重要类型。

狂热的不确定性

Aleatoric不确定性衡量您无法从数据中理解的内容。可以通过提高精度来观察所有解释变量的能力来解释它。将任意不确定性视为感知不确定性。实际上有两种类型的任意不确定性,异方差和同方差,但我只是在这篇文章中涉及异方差的不确定性。博客文章更深入地介绍了Homoscedastic 。

立体图像中任意不确定性的具体示例是遮挡(相机无法看到的场景的部分),缺少视觉特征(即空白墙),或暴露区域上方/下方(眩光和阴影)。

alt图像

遮挡示例

alt图像

缺乏视觉功能的例子

alt图像

曝光不足的例子

认识不确定性

认知不确定性衡量的是由于缺乏培训数据,您的模型不知道什么。它可以通过无限的训练数据来解释。将认知不确定性视为模型不确定性。

观察行动中认知不确定性的一种简单方法是在25%的数据集上训练一个模型,并在整个数据集上训练第二个模型。仅在25%的数据集上训练的模型将具有比在整个数据集上训练的模型更高的平均认知不确定性,因为它看到的示例更少。

在现在着名的Not Hotdog应用程序中发现了一个有趣的认知不确定性的例子。根据我自己对应用程序的体验,该模型表现非常出色。但经过仔细检查,似乎网络从未接受过“非热狗”图像培训,其中包括图像中项目的番茄酱。因此,如果模型显示你的腿上有番茄酱的图片,那么该模型就会被认为是热狗。贝叶斯深度学习模型将预测这些情况下的高认识不确定性。

为什么不确定性很重要

在机器学习中,我们试图创建现实世界的近似表示。今天创建的流行深度学习模型产生点估计但不是不确定性值。了解您的模型是否缺乏信心或错误过度自信可以帮助您推断您的模型和数据集。上面解释的两种不确定性是由于不同的原因导入的。

注意:在分类问题中,softmax输出为您提供每个类的概率值,但这与不确定性不同。softmax概率是输入相对于其他类的给定类的概率。因为概率是相对于其他类的,所以它无助于解释模型的整体置信度。

为什么Aleatoric的不确定性很重要?

在观测空间的某些部分具有比其他部分更高的噪声水平的情况下,对于不明显的不确定性很重要 例如,任意不确定性在涉及自驾车的第一次死亡中起了作用。特斯拉说,在这次事件中,汽车的自动驾驶仪未能识别出明亮的天空中的白色卡车。能够预测任意不确定性的图像分割分类器将认识到图像的该特定区域难以解释并且预测高不确定性。在特斯拉事件的情况下,虽然汽车的雷达可以“看到”卡车,但雷达数据与图像分类器数据不一致,并且汽车的路径规划者最终忽略了雷达数据(已知雷达数据有噪声)。

alt图像

即使对于人来说,在道路上有很多眩光的情况下驾驶也很困难

为什么认识不确定性很重要?

认知不确定性很重要,因为它确定了模型从未被训练过去理解的情况,因为情况不在训练数据中。机器学习工程师希望我们的模型能够很好地适应与训练数据不同的情况; 然而,在深度学习的安全关键应用中,希望是不够的。高认知不确定性是一个红旗,模型更有可能做出不准确的预测,当这种情况发生在安全关键应用程序中时,该模型不应该被信任。

认知不确定性也有助于探索数据集。例如,认知不确定性对20世纪80年代这种特殊的神经网络事故有所帮助。在这种情况下,研究人员训练了一个神经网络识别隐藏在树木中的坦克与没有坦克的树木。经过培训,网络在训练集和测试集上表现非常出色。唯一的问题是坦克的所有图像都是在阴天拍摄的,所有没有坦克的图像都是在晴天拍摄的。分类器实际上已经学会识别晴天和阴天。哎呦。

alt图像 alt图像

坦克和阴天没有坦克和晴天

深度学习模型中的不确定性预测在机器人技术中也很重要。我目前正在参加Udacity自动驾驶汽车nanodegree,并且一直在学习汽车/机器人用于识别和跟踪物体的技术。自驾车使用称为卡尔曼滤波器的强大技术来跟踪物体。卡尔曼滤波器结合了一系列包含统计噪声的测量数据,并产生比任何单次测量更准确的估计。传统的深度学习模型无法为卡尔曼滤波器做出贡献,因为它们只预测结果而不包括不确定性项。理论上,贝叶斯深度学习模型可以促进卡尔曼滤波器跟踪。

alt图像

雷达和激光雷达数据合并到卡尔曼滤波器中。也可以合并图像数据。

计算深度学习分类模型的不确定性

阿瓦里克和认知的不确定性是不同的,因此,它们的计算方式不同。

计算任意不确定性

Aleatoric不确定性是输入数据的函数。因此,深度学习模型可以通过使用修改的损失函数来学习预测任意不确定性。对于分类任务,贝叶斯深度学习模型将具有两个输出,即softmax值和输入方差,而不是仅预测softmax值。教导模型预测任意方差是无监督学习的一个例子,因为该模型没有可供学习的方差标签。下面是标准分类交叉熵损失函数和计算贝叶斯分类交叉熵损失的函数。

import numpy as np
from keras import backend as K
from tensorflow.contrib import distributions

# standard categorical cross entropy
# N data points, C classes
# true - true values. Shape: (N, C)
# pred - predicted values. Shape: (N, C)
# returns - loss (N)
def categorical_cross_entropy(true, pred):
	return np.sum(true * np.log(pred), axis=1)

# Bayesian categorical cross entropy.
# N data points, C classes, T monte carlo simulations
# true - true values. Shape: (N, C)
# pred_var - predicted logit values and variance. Shape: (N, C + 1)
# returns - loss (N,)
def bayesian_categorical_crossentropy(T, num_classes):
  def bayesian_categorical_crossentropy_internal(true, pred_var):
    # shape: (N,)
    std = K.sqrt(pred_var[:, num_classes:])
    # shape: (N,)
    variance = pred_var[:, num_classes]
    variance_depressor = K.exp(variance) - K.ones_like(variance)
    # shape: (N, C)
    pred = pred_var[:, 0:num_classes]
    # shape: (N,)
    undistorted_loss = K.categorical_crossentropy(pred, true, from_logits=True)
    # shape: (T,)
    iterable = K.variable(np.ones(T))
    dist = distributions.Normal(loc=K.zeros_like(std), scale=std)
    monte_carlo_results = K.map_fn(gaussian_categorical_crossentropy(true, pred, dist, undistorted_loss, num_classes), iterable, name='monte_carlo_results')
    
    variance_loss = K.mean(monte_carlo_results, axis=0) * undistorted_loss
    
    return variance_loss + undistorted_loss + variance_depressor
  
  return bayesian_categorical_crossentropy_internal

# for a single monte carlo simulation, 
#   calculate categorical_crossentropy of 
#   predicted logit values plus gaussian 
#   noise vs true values.
# true - true values. Shape: (N, C)
# pred - predicted logit values. Shape: (N, C)
# dist - normal distribution to sample from. Shape: (N, C)
# undistorted_loss - the crossentropy loss without variance distortion. Shape: (N,)
# num_classes - the number of classes. C
# returns - total differences for all classes (N,)
def gaussian_categorical_crossentropy(true, pred, dist, undistorted_loss, num_classes):
  def map_fn(i):
    std_samples = K.transpose(dist.sample(num_classes))
    distorted_loss = K.categorical_crossentropy(pred + std_samples, true, from_logits=True)
    diff = undistorted_loss - distorted_loss
    return -K.elu(diff)
  return map_fn

我创建的损失函数是基于损失函数文件。在本文中,损失函数创建了一个均值为零的正态分布和预测的方差。它通过从分布中取样来扭曲预测的logit值,并使用扭曲的预测来计算softmax分类交叉熵。损失函数运行T Monte Carlo样本,然后将T样本的平均值作为损失。

alt图像

图1:二进制分类的Softmax分类交叉熵与logit差异

在图1中,y轴是softmax分类交叉熵。x轴是“正确”logit值与“错误”logit值之间的差异。'right'表示此预测的正确类。'错'表示此预测的错误类。我将使用术语'logit difference'来表示图1的x轴。当图1中的'logit difference'为正时,softmax预测将是正确的。当'logit difference'为负时,预测将是不正确的。当我解释任意损失函数时,我将继续使用术语'logit difference','right'logit和'wrong'logit。

图1有助于理解正态分布失真的结果。当使用正态分布使对数值(在二元分类中)失真时,失真有效地创建具有原始预测的“对数差异”的平均值和作为分布方差的预测方差的正态分布。将softmax交叉熵应用于失真的logit值与沿着图1中的线采样“logit difference”值相同。

采用失真logits的分类交叉熵理想情况下应该会产生一些有趣的属性。

  1. 当预测的logit值远大于任何其他logit值(图1的右半部分)时,增加方差应该只会增加损失。这是正确的,因为导数在图的右半部分是负的。即,与“logit差异”的相等减少相比,增加'logit差异'导致softmax分类交叉熵的略微减小。在这种情况下,最小损失应接近0。
  2. 当'错误'logit远大于'right'logit(图的左半部分)并且方差为~0时,损失应为〜wrong_logit-right_logit。你可以看到这是在图1的右半部分。当'logit difference'是-4时,softmax交叉熵是4.图的这一部分的斜率是〜-1所以这应该是真的' logit差异'继续下降。
  3. 为了使模型能够学习任意不确定性,当'错误'的logit值大于'right'logit值(图的左半部分)时,对于大于0的方差值,应该最小化损失函数。具有较高的任意不确定性(即模型难以对该图像进行准确预测),该特征鼓励模型在训练期间通过增加其预测方差来找到局部损失最小值。

通过增加方差,我能够使用本文中建议的损失函数来减少“错误”logit值大于“正确”logit值时的损失,但由于增加方差而导致的损失减少非常小(<0.1)。在训练期间,我的模型很难在这个轻微的局部最小值上获得,而我模型中的任意变化预测没有意义。我相信这是因为图的左半部分的图1的斜率是-1。沿着斜率为-1的线对正态分布进行采样将导致另一个正态分布,并且平均值将与之前大致相同,但我们想要的是随着方差的增加T样本的平均值减小。

为了使模型更容易训练,我想随着方差的增加创造更显着的损失变化。就像在论文中一样,我的上述损失函数使用平均值为0的正态分布和预测的方差扭曲了T Monte Carlo样本的logits,然后计算每个样本的分类交叉熵。为了在方差增加时获得更显着的损失变化,需要对蒙特卡罗样本进行加权所需的损失函数,其中损失比损失增加的样本减少更多。我的解决方案是使用洗脱激活功能,这是一个以0为中心的非线性函数。

alt图像

ELU激活功能

我将洗脱函数应用于分类交叉熵的变化,即与失真损失相比的原始未失真损失,undistorted_loss - distorted_loss。对于图1的左半部分,洗脱液使正态分布的平均值偏离零。对于接近0的非常小的值,洗脱液也是线性的,因此图1的右半部分的平均值保持相同。

alt图像

图2:损失的平均变化和损失的平均变化失真。

在图2中,right < wrong对应于图1左半部分的wrong < right一个点,对应于图2右半部分的一个点。您可以看到来自“错误”logit情况的结果分布看起来类似于正态分布和“正确”的情况主要是接近于零的小值。在应用-elu损失变化后,平均值right < wrong变得更大。在此示例中,它从-0.16更改为0.25。wrong < right住宿的意思大致相同。我将图2中下图的均值称为“损失的扭曲平均变化”。随着方差在图1的右半部分增加,“损失的失真平均变化”应该保持在0附近,并且当图1的右半部分的方差增加时,应该总是增加。

然后,我通过原始未失真的分类交叉熵来缩放“损失的扭曲平均变化”。这样做是因为对于大于三的所有logit差异,错误的logit情况下的失真平均变化大致相同(因为该行的导数为0)。为了确保损失大于零,我添加了未失真的分类交叉熵。“损失的失真平均变化”总是随着方差的增加而减小,但是对于小于无穷大的方差值,损失函数应该最小化。为了确保最小化损失的方差小于无穷大,我添加了方差项的指数。如图3所示,方差的指数是方差经过2后的主导特征。

alt图像

图3:不同“错误”logit值的Aleatoric方差与损失

alt图像

图4:不同“错误”logit值的最小任意差异和最小损失

这些是计算二元分类示例的上述损失函数的结果,其中“正确”的logit值保持恒定为1.0,并且每行的“错误”logit值发生变化。当'错误'的logit值小于1.0(因此小于'right'logit值)时,最小方差为0.0。随着错误的“logit”值的增加,最小化损失的方差也会增加。

注意:生成此图时,我运行10,000次蒙特卡罗模拟以创建平滑线条。在训练模型时,我只进行了100次蒙特卡罗模拟,因为这足以得到合理的平均值。

alt图像

脑过载?在继续之前,先吸一次适当的饮料。

计算认知不确定性

建模认知不确定性的一种方法是在测试时使用蒙特卡洛辍学采样(一种变分推断)。有关为什么辍学可以模拟不确定性的完整解释,请查看博客和白皮书白皮书。在实践中,蒙特卡洛辍学抽样意味着包括模型中的辍学和在测试时打开辍学多次运行模型以创建结果分布。然后,您可以计算预测熵(预测分布中包含的平均信息量)。

要了解使用辍学计算认知不确定性,请考虑将猫狗图像垂直分成两半。

alt图像 alt图像

如果你看到左半边,你会预测狗。如果你看到右半边你会预测猫。完美的50-50分裂。这个图像具有很高的认知不确定性,因为图像具有与猫类和狗类相关联的特征。

以下是两种计算认知不确定性的方法。他们做的完全相同,但第一个更简单,只使用numpy。第二个使用额外的Keras层(并获得GPU加速)来进行预测。

# model - the trained classifier(C classes) 
#					where the last layer applies softmax
# X_data - a list of input data(size N)
# T - the number of monte carlo simulations to run
def montecarlo_prediction(model, X_data, T):
	# shape: (T, N, C)
	predictions = np.array([model.predict(X_data) for _ in range(T)])

	# shape: (N, C)
	prediction_probabilities = np.mean(predictions, axis=0)
	
	# shape: (N)
	prediction_variances = np.apply_along_axis(predictive_entropy, axis=1, arr=prediction_probabilities)
	return (prediction_probabilities, prediction_variances)

# prob - prediction probability for each class(C). Shape: (N, C)
# returns - Shape: (N)
def predictive_entropy(prob):
	return -1 * np.sum(np.log(prob) * prob, axis=1)
from keras.models import Model
from keras.layers import Input, RepeatVector
from keras.engine.topology import Layer
from keras.layers.wrappers import TimeDistributed

# Take a mean of the results of a TimeDistributed layer.
# Applying TimeDistributedMean()(TimeDistributed(T)(x)) to an
# input of shape (None, ...) returns output of same size.
class TimeDistributedMean(Layer):
	def build(self, input_shape):
		super(TimeDistributedMean, self).build(input_shape)

	# input shape (None, T, ...)
	# output shape (None, ...)
	def compute_output_shape(self, input_shape):
		return (input_shape[0],) + input_shape[2:]

	def call(self, x):
		return K.mean(x, axis=1)


# Apply the predictive entropy function for input with C classes. 
# Input of shape (None, C, ...) returns output with shape (None, ...)
# Input should be predictive means for the C classes.
# In the case of a single classification, output will be (None,).
class PredictiveEntropy(Layer):
	def build(self, input_shape):
		super(PredictiveEntropy, self).build(input_shape)

	# input shape (None, C, ...)
	# output shape (None, ...)
	def compute_output_shape(self, input_shape):
		return (input_shape[0],)

	# x - prediction probability for each class(C)
	def call(self, x):
		return -1 * K.sum(K.log(x) * x, axis=1)


def create_epistemic_uncertainty_model(checkpoint, epistemic_monte_carlo_simulations):
	model = load_saved_model(checkpoint)
	inpt = Input(shape=(model.input_shape[1:]))
	x = RepeatVector(epistemic_monte_carlo_simulations)(inpt)
	# Keras TimeDistributed can only handle a single output from a model :(
	# and we technically only need the softmax outputs.
	hacked_model = Model(inputs=model.inputs, outputs=model.outputs[1])
	x = TimeDistributed(hacked_model, name='epistemic_monte_carlo')(x)
	# predictive probabilities for each class
	softmax_mean = TimeDistributedMean(name='epistemic_softmax_mean')(x)
	variance = PredictiveEntropy(name='epistemic_variance')(softmax_mean)
	epistemic_model = Model(inputs=inpt, outputs=[variance, softmax_mean])

	return epistemic_model

# 1. Load the model
# 2. compile the model
# 3. Set learning phase to train
# 4. predict
def predict():
  model = create_epistemic_uncertainty_model('model.ckpt', 100)
  model.compile(...)

  # set learning phase to 1 so that Dropout is on. In keras master you can set this
	# on the TimeDistributed layer
	K.set_learning_phase(1)

	epistemic_predictions = model.predict(data)

注意:认知不确定性不用于训练模型。它仅在评估测试/现实世界示例时在测试时(但在训练阶段)计算。这与任意不确定性不同,预测作为训练过程的一部分。而且,根据我的经验,比任意不确定性预测更容易产生合理的认知不确定性预测。

训练贝叶斯深度学习分类器

除了上面的代码之外,训练贝叶斯深度学习分类器来预测不确定性不需要超出通常用于训练分类器的额外代码。

def resnet50(input_shape):
	input_tensor = Input(shape=input_shape)
	base_model = ResNet50(include_top=False, input_tensor=input_tensor)
	# freeze encoder layers to prevent over fitting
	for layer in base_model.layers:
		layer.trainable = False

	output_tensor = Flatten()(base_model.output)
	return Model(inputs=input_tensor, outputs=output_tensor)

对于这个实验中,我使用的冷冻卷积层从Resnet50与权重ImageNet来编码图像。我最初试图在没有冻结卷积层的情况下训练模型,但发现模型很快变得过度合适。

def create_bayesian_model(encoder, input_shape, output_classes):
	encoder_model = resnet50(input_shape)
	input_tensor = Input(shape=encoder_model.output_shape[1:])
	x = BatchNormalization(name='post_encoder')(input_tensor)
	x = Dropout(0.5)(x)
	x = Dense(500, activation='relu')(x)
	x = BatchNormalization()(x)
	x = Dropout(0.5)(x)
	x = Dense(100, activation='relu')(x)
	x = BatchNormalization()(x)
	x = Dropout(0.5)(x)

	logits = Dense(output_classes)(x)
	variance_pre = Dense(1)(x)
	variance = Activation('softplus', name='variance')(variance_pre)
	logits_variance = concatenate([logits, variance], name='logits_variance')
	softmax_output = Activation('softmax', name='softmax_output')(logits)

	model = Model(inputs=input_tensor, outputs=[logits_variance,softmax_output])

	return model

我的模型的可训练的一部分是两套BatchNormalizationDropoutDense,和relu在ResNet50输出的顶层。使用单独的Dense图层计算logits和方差。请注意,方差层应用softplus激活函数以确保模型始终预测大于零的方差值。然后将logit和variance层重新组合用于任意损失函数,并且仅使用logit层计算softmax。

model.compile(
	 优化=亚当(LR = 1E-3 衰变= 0.001),
	 损耗= {
	 ' logits_variance ':bayesian_categorical_crossentropy(10010),
	 ' softmax_output '' categorical_crossentropy '
	},
	metrics = { ' softmax_output ':metrics.categorical_accuracy},
	 loss_weights = { ' logits_variance ':。2' softmax_output '1。})

我使用两个损失训练模型,一个是任意不确定性损失函数,另一个是标准分类交叉熵函数。这允许Dense创建logits 的最后一层仅学习如何产生更好的logit值,而Dense创建方差的层仅学习预测方差。前两个Dense层将对这两种损失进行培训。任意不确定性损失函数的加权小于分类交叉熵损失,因为任意不确定性损失包括分类交叉熵损失作为其中一个术语。

我使用100蒙特卡罗模拟来计算贝叶斯损失函数。每个时期花了大约70秒。我发现蒙特卡罗模拟的数量从100增加到1,000,每个训练时期增加了大约4分钟。

我通过随机应用0.5或2.0的伽玛值来增加数据到训练集,以减少或增加每个图像的亮度。在实践中,我发现cifar10数据集没有很多图像在理论上表现出很高的任意不确定性。这可能是设计上的。通过将具有调整的伽马值的图像添加到训练集中的图像,我试图给模型更多应该具有高任意不确定性的图像。

alt图像

具有伽马值失真的示例图像。1.0没有失真

不幸的是,预测认知不确定性需要相当长的时间。对于完全连接的层,我的Mac CPU需要大约2-3秒来预测训练集的所有50,000个类,但是对于认知不确定性预测超过五分钟。这并不令人惊讶,因为认知不确定性需要在每张图像上运行蒙特卡罗模拟。我进行了100次蒙特卡罗模拟,因此可以合理地预测预测过程比预测不确定性需要大约100倍的时间来预测认知不确定性。

最后,我的项目设置为轻松切换底层编码器网络,并为将来的其他数据集训练模型。如果您想深入了解自己的贝叶斯深度学习分类器,请随意使用它。

结果

alt图像

cifar10中每个类的示例

我的模型在测试数据集上的分类准确率为86.4%。无论如何,这不是一个惊人的分数。我能够产生高于93%的分数,但只能牺牲任意不确定性的准确性。我可以使用一些不同的超参数来提高我的分数。我花了很少的时间调整两个损失函数的权重,我怀疑改变这些超参数可以大大提高我的模型精度。我也可以解冻Resnet50层并训练它们。虽然获得更好的准确度得分对这个数据集很有意思,贝叶斯深度学习既涉及预测和不确定性估计,所以我将花费其余的时间来评估我的模型的不确定性预测的有效性。

alt图像

图5:测试集的不确定性平均值和标准偏差

任意不确定性值往往比认知不确定性小得多。这两个值无法直接在同一图像上进行比较。然而,可以将它们与模型为该数据集中的其他图像预测的不确定性值进行比较。

alt图像

图6:“正确”logit值的相对等级的不确定性。

为了进一步探索不确定性,我根据正确logit的相对值将测试数据分成三组。在图5中,“first”包括所有正确的预测(即'right'标签的logit值是最大值)。'second',包括'right'标签是第二大logit值的所有情况。'rest'包括所有其他情况。86.4%的样本属于“第一”组,8.7%属于“第二”组,4.9%属于“休息”组。图5显示了由这三组分组的测试集的任意和认知不确定性的平均值和标准差。正如我所希望的那样,认知和任意不确定性与“正确”对数的相对等级相关。这表明模型更可能识别不正确的标签,因为它不确定。此外,当模型的预测正确时,模型预测大于零的不确定性。我期望模型能够展现出这种特性,因为即使模型的预测是正确的,模型也是不确定的。

alt图像

具有最高任意不确定性的图像

alt图像

具有最高认知不确定性的图像

以上是具有最高任意性和认知不确定性的图像。虽然看图像很有意思,但我不清楚为什么这些图像图像具有高度的任意性或认知不确定性。这是训练图像分类器产生不确定性的一个缺点。整个图像的不确定性降低到单个值。在图像分割模型中理解不确定性通常要容易得多,因为更容易比较图像中每个像素的结果。

alt图像

“说明语义分割的任意性和认知不确定性之间的区别。你可以注意到任意不确定性捕获了标签噪声的对象边界。底行显示了分割模型的失败情况,当模型不熟悉人行道时,相应的认知不确定性增加。“ 链接

如果我的模型很好地理解任意不确定性,我的模型应该预测较低对比度,高亮度/暗度或高遮挡的图像较大的任意不确定度值为了测试这个理论,我将一系列伽玛值应用于我的测试图像以增加/减少增强图像的像素强度和预测结果。

alt图像

图7:左侧:应用了伽玛值的图像和不确定性。右侧:原始图像的图像和不确定性。

模型在增强图像上的准确度为5.5%。这意味着伽马图像完全欺骗了我的模型。该模型没有经过训练,无法在这些伽马失真上得分,因此可以预期。图6显示了左侧八个增强图像和右侧八个原始不确定性和图像的预测不确定性。前四幅图像具有最高预测的增强图像的任意不确定性,后四幅图像具有最低的增强图像的任意不确定性。我很高兴看到该模型预测每个增强图像与原始图像相比更高的任意和认知不确定性!

下一步

本文详述的模型仅探讨了贝叶斯深度学习冰山的一角,并且我认为可以通过几种方式改进模型的预测。例如,我可以继续使用损失权重并解冻Resnet50卷积层,看看我是否可以获得更好的准确度得分而不会丢失上面详述的不确定性特征。我还可以尝试在数据集上训练模型,该数据集具有更多具有高度任意不确定性的图像。一个候选人是德国交通标志识别基准我在其中一个Udacity项目中使用过的数据集。该数据集专门用于使分类器“应对由于光照变化,部分遮挡,旋转,天气条件引起的视觉外观的大变化”。对我来说听起来像是狂热的不确定性!

除了试图改进我的模型,我还可以进一步探索我训练的模型。一种方法是查看我的模型如何处理对抗性示例。要做到这一点,我可以使用像Ian Goodfellow创建的CleverHans这样的库。该库使用对抗神经网络来帮助探索模型漏洞。看看CleverHans产生的对抗性例子是否也会导致很大的不确定性,这将会很有趣。

我很兴奋探索的另一个库是Edward,一个用于概率建模,推理和批评的Python库。Edward支持使用概率分布创建网络层,并且可以轻松执行变分推理。这篇博文使用Edward在MNIST数据集上训练贝叶斯深度学习分类器。

如果你已经做到这一点,我印象非常深刻和感激。希望这篇文章能激发你在下一个深度学习项目中加入不确定性。

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值