TensorFlow从1到2(三)数据预处理和卷积神经网络

TensorFlow从1到2(三)数据预处理和卷积神经⽹络
数据集及预处理
从这个例⼦开始,相当⽐例的代码都来⾃于的⽰例。开始的⼏个还好,但随后的程序都将需要⼤量的算⼒⽀持。Google Colab是⼀个⾮常棒的云端实验室,提供含有TPU/GPU⽀持的Python执⾏环境(需要在Edit→Notebook Settings设置中打开)。速度⽐不上配置优良的本地电脑,但⾄少超过平均的开发环境。
所以如果你的电脑运⾏速度不理想,建议你尝试去官⽅⽂档中,使⽤相应代码的对应链接进⼊Colab执⾏试⼀试。
还允许新建Python笔记,来尝试⾃⼰的实验代码。当然这⼀切的前提,是需要你科学上⽹。
上⼀个例⼦已经完全使⽤了TensorFlow 2.0的库来实现。但数据集仍然沿⽤了TensorFlow 1.x讲解时所使⽤的样本
TensorFlow 2.0默认使⽤Keras的datasets类来管理数据集,包括Keras内置模型已经训练好的⽣产数据集,和类似MNIST这种学习项⽬所⽤到的练习数据集。
使⽤Keras载⼊数据集同样只是⼀⾏代码:
(train_images, train_labels), (test_images, test_labels) = ist.load_data()
Keras.datasets默认是从⾕歌⽹站下载数据集,以MNIST为例,数据下载地址是:。⽂件下载之后,放置到~/.keras/datasets⽂件夹,以后执⾏程序的时候,会⾃动从本地读取数据。数据保存路径Linux/Mac都是如此,Windows同样是在⽤户主⽬录,⽐如:
c:\Users\Administrator.keras\datasets。
接着是数据预处理的问题,主要是从原始的图⽚、标注,转换为机器学习所需要的规范化之后的数据。我们在TensorFlow 1.x中所使⽤的数据实际是已经规范化之后的。我们可以使⽤Python3的交互模式,载⼊数据之后,查看⼀下数据:
$ python3
Python 3.7.3 (default, Mar 27 2019, 09:23:39)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import input_data
>>> mnist = ad_data_sets("data/", one_hot=True)
Extracting
Extracting
Extracting
Extracting
>>> ain.images[0]
储血冰箱array([0.        , 0.        , 0.        , 0.        , 0.        ,
...省略部分...
0.        , 0.        , 0.        , 0.        , 0.        ,
0.9215687 , 0.9215687 , 0.9215687 , 0.9215687 , 0.9215687 ,
0.9843138 , 0.9843138 , 0.9725491 , 0.9960785 , 0.9607844 ,
0.9215687 , 0.74509805, 0.08235294, 0.        , 0.        ,
...省略部分...
0.        , 0.        , 0.        , 0.        , 0.        ,
0.        , 0.        , 0.        , 0.        ], dtype=float32)
>>> ain.labels[0]
array([0., 0., 0., 0., 0., 0., 0., 1., 0., 0.])
对于图,就是28x28的⼆维数组,其中每⼀个数据,代表⼀个点,数据的值越接近1,代表这个点的颜⾊越接近⽩⾊;反之,则颜⾊越接近⿊⾊。借⽤中的⼀幅图来帮你回忆⼀下这个关系(上⼀篇中,图⽚显⽰部分的代码,功能也是还原这组数据):
对于标签,因为我们是识别为0-9共10个数字,是10个输出的分类器。所以标签组某⼀个值为1,表⽰图像代表的⼿写数字属于该分类。同样借⽤⼀下原图:
如果想将这样的分类数据转成我们习惯的0-9数字,可以使⽤TensorFlow中内置的函数argmax:
.
..接着上⾯的交互模式继续执⾏...
>>> import tensorflow as tf
>>> train_labels = tf.ain.labels, 1)
>>> train_labels
<tf.Tensor: id=2, shape=(55000,), dtype=int64, numpy=array([7, 3, 4, ..., 5, 6, 8])>
现在的数据看起来很习惯了吧?更幸福的是,使⽤Keras的的分类器模型训练,已经可以直接使⽤这样的标签数据了。
ist.load_data()所载⼊的样本数据,跟TensorFlow 1.0所使⽤的数据有⼀些区别。其中的图像数据并未做规范化,仍然是通常BMP图像中的0-255的字节数据⽅式。标签数据,也直接是我们更熟悉的0-9数字标签。这两个微⼩的变化提现了TensorFlow理念的转变,TensorFlow更贴近真实的⼯作环境了。
我们同样在交互模式来看⼀下这两组数据:
$ python3
Python 3.7.3 (default, Mar 27 2019, 09:23:39)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
卫生杯>>> from tensorflow import keras
>>> (train_images, train_labels), (test_images, test_labels) = ist.load_data()
>>> train_images[0]
array([[  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0],
...省略部分...
[  0,  0,  0,  0,  0,  0,  0,  0,  30,  36,  94, 154, 170,
253, 253, 253, 253, 253, 225, 172, 253, 242, 195,  64,  0,  0,
0,  0],
[  0,  0,  0,  0,  0,  0,  0,  49, 238, 253, 253, 253, 253,
253, 253, 253, 253, 251,  93,  82,  82,  56,  39,  0,  0,  0,
0,  0],
[  0,  0,  0,  0,  0,  0,  0,  18, 219, 253, 253, 253, 253,
253, 198, 182, 247, 241,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0],
[  0,  0,  0,  0,  0,  0,  0,  0,  80, 156, 107, 253, 253,
205,  11,  0,  43, 154,  0,  0,  0,  0,  0,  0,  0,  0,
srte0,  0],
[  0,  0,  0,  0,  0,  0,  0,  0,  0,  14,  1, 154, 253,
90,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0],
...省略部分...
[  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0]], dtype=uint8)
>>> train_labels
array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)
就像从上⼀个系列中我就⼀直强调的,TensorFlow的使⽤越来越容易,成熟的模型越来越多。难度更多的会集中在样本的选取和预处理,所以⼀定要多关注对原始数据的理解。
TensorFlow 2.0可以直接处理如上所⽰的标签数据。图像的数据则仍然需要规范化,图像数据的取值范围我们很清楚是0-255,规范化也很简单:
# 数据规范化为0-1范围的浮点数
train_images = train_images / 255.0
test_images1 = test_images / 255.0
下⾯看看完整的代码:
#!/usr/bin/env python3
# tensorflow库
import tensorflow as tf
# tensorflow 已经内置了keras
from tensorflow import keras
# 引⼊绘图库
import matplotlib.pyplot as plt
# 第⼀次使⽤会⾃动从⽹上下载mnist的训练样本
(train_images, train_labels), (test_images, test_labels) = ist.load_data()
def plot_image(i, imgs, labels, predictions):
# TensorFlow 2.x的数据已经是0-255范围,⽆需再次还原
image = imgs[i]
label = labels[i]
prediction = tf.argmax(predictions[i])
# 绘制样本图
plt.imshow(image)
# 显⽰标签值,对⽐显⽰预测值和实际标签值
plt.xlabel("predict:{} label:{}".format(prediction, label))
def show_samples(num_rows, num_cols, images, labels, predictions):
num_images = num_rows*num_cols
plt.figure('Predict Samples', figsize=(2*num_cols, 2*num_rows))
# 循环显⽰前num_rows*num_cols副样本图⽚
for i in range(num_images):
plt.subplot(num_rows, num_cols, i+1)
plot_image(i, images, labels, predictions)
plt.show()
# 数据规范化为0-1范围的浮点数
train_images = train_images / 255.0
test_images1 = test_images / 255.0
# 定义神经⽹络模型
model = keras.Sequential([
# 输⼊层把28x28的2维矩阵转换成1维
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(10, activation='softmax')
])
# 编译模型
modelpile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 使⽤训练集数据训练模型
model.fit(train_images, train_labels, epochs=5)
# 使⽤测试集样本验证识别准确率
test_loss, test_acc = model.evaluate(test_images1, test_labels)
print('\nTest accuracy:', test_acc)
# 完整预测测试集样本
predictions = model.predict(test_images1)
# 显⽰测试样本预测结果
show_samples(4, 6, test_images, test_labels, predictions)
代码中,图⽚显⽰的部分也对应取消了把规范化的数据还原为0-255原始图像数据的过程。其它部分则并没有什么变化。
电梯广告框现在,MNIST已经是完整的TensorFlow 2.0的原⽣代码了。绕了这么远,希望能帮你更深刻理解这些代码背后的⼯作。
卷积和池化
在前⼀个系列中,卷积和池化部分据很多反馈说是⼀个很严重的门槛。有读者说完全算不清每⼀层和相连接的层之间的数据关系。
在TensorFlow 2.0中,就像前⾯说过的,这种层与层之间的数据维度模型完全是⽆需⾃⼰计算的,Keras会⾃动匹配这种数据关系。因此单纯从这⼀点上说,在TensorFlow 2.0中,⽆论多复杂的模型构建都不会再成为问题。只是会多⼀点其它的担⼼,那就是这样隐藏起来机器学习本质上的数学模型,究竟对程序员来说是好事还是坏事?
TensorFlow 1.x中使⽤卷积神经⽹络解决MNIST问题的讲解在。篇幅很长,这⾥就不重贴了。在TensorFlow 2.0中,则只是⼀个函数⼏⾏代码(请尽量跟TensorFlow 1.x版本的代码对应着看。对卷积、池化的概念已经忘记的也强烈建议去前系列复习⼀下):
# 定义卷积池化神经⽹络模型
model = keras.Sequential([
keras.layers.Conv2D(32, (5, 5), strides=(1, 1),
padding='same', activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2),
strides=(2, 2), padding='same'),
keras.layers.Conv2D(64, (5, 5), strides=(1, 1),
padding='same', activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2),
strides=(2, 2), padding='same'),
keras.layers.Flatten(),  # 下⾯的神经⽹络需要1维的数据
keras.layers.Dense(1024, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(10, activation='softmax')
])
Keras让模型构建的过程变得极其容易。
从原理上说,卷积是对图像的⼆维数据做扫描,还需要指定图像的⾊深。所以在样本预处理的阶段,我们还要对其做⼀个变形:
# 卷积需要2维数据,还需要指定⾊深,因此是(样本数,长,宽,⾊深)
train_images = shape(train_labels.shape[0], 28, 28, 1)
test_images1 = shape(test_labels.shape[0], 28, 28, 1)
训练集的样本我们直接⽤变形后的数据替代了原始样本。测试集则另外使⽤了⼀个变量保留了原始的测试集,这是因为我们显⽰测试集图⽚的时候,使⽤原始数据集显然更⽅便。
实际上整个代码只有这么两点区别,不过为了你练习的时候⽅便,还是把完整代码贴⼀遍:
#!/usr/bin/env python3
# tensorflow库
import tensorflow as tf
# tensorflow 已经内置了keras
from tensorflow import keras
# 引⼊绘图库
import matplotlib.pyplot as plt
# 第⼀次使⽤会⾃动从⽹上下载mnist的训练样本
(train_images, train_labels), (test_images, test_labels) = ist.load_data()
# 数据路径:~/.keras/datasets/mnist.npz程控步进衰减器系统
def plot_image(i, imgs, labels, predictions):
image = imgs[i]
label = labels[i]
prediction = tf.argmax(predictions[i])
hdpe成品排水沟# 绘制样本图
plt.imshow(image)
# 显⽰标签值
plt.xlabel("predict:{} label:{}".format(prediction, label))
def show_samples(num_rows, num_cols, images, labels, predictions):
num_images = num_rows*num_cols
plt.figure('Predict Samples', figsize=(2*num_cols, 2*num_rows))
# 循环显⽰前4*6副训练集样本图⽚
for i in range(num_images):
plt.subplot(num_rows, num_cols, i+1)
plot_image(i, images, labels, predictions)
plt.show()
# 数据规范化为0-1范围的浮点数
train_images = train_images / 255.0
test_images1 = test_images / 255.0
# 卷积需要2维数据,还需要指定⾊深,因此是(样本数,长,宽,⾊深)
train_images = shape(train_labels.shape[0], 28, 28, 1)
test_images1 = shape(test_labels.shape[0], 28, 28, 1)
# 定义卷积池化神经⽹络模型
model = keras.Sequential([
keras.layers.Conv2D(32, (5, 5), strides=(1, 1),
padding='same', activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2),
strides=(2, 2), padding='same'),
keras.layers.Conv2D(64, (5, 5), strides=(1, 1),
padding='same', activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2),
strides=(2, 2), padding='same'),
keras.layers.Flatten(),  # 下⾯的神经⽹络需要1维的数据
keras.layers.Dense(1024, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(10, activation='softmax')
])
# 编译模型
modelpile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 使⽤训练集数据训练模型
model.fit(train_images, train_labels, epochs=3)
# 使⽤测试集样本验证识别准确率
test_loss, test_acc = model.evaluate(test_images1, test_labels)
print('\nTest accuracy:', test_acc)
# 完整预测测试集样本
predictions = model.predict(test_images1)
# 显⽰测试样本预测结果
show_samples(4, 6, test_images, test_labels, predictions)
程序执⾏的时候,在控制台的输出信息类似下⾯:
$ chmod +x mnist-conv-maxpool-v2.py
$ ./mnist-conv-maxpool-v2.py
Epoch 1/3
60000/60000 [==============================] - 141s 2ms/sample - loss: 0.1139 - accuracy: 0.9643
Epoch 2/3
60000/60000 [==============================] - 143s 2ms/sample - loss: 0.0417 - accuracy: 0.9869
Epoch 3/3
60000/60000 [==============================] - 138s 2ms/sample - loss: 0.0312 - accuracy: 0.9904
10000/10000 [==============================] - 7s 659us/sample - loss: 0.0289 - accuracy: 0.9903
Test accuracy: 0.9903
在样本集的测试上,卷积神经⽹络的版本可以达到超过99%的正确率。
这个正确率,只进⾏了3次的训练迭代,当然因为卷积神经⽹络模型的复杂,这3次的训练就远远⽐上⼀例中的5次训练速度更慢。(待续...)

本文发布于:2024-09-21 03:14:14,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/215958.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   样本   需要   模型   卷积   测试   神经
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议