数据集: MINST
包含60000张训练图像和10000张测试图像
#加载Keras中的MNIST数据集
from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
#训练和测试数据查看
train_images.shape #(60000, 28, 28)
len(train_labels) #60000
train_labels #array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)
test_images.shape #(10000, 28, 28)
len(test_labels) #10000
test_labels #array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)
工作流程
#网络架构
from keras import models
from keras import layers
network = models.Sequential() #相当于生成一个容器
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))
本例子包含两个Dense层,是密集连接(全连接)的神经层;
第二层是一个10路softmax层,会返回一个由10个概率值(总和为1)的数组;
//每个概率值表示当前数字图像属于10个数字类别之一的概率;
network.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
#optimizer:优化
#loss:损失
#metrics:指标(精度)
#对数据进行预处理,将其变换为网络要求的形状,并缩放到所 有值都在 [0, 1] 区间
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255
from keras.utils import to_categorical
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
#拟合模型
#在 Keras 中这一步是通过调用网络的 fit 方法来完成的—— 我们在训练数据上拟合(fit)模型。
network.fit(train_images, train_labels, epochs=5, batch_size=128)
##输出
#Epoch 1/5
#60000/60000 [=============================] - 9s - loss: 0.2524 - acc: 0.9273
#Epoch 2/5
#51328/60000 [=======================>.....] - ETA: 1s - loss: 0.1035 - acc: 0.9692
#Epoch 3/5
#60000/60000 [==============================] - 1s - loss: 0.0687 - acc: 0.9793
#Epoch 4/5
#60000/60000 [==============================] - 1s - loss: 0.0508 - acc: 0.9848
#Epoch 5/5
#60000/60000 [==============================] - 1s - loss: 0.0382 - acc: 0.9890
test_loss, test_acc = network.evaluate(test_images, test_labels)
#训练过程中显示了两个数字:一个是网络在训练数据上的损失(loss),另一个是网络在 训练数据上的精度(acc)。我们很快就在训练数据上达到了 0.989(98.9%)的精度。
print('test_acc:', test_acc)
可视化部分:https://www.freesion.com/article/7219811139/
张量也称数据容器,张量是矩阵向任意维度的推广, 张量的维度(dimension)通常叫作轴(axis)。
向量数据:2D 张量,形状为 (samples, features)。
时间序列数据或序列数据:3D 张量,形状为 (samples, timesteps, features)。
图像:4D 张量,形状为 (samples, height, width, channels) 或 (samples, channels, height, width)。
视频:5D 张量,形状为 (samples, frames, height, width, channels) 或 (samples, frames, channels, height, width)。
1、标量(0D 张量)
仅包含一个数字的张量叫作标量(scalar,也叫标量张量、零维张量、0D 张量)。
在 Numpy 中,一个 float32 或 float64 的数字就是一个标量张量(或标量数组)。你可以用 ndim 属性来查看一个 Numpy 张量的轴的个数。标量张量有 0 个轴(ndim == 0)。张量轴的个数也叫作阶(rank)。
import numpy as np
x = np.array(12)
x
#输出array(12)
x.ndim
#输出0
2、向量(1D 张量)
数字组成的数组叫作向量(vector)或一维张量(1D 张量)。
一维张量只有一个轴。维度 (dimensionality)可以表示沿着某个轴上的元素个数(比如 5D 向量),也可以表示张量中轴的个 数(比如 5D 张量)。
x = np.array([12, 3, 6, 14, 7])
x
#输出array([12, 3, 6, 14, 7])
x.ndim
#输出1
#这个向量5个元素,所以被称为5D向量。
#不要把5D向量和5D张量弄混。5D 向量只有一个轴,沿着轴有5个维度,而5D张量有5个轴(沿着每个轴可能有任意个维度)。
一个 Numpy 向量
3、矩阵(2D 张量)
向量组成的数组叫作矩阵(matrix)或二维张量(2D 张量)。
矩阵有 2 个轴(通常叫作行和 列)。你可以将矩阵直观地理解为数字组成的矩形网格。
x = np.array([[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]])
x.ndim
#输出2
#第一个轴上的元素叫作行(row),第二个轴上的元素叫作列(column)。在上面的例子中, [5, 78, 2, 34, 0] 是 x 的第一行,[5, 6, 7] 是第一列。
一个Numpy矩阵
4、3D张量与更高维张量
将多个矩阵组合成一个新的数组,可以得到一个 3D 张量,你可以将其直观地理解为数字组成的立方体。
x = np.array([[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]],
[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]],
[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]]])
x.ndim
#输出3
一个Numpy的3D张量
将多个3D张量组合成一个数组,可以创建一个 4D 张量,以此类推。深度学习处理的一般是 0D 到 4D 的张量,但处理视频数据时可能会遇到 5D 张量。
张量是由以下三个关键属性来定义的。
轴的个数(阶)——例如,3D 张量有 3 个轴,矩阵有 2 个轴。这在 Numpy 等 Python 库中也叫张量的 ndim。
形状——这是一个整数元组,表示张量沿每个轴的维度大小(元素个数)。例如,前面矩阵示例的形状为 (3, 5),3D 张量示例的形状为 (3, 3, 5)。向量的形状只包含一个元素,比如 (5,),而标量的形状为空,即 ()。
数据类型(在 Python 库中通常叫作 dtype)——这是张量中所包含数据的类型,例如,张量的类型可以是 float32、uint8、float64 等。在极少数情况下,你可能会遇到字符 (char)张量。注意,Numpy(以及大多数其他库)中不存在字符串张量,因为张量存储在预先分配的连续内存段中,而字符串的长度是可变的,无法用这种方式存储。
#首先加载 MNIST 数据集。
from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
#给出张量 train_images 的轴的个数,即 ndim 属性。
print(train_images.ndim) 3
#形状。
print(train_images.shape) (60000, 28, 28)
#数据类型,即 dtype 属性。
print(train_images.dtype) uint8
#这里 train_images 是一个由8位整数组成的3D张量。更确切地说,它是 60 000个矩阵组成的数组,每个矩阵由 28×28 个整数组成。每个这样的矩阵都是一张灰度图像,元素取值范围为 0~255。
#我们用 Matplotlib 库(Python 标准科学套件的一部分)来显示这个 3D 张量中的第 4 个数字
digit = train_images[4]
import matplotlib.pyplot as plt
plt.imshow(digit, cmap=plt.cm.binary)
plt.show()
MNIST例子中处理的数据
张量切片:选择张量特定的元素
#下面这个例子选择第10~100个数字(不包括第 100 个),并将其放在形状为 (90, 28, 28) 的数组中。
my_slice = train_images[10:100]
print(my_slice.shape
#(90, 28, 28)
#它等同于下面这个更复杂的写法,给出了切片沿着每个张量轴的起始索引和结束索引。 注意,: 等同于选择整个轴。
my_slice = train_images[10:100, :, :]
my_slice.shape
#(90, 28, 28)
#等同于前面的例子
my_slice = train_images[10:100, 0:28, 0:28]
my_slice.shape
#(90, 28, 28)
Numpy数组上的张量切片运算
深度学习模型会将数据集拆分成小批量
#批量大小为 128。
batch = train_images[:128]
#然后是下一个批量。
batch = train_images[128:256]
#然后是第 n 个批量。
batch = train_images[128 * n:128 * (n + 1)]
#对于这种批量张量,第一个轴(0 轴)叫作批量轴(batch axis)或批量维度(batch dimension)。
MNIST 数据集的一个批量
https://zhuanlan.zhihu.com/p/144259469