Python 无监督学习实用指南:6~10(5)

简介: Python 无监督学习实用指南:6~10(5)

Python 无监督学习实用指南:6~10(4)https://developer.aliyun.com/article/1426889

该代码显示在以下代码片段中:

import tensorflow as tf
def generator(z, is_training=True):
    with tf.variable_scope('generator'):
        conv_0 = tf.layers.conv2d_transpose(inputs=z,
                                            filters=1024,
                                            kernel_size=(4, 4),
                                            padding='valid')
        b_conv_0 = tf.layers.batch_normalization(inputs=conv_0, training=is_training)
        conv_1 = tf.layers.conv2d_transpose(inputs=tf.nn.leaky_relu(b_conv_0),
                                            filters=512,
                                            kernel_size=(4, 4),
                                            strides=(2, 2),
                                            padding='same')
        b_conv_1 = tf.layers.batch_normalization(inputs=conv_1, training=is_training)
        conv_2 = tf.layers.conv2d_transpose(inputs=tf.nn.leaky_relu(b_conv_1),
                                            filters=256,
                                            kernel_size=(4, 4),
                                            strides=(2, 2),
                                            padding='same')
        b_conv_2 = tf.layers.batch_normalization(inputs=conv_2, training=is_training)
        conv_3 = tf.layers.conv2d_transpose(inputs=tf.nn.leaky_relu(b_conv_2),
                                            filters=128,
                                            kernel_size=(4, 4),
                                            strides=(2, 2),
                                            padding='same')
        b_conv_3 = tf.layers.batch_normalization(inputs=conv_3, training=is_training)
        conv_4 = tf.layers.conv2d_transpose(inputs=tf.nn.leaky_relu(b_conv_3),
                                            filters=1,
                                            kernel_size=(4, 4),
                                            strides=(2, 2),
                                            padding='same')
        return tf.nn.tanh(conv_4)

评论者的 DAG 基于以下几组:

  • 具有(2, 2)步幅的 1284×4个过滤器的 2D 卷积,相同填充,以及 LReLU 输出
  • 256 个4×4过滤器的 2D 卷积,步幅为(2, 2),相同填充,以及线性输出
  • 批量规范化和 LReLU 激活
  • 带有 512 个4×4过滤器的 2D 卷积,步幅为(2, 2),相同填充,以及线性输出
  • 批量规范化和 LReLU 激活
  • 具有 1,0244×4过滤器的 2D 卷积,步幅为(2, 2),相同填充,以及线性输出
  • 批量规范化和 LReLU 激活
  • 具有 1 个4×4过滤器的 2D 卷积,步幅为(2, 2),有效填充和线性输出

相应的代码块为,如下所示:

import tensorflow as tf
def critic(x, is_training=True, reuse_variables=True):
    with tf.variable_scope('critic', reuse=reuse_variables):
        conv_0 = tf.layers.conv2d(inputs=x,
                                  filters=128,
                                  kernel_size=(4, 4),
                                  strides=(2, 2),
                                  padding='same')
        conv_1 = tf.layers.conv2d(inputs=tf.nn.leaky_relu(conv_0),
                                  filters=256,
                                  kernel_size=(4, 4),
                                  strides=(2, 2),
                                  padding='same')
        b_conv_1 = tf.layers.batch_normalization(inputs=conv_1, training=is_training)
        conv_2 = tf.layers.conv2d(inputs=tf.nn.leaky_relu(b_conv_1),
                                  filters=512,
                                  kernel_size=(4, 4),
                                  strides=(2, 2),
                                  padding='same')
        b_conv_2 = tf.layers.batch_normalization(inputs=conv_2, training=is_training)
        conv_3 = tf.layers.conv2d(inputs=tf.nn.leaky_relu(b_conv_2),
                                  filters=1024,
                                  kernel_size=(4, 4),
                                  strides=(2, 2),
                                  padding='same')
        b_conv_3 = tf.layers.batch_normalization(inputs=conv_3, training=is_training)
        conv_4 = tf.layers.conv2d(inputs=tf.nn.leaky_relu(b_conv_3),
                                  filters=1,
                                  kernel_size=(4, 4),
                                  padding='valid')
        return conv_4

由于与 DCGAN 没有特别的区别,因此无需添加其他注释。 因此,我们可以继续进行图的定义和整体 DAG ,如下所示:

import tensorflow as tf
nb_epochs = 100
nb_critic = 5
batch_size = 64
nb_iterations = int(nb_samples / batch_size)
code_length = 100
graph = tf.Graph()
with graph.as_default():
    input_x = tf.placeholder(tf.float32, shape=(None, width, height, 1))
    input_z = tf.placeholder(tf.float32, shape=(None, code_length))
    is_training = tf.placeholder(tf.bool)
    gen = generator(z=tf.reshape(input_z, (-1, 1, 1, code_length)), is_training=is_training)
    r_input_x = tf.image.resize_images(images=input_x, size=(64,64),    
                                       method=tf.image.ResizeMethod.BICUBIC)
     crit_1_l = critic(x=r_input_x, is_training=is_training, reuse_variables=False)
     crit_2_l = critic(x=gen, is_training=is_training, reuse_variables=True)
     loss_c = tf.reduce_mean(crit_2_l - crit_1_l)
     loss_g = tf.reduce_mean(-crit_2_l)
     variables_g = [variable for variable in tf.trainable_variables() 
                     if variable.name.startswith('generator')]
     variables_c = [variable for variable in tf.trainable_variables() 
                     if variable.name.startswith('critic')]
     with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)):
         optimizer_c = tf.train.AdamOptimizer(0.00005, beta1=0.5, beta2=0.9).\
                             minimize(loss=loss_c, var_list=variables_c)
         with tf.control_dependencies([optimizer_c]):
             training_step_c = tf.tuple(tensors=[
                                     tf.assign(variable, tf.clip_by_value(variable, -0.01, 0.01))
                                                             for variable in variables_c])
         training_step_g = tf.train.AdamOptimizer(0.00005, beta1=0.5, beta2=0.9).\
                                  minimize(loss=loss_g, var_list=variables_g)

通常,第一步是声明占位符,该占位符与 DCGAN 相同。 但是,由于已经针对 64×64 图像优化了模型(特别是卷积或转置卷积的序列),因此我们将使用tf.image.resize_images()方法来调整原始样本的大小。 此操作将导致有限的质量损失; 因此,在生产应用中,我强烈建议您使用针对原始输入大小优化的模型。 在生成器和标注器都声明之后(如我们在上一个示例中讨论的那样,由于需要分别优化损失函数,因此我们需要两个实例共享相同的变量),我们可以设置损失。 在这种情况下,它们的计算非常简单且快速,但是我们为此付出了代价,并为此网络可以应用更小的校正。 实际上,在这种情况下,我们并没有直接最小化批评者损失函数; 相反,我们首先使用运算符optimizer_c计算并应用梯度,然后使用运算符training_step_c裁剪所有评论者变量。 因为我们只想调用此运算符,所以已在使用指令tf.control_dependencies([optimizer_c])定义的上下文中声明了它。 这样,当请求一个会话来计算traning_step_c时,TensorFlow 将注意首先运行optimizer_c,但是只有在结果准备好后,才会执行 main 命令(简单地裁剪变量)。 正如我们在理论中所解释的那样,此步骤对于保证评论者仍然具有 L-Lipschitz 函数是必要的,因此,允许使用从 Kantorovich-Rubinstein 定理得到的简化 Wasserstein 距离表达式。

当图完全定义后,可以创建一个会话并初始化所有变量,如下所示:

import tensorflow as tf
session = tf.InteractiveSession(graph=graph)
tf.global_variables_initializer().run()

现在,所有组件都已设置好,我们准备开始训练过程,该过程分为标注者训练步骤的nb_critic(在我们的情况下为五次)迭代和生成器训练步骤的一次执行,如下:

import numpy as np
samples_range = np.arange(X_train.shape[0])
for e in range(nb_epochs):
    c_losses = []
    g_losses = []
    for i in range(nb_iterations):
        for j in range(nb_critic):
            Xi = np.random.choice(samples_range, size=batch_size)
            X = np.expand_dims(X_train[Xi], axis=3)
            Z = np.random.uniform(-1.0, 1.0, size=(batch_size, code_length)).astype(np.float32)
            _, c_loss = session.run([training_step_c, loss_c],
                                        feed_dict={
                                            input_x: X,
                                            input_z: Z,
                                            is_training: True
                                        })
            c_losses.append(c_loss)
        Z = np.random.uniform(-1.0, 1.0, size=(batch_size, code_length)).astype(np.float32)
        _, g_loss = session.run([training_step_g, loss_g],
                                    feed_dict={
                                        input_x: np.zeros(shape=(batch_size, width, height, 1)),
                                        input_z: Z,
                                        is_training: True
                                    })
        g_losses.append(g_loss)
    print('Epoch {}) Avg. critic loss: {} - Avg. generator loss: {}'.format(e + 1,
                                                                            np.mean(c_losses),
                                                                            np.mean(g_losses)))

在此过程结束时(可能会很长,尤其是在没有任何 GPU 支持的情况下可能会很长),为了获得视觉确认,我们可以再次生成一些示例,如下所示:

import numpy as np
Z = np.random.uniform(-1.0, 1.0, size=(30, code_length)).astype(np.float32)
Ys = session.run([gen],
                  feed_dict={
                      input_z: Z,
                      is_training: False
                  })
Ys = np.squeeze((Ys[0] + 1.0) * 0.5 * 255.0).astype(np.uint8)

结果显示在以下屏幕截图中:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6qX4YYm-1681652675179)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/handson-unsup-learn-py/img/c547737d-8732-4c0e-bcb3-2b1ab893d875.png)]

WGAN 生成的样本

可以看到,WGAN 已收敛到合理的最终配置。 图像质量受大小调整操作的强烈影响; 但是,有趣的是,生成的样本平均比原始样本要复杂。 例如,衣服的质地和形状受其他因素(例如,包和鞋子)的影响,结果是模型不规则,新颖样本数量增加。 但是,与 Olivetti 人脸数据集相反,在这种情况下,很难理解样本是否由异质属性的混合物组成,因为数据生成过程(例如标准 MNIST)具有至少 10 种原始的类。

WGAN 不会陷入模式崩溃,但是不同区域的强烈分离使模型无法轻松合并元素,正如我们在人脸观察到的那样。 作为练习,我邀请读者对 Olivetti 人脸数据集重复该示例,找到最佳的超参数配置,并将结果与标准 DCGAN 获得的结果进行比较。

自组织映射

自组织映射是 Willshaw 和 Von Der Malsburg 首次提出的模型(在《如何通过自组织建立模式化的神经连接》中),目的是找到一种描述大脑中发生的不同现象的方法。 实际上,他们观察到许多动物的大脑的某些区域可以发展出内部组织的结构,这些结构的子组件相对于特定的输入模式(例如,某些视觉皮层区域对垂直或水平带非常敏感)可以选择性地接受。 SOM 的中心思想可以通过考虑聚类过程来综合,该聚类过程旨在找出样本的低级属性,这要归功于其对聚类的分配。 主要的实际差异是,在 SOM 中,单个单元通过称为赢家通吃的学习过程,成为一部分样本总体(即数据生成过程的区域)的代表。 。 这样的训练过程首先是引起所有单元(我们将其称为神经元)的响应并增强所有权重,然后通过减小最活跃单元周围的影响区域来进行,直到单个单元成为唯一的响应神经元为止。 给定输入模式。

下图综合了该过程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IfJaRWIO-1681652675180)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/handson-unsup-learn-py/img/0603623a-f55d-4792-a188-2b84df0f58c7.png)]

SOM 开发的墨西哥帽选择性

在初始步骤中,许多单元会响应相同的输入模式,但是我们已经可以观察到x[i]附近的优势。 但是,立即选择此设备可能会导致收敛过早,从而导致准确率下降。 这就是为什么获胜单元周围的半径逐渐减小的原因(观察到一种称为墨西哥帽的现象,因为其形状特殊)。 当然,在此过程中,最初的获胜单元无法保持稳定; 因此,重要的是要避免半径的快速减小,以免引起其他潜在单位被引出。 当呈现特定模式时,当神经元保持最活跃时,它将被略微转换为实际的赢家,因此,这将花费全部,因为不会再加强任何其他单元。

一些非常著名和有用的 SOM 是 Kohonen 映射(首次出现在《拓扑正确特征映射的自组织形成》)。 它们的结构像投影到由N神经元组成的二维流形(最经典的情况是平坦的二维区域)上的平面一样。 从现在开始,为简单起见,我们将考虑映射到包含k×p单元的矩阵的曲面,每个曲面均使用突触权重w[ij] ∈ R^n进行建模 (大小与输入模式相同,x[i] ∈ R^n)。 因此,权重矩阵变为W(i, j) ∈ R^(k×p×n)。 从实际的角度来看,在此模型中,由于不执行内部转换,因此神经元通过相应的权重向量表示。 当呈现模式x[i]时,获胜神经元n[w](作为元组)的确定如下: 使用以下规则:*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eqtdh1Sg-1681652675180)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/handson-unsup-learn-py/img/1d22e1e2-5d4d-472e-90eb-af603c0116eb.png)]

训练过程通常分为两个不同的阶段:调整收敛。 在调整阶段,更新会扩展到获胜单元的所有邻居,而在后者期间,只会增强权重W(n[w])。 但是,平滑而渐进的下降比快速下降更可取; 因此, n[s](i, j)的邻域大小的常见选择是基于径向基函数RBF)具有指数衰减的方差:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gFMSUMe8-1681652675180)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/handson-unsup-learn-py/img/1cc30811-63e7-4ceb-a338-df23c28ca834.png)]

初始方差(与最大邻域成比例)为x[i],并且根据时间常数τ呈指数衰减。 根据经验,当t > 4τ时,σ(t) ≈ 0,因此τ应该设置为 1/4 调整阶段的训练周期数:τ = 0.25•t[adj]。 一旦定义了邻域,就可以根据它们与每个样本的不相似性来更新所有成员的权重,x[i]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v6oXe2Bb-1681652675180)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/handson-unsup-learn-py/img/13a00879-7f4e-4444-a3e9-7cb93b92e001.png)]

在先前的公式中,学习率η(t)也是训练周期的函数,因为最好在早期(尤其是在调整阶段)施加更大的灵活性 ,但最好在收敛阶段设置较小的η,以便进行较小的修改。 降低学习率的一个非常常见的选择类似于邻域大小:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7S8rQud2-1681652675180)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/handson-unsup-learn-py/img/d9a02b2e-3f25-46de-abc6-0030f3866ecc.png)]

学习规则的作用是迫使获胜单元的权重接近特定模式,因此在训练过程结束时,每个模式都应引起代表一个定义明确的特征集的单个单元的响应。 。 形容词的自组织性源自这种模型必须优化单元的能力,以便使相似的模式彼此靠近(例如,如果竖线引起单元的响应,则稍微旋转的单元应引起单元的响应)。 邻居)。

Kohonen 映射的示例

在此示例中,我们要训练一个 8×8 正方形 Kohonen 映射以接受 Olivetti 人脸数据集。 由于每个样本都是 64×64 灰度图像,因此我们需要分配一个形状等于(8,8,4,096)的权重矩阵。 训练过程可能会很长; 因此,我们会将映射限制为 100 个随机样本(当然,读者可以自由删除此限制,并使用整个数据集训练模型)。

像往常一样,让我们开始加载并规范化数据集,如下所示:

import numpy as np
from sklearn.datasets import fetch_olivetti_faces
faces = fetch_olivetti_faces(shuffle=True)
Xcomplete = faces['data'].astype(np.float64) / np.max(faces['data'])
np.random.shuffle(Xcomplete)
X = Xcomplete[0:100]

现在,让我们为距离函数的方差σ(t)以及学习率η(t)定义指数衰减函数,如下所示[ :

import numpy as np
eta0 = 1.0 sigma0 = 3.0 tau = 100.0 def eta(t):
 return eta0 * np.exp(-float(t) / tau)
def sigma(t):
 return float(sigma0) * np.exp(-float(t) / tau)

在该示例中,我们采用初始学习率η(0) = 1,半径方差σ(0) = 3* 。 之所以选择时间常数等于 100,是因为我们计划执行 500 个调整迭代和500收敛迭代(1000总迭代)。 在以下代码段中声明了相应的值:

nb_iterations = 1000 nb_adj_iterations = 500

在这一点上,我们可以基于差值w-x的 L2 范数定义权重矩阵(初始化为w[ij] ~ N(0, 0.01))和负责计算获胜单元的函数,如下所示:

import numpy as np
pattern_length = 64 * 64 pattern_width = pattern_height = 64  matrix_side = 8 
W = np.random.normal(0, 0.1, size=(matrix_side, matrix_side, pattern_length))
def winning_unit(xt):
    distances = np.linalg.norm(W - xt, ord=2, axis=2)
    max_activation_unit = np.argmax(distances)
    return int(np.floor(max_activation_unit / matrix_side)), max_activation_unit % matrix_side

在开始训练周期之前,预先计算距离矩阵dm(x[0], y[0], x[1], y[1]),其中每个元素代表(x[0], y[0])(x[1], y[1])。 如以下片段所示,此步骤避免了必须确定获胜单元的邻域时的计算开销:

import numpy as np
precomputed_distances = np.zeros((matrix_side, matrix_side, matrix_side, matrix_side))
for i in range(matrix_side):
    for j in range(matrix_side):
        for k in range(matrix_side):
            for t in range(matrix_side):
                precomputed_distances[i, j, k, t] = \
                    np.power(float(i) - float(k), 2) + np.power(float(j) - float(t), 2)
def distance_matrix(xt, yt, sigmat):
    dm = precomputed_distances[xt, yt, :, :]
    de = 2.0 * np.power(sigmat, 2)
    return np.exp(-dm / de)

函数distance_matrix()计算一个正方形矩阵,该正方形矩阵包含所有以(xt, yt)为中心的神经元的指数衰减影响。 现在,我们具有创建训练过程所需的所有构造块,该训练过程基于我们先前描述的权重更新规则,如下所示:

import numpy as np
sequence = np.arange(0, X.shape[0])
t = 0
for e in range(nb_iterations):
    np.random.shuffle(sequence)
    t += 1
    if e < nb_adj_iterations:
        etat = eta(t)
        sigmat = sigma(t)
    else:
        etat = 0.2
        sigmat = 1.0
    for n in sequence:
        x_sample = X[n]
        xw, yw = winning_unit(x_sample)
        dm = distance_matrix(xw, yw, sigmat)
        dW = etat * np.expand_dims(dm, axis=2) * (x_sample - W)
        W += dW
    W /= np.linalg.norm(W, axis=2).reshape((matrix_side, matrix_side, 1))
    if e > 0 and e % 100 == 0:
        print('Training step: {}'.format(t-1))

在每个循环中,执行以下步骤:

  1. 为了避免相互关联,对输入样本的顺序进行了混洗。
  2. 计算学习率和距离方差(收敛值为η[∞] = 0.2σ[∞] = 1)。
  3. 对于每个样本,适用以下条件:
  1. 计算获胜单元。
  2. 计算距离矩阵。
  3. 计算和应用权重更新。
  1. 权重被重新归一化,以避免溢出。

现在,我们可以在训练过程结束时显示权重矩阵,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RgQiCLrz-1681652675181)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/handson-unsup-learn-py/img/88ce6334-3cd3-41c5-a1de-9885b75dde3f.png)]

训练过程结束时的 Kohonen 映射权重矩阵

可以看到,每个权重都集中在人脸的通用结构上(因为数据集仅包含这种模式); 但是,不同的权重已变得对特定的输入属性更敏感。 我建议您开始观察左上脸的元素(例如,眼睛或嘴巴),然后沿终止于中央砝码的螺旋线沿顺时针方向旋转。 这样,很容易看到接收字段中的修改。 作为练习,我邀请读者使用其他数据集(例如 MNIST 或 Fashion MNIST)测试模型,并对最终权重矩阵进行手动标记(例如,考虑到此示例,特定权重可以表示笑脸) 戴着眼镜,大鼻子)。 在标记每个元素之后,可以通过直接提供标记作为输出来投影原始样本并检查哪些神经元更易接受。

总结

在本章中,我们介绍了 GAN 的概念,并讨论了 DCGAN 的示例。 这种模型具有通过使用 minimax 游戏中涉及的两个神经网络来学习数据生成过程的能力。 生成器必须学习如何返回与训练过程中使用的其他样本没有区别的样本。 判别者或批评者必须变得越来越聪明,只为有效样本分配高概率。 对抗训练方法的基础是,通过学习如何用具有与真实属性相同的合成样本作弊的方法,迫使生成器与判别器竞争。 同时,生成器被迫通过选择越来越多来与歧视者抗争。 在我们的示例中,我们还分析了一个称为 WGAN 的重要变体,当标准模型无法复制有效样本时可以使用该变体。

SOM 是基于大脑特定区域功能的结构,该结构迫使其特定单元学习输入样本的特定特征。 这样的模型会自动进行自我组织,从而使响应相似模式的单元更加接近。 一旦提供了一个新样本,就足以计算获胜单元,该单元的权重与样本的距离最短; 并且在贴标过程之后,可以立即了解引起响应的特征(例如,垂直线或高级特征,例如是否有眼镜或胡须或人脸形状)。

问题

  1. 在 GAN 中,生成器和判别器的作用与自编码器中的编码器和解码器相同。 它是否正确?
  2. 判别器能否输出(-1, 1)范围内的值?
  3. GAN 的问题之一是判别器过早收敛。 这个正确吗?
  4. 在 Wasserstein GAN 中,批评家(区分者)在训练阶段是否比生成器慢?
  5. 考虑到前面的问题,不同速度的原因是什么?
  6. U(-1, 0)U(1, 2)之间的 Jensen-Shannon 散度值是多少?
  7. 赢家通吃战略的目标是什么?
  8. SOM 训练过程的调整阶段的目的是什么?

进一步阅读

  • Generative Adversarial Networks, Goodfellow I. J., Pouget-Abadie J., Mirza M., Xu B., Warde-Farley D., Ozair S., Courville A., and Bengio Y., arXiv:1406.2661 [stat.ML]
  • Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks, Radford A., Metz L., and Chintala S., arXiv:1511.06434 [cs.LG]
  • Wasserstein GAN, Arjovsky M., Chintala S., and Bottou L., arXiv:1701.07875 [stat.ML]
  • How Patterned Neural Connections Can Be Set Up by Self-Organization, Willshaw, D. J. and Von Der Malsburg, C., Proceedings of the Royal Society of London, B/194, N. 1117, 1976
  • Self-Organized Formation of Topologically Correct Feature Maps, Kohonen T., Biological Cybernetics, 43/1, 1982
  • Mastering Machine Learning Algorithms, Bonaccorso G., Packt Publishing, 2018

十、习题

第一章

  1. 无监督学习可以独立于有监督的方法应用,因为其目标是不同的。 如果问题需要监督的方法,则通常不能采用无监督的学习作为替代解决方案。 通常,无监督方法尝试从数据集中提取信息片段(例如,聚类)而没有任何外部提示(例如预测错误)。 相反,受监督的方法需要提示才能更正其参数。
  2. 由于目标是找到趋势的原因,因此有必要执行诊断分析。
  3. 否; 从单个分布中提取n个独立样本的可能性作为单个概率的乘积(主要假设请参见问题 4)。
  4. 主要假设是样本是独立同分布IID)的。
  5. 性别可以编码为数字特征(例如,单热编码); 因此,我们需要考虑两种可能性。 如果在属性之间不存在性别,而其他特征与性别不相关,则聚类结果是完全合理的。 如果存在性别(作为通用聚类方法)是基于样本之间的相似性的,则 50/50 的结果表示性别不是歧视性特征。 换句话说,给定两个随机选择的样本,它们的相似性不受性别影响(或受到轻微影响),因为其他特征占主导。 例如,在这种特殊情况下,平均分数或年龄有较大的差异,因此它们的影响更大。
  6. 我们可以预期会有更紧凑的群体,其中每个主要特征的范围都较小。 例如,一个小组可以包含 13-15 岁的学生,并带有所有可能的分数,依此类推。 另外,我们可以观察基于单个特征的细分(例如年龄,平均分数等)。 最终结果取决于向量的数值结构,距离函数,当然还取决于算法。
  7. 如果每个客户均由包含其兴趣摘要的特征向量表示(例如,基于他/她购买或看过的产品),我们可以找到集群分配,检查哪些元素可以表征集群(例如书籍,电影,衣服,特定品牌等),并使用这些信息来推荐潜在产品(即类似用户购买的产品)。 该概念基于在相同集群的成员之间共享信息的主要思想,这要归功于它们的相似性。

第二章

  1. 曼哈顿距离与 Minkowski 距离相同,其中p = 1; 因此,我们希望观察到更长的距离。
  2. 否; 收敛速度主要受质心的初始位置影响。
  3. 是; K 均值设计用于凸群集,而对于凹群集则表现较差。
  4. 这意味着所有聚类(样本百分比可忽略不计)分别仅包含属于同一类别(即具有相同真实标签)的样本。
  5. 它表示真实标签分配和分配之间的中等/强烈的负差异。 这个值是明显的负条件,不能接受,因为绝大多数样本已分配给错误的聚类。
  6. 不可以,因为调整后的 Rand 分数是根据真实情况得出的(也就是说,预期的群集数是固定的)。
  7. 如果所有基本查询都需要相同的时间,则会在60 - (2×4) - 2 = 50秒内执行它们。 因此,它们每个都需要50/100 = 0.5秒。 在叶子大小= 50的情况下,我们可以期望将 50-NN 查询的执行时间减半,而对基本查询没有影响。 因此,可用于基本查询的总时间变为60 - (2×2) - 2 = 54秒。 因此,我们可以执行 108 个基本查询。
  8. 否; 球树是一种不会遭受维度诅咒的数据结构,其计算复杂度始终为O(N log M)
  9. 高斯N([-1.0, 0.0], diag[0.1, 0.2])N([-0.8, 0.0], diag[0.3, 0.3])重叠(即使所得聚类非常伸展),而第三个则足够远(考虑均值和方差),可以被单独的聚类捕获。 因此,最佳群集大小为 2,而 K 均值很难将大斑点正确地分为两个内聚分量(特别是对于大量样本)。
  10. VQ 是一种有损压缩方法。 仅当语义没有通过小或中转换而改变时,才可以使用它。 在这种情况下,如果不修改基础语义就不可能与另一个交换令牌。

第三章

  1. 否; 在凸集中,给定两个点,连接它们的线段始终位于该集内。
  2. 考虑到数据集的径向结构,RBF 内核通常可以解决该问题。
  3. ε = 1.0的情况下,许多点无法达到密度。 当球的半径减小时,我们应该期望有更多的噪点。
  4. 否; K 中心点可以采用任何度量。
  5. 否; DBSCAN 对几何不敏感,并且可以管理任何种类的群集结构。
  6. 我们已经表明,小批量 K 均值的表现稍差于 K 均值。 因此,答案是肯定的。 使用批量算法可以节省内存。
  7. 考虑到噪声的方差为σ^2 = 0.005 → σ ≈ 0.07,它比聚类标准差小约 14 倍,因此,我们不能期望这么多的新分配(80%)在稳定的群集配置中。

第四章

  1. 在凝聚方法中,该算法从每个样本(被视为一个集群)开始,然后继续合并子集群,直到定义了一个集群。 在分裂方法中,该算法从包含所有样本的单个群集开始,然后通过拆分将其进行到每个样本组成一个群集为止。
  2. 最近的点是(0, 0)(0, 1),因此单键是L[s](a, b) = 1。 最远的点是(-1, -1)(1, 1),因此完整的链接是L[c(a, b) = 2√2
  3. 否; 树状图是给定度量和链接的层次聚类过程的树表示。
  4. 在凝聚聚类中,树状图的初始部分包含所有样本作为自治聚类。
  5. y轴报告差异。
  6. 将较小的群集合并为较大的群集时,差异性会增加。
  7. 是; 那就是 cophenetic 矩阵的定义。
  8. 连通性约束允许施加约束,因此将约束合并到聚合过程中,从而迫使其将某些元素保留在同一群集中。

第五章

  1. 硬聚类基于固定分配; 因此,样本x[i]将始终属于单个群集。 相反,相对于每个聚类,软聚类返回一个度向量,该向量的元素表示隶属度(例如,(0.1、0.7、0.05、0.15))。
  2. 否; 模糊 c 均值是 K 均值的扩展,它不适用于非凸几何。 但是,软分配可以评估相邻群集的影响。
  3. 主要假设是,数据集是从可以用多个高斯分布的加权和有效地近似的分布中得出的。
  4. 这意味着第一个模型的参数数量是第二个模型的两倍。
  5. 第二个是因为它可以用更少的参数实现相同的结果。
  6. 因为我们要为组件的自动选择采用这种模型。 这意味着我们要从更大数量的权重开始,期望它们中的许多权重将被迫接近 0。由于 Dirichlet 分布具有非常稀疏的性质并且适用于单纯形,因此,这是最佳的选择。 先验。
  7. 如果它们是从相同的来源收集的,并且已验证标记的来源,我们可以采用半监督方法(例如,生成高斯混合物),以便为其余样本找到最合适的标记。

第六章

  1. 由于随机变量显然是独立的,因此P(Tall, Rain) = P(Tall)P(Rain) = 0.75 * 0.2 = 0.15
  2. 直方图的主要缺点之一是,当桶的数量太大时,它们中的许多都开始为空,因为在所有值范围内都没有样本。 在这种情况下,X的基数可以小于 1,000,或者即使具有超过 1,000 个样本,相对频率也可以集中在小于 1,000 的多个桶中。
  3. 样本总数为 75,并且各个条带的长度相等。 因此, P(0 < x < 2) = 20/75 ≈ 0.27P(2 < x < 4) = 30/75 = 0.4P(4 < x < 6) = 25/75 ≈ 0.33。 由于我们没有任何样本,因此我们可以假设P(x > 6) = 0; 因此,P(x > 2) = P(2 < x < 4) + P(4 < x < 6) ≈ 0.73。 考虑到0.73•75 ≈ 55,这是属于x > 2的桶的样本数,我们立即得到确认。
  4. 在正态分布N(0, 1)中,最大密度为p(0) ≈ 0.4。 在大约三个标准差之后,p(x) ≈ 0; 因此,通常无法将样本p(x) = 0.35的样本x视为异常。
  5. min(std(X), IQR(X) /1.34) ≈ 2.24时,最佳带宽为h = 0.9•2.24•500^(-0.2) = 0.58
  6. 即使可以采用高斯核,在给出分布描述的情况下,我们也应首先选择指数核,这样可以使均值周围迅速下降。
  7. 这将是最合乎逻辑的结论。 实际上,就新颖性而言,我们也应该期望新样本会改变分布,以便为新颖性建模。 如果在重新训练模型后概率密度仍然很低,则样本很可能是异常的。

第七章

  1. 协方差矩阵已经是对角线; 因此,特征向量是标准xy,分别为(1, 0)(0, 1),特征值是 2 和 1。因此,x轴是主要成分,y轴是第二个成分。
  2. 由于球B[0.5](0, 0)是空的,因此在该点(0, 0)周围没有样本。 考虑到水平方差σ[x]^2 = 2,我们可以想象X被分解为两个斑点,因此可以想象x = 0行是水平判别器。 但是,这只是一个假设,需要使用实际数据进行验证。
  3. 不,他们不是。 PCA 之后的协方差矩阵不相关,但不能保证统计独立性。
  4. 是; Kurt(X)的分布是超高斯分布,因此达到峰值且尾巴很重。 这样可以保证找到独立的组件。
  5. 由于X包含负数,因此无法使用 NNMF 算法。
  6. 否; 由于字典有 10 个元素,因此意味着文档由许多重复出现的项目组成,因此字典不够完整( 10 < 30)。
  7. 样本(x, y) ∈ R^2通过二次多项式变换为(ax, by, cx^2, dy^2, exy, f) ∈ R^6

第八章

  1. 不,他们没有。 编码器和解码器都必须在功能上对称,但是它们的内部结构也可以不同。
  2. 否; 输入信息的一部分在转换过程中丢失,而其余部分则在代码输出Y和自编码器变量之间分配,该变量与基础模型一起对所有转换进行编码。
  3. min(sum(z[i]))= 0min(sum(z[i]))= 128时,等于 36 的总和既可以表示稀疏(如果标准差较大),也可以表示具有较小值的均匀分布(当标准差接近零时)。
  4. sum(z[i]) = 36时,std(z[i]) = 0.03意味着大多数值都围绕0.28 * (0.25÷0.31),该代码可以视为密集代码。
  5. 否; 一个 Sanger 网络(以及 Rubner-Tavan 网络)需要输入样本x[i] ∈X
  6. 从最大特征值到最小特征值(即从第一个主成分到最后一个主成分)以降序提取成分。 因此,无需进一步分析来确定其重要性。
  7. 是; 从最后一层开始,可以对每个内部层的值进行采样,直到第一层为止。 通过选择每个概率向量的argmax(·)获得最可能的输入值。

第九章

  1. 否; 生成器和判别器在功能上是不同的。
  2. 不,不是这样,因为判别器的输出必须是一个概率(即p[i] ∈ (0, 1))。
  3. 是; 这是正确的。 判别器可以学习非常快地输出不同的概率,,其损失函数的斜率可以变得接近于 0,从而减小了提供给生成器的校正反馈的幅度。
  4. 是; 通常会比较慢。
  5. 评论者比较慢,因为每次更新后都会对变量进行裁剪。
  6. 由于支撑脱节,Jensen-Shannon 散度等于log(2)
  7. 目标是开发高度选择性的单元,其响应仅由特定特征集引起。
  8. 在训练过程的早期阶段,不可能知道最终的组织。 因此,强制某些单元的过早专业化不是一个好习惯。 调整阶段允许许多神经元成为候选神经元,与此同时,逐渐增加最有前途的神经元(将成为赢家)的选择性。
相关文章
|
7月前
|
机器学习/深度学习 运维 算法
Python 无监督学习实用指南:6~10(1)
Python 无监督学习实用指南:6~10(1)
61 0
Python 无监督学习实用指南:6~10(1)
|
7月前
|
机器学习/深度学习 存储 算法
Python 无监督学习实用指南:1~5(3)
Python 无监督学习实用指南:1~5(3)
77 0
Python 无监督学习实用指南:1~5(3)
|
7月前
|
机器学习/深度学习 算法 数据挖掘
Python 无监督学习实用指南:1~5(2)
Python 无监督学习实用指南:1~5(2)
84 0
Python 无监督学习实用指南:1~5(2)
|
7月前
|
机器学习/深度学习 算法 关系型数据库
Python 无监督学习实用指南:6~10(4)
Python 无监督学习实用指南:6~10(4)
61 0
|
7月前
|
机器学习/深度学习 存储 算法
Python 无监督学习实用指南:1~5(5)
Python 无监督学习实用指南:1~5(5)
71 0
|
7月前
|
机器学习/深度学习 存储 算法
Python 无监督学习实用指南:1~5(1)
Python 无监督学习实用指南:1~5(1)
141 0
Python 无监督学习实用指南:1~5(1)
|
7月前
|
机器学习/深度学习 自然语言处理 算法
Python 无监督学习实用指南:6~10(3)
Python 无监督学习实用指南:6~10(3)
101 0
|
7月前
|
机器学习/深度学习 移动开发 运维
Python 无监督学习实用指南:6~10(2)
Python 无监督学习实用指南:6~10(2)
91 0
|
7月前
|
机器学习/深度学习 存储 算法
Python 无监督学习实用指南:1~5(4)
Python 无监督学习实用指南:1~5(4)
115 0
|
机器学习/深度学习 算法 Python
【机器学习算法-python实现】K-means无监督学习实现分类
1.背景         无监督学习的定义就不多说了,不懂得可以google。因为项目需要,需要进行无监督的分类学习。         K-means里面的K指的是将数据分成的份数,基本上用的就是算距离的方法。         大致的思路就是给定一个矩阵,假设K的值是2,也就是分成两个部分,那么我们首先确定两个质心。一开始是找矩阵每一列的最大值max,最小值min,算出range=max-
1238 0