手写kmeans算法
开篇在本系列的前面几期中,我们介绍了包含决策树及其相关算法在内的一系列有监督学习算法。本期不妨换换口味,学习一种比较简单的无监督学习算法: k-means.
k-means 算法理论讲解你可能已经听说过这个算法,没有也不要紧,它的原理并不复杂,让我们来看看~
给你一批样本的数据,就像这样:其中不同的id代表不同样本,共10个样本。x和y是两个特征,每一个样本都有且只有这两个特征。
现在希望你能够对这些样本进行分类。
我们知道,在属于有监督学习的分类问题中,训练数据往往会包含类别标签。而上面这份数据本身是不含标签的,所以这并不是一个分类问题。
既然不知道类别标签,你又让我对这些样本进行分类,那如何聚类?又要聚成几类呢?
其实,在k-means中,最终聚成几类是由我们自己决定的;这里的类别标签通常用数字表示,如0,1,2等;当我们指定好类别总数后,每一个样本被归到哪一类,就需要聚类算法自己去学习了。
k-means算法学习将相似的样本聚在一起,称为一个类别(也称为一个”簇”),而将不相似的样本划分到不同的类别(“簇”)中。
这里的相似程度,通常是用样本之间的距离来度量的,比如最常用的欧氏距 ...
BrainF语言解释器的Python实现
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960def interp(code): data=[0 for _ in range(30000)] pc=0 ptr=0 st=[]#list模拟stack while(pc<len(code)): c=code[pc] print("正在处理字符'{}'".format(c)) if c=='<': ptr-=1 elif c=='>': ptr+=1 elif c=='+': data[ptr]+=1 ...
折腾Insightface-PyTorch的辛酸历程
2020年11月25号:配置环境(python3.5),运行prepare_data.py,成功提取训练集数据到imgs文件夹;但在提取测试集时报错,原因是python3.5及其之前的版本中的Path()都不继承自str类,于是手动给路径包裹了str(),成功提取除二进制格式保存的文件分别至单独的文件夹(blp后缀,不知道这是什么,先放着);
2020年11月26号:运行python train.py失败,从gihub issue了解到作者用了python3.6,于是重新配环境,试错,期间遇到了各种包装不上以及其他问题(发现作者还用了mxnet用于提取数据);
2020年11月27号:继续配环境,好像是配好了(python3.6),虽然还会报numpy的错误:ModuleNotFoundError: No module named 'numpy.core._multiarray_umath',但是并不影响模型的训练;
于是开始运行train.py,会报RuntimeError: cuda runtime error (2) : out of memory at / ...
计算机视觉任务
分类
一图一标签
语义分割
像素级分类
那怎么做语义分割呢?
滑动窗口在一开始,人们想到了滑动窗口
如上图所示,滑动窗口的思路是:对图中的每一个像素点,以该像素点为中心,取一个区域(手动指定窗口大小),对该区域利用卷积神经网络做分类,区域所属类别即为该区域对应像素点的所属类别。
尽管这是完全能用的吧,但由于一张图中的像素点个数有时候会特别多(比如高分辨率图片),此时,采用滑动窗口会带来较大的运算量,所以有了下面的全卷积网络方法。
全卷积使用全卷积做语义分割的思路如下图所示
对于一张输入的图片,使用padding保证在卷积过程中得到特征图尺寸与输入图片尺寸一致,做多次卷积;在最后一次卷积时,使用C个卷积核以保证最后输出的通道数为C,这里的C是全部类别的个数;最后,对于每一个像素点,分别计算该像素点在通道维度上的取值(由于通道数等于类别数等于C,所以此时会有C个值)与标准答案(形式见下面的补充)之间的交叉熵,再把全部像素点计算得到的交叉熵相加,就得到了总的损失,接下来反向回传就可以更新参数,优化模型了。
【补充】这里每一个像素点所属类别的标准答案是一个数,将其做one-hot操作 ...
ResNet
Why ResNet ?
当神经网络层数变深时,模型性能可能会不增反降。
举个例子,对于某数据集,考虑以下情况:
在测试集上,100层的网络性能低于20层的网络
在训练集上,100层的网络性能低于20层的网络
单单看前者,猜想出现过拟合的可能性较大。因为100层的网络能够拟合更加复杂的函数,对训练集的拟合效果也会更好,但可能导致在测试集上表现并不好(100层网络可能仅仅是记住了训练集的每一个样本的特征及其训练标签,而在面对新的没有见过的样本(比如测试样本)时,就无能为力了)。
然而,再看后者,在训练集上都不达标了,这显然不是过拟合,并且网络越深性能越差,一定是某些其他地方出了问题!
没错,在100层网络的训练过程中,网络的正、反向信息流动不顺畅,从而导致网络没有充分被训练,这正是上面的例子中现象产生的原因!
**残差网络(ResNet)**的提出解决了这一问题,它通过从当前层(不妨记作Current Layer)直接向经过某个网络块(不妨记作F_Block)后得到的后面的层(不妨记作Layer)之间加一条线,使得Current Layer的信息可以直接传给Layer。这样,即使F ...
CycleGAN
导入相关包123456789101112import tensorflow as tfimport tensorflow_addons as tfafrom tensorflow.keras.layers import Dropout, Concatenate,BatchNormalization,LeakyReLU,UpSampling2D, Conv2Dfrom tensorflow.keras.optimizers import Adamimport matplotlib.pyplot as pltimport sysimport osfrom skimage.transform import resizeimport imageiofrom glob import globimport numpy as nptf.keras.backend.set_floatx('float64')
读取数据1234567891011121314151617181920212223242526272829303132333435363738394041424344454 ...
SRGAN
通过采样等方式获取高清图片的低分辨率版本,两者形成一一映射的关系,作为准备好的数据集。
不同于之前的GAN的输入为noise,SRGAN 的输入为低分辨率图片,希望通过对抗的方式学习如何生成低分辨率图片的超清版本。
主要改动的地方除了生成器和判别器的架构外,就是损失函数了:判别器的损失函数无需改动,而生成器的损失函数在原来的基础上,需要再增加两项,一个是真实图片与生成图片的均方误差,另一个是真实图片与生成图片经过vgg19提取得到的特征之间的均方误差(论文中把这两个合起来叫做内容损失,而之前生成器的损失叫做对抗损失,内容损失+对抗损失=感知损失)。
代码导入相关函数1234567import tensorflow as tfimport matplotlib.pyplot as pltimport numpy as npfrom tensorflow.keras import layersimport scipy#需要执行 pip install scipy==1.2.1 来给scipy降级from glob import globimport datetime
准备数据12345 ...
infoGAN
导入相关函数12345import tensorflow as tfimport matplotlib.pyplot as pltimport numpy as npfrom tensorflow.keras import layersfrom tensorflow.keras.utils import to_categorical
准备数据1(train_images,train_labels),(_,_)=tf.keras.datasets.mnist.load_data()
1train_images.shape
(60000, 28, 28)
1train_images.dtype
dtype('uint8')
1train_images=train_images.reshape(train_images.shape[0],28,28,1).astype('float32')
1train_images.shape
(60000, 28, 28, 1)
1train_images.dtype
...
ACGAN
网络结构ACGAN 可以看作是CGAN和SGAN的融合:
模仿CGAN,将类别标签class也输入生成器
模仿SGAN,判别器不仅仅输出真假,还充当分类器
搭建模型由于ACGAN可以看作是CGAN和SGAN的融合,因此在代码实现上也是综合了两者的代码,主要修改部分为损失函数和两个网络结构,具体见代码注释
ACGAN的损失部分如下:
判别损失:
分类损失:
判别器的损失为$L_C+L_S$,意思是让判别器既能判别图片的真伪,又有不错的分类能力;
生成器的损失为$L_C-L_S$,意思是让判别器不能判别图片的真伪,但还有不错的分类能力。
导入相关函数12345import tensorflow as tfimport matplotlib.pyplot as pltimport numpy as npfrom tensorflow.keras import layersfrom tensorflow.keras.utils import to_categorical
准备数据1(train_images,train_labels),(_,_)=tf.keras.datasets ...
对前面三篇文章的总结
序章起初,我觉得使用Keras的那些API,比如train_on_batch,compile等等,极大的减少了代码量,对刚刚入门的小白来说比较友好。
在开始接触GAN之后,发现一些关于GAN的书籍,比如GANs in action,一些关于GAN的博客,如machinelearningmastery,CSDN以及一些能搜到的视频教程,很多都是用的Keras或者tf.keras
于是我也准备学习用tf.keras来实现各种GAN。
后来,经过一小段时间的学习,虽然也跟着别人的代码写出了几个能跑通的GAN,但总觉得keras的代码怪怪的。
高度封装的API,虽然容易使得小白入门,但同时也使得使用者对其内部的机制还是不怎么了解。比如之前困扰我很久的一个问题,就是关于模型的trainable参数的设置问题,明明已经设置为discriminator.trainable=False了,在后面的train_on_batch时,discriminator还能被训练。最后找到了一个不太确定的答案,详细见这篇文章:
https://fx0809.gitee.io/2020/10/12/Keras%E4%B ...