作者:欧新宇(Xinyu OU)
本文档所展示的测试结果,均运行于:Intel Core i7-7700K CPU 4.2GHz, nVidia GeForce GTX 1080 Ti
建设中...
在设计卷积神经网络的时候,常见类包括卷积层Conv2D,池化层Pool2D,全连接层Linear。
class paddle.fluid.dygraph.Conv2D(num_channels, num_filters, filter_size, stride=1, padding=0, dilation=1, groups=None, param_attr=None, bias_attr=None, use_cudnn=True, act=None, dtype='float32')
class paddle.fluid.dygraph.Pool2D(pool_size=-1, pool_type='max', pool_stride=1, pool_padding=0, global_pooling=False, use_cudnn=True, ceil_mode=False, exclusive=True)
class paddle.fluid.dygraph.Linear(input_dim, output_dim, param_attr=None, bias_attr=None, act=None, dtype='float32')
【知识点】
import numpy as np
import paddle
import paddle.fluid as fluid # 载入基于fluid框架的paddle
from paddle.fluid.dygraph import Linear, Conv2D, Pool2D
use_cuda = False # True, False 如果设备有GPU,怎么我们可以启用GPU进行快速训练
PLACE = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
Layer | Input | Kernels_num | Kernels_size | Stride | Padding | PoolingType | Output | Parameters |
---|---|---|---|---|---|---|---|---|
Input | 1×32×32 | |||||||
Conv1 | 1×32×32 | 6 | 1×5×5 | 1 | 0 | 6×28×28 | (1×5×5+1)×6=156 | |
Pool1 | 6×28×28 | 6 | 6×2×2 | 2 | 0 | max | 6×14×14 | 0 |
Conv2 | 6×14×14 | 16 | 6×5×5 | 1 | 0 | 16×10×10 | (6×5×5+1)×16=2416 | |
Pool2 | 16×10×10 | 16 | 16×2×2 | 2 | 0 | max | 16×5×5 | 0 |
Conv3 | 16×5×5 | 120 | 16×5×5 | 1 | 0 | 120×1×1 | (16×5×5+1)×120=48120 | |
FC1 | (120×1×1)×1 | 84×1 | (120+1)×84=10164 | |||||
FC2 | 84×1 | 10×1 | (84+1)×10=850 | |||||
Output | 10×1 | |||||||
Total = 61706 |
# 定义卷积神经网络LeNet
class LeNet(fluid.dygraph.Layer):
name_scope = 'LeNet'
def __init__(self, num_classes=10): # 初始化LeNet类,并为LeNet增加对象self.x
super(LeNet, self).__init__()
self.conv1 = Conv2D(num_channels=1, num_filters=6, filter_size=5, stride=1, act='relu')
self.pool1 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
self.conv2 = Conv2D(num_channels=6, num_filters=16, filter_size=5, stride=1, act='relu')
self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
self.conv3 = Conv2D(num_channels=16, num_filters=120, filter_size=5, stride=1, act='relu')
#conv3层输出通道数为120
self.fc1 = Linear(input_dim=120, output_dim=84, act='relu')
# 在最后一个全连接层如果不定义激活函数act='softmax',可以直接在最后的输出层定义激活函数
self.fc2 = Linear(input_dim=84, output_dim=num_classes)
def forward(self,input): # 为MLP类增加forward方法
# print(input.shape)
x = self.conv1(input)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = self.conv3(x)
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = self.fc1(x)
y = self.fc2(x)
return y
# 使用np.random创建一个随机数组[N, C, H, W]作为输入数据
# 此处设置batch_size: N = 10
x = np.random.randn(*[10,1,32,32]).astype('float32')
with fluid.dygraph.guard(PLACE):
model = LeNet() # 将模型实例化
x = fluid.dygraph.to_variable(x) # 将临时变量转换成动态图变量
for item in model.sublayers(): # 遍历模型的所有子层
try:
x = item(x)
except:
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = item(x)
if len(item.parameters())==2:
# 查看卷积和全连接层的数据和参数的形状,
# 其中item.parameters()[0]是权重参数w,item.parameters()[1]是偏置参数b
print('{}:{}, w:{}, b:{}'.format(item.full_name(), x.shape, item.parameters()[0].shape, item.parameters()[1].shape))
else:
# 池化层没有参数
print('{}:{}'.format(item.full_name(), x.shape))
conv2d_0:[10, 6, 28, 28], w:[6, 1, 5, 5], b:[6] pool2d_0:[10, 6, 14, 14] conv2d_1:[10, 16, 10, 10], w:[16, 6, 5, 5], b:[16] pool2d_1:[10, 16, 5, 5] conv2d_2:[10, 120, 1, 1], w:[120, 16, 5, 5], b:[120] linear_0:[10, 84], w:[120, 84], b:[84] linear_1:[10, 10], w:[84, 10], b:[10]
LeNet-5的原始属于是32×32,但是由于MNIST数据集的样本为28×28,因此需要对LeNet-5进行一定的调整。此次我们暂定调整后的网络名称为MNIST。
Layer | Input | Kernels_num | Kernels_size | Stride | Padding | PoolingType | Output | Parameters |
---|---|---|---|---|---|---|---|---|
Input | 1×28×28 | 1×28×28 | ||||||
Conv1 | 1×28×28 | 6 | 1×5×5 | 1 | 0 | 6×24×24 | (1×5×5+1)×6=156 | |
Pool1 | 6×24×24 | 6 | 6×2×2 | 2 | 0 | Max | 6×12×12 | 0 |
Conv2 | 6×12×12 | 16 | 6×5×5 | 1 | 0 | 16×8×8 | (6×5×5+1)×16=2416 | |
Pool2 | 16×8×8 | 16 | 16×2×2 | 2 | 0 | Max | 16×4×4 | 0 |
Conv3 | 16×4×4 | 120 | 16×4×4 | 1 | 0 | 120×1×1 | (16×4×4+1)×120=30720 | |
FC1 | (120×1×1)×1 | 120×1 | (120+1)×64=7744 | |||||
FC2 | 120×1 | 84×1 | (84+1)×10=650 | |||||
Output | 84×1 | 10×1 | ||||||
Total = 41686 |
# 定义卷积神经网络CIFAR
class mnist(fluid.dygraph.Layer):
name_scope = 'mnist'
def __init__(self, num_classes=10): # 初始化CIFAR类,并为CIFAR增加对象self.x
super(mnist, self).__init__()
self.conv1 = Conv2D(num_channels=1, num_filters=6, filter_size=5, stride=1, act='relu')
self.pool1 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
self.conv2 = Conv2D(num_channels=6, num_filters=16, filter_size=5, stride=1, act='relu')
self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
self.conv3 = Conv2D(num_channels=16, num_filters=120, filter_size=4, stride=1, act='relu')
#conv3层输出通道数为120
self.fc1 = Linear(input_dim=120, output_dim=84, act='relu')
# 在最后一个全连接层如果不定义激活函数act='softmax',可以直接在最后的输出层定义激活函数
self.fc2 = Linear(input_dim=84, output_dim=num_classes)
def forward(self,input): # 为CNN类增加forward方法
# print(input.shape)
x = self.conv1(input)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = self.conv3(x)
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = self.fc1(x)
y = self.fc2(x)
return y
# 使用np.random创建一个随机数组[N, C, H, W]作为输入数据
# 此处设置batch_size: N = 10
x = np.random.randn(*[10,1,28,28]).astype('float32')
with fluid.dygraph.guard(PLACE):
model = mnist() # 将模型实例化
x = fluid.dygraph.to_variable(x) # 将临时变量转换成动态图变量
for item in model.sublayers(): # 遍历模型的所有子层
try:
x = item(x)
except:
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = item(x)
if len(item.parameters())==2:
# 查看卷积和全连接层的数据和参数的形状,
# 其中item.parameters()[0]是权重参数w,item.parameters()[1]是偏置参数b
print('{}:{}, w:{}, b:{}'.format(item.full_name(), x.shape, item.parameters()[0].shape, item.parameters()[1].shape))
else:
# 池化层没有参数
print('{}:{}'.format(item.full_name(), x.shape))
conv2d_0:[10, 6, 24, 24], w:[6, 1, 5, 5], b:[6] pool2d_0:[10, 6, 12, 12] conv2d_1:[10, 16, 8, 8], w:[16, 6, 5, 5], b:[16] pool2d_1:[10, 16, 4, 4] conv2d_2:[10, 120, 1, 1], w:[120, 16, 4, 4], b:[120] linear_0:[10, 84], w:[120, 84], b:[84] linear_1:[10, 10], w:[84, 10], b:[10]
Layer | Input | Kernels_num | Kernels_size | Stride | Padding | PoolingType | Output | Parameters |
---|---|---|---|---|---|---|---|---|
Input | 3×32×32 | 3×32×32 | ||||||
Conv1 | 3×32×32 | 32 | 3×5×5 | 1 | 0 | 32×28×28 | (3×5×5+1)×32=2432 | |
Pool1 | 32×28×28 | 32 | 32×2×2 | 2 | 0 | Max | 32×14×14 | 0 |
Conv2 | 32×14×14 | 32 | 32×5×5 | 1 | 0 | 32×10×10 | (32×5×5+1)×32=25632 | |
Pool2 | 32×10×10 | 32 | 32×2×2 | 2 | 0 | Avg | 32×5×5 | 0 |
Conv3 | 32×5×5 | 64 | 32×4×4 | 1 | 0 | 64×2×2 | (32×4×4+1)×64=32832 | |
Pool3 | 64×2×2 | 64 | 64×2×2 | 2 | 0 | Avg | 64×1×1 | 0 |
FC1 | (64×1×1)×1 | 64×1 | (64+1)×64=4160 | |||||
FC2 | 64×1 | 64×10 | (64+1)×10=650 | |||||
Output | 10×1 | |||||||
Total = 65706 |
# 定义卷积神经网络CIFAR
class Cifar10(fluid.dygraph.Layer):
name_scope = 'Cifar10'
def __init__(self, num_classes=10): # 初始化CIFAR类,并为CIFAR增加对象self.x
super(Cifar10, self).__init__()
self.conv1 = Conv2D(num_channels=3, num_filters=32, filter_size=5, stride=1, act='relu')
self.pool1 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
self.conv2 = Conv2D(num_channels=32, num_filters=32, filter_size=5, stride=1, act='relu')
self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='avg')
self.conv3 = Conv2D(num_channels=32, num_filters=64, filter_size=4, stride=1, act='relu')
self.pool3 = Pool2D(pool_size=2, pool_stride=2, pool_type='avg')
self.fc1 = Linear(input_dim=64, output_dim=64)
self.fc2 = Linear(input_dim=64, output_dim=num_classes)
def forward(self,input): # 为MLP类增加forward方法
x = self.conv1(input)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = self.conv3(x)
x = self.pool3(x)
print(x)
x = fluid.layers.reshape(x, [x.shape[0], -1])
print(x)
x = self.fc1(x)
y = self.fc2(x)
return y
# 使用np.random创建一个随机数组[N, C, H, W]作为输入数据
# 此处设置batch_size: N = 10
x = np.random.randn(*[10,3,32,32]).astype('float32')
with fluid.dygraph.guard(PLACE):
model = Cifar10() # 将模型实例化
x = fluid.dygraph.to_variable(x) # 将临时变量转换成动态图变量
for item in model.sublayers(): # 遍历模型的所有子层
try:
x = item(x)
except:
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = item(x)
if len(item.parameters())==2:
# 查看卷积和全连接层的数据和参数的形状,
# 其中item.parameters()[0]是权重参数w,item.parameters()[1]是偏置参数b
print('{}:{}, w:{}, b:{}'.format(item.full_name(), x.shape, item.parameters()[0].shape, item.parameters()[1].shape))
else:
# 池化层没有参数
print('{}:{}'.format(item.full_name(), x.shape))
conv2d_0:[10, 32, 28, 28], w:[32, 3, 5, 5], b:[32] pool2d_0:[10, 32, 14, 14] conv2d_1:[10, 32, 10, 10], w:[32, 32, 5, 5], b:[32] pool2d_1:[10, 32, 5, 5] conv2d_2:[10, 64, 2, 2], w:[64, 32, 4, 4], b:[64] pool2d_2:[10, 64, 1, 1] linear_0:[10, 64], w:[64, 64], b:[64] linear_1:[10, 10], w:[64, 10], b:[10]
需要注意的是,在Alexnet中实际输入的尺度会被Crop为$3×227×227$
Layer | Input | Kernels_num | Kernels_size | Stride | Padding | PoolingType | Output | Parameters |
---|---|---|---|---|---|---|---|---|
Input | 3×227×227 | |||||||
Conv1 | 3×227×227 | 96 | 3×11×11 | 4 | 0 | 96×55×55 | (3×11×11+1)×96=34944 | |
Pool1 | 96×55×55 | 96 | 96×3×3 | 2 | 0 | max | 96×27×27 | 0 |
Conv2 | 96×27×27 | 256 | 96×5×5 | 1 | 2 | 256×27×27 | (96×5×5+1)×256=614656 | |
Pool2 | 256×27×27 | 256 | 256×3×3 | 2 | 0 | max | 256×13×13 | 0 |
Conv3 | 256×13×13 | 384 | 256×3×3 | 1 | 1 | 384×13×13 | (256×3×3+1)×384=885120 | |
Conv4 | 384×13×13 | 384 | 384×3×3 | 1 | 1 | 384×13×13 | (384×3×3+1)×384=1327488 | |
Conv5 | 384×13×13 | 256 | 384×3×3 | 1 | 1 | 256×13×13 | (384×3×3+1)×256=884992 | |
Pool5 | 256×13×13 | 256 | 256×3×3 | 2 | 0 | max | 256×6×6 | 0 |
FC6 | (256×6×6)×1 | 4096×1 | (9216+1)×4096=37752832 | |||||
FC7 | 4096×1 | 4096×1 | (4096+1)×4096=16781312 | |||||
FC8 | 4096×1 | 1000×1 | (4096+1)×1000=4097000 | |||||
Output | 1000×1 | |||||||
Total = 62378344 |
其中卷积层参数:3747200,占总参数的6%。
# 定义卷积神经网络LeNet
class Alexnet(fluid.dygraph.Layer):
name_scope = 'Alexnet'
def __init__(self, num_classes=1000): # 初始化LeNet类,并为LeNet增加对象self.x
super(Alexnet, self).__init__()
self.conv1 = Conv2D(num_channels=3, num_filters=96, filter_size=11, stride=4, act='relu')
self.pool1 = Pool2D(pool_size=3, pool_stride=2, pool_type='max')
self.conv2 = Conv2D(num_channels=96, num_filters=256, filter_size=5, stride=1, padding=2, act='relu')
self.pool2 = Pool2D(pool_size=3, pool_stride=2, pool_type='max')
self.conv3 = Conv2D(num_channels=256, num_filters=384, filter_size=3, stride=1, padding=1, act='relu')
self.conv4 = Conv2D(num_channels=384, num_filters=384, filter_size=3, stride=1, padding=1, act='relu')
self.conv5 = Conv2D(num_channels=384, num_filters=256, filter_size=3, stride=1, padding=1, act='relu')
self.pool5 = Pool2D(pool_size=3, pool_stride=2, pool_type='max')
#conv3层输出通道数为120
self.fc6 = Linear(input_dim=256*6*6, output_dim=4096, act='relu')
# 在最后一个全连接层如果不定义激活函数act='softmax',可以直接在最后的输出层定义激活函数
self.fc7 = Linear(input_dim=4096, output_dim=4096)
self.fc8 = Linear(input_dim=4096, output_dim=num_classes)
def forward(self,input): # 为MLP类增加forward方法
# print(input.shape)
x = self.conv1(input)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.conv5(x)
x = self.pool5(x)
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = self.fc6(x)
x = self.fc7(x)
y = self.fc8(x)
return y
# 使用np.random创建一个随机数组[N, C, H, W]作为输入数据
# 此处设置batch_size: N = 10
x = np.random.randn(*[10,3,227,227]).astype('float32')
with fluid.dygraph.guard(PLACE):
model = Alexnet() # 将模型实例化
x = fluid.dygraph.to_variable(x) # 将临时变量转换成动态图变量
for item in model.sublayers(): # 遍历模型的所有子层
try:
x = item(x)
except:
x = fluid.layers.reshape(x, [x.shape[0], -1])
x = item(x)
if len(item.parameters())==2:
# 查看卷积和全连接层的数据和参数的形状,
# 其中item.parameters()[0]是权重参数w,item.parameters()[1]是偏置参数b
print('{}:{}, w:{}, b:{}'.format(item.full_name(), x.shape, item.parameters()[0].shape, item.parameters()[1].shape))
else:
# 池化层没有参数
print('{}:{}'.format(item.full_name(), x.shape))
conv2d_0:[10, 96, 55, 55], w:[96, 3, 11, 11], b:[96] pool2d_0:[10, 96, 27, 27] conv2d_1:[10, 256, 27, 27], w:[256, 96, 5, 5], b:[256] pool2d_1:[10, 256, 13, 13] conv2d_2:[10, 384, 13, 13], w:[384, 256, 3, 3], b:[384] conv2d_3:[10, 384, 13, 13], w:[384, 384, 3, 3], b:[384] conv2d_4:[10, 256, 13, 13], w:[256, 384, 3, 3], b:[256] pool2d_2:[10, 256, 6, 6] linear_0:[10, 4096], w:[9216, 4096], b:[4096] linear_1:[10, 4096], w:[4096, 4096], b:[4096] linear_2:[10, 1000], w:[4096, 1000], b:[1000]
直接从paddle.dataset中载入数据是比较简单的,paddle写好了所有的载入代码和预处理代码。因此,通常使用该方法进行载入,不需要再进行预处理了。
mnist数据集
train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.mnist.train(), buf_size=256), batch_size=128, drop_last=False)
test_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.mnist.test(), buf_size=256), batch_size=128, drop_last=False)
cifar数据集
train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.cifar.train10(), buf_size=512), batch_size=128, drop_last=False)
test_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.cifar.test10(), buf_size=512), batch_size=128, drop_last=False)
拿到样本后,首先需要做以下几件事:
# 生成图像列表
import os
dataset_root_path = 'D:\\WebStation\\ExpDatasets\\VehicleLicense'
data_path = os.path.join(dataset_root_path, 'trainval')
num_test = 0
num_train = 0
label = 0
label_name = {}
train_list = os.path.join(dataset_root_path, 'VehicleLicense_train.txt')
test_list = os.path.join(dataset_root_path, 'VehicleLicense_test.txt')
if(os.path.exists(train_list)):
os.remove(train_list)
if(os.path.exists(test_list)):
os.remove(test_list)
character_folders = os.listdir(data_path)
# print(character_folders)
for character_folder in character_folders:
with open(train_list, 'a') as f_train:
with open(test_list, 'a') as f_test:
label_name[str(label)] = character_folder
character_imgs = os.listdir(os.path.join(data_path,character_folder))
count = 0
for img in character_imgs:
if count%10 == 0: # 抽取大约10%的样本作为测试数据
f_test.write(os.path.join(data_path, character_folder, img) + '\t' + str(label) + '\n')
num_test += 1
else:
f_train.write(os.path.join(data_path, character_folder, img) + '\t' + str(label) + '\n')
num_train += 1
count +=1
label += 1
print('图像列表已生成,其中训练集样本{}个,测试集样本{}个。'.format(num_train, num_test))
图像列表已生成,其中训练集样本14506个,测试集样本1645个。
def preprocessing(img):
img = img.convert('L')
img = img.resize((20, 20), Image.ANTIALIAS)
img = np.array(img).astype('float32')
img = img/255.0
# print(img.shape)
return img
# 定义训练集和测试集的reader
def data_mapper(sample):
img, label = sample
img = Image.open(img)
img = preprocessing(img)
return img, label
from multiprocessing import cpu_count
def data_reader(data_list_path):
def reader():
with open(data_list_path, 'r') as f:
lines = f.readlines()
for line in lines:
img, label = line.split('\t')
yield img, int(label)
return paddle.reader.xmap_readers(data_mapper, reader, cpu_count(), 512)
# return reader
train_reader = paddle.batch(paddle.reader.shuffle(reader=data_reader(train_list), buf_size=512), batch_size=128, drop_last=False)
test_reader = paddle.batch(paddle.reader.shuffle(reader=data_reader(test_list), buf_size=512), batch_size=128, drop_last=False)
VehicleLicese数据集是从图片进行采集,因此获取到的batchdata是以文件路径
的形式存在, 因此需要进行预处理,手动将样本路径转换为$样本数组=[图像, 标签]$;而mnist和cifar直接从paddle.dataset中获取,因此获取到的batchdata是以数组的形式存在。
# 1. 导入依赖及全局参数设置
# 样本数据,数据以元组tuple类型进行保存
import numpy as np
import paddle
import matplotlib.pyplot as plt
from PIL import Image
dataset = 'cifar10' # mnist, cifar10, VehicleLicese
BUF_SIZE = 256
BATCH_SIZE = 2
# 2. 设置样本读取器
if dataset is 'mnist':
imgSize = 28
train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.mnist.train(), buf_size=BUF_SIZE), batch_size=BATCH_SIZE, drop_last=False)
test_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.mnist.test(), buf_size=BUF_SIZE), batch_size=BATCH_SIZE, drop_last=False)
elif dataset is 'cifar10':
imgSize = 32
train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.cifar.train10(), buf_size=BUF_SIZE), batch_size=BATCH_SIZE, drop_last=False)
test_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.cifar.test10(), buf_size=BUF_SIZE), batch_size=BATCH_SIZE, drop_last=False)
elif dataset is 'VehicleLicese':
imgSize = 20
train_reader = paddle.batch(paddle.reader.shuffle(reader=data_reader(train_list), buf_size=BUF_SIZE), batch_size=BATCH_SIZE, drop_last=False)
test_reader = paddle.batch(paddle.reader.shuffle(reader=data_reader(test_list), buf_size=BUF_SIZE), batch_size=BATCH_SIZE, drop_last=False)
# 3. 从训练样本读取器中获取一个批次的数据
batchdata = next(train_reader()) # 从数据提供其中获取一个数据
print('Data_reader的BatchSize为: {}'.format(len(batchdata)))
# 显示samledata的内容
# print(sampledata)
# 4. 单独显示样本中的图像和标签
sampledata = batchdata[0] # 从批数据中获取第一个样本
image, label = sampledata # 采样数据包含两个维度, 分别是[图像, 标签]
if dataset is 'cifar10':
print('{}数据集展示:'.format(dataset))
img = np.array(image).astype('float32').reshape(3,imgSize,imgSize) # 将图像转换为二维形态用于显示
img = img.transpose((1,2,0)) # paddle.dataset将原始数据进行了通道的变换,为了便于显示需要再转换回来
plt.figure(figsize=(2,2))
plt.imshow(img)
else:
print('{}数据集展示:'.format(dataset))
img = np.array(image).astype('float32').reshape(imgSize,imgSize) # 将图像转换为二维形态用于显示
plt.figure(figsize=(2,2))
plt.imshow(img)
print('图像维度为:{}'.format(image.shape)) # 显示样本的形态
print('图像标签为:{}'.format(label)) # 显示标签
Data_reader的BatchSize为: 2 cifar10数据集展示: 图像维度为:(3072,) 图像标签为:2
以batch形式进行查看,需要使用enumerate()进行枚举, 每次从总数据中取一个batch进行处理. 此处仅做简化显示,详细使用可以参考单样本查看
来显示图像.
for batch_id, data in enumerate(train_reader()):
images = np.array([x[0] for x in data], dtype='float32')
labels = np.array([x[1] for x in data], dtype='int64')
print('批样本的维度: {}'.format(len(data)))
print('样本的标签为: {}'.format(labels[0]))
print('样本的图像为: \n{}'.format(images[0]))
break
批样本的维度: 2 样本的标签为: 9 样本的图像为: [0.64705884 0.58431375 0.49411765 ... 0.20784314 0.2 0.3137255 ]