20210608 TensorFlow 实现数字图片分类
0-1 导包
import warnings warnings.filterwarnings("ignore") import keras import numpy as np import tensorflow as tf import matplotlib.pyplot as plt
1-1 构造数据
调用接口去下载数据
mnist = keras.datasets.mnist # 导入 mnist (train_images, train_labels),(test_images,test_labels) = mnist.load_data()
60000条训练集,10000条测试集
print("train image shape:",train_images.shape,"train label",train_labels.shape) print("test image shape:",test_images.shape,"test label",test_labels.shape)
-->
train image shape: (60000, 28, 28) train label (60000,)
test image shape: (10000, 28, 28) test label (10000,)
60000条训练集分为训练的图片和标签,图片是手写的数字图片,长和宽都是 28,标签就是数字集,测试集是 10000 个图片,测试标签也是 10000
1-1-1 显示数据和标签
print("image data:",train_images[0]) print("label data:",train_labels[0])
# 数据太多太大,这里便不展示了
# label data: 5
1-1-2
defplot_img(img): plt.imshow(img.reshape(28,28),cmap="binary") # camp = "binary" 使用灰度图表示 plt.show() # 查看图片 plot_img(train_images[3]) plot_img(train_images[0])
1-1-3 现在进行一个 0 1 的二分类
data_0 = [] data_1 = [] # zip 把里面的子数据 拿出来了,img是(28,28);label 标签是一个值 for img,label in zip(train_images, train_labels): if label == 0: # 首先需要把图片拍平,现在的训练是一种类似 DNN 神经网络的模式 # 所以无法传入 28*28 的图片进行训练,reshape(28*28),将二阶变为一阶的 784 # 除以 255 的作用是,约束到 0 到 1 之间 img = img.reshape(28*28)/255 # 将图片和 label 放一起,变成 785 个数据,赋给 img img = np.append(img,label) data_0.append(img) if label == 1: img = img.reshape(28*28)/255 img = np.append(img,label) data_1.append(img) data_0 = np.array(data_0) data_1 = np.array(data_1) all_data = np.concatenate([data_0,data_1]) print(all_data.shape)
# --> (12665, 785)
# 前 784 是像素,最后的 1 是标签
np.random.shuffle(all_data) # np.random.shuffle 打乱顺序,避免前面全是0,后面全是 1 # 切分训练集和数据集,按理说 20% 测试集,80%训练集,这里只是简单的 前面的作为训练集,后200个作为测试集 train_data = all_data[:-200] test_data = all_data[-200:]
2-1 数据分块
# 生成器 def gen_batch(data,batch_size): np.random.shuffle(data) # 打乱,增加随机性 for i in range(len(data) // batch_size): cursor = batch_size * i batch_data = data[cursor : cursor + batch_size] x = batch_data[:, 0:784] # 第一维度全取,第二维度取前 784 个像素,最后一个是标签 y = batch_data[:, 784] yield x,y.reshape(-1,1) remainder = len(data) % batch_size if remainder != 0: x, y = data[-remainder:, 0:784], data[-remainder:, 784] yield x, y.reshape(-1,1) for x_,y_ in gen_batch(train_data,128): print(x_.shape) print(y_.shape) print('-------') break
# -->
# (128, 784)
# (128, 1)
# -------
3-1 超参数
learing_rate = 0.01 num_train_epochs = 50 # 循环训练集总轮数 display_per_step = 100 batch_size = 128
4-1 计算图
graph = tf.Graph() with graph.as_default(): x = tf.placeholder(shape=[None,784], dtype=tf.float32, name='x') y = tf.placeholder(shape=[None,1], dtype=tf.float32, name='y') w = tf.Variable(tf.ones(shape=[784,1]), dtype=tf.float32) b = tf.Variable(0, dtype=tf.float32) logits = tf.matmul(x, w) + b y_pred = tf.sigmoid(logits) # 定义loss with tf.name_scope("loss"): loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=logits), name="calculate_loss") # 定义优化器 with tf.name_scope("SGD"): optimizer = tf.train.GradientDescentOptimizer(learing_rate) train_step = optimizer.minimize(loss) # 定义正确率 with tf.name_scope("calculation_accuracy"): res_pred = tf.cast(tf.greater_equal(y_pred, 0.5), dtype=tf.float32) acc = tf.reduce_mean(tf.cast(tf.equal(res_pred, y), dtype=tf.float32))
5-1 运行计算图
with tf.Session(graph=graph) as sess: init = tf.global_variables_initializer() sess.run(init) step = 0 for epoch in range(num_train_epochs): for x_, y_ in gen_batch(train_data, batch_size): step += 1 _, l, acc_ = sess.run([train_step, loss, acc], feed_dict={x: x_, y: y_}) if step % display_per_step == 0: print("step: {:>4}, loss: {:.4}, acc: {:.4%}".format(step, l, acc_)) print('training over') x_test,y_test = next(gen_batch(test_data,200)) # 取出全部测试集数据 # 查看测试集的 loss 和正确率 loss_test, acc_test = sess.run([loss, acc],feed_dict={x: x_test, y: y_test}) print("test loss is {:.4}, acc is {:.4%}".format(loss_test, acc_test)) res_weights = sess.run([w, b]) # res_weights 存在的目的是进行模型的预测,给出一张图片,判断能否正确预测
-->
step: 100, loss: 43.14, acc: 60.1562%
step: 200, loss: 34.86, acc: 50.7812%
step: 300, loss: 19.21, acc: 52.3438%
……
step: 4700, loss: 0.09711, acc: 96.8750%
step: 4800, loss: 0.1117, acc: 97.6562%
step: 4900, loss: 0.0001993, acc: 100.0000%
training over
test loss is 0.04518, acc is 99.0000%
6-1 模型预测
def plot_img(img): plt.imshow(img.reshape(28,28),cmap="binary") plt.show() test_img = test_data[7,:784] plot_img(test_img)
6-2
graph = tf.Graph() with graph.as_default(): x = tf.placeholder(shape=[None,784], dtype=tf.float32, name='x') y = tf.placeholder(shape=[None,1], dtype=tf.float32, name='y') # w 和 b 是前面训练好的值 w = tf.Variable(res_weights[0], dtype=tf.float32) b = tf.Variable(res_weights[1], dtype=tf.float32) logits = tf.matmul(x, w) + b y_pred = tf.sigmoid(logits) # 定义loss with tf.name_scope("loss"): loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=logits), name="calculate_loss") # 定义优化器 with tf.name_scope("SGD"): optimizer = tf.train.GradientDescentOptimizer(learing_rate) train_step = optimizer.minimize(loss) # 定义正确率 with tf.name_scope("calculation_accuracy"): res_pred = tf.cast(tf.greater_equal(y_pred, 0.5), dtype=tf.float32) acc = tf.reduce_mean(tf.cast(tf.equal(res_pred, y), dtype=tf.float32))
with tf.Session(graph=graph) as sess: # 初始化权重,将前面训练好的权重,放到计算图里 init = tf.global_variables_initializer() sess.run(init) # test_data[7,:784].shape 是 (784,) # 但是 x = tf.placeholder(shape=[None,784], dtype=tf.float32, name='x') # 所以需要 reshape 成为 (1,-1),也就是第一维是 1,第二维就是 784/1 # 所以 当前这里图片 的 shape 就是 (1,784) x_ = test_data[7,:784].reshape(1,-1) # 从这地方可以看出,预测输出的时候,并没有使用标签,所以传参时只传 x 就可以 res_p = sess.run(res_pred, feed_dict={x: x_}) print(res_p)
# --> [[0.]]
预测出的结果是 0,所以简单的网络结构确实可以对测试集的手写数字图片进行预测,这就是一个数字的图片分类
部分代码解释:
1. 1-1-3 中的 zip()
https://blog.51cto.com/u_15149862/2847102
2. 1-1-3 中列表的使用,比如 train_data = all_data[:-200]
https://blog.51cto.com/u_15149862/2704954
3. 2-1 中的生成器
https://blog.51cto.com/u_15149862/2844458
4. TensorFlow 基本用法
https://blog.51cto.com/u_15149862/2825353

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
苹果iPadOS 15特性汇总:生产力表现提升 告别“买后爱奇艺”
6月8日凌晨,苹果WWDC21如期发布,其中iPadOS也迎来了自己的全新版本iPadOS15。 苹果在发布会中提到,依托iPdaOS构建的各项独特功能,才令iPad有了独一无二的移动能力和触控表现。 全新升级的iPadOS15也将会使iPad的功能更加丰富强大。 自由奔放的组件排列 今年的iPadOS15将在主屏幕交互上有重大升级,支持小组件和单个应用混合排列,使用者可以按照自己的喜好,随意组合屏幕上的顺序排列,做到极具个性化。 此外苹果还推出了一些适应iPad大屏的小组件,轻轻一扫,即可随意切换影音、游戏和照片等不同类型主页,做到高效流畅交互。 高效整理的应用资源库 为了方便使用者轻松找到不常用的应用,此前的iPadOS 15效仿iOS也推出了iPad的应用资源库。 所有应用都能在应用资源库中轻松找到,使用逻辑和iPhone的应用资源库使用基本一致,但iPadOS上的这个应用资源库可以做到随时从程序坞直接上拉使用,这一点上来说,比iOS的应用资源库更胜一筹。 简单快捷的多任务管理 多任务管理也是iPadOS15的升级亮点之一,相比之前复杂繁琐的分屏操作,此次的iPadOS15新增了...
- 下一篇
太方便了!利用Python对批量Pdf转Word
在wps或者office里面可以将pdf转word,不过**只能免费转前面5页**,超过5页就**需要会员**。今天教大家一个Python办公小技巧:**批量Pdf转Word** ,这样可以自由想转多少页都可以。 **思路**:这里主要是利用了Python的pdfmine3k库去**提取**pdf文本内容,通过python-docx库去将内容**保存**到word中。 下面先看一下效果:  # 01 环境准备 在开始编写代码之前,咱们先安装一些用到的Python库,安装目录如下: ``` pipinstall pdfminer ``` **注意**: 使用 pipinstall docx 安装模块 docx 后,发现不能正常使用, 并报错moduleNotFoundError:No module named 'exceptions' **正解**: ``` ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS关闭SELinux安全模块
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8编译安装MySQL8.0.19
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7,CentOS8安装Elasticsearch6.8.6