在这篇文章中,我们将探讨如何使用 Self-Organizing Map (SOM) 进行颜色聚类。我们将利用 MiniSom
库来创建和训练一个 SOM 网络,并用它来聚类一组基本颜色数据。SOM 是一种无监督学习的神经网络模型,特别适用于数据降维和可视化。
什么是 Self-Organizing Map (SOM)?
SOM(自组织映射)由芬兰学者 Teuvo Kohonen 在 1980 年代提出,是一种无监督学习的神经网络模型。SOM 的主要特点包括:
- 无监督学习:不需要预先标记的数据,网络通过数据自身的特性进行学习和分类。
- 拓扑保持:通过竞争学习机制,保持数据的拓扑结构,相似的数据点在低维空间中保持相邻关系。
- 降维和可视化:将高维数据映射到二维空间,便于观察和分析数据的内在结构。
实例代码:颜色聚类
下面是一个使用 MiniSom
库实现颜色聚类的示例代码:
pip install MiniSom matplotlib numpy==1.26.4
import numpy as np
import matplotlib.pyplot as plt
from minisom import MiniSom
# 生成颜色数据
colors = np.array(
[[0., 0., 0.], # 黑色
[0., 0., 1.], # 蓝色
[0., 1., 0.], # 绿色
[0., 1., 1.], # 青色
[1., 0., 0.], # 红色
[1., 0., 1.], # 洋红
[1., 1., 0.], # 黄色
[1., 1., 1.]]) # 白色
# 创建并训练SOM
som = MiniSom(x=30, y=30, input_len=3, sigma=1.0, learning_rate=0.5)
som.random_weights_init(colors)
som.train_random(colors, 10000)
# 存储网格尺寸
som_x, som_y = 30, 30
# 可视化结果
plt.figure(figsize=(7, 7))
for i, color in enumerate(colors):
w = som.winner(color)
plt.text(w[0] + 0.5, w[1] + 0.5, str(i), ha='center', va='center',
bbox=dict(facecolor=color, alpha=0.8, lw=0))
plt.xlim([0, som_x])
plt.ylim([0, som_y])
plt.title('Color clustering with SOM')
plt.show()
代码解析
-
生成颜色数据:
我们创建了一个包含 8 种基本颜色的 RGB 值数组。colors = np.array( [[0., 0., 0.], # 黑色 [0., 0., 1.], # 蓝色 [0., 1., 0.], # 绿色 [0., 1., 1.], # 青色 [1., 0., 0.], # 红色 [1., 0., 1.], # 洋红 [1., 1., 0.], # 黄色 [1., 1., 1.]]) # 白色
-
创建并训练 SOM:
我们使用MiniSom
创建一个 30x30 的 SOM 网络,并指定输入长度为 3(对应 RGB 值),sigma 为 1.0,学习率为 0.5。然后,我们使用颜色数据初始化随机权重,并进行 100 次随机训练。som = MiniSom(x=30, y=30, input_len=3, sigma=1.0, learning_rate=0.5) som.random_weights_init(colors) som.train_random(colors, 100)
-
存储网格尺寸:
手动存储 SOM 的网格尺寸为som_x
和som_y
。som_x, som_y = 30, 30
-
可视化结果:
我们创建一个图形并设置大小,然后遍历颜色数据,找到每种颜色的获胜节点(BMU),并在图中相应位置添加标签。最后,设置图的 x 和 y 轴范围为网格尺寸,并显示图形。plt.figure(figsize=(7, 7)) for i, color in enumerate(colors): w = som.winner(color) plt.text(w[0] + 0.5, w[1] + 0.5, str(i), ha='center', va='center', bbox=dict(facecolor=color, alpha=0.8, lw=0)) plt.xlim([0, som_x]) plt.ylim([0, som_y]) plt.title('Color clustering with SOM') plt.show()
结果分析
运行上述代码后,将会得到一个图像,显示颜色数据在 SOM 网格上的分布。每个颜色数据被映射到 SOM 网络中的一个节点,通过这种方式,我们可以看到 SOM 如何将相似颜色聚类在一起。
总结
Self-Organizing Map (SOM) 是一种强大的无监督学习工具,特别适用于数据降维和可视化。在本教程中,我们使用 MiniSom
库创建和训练了一个 SOM 网络,并展示了如何使用它进行颜色聚类。通过这种方式,我们可以直观地观察颜色数据的分布和聚类情况。希望这个教程对你理解和应用 SOM 有所帮助。
附PyTouch实现
pip install torch matplotlib numpy==1.26.4
import matplotlib.pyplot as plt
import torch
# SOM类定义
class SOM(torch.nn.Module):
def __init__(self, m, n, dim, lr=0.5, sigma=None):
super(SOM, self).__init__()
self.m = m
self.n = n
self.dim = dim
self.lr = lr
self.sigma = sigma if sigma else max(m, n) / 2.0
self.weights = torch.randn(m * n, dim)
self.locations = self._create_locations(m, n)
def _create_locations(self, m, n):
locations = []
for i in range(m):
for j in range(n):
locations.append([i, j])
return torch.tensor(locations, dtype=torch.float)
def forward(self, x):
dists = torch.cdist(x, self.weights)
bmu_indices = torch.argmin(dists, dim=1)
return bmu_indices
def train_step(self, x):
bmu_indices = self.forward(x)
for i, bmu_idx in enumerate(bmu_indices):
bmu_loc = self.locations[bmu_idx]
dists_to_bmu = torch.sum((self.locations - bmu_loc) ** 2, dim=1)
influence = torch.exp(-dists_to_bmu / (2 * self.sigma ** 2))
lr_influence = self.lr * influence.unsqueeze(1)
self.weights += lr_influence * (x[i] - self.weights)
# 生成颜色数据
colors = torch.tensor(
[[0., 0., 0.], # 黑色
[0., 0., 1.], # 蓝色
[0., 1., 0.], # 绿色
[0., 1., 1.], # 青色
[1., 0., 0.], # 红色
[1., 0., 1.], # 洋红
[1., 1., 0.], # 黄色
[1., 1., 1.]], # 白色
dtype=torch.float
)
# 创建并训练SOM
som = SOM(m=30, n=30, dim=3, lr=0.5, sigma=1.0)
# 训练过程
for epoch in range(100):
som.train_step(colors)
# 可视化结果
plt.figure(figsize=(7, 7))
for i, color in enumerate(colors):
bmu_idx = som.forward(color.unsqueeze(0)).item()
bmu_loc = som.locations[bmu_idx]
plt.text(bmu_loc[0] + 0.5, bmu_loc[1] + 0.5, str(i), ha='center', va='center',
bbox=dict(facecolor=color.numpy(), alpha=0.8, lw=0))
plt.xlim([0, som.m])
plt.ylim([0, som.n])
plt.title('Color clustering with SOM (PyTorch)')
plt.show()