结合高斯过程与神经网络处理图像数据
立即解锁
发布时间: 2025-08-31 01:48:33 阅读量: 7 订阅数: 25 AIGC 

# 结合高斯过程与神经网络处理图像数据
## 1. 图像数据协方差计算问题
在处理结构化数据时,常见的高斯过程(GP)核会面临一些问题。为了突出这个问题,我们选取了三个特定的数据点,分别称为点 A、点 B 和点 C,它们的索引如下:
```python
ind1 = 304
ind2 = 786
ind3 = 4
```
在查看这些图像实际显示的数字之前,我们使用径向基函数(RBF)核来计算它们的协方差矩阵:
```python
>>> rbf_kernel(train_x[[ind1, ind2, ind3], :]).evaluate()
tensor([[1.0000e+00, 4.9937e-25, 0.0000e+00],
[4.9937e-25, 1.0000e+00, 0.0000e+00],
[0.0000e+00, 0.0000e+00, 1.0000e+00]], ...)
```
这是一个 3x3 的协方差矩阵,其对角元素的值为 1,表示各个变量的方差,而非对角元素表示不同的协方差。我们可以看到,点 A 和点 C 完全不相关,协方差为零,而点 A 和点 B 略有相关性。根据 RBF 核,点 A 和点 B 彼此相似,与点 C 完全不同。
然而,实际情况并非如此。实际上,点 A 和点 C 具有相同的标签(数字 9)。RBF 核认为点 A 和点 B 相关的原因是,虽然点 A 和点 B 的标签不同,但图像本身在许多像素匹配的意义上是相似的。实际上,构成数字尾部的笔画在两幅图像中几乎完全匹配。因此,从某种意义上说,RBF 核在完成其工作,计算图像之间的差异,并根据该差异输出一个表示它们协方差的数字。但问题在于,它仅通过比较像素本身来计算差异,而这并不是我们试图学习的指标,即数字的值。
仅查看像素值,RBF 核高估了具有不同标签的点 A 和点 B 之间的协方差,低估了具有相同标签的点 A 和点 C 之间的协方差。这就像一个不恰当的“房屋核”,仅通过前门的颜色来决定两栋房子是否相关,从而导致对房价的不准确预测。类似地,RBF 核在比较两幅图像时,仅考虑像素值,而不考虑更高级别的模式,这导致了较差的预测性能。
## 2. 在图像数据上训练 GP
由于使用了错误的相似性度量,RBF 核混淆了点 B 和点 C 中哪个与点 A 相关,这在训练 GP 时会导致较差的结果。我们再次使用 MNIST 数据集,这次提取 1000 个数据点作为训练集,另外 500 个点作为测试集。数据准备和学习工作流程如下:
```mermaid
graph LR
A[导入必要的库] --> B[转换以归一化像素值]
B --> C1[下载训练数据集]
B --> C2[下载测试数据集]
C1 --> D1[提取前 1000 个数据点]
C2 --> D2[提取前 500 个数据点]
D1 --> E[在训练集上训练 GP]
E --> F[在测试集上进行推理]
```
具体步骤如下:
1. **导入必要的库**:
```python
import torch
from torchvision import datasets, transforms
```
2. **转换以归一化像素值**:
```python
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
```
3. **下载数据集**:
```python
dataset1 = datasets.MNIST(
"../data", train=True, download=True, transform=transform
)
dataset2 = datasets.MNIST(
"../data", train=False, download=True, transform=transform
)
```
4. **提取数据点**:
```python
train_x = dataset1.data[:1000, ...].view(1000, -1).to(torch.float)
train_y = dataset1.targets[:1000]
test_x = dataset2.data[:500, ...].view(500, -1).to(torch.float)
test_y = dataset2.targets[:500]
```
5. **实现简单的 GP 模型**:
```python
import gpytorch
class GPModel(gpytorch.models.ExactGP):
def __init__(self, train_x, train_y, likelihood):
super().__init__(train_x, train_y, likelihood)
self.mean_module = gpytorch.means.ConstantMean()
self.covar_module = gpytorch.kernels.ScaleKernel(
gpytorch.kernels.RBFKernel()
)
def forward(self, x):
mean_x = self.mean_module(x)
covar_x = self.covar_module(x)
return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)
```
6. **初始化 GP 并进行训练**:
```python
from tqdm import tqdm
likelihood = gpytorch.likelihoods.GaussianLikelihood()
model = GPModel(train_x, train_y, likelihood)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)
model.train()
likelihood.train()
for i in tqdm(range(500)):
optimizer.zero_grad()
output = model(train_x)
loss = -mll(output, train_y)
loss.backward()
optimizer.step()
model.eval()
likelihood.eval()
```
7. **计算平均绝对误差(MAE)**:
```python
with torch.no_grad():
mean_preds = model(test_x).mean
print(torch.mean(torch.abs(mean_preds - test_y)))
```
输出结果为 2.7021167278289795,这意味着平均而言,GP 对图像中数字值的预测偏差接近 3。考虑到这项任务中只有 10 个值需要学习,这个性能相当低,这凸显了常规 GP 模型在处理结构化数据(如图像)时的无能。
## 3. 使用神经网络处理复杂结构化数据
### 3.1 为什么使用神经网络进行建模
神经网络在进行不确定性校准预测方面并不出色,特别是在数据获取成本较高的情况下,这也是 GP 在贝叶斯优化中被使用的原因。然而,神经网络擅长学习复杂的结构。这种灵活性源于神经网络中存在多个计算层(具体来说是矩阵乘法)。在神经网络中,每一层对应一个矩阵乘法,其输出随后通过一个非线性激活函数。通过在一次前向传播中串联多个这样的层,网络的输入可以以灵活的方式进行处理和操作,最终结果是神经网络可以很好地建模复杂函数。
如果 GP 的核(如 RBF 核)不能很好地处理复杂的数据结构,我们可以将这项工作交给神经网络,只将处理后的输入提供给 GP 的核。具体来说,输入 x 首先通过神经网络层,然后再传递给 GP 的均值函数和核。虽然最终结果仍然是一个多元正态(MVN)分布,但均值函数和核的输入现在是由神经网络产生的处理后的输入。这种方法很有前景,因为神经网络具有灵活的建模能力,能够从结构化输入数据中提取重要特征,并将其简化为适合 GP 核的数值。神经网络通常被称为组合模型的特征提取器,因为它从结构化数据中提取有利于 GP 建模的特征。
通过这种方式,我们可以利用神经网络的灵活学习能力,同时保持 GP 进行不确定性校准预测的能力。此外,训练这个组合模型的过程与训练常规 GP 相同:我们定义损失函数(即负对数似然),并使用梯度下降法找到最能解释我们数据的超参数值(通过最小化损失)。与仅优化均值常数
0
0
复制全文
相关推荐









