600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 基于MNIST数据集通过朴素贝叶斯学习生成随机手写体数字图像

基于MNIST数据集通过朴素贝叶斯学习生成随机手写体数字图像

时间:2023-06-06 02:34:23

相关推荐

基于MNIST数据集通过朴素贝叶斯学习生成随机手写体数字图像

好久没写博客了,话不多说,进入主题。

1、贝叶斯方法

关于贝叶斯方法,刘未鹏的文章一出,感觉不再需要其他文章了。读者可以阅读以下//09/21/the-magical-bayesian-method/

2、训练数据集

经典的手写数字图像训练和测试集来自/exdb/mnist/。读者可以下载。

3、具体实现过程

3.1 导入数据集

上面提到的数据由于编码问题,需要自己写导入方法,如果你也是用python的话,有现成的模板可以使用。推荐一个GitHub的下载地址

3.2 学习并生成图片

对于一张图像,例如数据集中28*28的图像,每个像素点像素值为0~255。这样一来,经过抽象,一张图像可以分为图像本身数据信息images和它所表示的意义label。其中,images是一个28*28=784维的特征集,且每个维度的特征有256个取值(0~255的像素值)label表示这个特征集的分类,为0~9分为10类。

根据贝叶斯方法,我们需要得到类别label的先验概率P(c) = {P(c_i)} (i=0~9)。这个过程可以通过简单的统计计算即可。然后在特定类别c的情况下,我们需要去统计计算出每个维度的特征值的后验概率P(x_j | c) = {P(x_j = k | c)} (j = 0~784, k = 0~255)。学习过程即可结束。

根据学习到的类别label的先验概率和特征向量的后验概率,在生成图像时,我们只需要根据相应的概率随机生成图像信息矩阵即可。首先是生成随机生成0~9的随机数,作为类别label的取值;然后在特定label的情况下,根据P(x_j | c)生成每个维度的随机概率取值,组成图像矩阵。

根据生成的图像矩阵,生成图像。

4、注意

关于根据分布概率生成随机数的方法,我采用的是将概率映射到0~1000的范围。比如概率分布是0.2,0.5, 0.3,那么生成0~1000范围的随机数,如果随机数是在在0~199范围的话,就映射为P=0.2的值,以此类推。

5、生成图片效果

6、Python实现代码

# -*- coding: utf-8 -*-print(__doc__)import mathimport pylab as plimport numpy as npfrom mnist import MNISTimport randomfrom collections import Counter# 按照分布概率采样,生成class随机数def prob_choice_class(probs):rnd = random.random() * sum(probs)for i, w in enumerate(probs):rnd -= wif rnd < 0:return i# 按照分布概率采样,生成feature随机数# 按照概率分布进行映射到0~1000区间def prob_choice_feature(probs):rnd = random.random() * 1000prob_section = []for i in range(0, len(probs)):if rnd >= sum(prob_section):prob_section.append(int(probs[i]*1000))if rnd < sum(prob_section) or i == len(probs)-1:return i# 开源数据集mndata = MNIST('data')mndata.load_training()# 平滑数据,转化为(samples, feature)的矩阵n_samples = len(mndata.train_images)data = np.array(mndata.train_images).reshape(n_samples, -1)# 统计数据count_class = Counter()count_feature = {}# 构建3维数组for x in range(0, 10):ycount = {}for y in range(0, 784):zcount = {}for z in range(0, 256):zcount[z] = 0ycount[y] = zcountcount_feature[x] = ycount# 分别统计class和featurefor i in range(0, len(data)):count_class[mndata.train_labels[i]] += 1for j in range(0, len(data[i])):count_feature[mndata.train_labels[i]][j][int(data[i][j])] += 1# 计算class的概率分布count_class_prob = []count_class_sum = sum(count_class.values())for key, value in count_class.iteritems():count_class_prob.append(float(value)/count_class_sum)# 计算每个像素维度的分布概率count_feature_prob = {}# 构建3维数组for x in range(0, 10):ycount = {}for y in range(0, 784):zcount = {}for z in range(0, 256):zcount[z] = 0ycount[y] = zcountcount_feature_prob[x] = ycount# 具体计算for i in range(0, 10):for j in range(0, 784):count_feature_sum = sum(count_feature[i][j].values())for k in range(0, 256):count_feature_prob[i][j][k] = float(count_feature[i][j][k])/count_feature_sum##file_class = open('model/classprob', 'w')##file_feature = open('model/featureprob', 'w')##file_class.write(str(count_class_prob))##file_feature.write(str(count_feature_prob))##file_class.close()##file_feature.close()# 根据模型构建图片# 指定构建图片数量nr_target = 10# 图片的像素维度(28*28=784)nr_feature = 784# 开始生成图片像素矩阵class_ = []feature = []for x in xrange(nr_target):target = prob_choice_class(count_class_prob)class_.append(target)for y in xrange(nr_feature):feature.append(float(prob_choice_feature(count_feature_prob[target][y])))features = np.array(feature).reshape((nr_target, 28, 28))# 根据矩阵保存为相应图片# 图片命名规则:编号_类别(num_class)num = 0for index, (image, prediction) in enumerate(zip(features, class_)):pl.subplot(1, 1, 1)pl.axis('off')pl.imshow(image, cmap=pl.cm.gray_r, interpolation='nearest')pl.savefig('pic/'+repr(num)+'_%i' % prediction)## pl.title('Create: %i' % prediction)num += 1##pl.show()

#END ICTwangbiao

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。