Skip to main content

由内核机器驱动的连接主义模型。

项目描述


# kerNET

kerNET 是一个简单的、高级的、基于 PyTorch 的 API,可帮助您轻松构建内核机器驱动的连接模型。它基于 [PyTorch](http://pytorch.org/) 以使 GPU 加速成为可能(就像神经网络一样,这些模型需要对大型矩阵进行操作)。
kerNET 本质上是 PyTorch 加上一些额外的层,这些层是此类模型的构建块。
为方便起见,还提供了一些更高级别的模型抽象,包括 [本文] (https://arxiv.org/abs/1802.03774) 中提出的多层内核网络 (MLK​​N)。

在这里使用内核机器构建网络就像在 PyTorch 中构建神经网络一样简单:您基本上只需要阅读 [这个很棒的教程](http://pytorch.org/tutorials/beginner/blitz/neural_networks_tutorial.html#sphx- glr-beginner-blitz-neural-networks-tutorial-py)。

依赖项:
- Python 3
- PyTorch 0.4.0

目前,使用此 API 的最佳方式是通过 fork 或通过 ``git clone``。希望您喜欢它,任何建议或贡献将不胜感激!

---------

## 多层内核网络

MLKN 相当于内核机器领域中的全连接前馈神经网络。它就像 [多层感知器 (MLP)] (https://en.wikipedia.org/wiki/Multilayer_perceptron) 一样工作,只是在后台,现在一切都由 [内核机器] (https://en. wikipedia.org/wiki/Radial_basis_function_network)。

在此存储库中,您将找到一个预构建但仍高度可定制的 MLKN 模型。您可以像使用任何其他高级神经网络 API 一样轻松配置网络的大小和其他一些功能。训练方面,除了 PyTorch 的所有原生方法外,我们还为您实现了【建议的分层方法】(https://arxiv.org/abs/1802.03774),您只需在几行代码中指定一些超参数即可让事情顺利进行。论文中使用的一些数据集也可以随时供您测试模型。

### 为 [鸢尾花数据集](https://en.wikipedia.org/wiki/Iris_flower_data_set)逐层训练 MLKN 分类器

对数据进行一些导入和预处理以做好准备。
```python
将 numpy 导入为 np
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
import torch
from torch.autograd import Variable

x, y = load_iris(return_X_y=True)

# 将特征归一化为 0 均值和单位方差
normalizer = StandardScaler()
x = normalizer。 fit_transform(x)
n_class = int(np.amax(y) + 1)

# 将 numpy 数据转换为 torch 对象
dtype = torch.FloatTensor
if torch.cuda.is_available():
dtype = torch.cuda.FloatTensor
X = Variable(torch .from_numpy(x).type(dtype), requires_grad=False)
Y = Variable(torch.from_numpy(y).type(dtype), requires_grad=False)

# 随机置换数据
new_index = torch.randperm(X.shape[0 ])
X, Y = X[new_index], Y[new_index]

# 将数据平均分成训练和测试
index = len(X)//2
x_train, y_train = X[:index], Y[:index]
x_test, y_test = X [index:], Y[index:]
```

MLKNClassifier 是一个预先构建的 MLKN 模型,已经配置了分层训练。它被实现用于具有任意数量的类的分类。
```python
from models.mlkn import MLKNClassifier
mlkn = MLKNClassifier()
```

让我们实现一个双层 MLKN,第一层有 15 个内核机器,第二层有 ```n_class``` 内核机器(因为我们稍后将使用交叉熵作为我们的损失函数,并将第二层训练为 RBFN) . ```kerLinear``` 是一个 ```torch.nn.Module``` 对象,表示使用相同高斯内核的内核机器层 ```k(x, y) = exp(-||xy| |_2^2 / (2 * sigma^2))```。```sigma``` 控制内核宽度。对于输入层中的```X```,将你希望将内核机器置于中心的随机样本(通常是训练集)传递给它,即```{x_i}```中的集合``f(u) = ∑_i a_i k(x_i, u) + b```。这个集合是这个层对象的一个​​属性,可以作为``layer.X``来访问。对于非输入层,将您想要集中在内核机器上的原始数据传递给```X```。在运行时,
```python
from layers.kerlinear import kerLinear
mlkn.add_layer(kerLinear(X=x_train, out_dim=15, sigma=5, bias=True))
mlkn.add_layer(kerLinear(X=x_train, out_dim=n_class, sigma=. 1,偏差=真))
```

对于大型数据集,由于内存不足,可能无法对整个训练集进行操作。在这种情况下,可以通过将训练集分成几个较小的子集并在每个子集上以单独的 ```kerLinear``` 对象为中心来交换内存充足性的并行性。这与将 Gram 矩阵分解为一堆子矩阵相同,并且不会对数值结果产生任何影响。我们已经实现了一个 ```kerLinearEnsemble``` 类和一个辅助函数 ```to_ensemble``` 来简化这个过程。下面的脚本将产生与之前添加层的方法相同的网络和相同的计算。```layer0``` 和 ```layer1``` 被分成许多较小的网络,每个网络有 30 个中心,权重和偏差不变。
```蟒蛇
from layers.kerlinear import kerLinear
from layers.ensemble import kerLinearEnsemble
import backend as K

ensemble = True
batch_size = 30

layer0 = kerLinear(X=x_train, out_dim=15, sigma=5, bias=True)
layer1 = kerLinear(X=x_train, out_dim=n_class, sigma=.1,bias=True)

if not ensemble:
mlkn.add_layer(layer0)
mlkn.add_layer(layer1)

else:
# 创建等效的集成层,以便可以将大型数据集拟合到内存中
mlkn.add_layer(K .to_ensemble(layer0, batch_size))
mlkn.add_layer(K.to_ensemble(layer1, batch_size))
```

然后我们为每一层添加优化器。这适用于任何```torch.optim.Optimizer```。每个优化器负责一个层,添加的顺序与层的顺序相同,即首先添加的优化器将分配给第一层(最接近输入的层)。对于每个优化器,可以将 ```params`` 指定给任何东西,并且在调用 ``fit``` 时在训练网络之前自动将其覆盖为正确层的权重。让我们使用 [Adam](https://arxiv.org/pdf/1412.6980.pdf) 作为此示例的优化器。请注意,对于 PyTorch 优化器,```weight_decay``` 是 l2-norm 正则化系数。
```python
mlkn.add_optimizer(torch.optim.Adam(params=mlkn.parameters(), lr=1e-3, weight_decay=0.1))
mlkn.add_optimizer(torch.optim.Adam(params=mlkn.parameters(), lr=1e-3, weight_decay=.1))
```

为输出层指定损失函数,这适用于任何 PyTorch 损失函数,但让我们对这个分类任务使用```torch.nn.CrossEntropyLoss```。
```python
mlkn.add_loss(torch.nn.CrossEntropyLoss())
```

适合模型。对于```n_epoch```,应该传递一个```int```的元组,第一个数字指定训练第一层的时期数,等等。``shuffle```控制整个数据集在每个时期随机打乱。如果 ```accumulate_grad``` 是 ```True```,则权重仅在每个 epoch 更新,而不是在每个 minibatch 使用该 epoch 中所有 minibatch 的累积梯度。如果它设置为```False```,每个小批量都会有一个更新。请注意,```fit``` 中的参数 ```X``` 是您想要训练模型的训练集,它可能与您的内核机器所集中的集不同(参数 ``` X``` 在初始化 ```kerLinear``` 对象时)。
```python
mlkn.fit(
n_epoch=(30, 30),
batch_size=30,
shuffle=True,
X=x_train,
Y=y_train,
n_class=n_class,
accumulate_grad=False

```

对测试集进行预测并打印错误。
```python
y_pred = mlkn.predict(X_test=x_test, batch_size=15)
err = mlkn.get_error(y_pred, y_test)
print('错误率: {:.2f}%'.format(err.data[0] * 100))
```

此示例可在 [examples/mlkn_classifier.py](https://github.com/michaelshiyu/kerNET/tree/master/examples) 获得。还有一些分类数据集供您试用模型。

---------

### 使用反向传播训练 MLKN

在 kerNET 中,我们还实现了具有最大定制自由度的通用 MLKN。也就是说,它没有预先配置贪心训练,因此使用标准反向传播和一些基于梯度的优化来训练它更容易。此外,它没有被定义为分类器,相反,它是一个通用学习机:无论你用 MLP 做什么,你都可以用 MLKN 来做。

通用 MLKN 的工作原理与 MLKNClassifier 几乎相同。首先我们实例化一个模型。
```python
import torch
from models.mlkn import MLKN
mlkn = MLKN()
```

添加层与我们为 MLKNClassifier 所做的相同。还支持集成层。
```python
从layers.kerlinear导入kerLinear
mlkn.add_layer(kerLinear(X=x_train,out_dim=15,sigma=5,bias=True))
mlkn.add_layer(kerLinear(X=x_train,out_dim=n_class,sigma=.1,bias=True))
```

对于回归,应该调整输出层的维度。
```python
mlkn.add_layer(kerLinear(ker_dim=x_train.shape[0], out_dim=y_train.shape[1], sigma=.1, bias=True))
```

添加优化器。这适用于任何```torch.optim.Optimizer```。与分层训练案例不同,这里有一个优化器负责整个网络的训练,因为我们使用的是反向传播。但是,当然,这并不意味着所有层都必须在完全相同的设置下进行训练:您仍然可以为每个层指定 [per-parameter options](http://pytorch.org/docs/master/optim.html)层。
```python
mlkn.add_optimizer(torch.optim.Adam(params=mlkn.parameters(), lr=1e-3, weight_decay=0.1))
```

指定损失函数。对于分类,```torch.nn.CrossEntropyLoss``` 可能是一个理想的选择,而对于回归,```torch.nn.MSELoss``` 是一个常见的选择。
```python
mlkn.add_loss(torch.nn.CrossEntropyLoss())
```
或者,对于回归,
```python
mlkn.add_loss(torch.nn.MSELoss())
```

训练模型并评估输出给定一些测试集。
```python
mlkn.fit(
n_epoch=30,
batch_size=30,
shuffle=True,
X=x_train,
Y=y_train,
accumulate_grad=True


y_raw = mlkn.evaluate(X_test=x_test, batch_size=15)
```

对于分类,人们可能对这个测试集的错误率感兴趣,而对于回归,MSE。

对于分类,
```python
_, y_pred = torch.max(y_raw, dim=1)
y_pred = y_pred.type_as(y_test)
err = (y_pred!=y_test).sum().type(torch.FloatTensor).div_ (y_test.shape[0])
print('error rate: {:.2f}%'.format(err.data[0] * 100))
```

对于回归,
```python
mse = torch.nn。 MSELoss()
print('mse: {:.4f}'.format(mse(y_raw, y_test).data[0]))
```

此示例可在 [examples/mlkn_generic.py](https://github.com/michaelshiyu/kerNET/tree/master/examples) 获得。有一些分类和回归数据集供您试用模型。


项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

kerNET-0.1.0.tar.gz (14.9 kB 查看哈希

已上传 source

内置分布

kerNET-0.1.0-py2.py3-none-any.whl (20.7 kB 查看哈希

已上传 py2 py3