Monte Carlo dropout.
几年前,剑桥大学的Yarin和Zoubin发现了一种在不改变神经网络结构或优化技术的情况下近似模型不确定性的方法。
这是一个简短的版本:通过在测试时在每个权重层之前使用dropout,并对几个迭代运行的预测,您可以近似估计贝叶斯不确定性。他们称这个过程被称为Monte Carlo dropout:
您向模型提供一个输入。
您可以预测对单个输入进行多次迭代,每次随机禁用神经网络的一小部分。
取平均输出值。这是你的预测。最后,测量迭代之间的方差。这是模型的不确定性。
直观上我是这样想的:你的预测随着模型的微小结构变化波动得越多,预测的不确定性就越大。
实现Monte Carlo dropout非常简单。在这里,我从一个简单的密集网络开始,来解决Keras构建的MNIST问题。默认情况下,dropout层只在培训期间启用。要在测试时启用dropout层,请为每个层设置training=True。
img_dim = 28
x_in = Input(shape=(img_dim, img_dim,))
x = Dropout(0.2)(x_in, training=True)
x = Dense(500, activation="relu")(x)
x = Dropout(0.2)(x, training=True)
x = Dense(250, activation="relu")(x)
x = Dropout(0.2)(x, training=True)
x_out = Dense(10, activation="softmax")(x)
model = Model(inputs=x_in, outputs=x_out)
model.compile(loss="categorical_crossentropy",
optimizer="rmsprop")
自定义预测函数,它可以迭代地预测并返回这些迭代的均值和方差。在这个例子中,我们测量的是标准差而不是方差,因为标准差和均值单位相同。
def predict_with_uncertainty(model,X,batch_size=None,num_iterations=100):
last_layer = model.layers[-1]
results = np.zeros((num_iterations, X.shape[0], last_layer.output_shape[1]),dtype="float")
for i in range(num_iterations):
results[i] = model.predict(X,batch_size=batch_size)
predictions = results.mean(axis=0)
uncertainty = results.std(axis=0)
return predictions, uncertainty
predictions, uncertainty = predict_with_uncertainty(model,your_data)