生成数据集: tf.data.Dataset.from_tensor_slices(tensor变量)

创建一个数据集,其元素是给定张量的切片

生成迭代器: next(iter())

next() 返回迭代器的下一个项目,iter()获取可迭代对象的迭代器

# 返回2项数据,图像x_test,目标y_test
db = tf.data.Dataset.from_tensor_slices((x_test,y_test))
# 迭代器得到的第0个元素是图像,第1个元素是目标
next(iter(db))[0].shape  # TensorShape([32, 32, 3])
next(iter(db))[1].shape  # TensorShape([])

重新洗牌: .shuffle(buffer_size)

将序列的所有元素随机排序,不打散x和y之间的相互对应关系。维持一个buffer_size大小的缓存,每次都会随机在这个缓存区抽取一定数量的数据

调用函数: .map(func)

将func函数作用于dataset中的每一个元素

def preprocess(x,y):x = tf.cast(x, dtype=tf.float32)/255y = tf.cast(y, dtype=tf.int32)y = tf.one_hot(y,depth=10)return(x,y)
# 对Dataset中的数据进行函数所指定的预处理操作
db2 = db.map(preprocess)
# 生成迭代器
res = next(iter(db2))
# 查看数据
print(res[0].shape,res[1])

生成对列: .batch(batch_size)

tensor队列生成器,作用是按照给定的tensor顺序,把batch_size个tensor推送到文件队列,作为训练一个batch的数据,等待tensor出队执行计算

#(5).batch 一次读取读取n张图片
db3 = db2.batch(32) # 每次读取32张图片
res = next(iter(db3)) # 生成迭代器,每次取出32张
print(res[0].shape,res[1].shape) #res[0]代表图像数据,res[1]代表目标
# (32, 32, 32, 3) (32, 10)

重复迭代: .repeat(count)

将数据重复count次,相当于我们训练时的epoch

db = tf.data.Dataset.from_tensor_slices((x_test,y_test))
db = db.repeat(2) # 迭代两次
db = db.repeat() # 永远不会退出

实例展示

只需要对训练数据y进行one-hot编码,因为训练集的y要和网络输出结果求损失。网络输出层得到的是每张图片属于每个分类的概率,是一个二维tensor,因此训练集的y也需要是一个二维tensor,才能做比较。而在测试过程中。预测出的结果是一个值,该图片属于哪个,真实值y_test也是一个值,只需要比较两个值是不是相同即可,不需要one-hot编码。

#(1)加载数据集,(x,y)存放训练数据,(x_test,y_test)存放测试数据
(x,y),(x_test,y_test) = datasets.fashion_mnist.load_data()
# 查看数据集信息
print('x-min:',x.min(),' x-max:',x.max(),' x-mean',x.mean())
print('x-shape:',x.shape,'\ny-shape:',y.shape)
print('x_test-shape:',x_test.shape,'\ny_test-shape:',y_test.shape)
print('y[:4]:',y[:4])  # 查看前4个y值#(2)定义预处理函数
y = tf.one_hot(y,depth=10)  # one-hot编码,转换成长度为10的向量,对应索引的值变为1def processing(x,y):x = tf.cast(x,tf.float32)/255.0  # x数据改变数据类型,并归一化y = tf.cast(y,tf.int32)  # 对目标y改变数据类型return(x,y)#(3)生成训练集的Dataset
ds = tf.data.Dataset.from_tensor_slices((x,y))
# 对训练数据预处理
ds = ds.map(processing)
# 重新洗牌,每次迭代读取100张图片
ds = ds.shuffle(1000).batch(100)#(4)生成测试集的Dataset
ds_tes = tf.data.Dataset.from_tensor_slices((x_test,y_test))
# 测试数据预处理
ds_tes = ds_tes.map(processing)
# 洗牌、确定batch
ds_tes = ds_tes.shuffle(1000).batch(100)

2. 前向传播

在上一节中我们完成了对训练数据的前向传播操作,接下来加入测试数据从第(9)步开始。

上一节内容:【深度学习】(1) 前向传播,附python完整代码

# 前向传播
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets # 数据集工具
import os  # 设置一下输出框打印的内容
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # '2'输出栏只打印error信息,其他乱七八糟的信息不打印#(1)获取mnist数据集
(x,y),(x_test,y_test) = datasets.mnist.load_data() #(2)转换成tensor类型,x数据类型一般为float32,y存放的是图片属于哪种具体类型,属于整型
x = tf.convert_to_tensor(x,dtype=tf.float32)/255.0
y = tf.convert_to_tensor(y,dtype=tf.int32)x_test = tf.convert_to_tensor(x_test,dtype=tf.float32)/255.0
y_test = tf.convert_to_tensor(y_test,dtype=tf.int32)#(3)查看数据内容
print('shape:',x.shape,y.shape,'\ndtype:',x.dtype,y.dtype)  #查看shape和数据类型
print('x的最小值:',tf.reduce_min(x),'\nx的最大值:',tf.reduce_max(x))  #查看x的数据范围
print('y的最小值:',tf.reduce_min(y),'\ny的最大值:',tf.reduce_max(y))  #查看y的数据范围#(4)预处理
y = tf.one_hot(y,depth=10) # 对训练数据的目标集的数值编码,变为长度为10的向量,对应索引的值变为1
lr = 1e-3 # 指定学习率#(5)指定一个选取数据的batch,一次取128个数据
train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128)
test_db = tf.data.Dataset.from_tensor_slices((x_test,y_test)).batch(128)#(6)构建网络
# 构建网络,自定义中间层的神经元个数
# [b,784] => [b,256] => [b,128] => [b,10]# 第一个连接层的权重和偏置,都变成tf.Variable类型,这样tf.GradientTape才能记录梯度信息
w1 = tf.Variable(tf.random.truncated_normal([784,256], stddev=0.1)) # 截断正态分布,标准差调小一点防止梯度爆炸
b1 = tf.Variable(tf.zeros([256])) #维度为[dim_out]
# 第二个连接层的权重和偏置
w2 = tf.Variable(tf.random.truncated_normal([256,128], stddev=0.1)) # 截断正态分布,维度为[dim_in, dim_out]
b2 = tf.Variable(tf.zeros([128])) #维度为[dim_out]
# 第三个连接层的权重和偏置
w3 = tf.Variable(tf.random.truncated_normal([128,10], stddev=0.1)) # 截断正态分布,维度为[dim_in, dim_out]
b3 = tf.Variable(tf.zeros([10])) #维度为[dim_out]#(7)前向传播运算
for i in range(50):  #对整个数据集迭代10次# 对数据集的所有batch迭代一次# x为输入的特征项,shape为[128,28,28],y为分类结果,shape为[128]for step,(x,y) in enumerate(train_db): # 返回下标和对应的值# 这里的x的shape为[b,28*28],从[b,w,h]变成[b,w*h]x = tf.reshape(x,[-1,28*28]) #对输入特征项的维度变换,-1会自动计算bwith tf.GradientTape() as tape: # 自动求导计算梯度,只会跟踪tf.Variable类型数据# ==1== 从输入层到隐含层1的计算方法为:h1 = w1 @ x1 + b1   # [b,784] @ [784,256] + [b,256] = [b,256]h1 = x @ w1 + b1  # 相加时会自动广播,改变b的shape,自动进行tf.broadcast_to(b1,[x.shape[0],256])# 激活函数,relu函数h1 = tf.nn.relu(h1)# ==2== 从隐含层1到隐含层2,[b,256] @ [256,128] + [b,128] = [b,128]h2 = h1 @ w2 + b2h2 = tf.nn.relu(h2)# ==3== 从隐含层2到输出层,[b,128] @ [128,10] + [b,10] = [b,10]out = h2 @ w3 + b3 # shape为[b,10]#(8)计算误差,输出值out的shape为[b,10],onehot编码后真实值y的shape为[b,10]# 计算均方差 mse = mean(sum((y-out)^2)loss_square = tf.square(y-out)  # shape为[b,10]loss = tf.reduce_mean(loss_square) # 得到一个标量# 梯度计算grads = tape.gradient(loss,[w1,b1,w2,b2,w3,b3])# 权重更新,lr为学习率,梯度每次下降多少# 注意:下面的方法,运算返回值是tf.tensor类型,在下一次运算会出现错误# w1 = w1 - lr * grads[0] # 返回的w1在grad的第0个元素# 因此需要原地更新函数,保证更新后的数据类型不变tf.Variablew1.assign_sub(lr * grads[0])b1.assign_sub(lr * grads[1])    w2.assign_sub(lr * grads[2])  b2.assign_sub(lr * grads[3]) w3.assign_sub(lr * grads[4])    b3.assign_sub(lr * grads[5]) if step % 100 == 0: #每100次显示一次数据print(f"第{step+1}次迭代,loss为{np.float(loss)}") #loss是tensor变量# loss为nan,出现梯度爆炸的情况,初始化权重的时候变小一点#(9)网络测试# total_correct统计预测对了的个数,total_num统计参与测试的个数total_correct, total_num = 0, 0# 对网络测试,test必须要使用当前阶段的权重w和偏置b,测试当前阶段的计算精度for step,(x,y) in enumerate(test_db):x = tf.reshape(x,[-1,28*28])# 对测试数据进行前向传播# 输入层[b,784] => [b,256] => [b,128] => 输出层[b,10]h1 = x @ w1 + b1 # 输入特征和第一层权重做内积,结果加上偏置h1 = tf.nn.relu(h1) # 计算后的结果放入激活函数中计算,得到下一层的输入# 隐含层1=>隐含层2h2 = tf.nn.relu(h1 @ w2 + b2)  # [b,256] => [b,128]# 隐含层2=>输出层out = h2 @ w3 + b3  # [b,128] => 输出层[b,10]#(10)输出概率计算# 计算概率,out:shape为[b,10],属于实数;prob:shape为[b,10],属于[0,1]之间# 使用softmax()函数,使实数out映射到[0,1]的范围prob = tf.nn.softmax(out,axis=1) # out是二维的,在第1个轴上映射,即把某张图片属于某个类的值变成概率# 概率最大的值所在的位置索引是预测结果,即属于第几个分类predict = tf.argmax(prob, axis=1,output_type=tf.int32) # 每张图片的概率最大值所在位置,shape[b,10],10所在的维度# 测试集的y不需要转换成one-hot,真实值y是一个数值,predict也是一个数值,两两相比较correct = tf.equal(predict, y) # 比较,返回布尔类型,相同为True,不同为Falsecorrect = tf.cast(correct,dtype=tf.int32) # 将布尔类型转换为int32类型correct = tf.reduce_sum(correct) # 每次取出的batch中,有多少张图片是预测对的# 1代表预测对了,0代表预测错了total_correct += int(correct)  # 统计对的个数,correct是tensor类型total_num += x.shape[0]  # 统计一共有多少组参与测试,x.shape=[128,28*28],x.shape[0]有128张图片# 数据集整体完成一次迭代后accuracy = total_correct / total_num # 计算每一轮循环的准确率print(f'accuracy={accuracy}')

迭代50轮,结果如下。优化方法,在下一节讨论。

第50个循环
第1次迭代,loss为0.04710124433040619
第101次迭代,loss为0.05284833908081055
第201次迭代,loss为0.050228558480739594
第301次迭代,loss为0.052753616124391556
第401次迭代,loss为0.05572255700826645
accuracy=0.7847

【深度学习】(2) 数据加载,前向传播2,附python完整代码相关推荐

  1. 【深度学习】(1) 前向传播,附python完整代码

    各位同学大家好,今天和大家分享一下TensorFlow2.0深度学习中前向传播的推导过程,使用系统自带的mnist数据集. 1. 数据获取 首先,我们导入需要用到的库文件和数据集.导入的x和y数据是数 ...

  2. 【深度学习】Keras加载权重更新模型训练的教程(MobileNet)

    [深度学习]Keras加载权重更新模型训练的教程(MobileNet) 文章目录 1 重新训练 2 keras常用模块的简单介绍 3 使用预训练模型提取特征(口罩检测) 4 总结 1 重新训练 重新建 ...

  3. Datawhale7月组队学习task1数据加载及探索性数据分析

    Datawhale7月task1数据加载及探索性数据分析 ​ 有幸了解到了Datawhale这样一个开源组织,欣然报名了2021年7月的组队学习的动手学数据分析系列课程 ​ 本系列目标:完成kaggl ...

  4. 【深度学习】(5) 简单网络,案例:服装图片分类,附python完整代码

    1. 数据获取 使用系统内部的服装数据集构建神经网络.首先导入需要的库文件,x和y中保存训练集的图像和目标.x_test和y_test中保存测试集需要的图像和目标.(x, y)及(x_test, y_ ...

  5. 深度学习之前馈神经网络(前向传播和误差反向传播)

    转自:https://www.cnblogs.com/Luv-GEM/p/10694471.html 这篇文章主要整理三部分内容,一是常见的三种神经网络结构:前馈神经网络.反馈神经网络和图网络:二是整 ...

  6. 深度学习:神经网络中的前向传播和反向传播算法推导

    1. 神经网络 这是一个常见的神经网络的图: 这是一个常见的三层神经网络的基本构成,Layer L1是输入层,Layer L2是隐含层,Layer L3是隐含层,当我们输入x1,x2,x3等数据时,通 ...

  7. python实现胶囊网络_深度学习精要之CapsuleNets理论与实践(附Python代码)

    摘要: 本文对胶囊网络进行了非技术性的简要概括,分析了其两个重要属性,之后针对MNIST手写体数据集上验证多层感知机.卷积神经网络以及胶囊网络的性能. 神经网络于上世纪50年代提出,直到最近十年里才得 ...

  8. 【深度学习】(7) 交叉验证、正则化,自定义网络案例:图片分类,附python完整代码

    各位同学好,今天和大家分享一下TensorFlow2.0深度学习中的交叉验证法和正则化方法,最后展示一下自定义网络的小案例. 1. 交叉验证 交叉验证主要防止模型过于复杂而引起的过拟合,找到使模型泛化 ...

  9. 400页《TensorFlow 2.0 深度学习算法实战》中文版教材免费下载(附随书代码+pdf)...

    Tensorflow自谷歌提出以来就成为最受欢迎的深度学习框架之一,到目前为止也已经被下载超过 4000 万次.其中TensorFlow2.0更是修复之前非常多的不人性的特性,备大家欢迎. 今天给大家 ...

最新文章

  1. 百度语音合成 js html,Node.js结合百度TTS接口实现文字转语音功能
  2. SQL Server 数据库状态选项
  3. 图解Linux的Socket
  4. vue之slot用法
  5. 图论--拓扑排序--模板
  6. 安卓JAVA调用lua_android中java与lua的相互调用
  7. magento 添加退出链接 Adding a Logout Link to Magento
  8. 批处理不同目录下的bat调用
  9. java 单例基类_PHP基于单例模式实现的数据库操作基类
  10. matlab虚拟现实之V-Realm Builder2中viewpoint节点的使用
  11. cc ai条码插件_科脉神秘黑科技产品横空出世,AI能为生鲜称重带来哪些变革?
  12. 豆瓣电影、纪录片、书籍......下载神器
  13. 深度IP转换器高匿名8级加密企业级专用IP软件
  14. 凝胶渗透色谱的基本概念(二)
  15. NIOS ii 实战篇 --- 按键控制LED
  16. 量化投资python_量化投资与python
  17. java判断线与矩形相交_判断任意多边形与矩形的相交(线段与矩形相交或线段与线段相交)...
  18. ping 命令的实现
  19. MySQL——超详细数据库触发器教程
  20. Email邮件发送设置 工具开发整理(网易邮箱、Mailgun为例) 上篇

热门文章

  1. svn 第一次使用注意事项
  2. Vue.js 源码目录设计(二)
  3. 第二阶段第八次spring会议
  4. Beta阶段总结博客(麻瓜制造者)
  5. 3种常见的linux版本,查看linux版本的三种常用方法
  6. PyTorch 笔记(04)— Tensor 属性方法(获取元素个数numel/neleme、查看形状size()/shape、增减维度squeeze()/unsqueeze()、resize形状)
  7. 从面试官角度观察到的程序员工资瓶颈,同时给出突破瓶颈的建议
  8. hadoop2.4.1集群搭建
  9. Java技术——Iterator和Enumeration的不同
  10. 齐鲁工业大学计算机读研,齐鲁工业大学考研难吗