《TensorFlow2深度学习》学习笔记(二)手动搭建并测试简单神经网络(附mnist.npz下载方式)
本实验使用了mnist.npz数据集,可以使用在线方式导入,但是我在下载过程中老是因为网络原因被打断,因此使用离线方式导入,离线包已传至github方便大家下载:
https://github.com/guangfuhao/Deeplearning/blob/master/mnist.npz (mnist.npz下载)
下面是全部代码:
#1.Import the neccessary libraries needed
import numpy as np
import tensorflow as tf
import matplotlib
from matplotlib import pyplot as plt ######################################################################## #2.Set default parameters for plots
matplotlib.rcParams['font.size'] = 20
matplotlib.rcParams['figure.titlesize'] = 20
matplotlib.rcParams['figure.figsize'] = [9, 7]
matplotlib.rcParams['font.family'] = ['STKaiTi']
matplotlib.rcParams['axes.unicode_minus']=False ########################################################################
#3.Initialize Parameters #Initialize learning rate
lr = 1e-3
#Initialize loss array
losses = []
#Initialize the weights layers and the bias layers
w1=tf.Variable(tf.random.truncated_normal([784,256],stddev=0.1))
b1=tf.Variable(tf.zeros([256]))
w2=tf.Variable(tf.random.truncated_normal([256,128],stddev=0.1))
b2=tf.Variable(tf.zeros([128]))
w3=tf.Variable(tf.random.truncated_normal([128,10],stddev=0.1))
b3=tf.Variable(tf.zeros([10])) ######################################################################## #4.Import the minist dataset by numpy offline
def load_mnist():
#define the directory where mnist.npz is(Please watch the '\'!)
path = r'F:\learning\machineLearning\forward_progression\mnist.npz'
f = np.load(path)
x_train, y_train = f['x_train'],f['y_train']
x_test, y_test = f['x_test'],f['y_test']
f.close()
return (x_train, y_train), (x_test, y_test)
(train_image,train_label),_ = load_mnist()
x = tf.convert_to_tensor(train_image, dtype=tf.float32) / 255.
y = tf.convert_to_tensor(train_label, dtype=tf.int32)
#Reshape x from [60k, 28, 28] to [60k, 28*28]
x=tf.reshape(x,[-1,28*28]) ######################################################################## #5.Combine x and y as a tuple and batch them
train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128)
'''
#Encapsulate train_db as an iterator object
train_iter = iter(train_db)
sample = next(train_iter)
''' ######################################################################## #6.Iterate database for 20 times
for epoch in range(20):
#For every batch:x:[128, 28*28],y: [128]
for step, (x, y) in enumerate(train_db):
with tf.GradientTape() as tape: # tf.Variable
# x: [b, 28*28]
# h1 = x@w1 + b1
# [b, 784]@[784, 256] + [256] => [b, 256] + [256] => [b, 256] + [b, 256]
h1 = x@w1 + tf.broadcast_to(b1, [x.shape[0], 256])
h1 = tf.nn.relu(h1)
# [b, 256] => [b, 128]
h2 = h1@w2 + b2
h2 = tf.nn.relu(h2)
# [b, 128] => [b, 10]
out = h2@w3 + b3 # y: [b] => [b, 10]
y_onehot = tf.one_hot(y, depth=10) # compute loss
# mse = mean(sum(y-out)^2)
# [b, 10]
loss = tf.square(y_onehot - out)
# mean: scalar
loss = tf.reduce_mean(loss) # compute gradients
grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
#Update the weights and the bias
w1.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:
print(epoch, step, 'loss:', float(loss)) losses.append(float(loss)) ######################################################################## #7.Show the change of losses via matplotlib
plt.figure()
plt.plot(losses, color='C0', marker='s', label='训练')
plt.xlabel('Epoch')
plt.legend()
plt.ylabel('MSE')
#Save figure as '.svg' file
#plt.savefig('forward.svg')
plt.show()
第一部分没什么好讲的,导入了numpy,tensorflow,matplot和pyplot库
import numpy as np
import tensorflow as tf
import matplotlib
from matplotlib import pyplot as plt
第二部分设置了matplot画图的一些参数
pylot使用rc配置文件来自定义图形的各种默认属性,称之为rc配置或rc参数。通过rc参数可以修改默认的属性,包括窗体大小、每英寸的点数、线条宽度、颜色、样式、坐标轴、坐标和网络属性、文本、字体等
font.size为字体大小,figure.titlesize为标题大小,figure.figsize为图像显示大小,font.family设置字体为STKaiTi显示中文,axes.unicode_minus设置正常显示字符
matplotlib.rcParams['font.size'] = 20
matplotlib.rcParams['figure.titlesize'] = 20
matplotlib.rcParams['figure.figsize'] = [9, 7]
matplotlib.rcParams['font.family'] = ['STKaiTi']
matplotlib.rcParams['axes.unicode_minus']=False
第三部分初始化一些参数,lr为学习率(我将lr调整为1e-2时最终的losses变的更小了,但是目前并不知道这个值会对网络的最终表现产生什么样的影响),就是控制参数在每次梯度下降中下降的速率,losses用来存储每次epoch结束时的loss,还用截断正态分布(在tf.truncated_normal中如果x的取值在区间(μ-2σ,μ+2σ)之外则重新进行选择。这样保证了生成的值都在均值附近)初始化了三层权重层和用0初始化了偏置层
#Initialize learning rate
lr = 1e-3
#Initialize loss array
losses = []
#Initialize the weights layers and the bias layers
w1=tf.Variable(tf.random.truncated_normal([784,256],stddev=0.1))
b1=tf.Variable(tf.zeros([256]))
w2=tf.Variable(tf.random.truncated_normal([256,128],stddev=0.1))
b2=tf.Variable(tf.zeros([128]))
w3=tf.Variable(tf.random.truncated_normal([128,10],stddev=0.1))
b3=tf.Variable(tf.zeros([10]))
第四部分导入了minist数据集并对x的维度做了预处理,其中path为自己本地下载的mnist.npz的位置,注意这里是右斜杠!
def load_mnist():
#define the directory where mnist.npz is(Please watch the '\'!)
path = r'F:\learning\machineLearning\forward_progression\mnist.npz'
f = np.load(path)
x_train, y_train = f['x_train'],f['y_train']
x_test, y_test = f['x_test'],f['y_test']
f.close()
return (x_train, y_train), (x_test, y_test)
(train_image,train_label),_ = load_mnist()
x = tf.convert_to_tensor(train_image, dtype=tf.float32) / 255.
y = tf.convert_to_tensor(train_label, dtype=tf.int32)
#Reshape x from [60k, 28, 28] to [60k, 28*28]
x=tf.reshape(x,[-1,28*28])
第五部分将数据集做了batch切分,每个batch为128(这里的batch大小为什么是128存疑,我试过200和100但没发现什么区别)条数据,至于什么是Batch和Epoch,可以直接向下至文末查看
train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128)
第六部分Epoch20次,用mse计算loss,下面为mse的解释:
tf.GradientTape(梯度带)
__init__(persistent=False,watch_accessed_variables=True)
作用:创建一个新的GradientTape
参数:
persistent: 布尔值,用来指定新创建的gradient tape是否是可持续性的。默认是False,意味着只能够调用一次gradient()函数
watch_accessed_variables: 布尔值,表明这个gradien tap是不是会自动追踪任何能被训练(trainable)的变量。默认是True。要是为False的话,意味着你需要手动去指定你想追踪的那些变量
下面的前向计算过程都需要包裹在 with tf.GradientTape() as tape 上下文中,使得前向计算时能够保存计算图信息,方便反向求导运算。assign_sub()将原地(In-place)减去给定的参数值,实现参数的自我更新操作
for epoch in range(20):
#For every batch:x:[128, 28*28],y: [128]
for step, (x, y) in enumerate(train_db):
with tf.GradientTape() as tape: # tf.Variable
# x: [b, 28*28]
# h1 = x@w1 + b1
# [b, 784]@[784, 256] + [256] => [b, 256] + [256] => [b, 256] + [b, 256]
h1 = x@w1 + tf.broadcast_to(b1, [x.shape[0], 256])
h1 = tf.nn.relu(h1)
# [b, 256] => [b, 128]
h2 = h1@w2 + b2
h2 = tf.nn.relu(h2)
# [b, 128] => [b, 10]
out = h2@w3 + b3 # y: [b] => [b, 10]
y_onehot = tf.one_hot(y, depth=10) # compute loss
# mse = mean(sum(y-out)^2)
# [b, 10]
loss = tf.square(y_onehot - out)
# mean: scalar
loss = tf.reduce_mean(loss) # compute gradients
grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
#Update the weights and the bias
w1.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:
print(epoch, step, 'loss:', float(loss)) losses.append(float(loss))
第七部分将losses随训练次数的增加的变化展示出来
plt.figure()
plt.plot(losses, color='C0', marker='s', label='训练')
plt.xlabel('Epoch')
plt.legend()
plt.ylabel('MSE')
#Save figure as '.svg' file
#plt.savefig('forward.svg')
plt.show()
下图是最终的loss曲线:
Batch和Epoch通俗易懂的解释:(参考自https://blog.csdn.net/weixin_42137700/article/details/84302045)
假设您有一个包含200个样本(数据行)的数据集,并且您选择的Batch大小为5和1,000个Epoch。
这意味着数据集将分为40个Batch,每个Batch有5个样本。每批五个样品后,模型权重将更新。
这也意味着一个epoch将涉及40个Batch或40个模型更新。
有1000个Epoch,模型将暴露或传递整个数据集1,000次。在整个培训过程中,总共有40,000Batch。
《TensorFlow2深度学习》学习笔记(二)手动搭建并测试简单神经网络(附mnist.npz下载方式)的更多相关文章
- Tensorflow学习:(二)搭建神经网络
一.神经网络的实现过程 1.准备数据集,提取特征,作为输入喂给神经网络 2.搭建神经网络结构,从输入到输出 3.大量特征数据喂给 NN,迭代优化 NN 参数 4.使 ...
- vue新手入门之使用vue框架搭建用户登录注册案例,手动搭建webpack+Vue项目(附源码,图文详解,亲测有效)
前言 本篇随笔主要写了手动搭建一个webpack+Vue项目,掌握相关loader的安装与使用,包括css-loader.style-loader.vue-loader.url-loader.sass ...
- Mybatis-Plus 实战完整学习笔记(二)------环境搭建
第二章 使用实例 1.搭建测试数据库 -- 创建库 CREATE DATABASE mp; -- 使用库 USE mp; -- 创建表 CREATE TABLE tbl_employee( ...
- 深度学习入门教程UFLDL学习实验笔记二:使用向量化对MNIST数据集做稀疏自编码
今天来做UFLDL的第二个实验,向量化.我们都知道,在matlab里面基本上如果使用for循环,程序是会慢的一逼的(可以说基本就运行不下去)所以在这呢,我们需要对程序进行向量化的处理,所谓向量化就是将 ...
- Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、
1:Scala之函数式编程学习笔记: :Scala函数式编程学习: 1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法: class User { private ...
- redis学习笔记(二)——java中jedis的简单使用
redis怎么在java中使用,那就是要用到jedis了,jedis是redis的java版本的客户端实现,原本原本想上来就直接学spring整合redis的,但是一口吃个胖子,还是脚踏实地,从基础开 ...
- hibernate框架学习笔记1:搭建与测试
hibernate框架属于dao层,类似dbutils的作用,是一款ORM(对象关系映射)操作 使用hibernate框架好处是:操作数据库不需要写SQL语句,使用面向对象的方式完成 这里使用ecli ...
- 剑指offer学习读书笔记--二维数组中的查找
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都是按照从上到下递增的顺序排序.请设计一个函数,输入这样的一个二维数组和一个整数,判断数组是否含有这个整数. 1 2 8 9 2 4 9 1 ...
- U3D学习使用笔记(二)
1.在移动端www.texture使用时不能实时加载纹理,www.LoadImageIntoTexture使用没问题 2.public FaceFeature FaceFeatureData ...
随机推荐
- Redis常用运维命令
1.启动命令 按照我其他博客的按照方法,启动命令为/etc/init.d/redis_6379 start 2.查看内存统计信息 [root@bogon ~]# redis-cli > info ...
- Linux——xargs命令学习
有时候我们会遇到需要将指定命令返回结果进行处理的情况 这种情况下,可能就需要写for循环之类的脚本进行处理了(目前我只能想到这种方法) 但是想起来还有一个xargs命令,组合这个命令就比较省事了. 场 ...
- Javascript判斷function是否定義
jQuery可以用 isFunction() 來進行判斷 如果僅使用Javascript可以使用以下的方法 function isFunction(fn){ return typeof fn === ...
- Eclipse使用Working Set
当Eclipse中创建了太多的project,太多了,看的眼花缭乱,不好管理,也不想更换工作空间,Eclipse中 Java Working Set 工作集,可以将这些project分组,就像文件夹分 ...
- 【C/C++开发】C++之enum枚举量声明、定义、使用与枚举类详解与枚举类前置类型声明
众所周知,C/C++语言可以使用#define和const创建符号常量,而使用enum工具不仅能够创建符号常量,还能定义新的数据类型,但是必须按照一定的规则进行,下面我们一起看下enum的使用方法. ...
- war包部署在tomcat下,使用windows service服务方式启动tomcat服务器,在包含调用dll的模块,报dll找不到问题的解决办法
问题描述: 开发了一个需要调用dll的java web程序,在idea开发环境下运行调试没问题,可以正常运行,在tomcat/bin下,运行批处理startup.bat,启动tomcat服务器,也可以 ...
- 使用Python的turtle画小绵羊
今天学习使用turtle画图,本来想实现个3D效果,结果2D都画了半天,画圆被绕晕了 目标图片: 实现代码: # -*- coding:utf-8 -*- # __author__ :kusy # _ ...
- python 的技巧
pi = 0 n = 100 for k in range(n): pi+=1/pow(16,k)*(\ #一行不够写或不易读时用\,则多行与一行一样 4/(8*k+1)-2/(8*k+4)-\ 1/ ...
- Spring中WebMvcConfigurer用到的JDK8特性
闲来无聊,随便翻看项目,发现WebMvcConfigurerAdapter已经过时了,它的作用也不用说了,就是起到适配器的作用,让实现类不用实现所有方法,可以根据实际需要去实现需要的方法. @Depr ...
- Eclipse项目上传和下载到码云上
本文将介绍如何将本地的项目提交到开源中国的码云(版本控制器)上.改教程讲解过程比较详细,跟着做实现起来很简单.由于自己本身也是一个新手,所以不做过多的解释,只是单纯的描述了该如何去做,大家一起学习共同 ...