GAN生成对抗网络基本概念及基于mnist数据集的代码实现

本文主要总结了GAN(Generative Adversarial Networks) 生成对抗网络的基本原理并通过mnist数据集展示GAN网络的应用。

GAN网络是由两个目标相对立的网络构成的,在所有GAN框架中都至少包含了两个部分,生成模型部分和判别模型部分。生成模型的目标是制造出一些与真实数据十分相似的伪造数据而判别模型的目标则恰恰相反,是找到如何分辨这些真实的数据以及伪造数据。

下图可以用来比较简明地理解GAN的工作原理 :
在这里插入图片描述
生成模型的输入是随机的噪声编码zzz,通过这个噪声生成的数据 G(z)G(z)G(z) 就是我们伪造出的数据了。判别模型的输入是一组混合了真实数据xxx以及伪造的数据G(z)G(z)G(z)的混合数据并输出D(G(z))D(G(z))D(G(z)) 以及D(x)D(x)D(x),代表了对真实数据和伪造数据的判定。如果我们把伪造数据的标签定为0,真实数据的标签定为1,那么判别模型的训练目标就是使D(G(z))D(G(z))D(G(z))无限接近0,使D(x)D(x)D(x)无限接近1,以此来达到分辨真实数据和伪造数据的目的。相反的,生成模型的训练目标则是要使得D(G(z))D(G(z))D(G(z))接近1,即达到欺骗判别模型,以假乱真的目的。我们不难发现,实际生成模型的训练离不开判别模型的判定,而判别模型的训练也需要生成模型生成的伪造数据,二者相辅相成。这一点在下面基于mnist数据集的训练代码中也会有所体现。

首先是import所需库并导入mnist数据,我们通过全部除以255的方法正则化用于训练和测试的图像。

import tensorflow as tf
from tensorflow import keras
from matplotlib import pyplot as plt
from keras.layers import Dense, Conv2DTranspose, BatchNormalization, Reshape, LeakyReLU, Conv2D
import numpy as np# load data from database mnist
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(path="mnist.npz")# normaliser à [0,1]
x_train = x_train/255.0
x_test = x_test/255.0

训练集x_train中包含了60000张 28*28的单通道灰度图片,每张图片对应标签为0-9的十个数字,下面展示其中一张代表了数字5的图片。
在这里插入图片描述

1. 生成模型部分

首先是我们的生成模型,如上所说,生成模型的输入为随机噪声,输出为伪造的数据。在这个例子中,我们最终要输出一张与真实图片大小一致的灰度图。生成模型由两类主要的层构成,其中之一就是全连接层dense,这个层实际上类似于CNN卷积神经网络中代表特征 feature 的一层,我们可以理解为它由数个低解析度的图像组成。之后需要的就是将解析度提升至的操作,这里用了Conv2DTranspose层,可以理解为是一个反向的pooling池化层(用于还原参数和数据)和一个2D卷积层的结合。Conv2DTranspose层中的参数stride设置为(2, 2) 即保证了每经过一次该层,输出的宽度和高度都扩大一倍。如下例所示,由7 * 7 经过两次Conv2DTranspose层使得最终输出的灰度图宽度和高度为 28 * 28 。生成模型的输出层是一个简单的2D卷积层,使用activation激励函数为sigmoid,这是由于sigmoid函数可以使得输出值属于[0, 1]的区间,也对应了我们在一开始在数据预处理的时候,将数据正则化至[0, 1]的操作。

# creation of a generator
def creation_generateur(dim_latent=10):generator = keras.models.Sequential()generator.add(Dense(128*7*7, input_dim=dim_latent))generator.add(Reshape((7,7,128)))# upsampling generator.add(Conv2DTranspose(filters=128,kernel_size=(5,5),strides=(2,2),padding="same"))generator.add(LeakyReLU(alpha=0.2))# upsampling generator.add(Conv2DTranspose(filters=128,kernel_size=(5,5),strides=(2,2),padding="same"))generator.add(LeakyReLU(alpha=0.2))generator.add(Conv2D(1, kernel_size=(7, 7), activation='sigmoid', padding="same"))return generator

2. 判别模型部分

接着我们创建GAN中的判别模型,相比生成模型而言,判别模型就更加简明,其实质就是一个classifier二元分类器。他由多个卷积层构成,其中添加了drop out用于防止过拟合。输出层是一个仅有一个神经元的全连接层,使用sigmoid作为激励函数。正如我们前文所提到的,判别模型会对输入进行分类,判别输入究竟是真实图像还是由生成模型伪造的图像。

# creation of a discriminator
def creation_discriminateur():discriminator = keras.models.Sequential()discriminator.add(Conv2D(filters=64, kernel_size=(5,5),strides=(2,2), input_shape=(28,28,1), padding="same")) discriminator.add(LeakyReLU(alpha=0.2))discriminator.add(keras.layers.Dropout(0.4))discriminator.add(Conv2D(filters=64, kernel_size=(3,3),strides=(2,2), padding="same"))discriminator.add(LeakyReLU(alpha=0.2))discriminator.add(keras.layers.Dropout(0.4))discriminator.add(keras.layers.Flatten())discriminator.add(keras.layers.Dense(1,activation='sigmoid'))return discriminator

3. 叠加模型(用于训练生成模型)

有了上述两部分代码,接下来我们可以构建基于生成模型部分以及判别模型部分的GAN神经网络。这里我们只是将两部分叠加起来,而并非构建第三个神经网络。这里构建GAN的方式与之后训练GAN是有关系的。如下代码所示,我们将生成模型与判别模型叠加起来,并让判别模型中的参数在该模型中不可训练。其实质是因为这个叠加模型GAN是用于训练生成模型的。整体的过程如下 : 输入是一组随机噪声,经过生成模型后变成了一组伪造的数字灰度图,再经过判别模型,输出一个0-1之间的值。这是梯度的正向传播过程。接着我们利用反向梯度传播来更新我们生成模型的各个权重,以此来达到使该叠加模型输出趋向于1。 这里其实就是GAN模型训练的重中之重,即生成模型的目标与判别模型相反,其目标为生成的伪造数据能更大概率被识别为是真实数据,即标签1。这一点在下一个部分GAN模型的训练中会更详细解释。

def creation_reseau_GAN(model_generateur, model_discriminateur):GAN = keras.models.Sequential()GAN.add(model_generateur)# 判别模型中的参数设置为不可训练discriminateur.trainable = FalseGAN.add(model_discriminateur)optimizer_GAN = keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5)GAN.compile(loss='binary_crossentropy', optimizer=optimizer_GAN)return GAN

4. GAN模型的训练过程

根据上述三个部分,我们创建完毕了所要用到的神经网络。在这个部分中我们就进入GAN模型的训练过程。

首先我们要给予生成模型一组随机噪声,以便其根据这个噪声创造不同的伪造数据,该噪声的意义在于避免所有的生成数据都是一样的。可以用高斯噪声或正态分布生成噪声,不同的噪声类型选取对模型训练的影响不大。

# 随机选取潜在编码(噪声)
def code_latent_aleatoire(dim_latent, nb_exemples):# distribution normal standard normal distribution# code_latent = np.random.normal(loc=0, scale=1, size=(nb_exemples, dim_latent))# code_latent = code_latent.reshape(nb_exemples, dim_latent)code_latent = np.random.randn(nb_exemples, dim_latent)return code_latent

为了判别模型的训练,我们同时需要真实的数据和伪造的数据,因此我们定义函数用于根据现有的生成模型和随机噪声来生成伪造图片,伪造图片的标签为0。同样的,定义另一个函数,用于在mnist数据中随机选取真实图片,真实图片的标签为1。

def construction_image_generateur(generateur_model, dim_latent, nb_exemples):# 生成随机噪声X = code_latent_aleatoire(dim_latent,nb_exemples)image_fraud = generateur_model.predict(X)# 生成的图片的真实标签为0Label_genere = np.zeros((nb_exemples,1))return image_fraud, Label_generedef tirage_reelle_aleatoire(base_de_donnees, nb_exemples):mat_images_reel = np.zeros((nb_exemples, 28, 28))for i in range(nb_exemples):index = np.random.randint(0, base_de_donnees.shape[0])mat_images_reel[i,:,:] = base_de_donnees[index,:,:]mat_images_reel = mat_images_reel.reshape(nb_exemples, 28, 28, 1)# 从mnist数据集选取的图片的标签均为1labels_reel = np.ones((nb_exemples, 1))return mat_images_reel, labels_reel

接下来就是重头戏,GAN网络的训练过程了。要训练一个gan模型,我们常用的方法是利用train_on_batch函数来训练。在每个batch中,首先训练判别模型,我们先构建一组由真实数据和伪造数据组成的数据集,训练判别模型使其能更准确分辨哪些数据是真实的而哪些数据是伪造的。紧接着在同一个batch中,训练叠加模型,通过随机噪声进入生成模型去生成伪造的图片,并给予他们一个假的标签,即所有的伪造图片我们都标为1,以此来使得生成模型向着使判别模型判定伪造图片为真的方向进行。

# GAN 模型的训练
def entrainement_GAN_model(model_generateur, model_discriminateur, base_de_donnees, dim_latent, GAN_model, epochs=20, batch_size=128):vector_loss_discriminateur = []vector_loss_gan = []# 通过数据集的大小以及batchsize计算每个epoch对应的batch数量total_batch = np.floor(base_de_donnees.shape[0]/batch_size).astype(np.int)# 对于每个epochfor nb_epoch in range(epochs):# 对于每个batchfor index_batch in range(total_batch):# 每个batch中有一半的图像为伪造图片x_fraud, y_fraud = construction_image_generateur(model_generateur, dim_latent=dim_latent, nb_exemples=int(batch_size/2))# 剩下的图像为真实的从mnist数据集中随机提取的图片x_reel, y_reel = tirage_reelle_aleatoire(base_de_donnees=base_de_donnees, nb_exemples=int(batch_size/2))# 叠加所有的数据 id_exemple, 28, 28x_chaque_batch = np.vstack((x_reel, x_fraud))# 叠加所有的标签 : id_exemple, labely_chaque_batch = np.vstack((y_reel, y_fraud))# 使用构建的一半真实一半伪造的数据训练判别模型,更新权重。loss_discriminateur = model_discriminateur.train_on_batch(x_chaque_batch, y_chaque_batch)# 接下来是每个Batch训练叠加模型的部分,其实质是用于训练生成模型。x_generateur = code_latent_aleatoire(dim_latent=dim_latent, nb_exemples=batch_size)# 这里我们要使得叠加模型的输出趋向于1,即使判别模型认为生成的图像也是真实的。y_gan = np.ones((batch_size,1))# 使用判别模型(叠加模型)的输出来训练生成模型gan_loss = GAN_model.train_on_batch(x_generateur, y_gan)# 显示每个batch对应的两个部分的lossprint("%d epochs,%d batches, loss_discriminateur : %f, loss_gan : %f"%(nb_epoch+1, index_batch+1, loss_discriminateur, gan_loss))# 保存模型以及图片部分if (nb_epoch + 1)%3 == 0:model_generateur.save("generateur_models/generateur_after_" + str(nb_epoch+1) + "_epoch_" + "loss_%3f"%(gan_loss) + ".h5")model_discriminateur.save("discriminateur_models/discriminateur_after_" + str(nb_epoch+1) + "_epoch_" + "loss_%3f"%(loss_discriminateur) + ".h5") GAN_model.save("gan_models/gan_after_" + str(nb_epoch+1) + "_epoch_" + "loss_%3f"%(gan_loss) + ".h5")generer_sauvegarde_images(model_generateur=model_generateur, after_epoch=nb_epoch)vector_loss_discriminateur.append(loss_discriminateur)vector_loss_gan.append(gan_loss)return vector_loss_discriminateur, vector_loss_gan

5. 附录(完整代码)及相关讨论

该部分中我将放出完整的代码以及结果。

import tensorflow as tf
from tensorflow import keras
from matplotlib import pyplot as plt
from keras.layers import Dense, Conv2DTranspose, BatchNormalization, Reshape, LeakyReLU, Conv2D
import numpy as np# creation of a generator
def creation_generateur(dim_latent=10):generator = keras.models.Sequential()generator.add(Dense(128*7*7, input_dim=dim_latent))generator.add(Reshape((7,7,128)))# upsampling generator.add(Conv2DTranspose(filters=128,kernel_size=(5,5),strides=(2,2),padding="same"))generator.add(LeakyReLU(alpha=0.2))# upsampling generator.add(Conv2DTranspose(filters=128,kernel_size=(5,5),strides=(2,2),padding="same"))generator.add(LeakyReLU(alpha=0.2))generator.add(Conv2D(1, kernel_size=(7, 7), activation='sigmoid', padding="same"))return generator# creation of a discriminator
def creation_discriminateur():discriminator = keras.models.Sequential()discriminator.add(Conv2D(filters=64, kernel_size=(5,5),strides=(2,2), input_shape=(28,28,1), padding="same")) discriminator.add(LeakyReLU(alpha=0.2))discriminator.add(keras.layers.Dropout(0.4))discriminator.add(Conv2D(filters=64, kernel_size=(3,3),strides=(2,2), padding="same"))discriminator.add(LeakyReLU(alpha=0.2))discriminator.add(keras.layers.Dropout(0.4))discriminator.add(keras.layers.Flatten())discriminator.add(keras.layers.Dense(1,activation='sigmoid'))return discriminatordef creation_reseau_GAN(model_generateur, model_discriminateur):GAN = keras.models.Sequential()GAN.add(model_generateur)# 判别模型中的参数设置为不可训练discriminateur.trainable = FalseGAN.add(model_discriminateur)optimizer_GAN = keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5)GAN.compile(loss='binary_crossentropy', optimizer=optimizer_GAN)return GAN# 随机选取潜在编码(噪声)
def code_latent_aleatoire(dim_latent, nb_exemples):# distribution normal standard normal distribution# code_latent = np.random.normal(loc=0, scale=1, size=(nb_exemples, dim_latent))# code_latent = code_latent.reshape(nb_exemples, dim_latent)code_latent = np.random.randn(nb_exemples, dim_latent)return code_latentdef construction_image_generateur(generateur_model, dim_latent, nb_exemples):# 生成随机噪声X = code_latent_aleatoire(dim_latent,nb_exemples)image_fraud = generateur_model.predict(X)# 生成的图片的真实标签为0Label_genere = np.zeros((nb_exemples,1))return image_fraud, Label_generedef tirage_reelle_aleatoire(base_de_donnees, nb_exemples):mat_images_reel = np.zeros((nb_exemples, 28, 28))for i in range(nb_exemples):index = np.random.randint(0, base_de_donnees.shape[0])mat_images_reel[i,:,:] = base_de_donnees[index,:,:]mat_images_reel = mat_images_reel.reshape(nb_exemples, 28, 28, 1)# 从mnist数据集选取的图片的标签均为1labels_reel = np.ones((nb_exemples, 1))return mat_images_reel, labels_reel# 用于保存和显示图片的函数
def generer_sauvegarde_images(model_generateur,after_epoch,nb_images_sqrt=5,dim_latent=100):nb_images = nb_images_sqrt * nb_images_sqrtimages_frauds, _ = construction_image_generateur(model_generateur,dim_latent=dim_latent,nb_exemples=nb_images)for i in range(nb_images):plt.subplot(nb_images_sqrt, nb_images_sqrt, i+1)plt.imshow(images_frauds[i].reshape(28,28))filepath = "images_fraudes_genere_%d.png" %(after_epoch+1)plt.savefig(filepath)plt.close()# GAN 模型的训练
def entrainement_GAN_model(model_generateur, model_discriminateur, base_de_donnees, dim_latent, GAN_model, epochs=20, batch_size=128):vector_loss_discriminateur = []vector_loss_gan = []# 通过数据集的大小以及batchsize计算每个epoch对应的batch数量total_batch = np.floor(base_de_donnees.shape[0]/batch_size).astype(np.int)# 对于每个epochfor nb_epoch in range(epochs):# 对于每个batchfor index_batch in range(total_batch):# 每个batch中有一半的图像为伪造图片x_fraud, y_fraud = construction_image_generateur(model_generateur, dim_latent=dim_latent, nb_exemples=int(batch_size/2))# 剩下的图像为真实的从mnist数据集中随机提取的图片x_reel, y_reel = tirage_reelle_aleatoire(base_de_donnees=base_de_donnees, nb_exemples=int(batch_size/2))# 叠加所有的数据 id_exemple, 28, 28x_chaque_batch = np.vstack((x_reel, x_fraud))# 叠加所有的标签 : id_exemple, labely_chaque_batch = np.vstack((y_reel, y_fraud))# 使用构建的一半真实一半伪造的数据训练判别模型,更新权重。loss_discriminateur = model_discriminateur.train_on_batch(x_chaque_batch, y_chaque_batch)# 接下来是每个Batch训练叠加模型的部分,其实质是用于训练生成模型。x_generateur = code_latent_aleatoire(dim_latent=dim_latent, nb_exemples=batch_size)# 这里我们要使得叠加模型的输出趋向于1,即使判别模型认为生成的图像也是真实的。y_gan = np.ones((batch_size,1))# 使用判别模型(叠加模型)的输出来训练生成模型gan_loss = GAN_model.train_on_batch(x_generateur, y_gan)# 显示每个batch对应的两个部分的lossprint("%d epochs,%d batches, loss_discriminateur : %f, loss_gan : %f"%(nb_epoch+1, index_batch+1, loss_discriminateur, gan_loss))# 保存模型以及图片部分if (nb_epoch + 1)%3 == 0:model_generateur.save("generateur_models/generateur_after_" + str(nb_epoch+1) + "_epoch_" + "loss_%3f"%(gan_loss) + ".h5")model_discriminateur.save("discriminateur_models/discriminateur_after_" + str(nb_epoch+1) + "_epoch_" + "loss_%3f"%(loss_discriminateur) + ".h5") GAN_model.save("gan_models/gan_after_" + str(nb_epoch+1) + "_epoch_" + "loss_%3f"%(gan_loss) + ".h5")generer_sauvegarde_images(model_generateur=model_generateur, after_epoch=nb_epoch)vector_loss_discriminateur.append(loss_discriminateur)vector_loss_gan.append(gan_loss)return vector_loss_discriminateur, vector_loss_gan# load data from database mnist
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(path="mnist.npz")
# normaliser à [0,1]
x_train = x_train/255.0
x_test = x_test/255.0
dim_code_latent = 100 
generateur = creation_generateur(dim_latent=dim_code_latent)
discriminateur = creation_discriminateur()
opt_discriminateur = keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5)
discriminateur.compile(loss=keras.losses.binary_crossentropy, optimizer=opt_discriminateur)
GAN = creation_reseau_GAN(generateur, discriminateur)
loss_discriminateur, loss_gan = entrainement_GAN_model(model_generateur=generateur, model_discriminateur=discriminateur,base_de_donnees=x_train, GAN_model=GAN, epochs=21, batch_size=256, dim_latent=dim_code_latent)

训练过后的生成模型就可以用来生成伪造图片,下图为经过9个epoch的训练后,所生成的伪造图片,我们可以发现生成的图像中已经有可以辨认出的数字,例如5,7,9。有理由认为我们在经过更多的epoch训练后,生成模型的细节将进一步完善。
在这里插入图片描述

小tips : 在训练GAN模型时,要时刻关注判别模型的loss以及accuracy。如果判别模型的loss下降的太快,这就意味着生成模型正在给我们生成一些垃圾数据,这些数据轻易地就被判别模型给判定为伪造了。一般而言,维持判别模型的loss在一定范围内会对整个GAN模型的训练有帮助。更进一步的说,一个完美的判别模型,即可以完美分辨真伪图片的判别模型不能给予生成模型足够的信息来产生合理的伪造图片,因此在训练的过程中时刻保持判别模型的非完美性是有必要的,这也增加了在处理更复杂问题时,GAN模型在调参方面的困难程度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/386828.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

autoencoder自编码器原理以及在mnist数据集上的实现

Autoencoder是常见的一种非监督学习的神经网络。它实际由一组相对应的神经网络组成(可以是普通的全连接层,或者是卷积层,亦或者是LSTMRNN等等,取决于项目目的),其目的是将输入数据降维成一个低维度的潜在编…

vscode编写插件详细过程

vscode编写插件详细过程 前言 之前编写了一个vscode插件用vscode写博客和发布,然后有园友要求写一篇来介绍如何开发一个vscode扩展插件,或者说介绍开发这个插件的过程。然而文章还没有写,园子里面已经有人发布一个文章,是园友上…

pytorch学习笔记 1. pytorch基础 tensor运算

pytorch与tensorflow是两个近些年来使用最为广泛的机器学习模块。开个新坑记录博主学习pytorch模块的过程,不定期更新学习进程。 文章较为适合初学者,欢迎对代码和理解指点讨论,下面进入正题。 import torch import numpy as npt1 torch.te…

2019年区块链的主旋律是中间层协议

2019年区块链的主旋律是中间层协议 过去一年加密资产市场从其峰值下跌超过85%的市值。但对我,一个坚定的区块链企业家,这实际上是一件好事,区块链的未来看起来比以往任何时候都更有希望。2017年ICO热潮开始的疯狂至少产生了一个强烈的积极影响…

tensorflow gpu windows配置步骤教学

本文主要针对在windows10环境下的tensorflow配置问题,在linux和mac等其他环境中的配置就不过多赘述(windows总是那个问题最多的环境,建议使用linux 😃)。 本文中配置的环境为 python 3.8.5 tensorflow-gpu 2.4.1 1. 更新nvidia显卡驱动至最…

【BJOI 2019】奥术神杖

题意 你有一个长度为 $n$ 的模板串(由 $0-9$ 这 $10$ 个数字和通配符 $.$ 组成),还有 $m$ 个匹配串(只由 $0-9$ 这 $10$ 个数字组成),每个匹配串有一个魔力值 $v_i$。你要把模板串的每个 $.$ 都换成一个数字…

C# 篇基础知识10——多线程

1.线程的概念 单核CPU的计算机中,一个时刻只能执行一条指令,操作系统以“时间片轮转”的方式实现多个程序“同时”运行。操作系统以进程(Process)的方式运行应用程序,进程不但包括应用程序的指令流,也包括运…

快速理解binary cross entropy 二元交叉熵

Binary cross entropy 二元交叉熵是二分类问题中常用的一个Loss损失函数,在常见的机器学习模块中都有实现。本文就二元交叉熵这个损失函数的原理,简单地进行解释。 首先是二元交叉熵的公式 : Loss−1N∑i1Nyi⋅log⁡(p(yi))(1−yi)⋅log(1−p(yi))Loss …

Docker搭建自己的GitLab

Docker搭建自己的GitLab docker 介绍 **GitLab: ** GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务 **Docker: ** Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖…

flowable 任务节点多实例使用

我们在使用Flowable 工作流引擎的时候,最常用的肯定是任务节点,因为在OA系统、审批系统、办公自动化系统中核心的处理就是流程的运转,在流程运转的时候,可能我们有这样的一个需求,在一个任务节点的时候,我们…

Linux的目录结构

Linux文件系统是呈树形结构,了解Linux文件系统的目录结构,对于我们驾驭Linux还是有必要的。 目录 说明 / Linux文件系统的入口,也是处于最高一级的目录 /bin 基本系统所需要的命令。功能和/usr/bin类似,这个目录中的文件都是…

一文看懂卷积神经网络CNN的核心

在之前,我总结了关于计算机神经网络与梯度下降的核心,详见下文链接 : 一文看懂计算机神经网络与梯度下降 本文主要会对图像相关的机器学习中最为重要的网络,卷积神经网络作个人的理解分析。 1. 为什么要使用卷积神经网络 在讲述原理之前&am…

[LeetCode] Two Sum

一刷&#xff1a; import java.util.Arrays;public class Solution1 { public int[] twoSum(int[] nums, int target) {int[] indexnew int[2];int sum0;for (int i 0; i < nums.length; i) {for (int j i1; j < nums.length; j) {sumnums[i]nums[j];index[0] i;index[…

机器学习理论梳理2 : KNN K近邻分类模型

本文主要梳理KNN&#xff0c;K近邻模型的基本原理。 从机器学习的大分类来看&#xff0c;K近邻模型属于监督学习中的一种判别式模型&#xff0c;常用于分类问题。初始的数据集中&#xff0c;包含了已经分类标签好的数据。一句话来说&#xff0c;K近邻模型就是通过计算实例与现…

docker安装配置gitlab详细过程

1、方法一 1 docker pull beginor/gitlab-ce:11.0.1-ce.0 2、方法二 如果服务器网路不好或者pull不下来镜像&#xff0c;只能在其它网路比较好的机器上pull下来镜像&#xff0c;导出成一个文件&#xff0c; 再下载上传到网路不好的机器上&#xff0c;然后再从文件中导出来&am…

集合对偶律:分别用图文证明

集合几个法则&#xff1a; 求证&#xff1a; 注&#xff1a;右上角C表示此集合的补集/余集 语言描述&#xff1a;A 并 B的补集 A的补集 交 B的补集 A交B的补集 A的补集 并 B的补集 文字证明&#xff1a;&#xff08;思路&#xff1a;证明两个集合相等&#xff0c;可证两集合…

keras实现嘴唇图像autoencoder

本文分享了我在silent speech 项目过程中实现的基于嘴唇图像数据集的autoencoder自编码器。输入输出都是64∗6464*6464∗64的嘴唇灰度图。自编码器由编码解码两个部分构成&#xff0c;同时实现了利用checkpoint在每个epoch运算时&#xff0c;自动保存测试集loss更小的模型。 数…

historyReverser array reverse

historyReverser & array reverse "use strict";/**** author xgqfrms* license MIT* copyright xgqfrms** description historyReverser* augments Reverse 逆向 / Recursive 递归* example* link**/const historyReverser (datas [], text , debug false)…

pip国内加载速度慢解决方法

在国内使用pip安装包时有时会发现安装速度非常慢&#xff0c;甚至连接不上源。 为了加快pip的下载速度&#xff0c;我们可以主动使用 -i命令来切换到国内源。 下面放出实测好用的国内源 : 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http:…