前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于深度学习系列笔记四(张量、批量、Dense)

关于深度学习系列笔记四(张量、批量、Dense)

作者头像
python与大数据分析
发布2022-03-11 13:31:23
7140
发布2022-03-11 13:31:23
举报
文章被收录于专栏:python与大数据分析

关于张量、张量运算、批量、梯度优化、随机梯度下降这几个概念和Dense的一些参数,简单而又难以理解的几个名词,花了几天时间才看了个七七八八,尤其是Dense的输入输出参数、权重和偏置向量是如何发挥作用的。

代码示例

代码语言:javascript
复制
import numpy as np

def printshape(x):
    #print('数据值=',x)
    print('数据形状=',x.shape)
    print('数据张量=',x.ndim)
    print('数据类型=',x.dtype)
x = np.array(12)
printshape(x)
#标量即0D张量  数据形状= ()
x = np.array([12, 3, 6, 14, 7])
printshape(x)
#向量即1D张量  数据形状= (5,)
x = np.array([[5, 78, 2, 34, 0],
              [6, 79, 3, 35, 1],
              [7, 80, 4, 36, 2]])
printshape(x)
#向量即2D张量  数据形状= (3, 5)
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.0]]])
printshape(x)
#向量即3D张量  数据形状= (3, 3, 5)

#张量是由以下三个关键属性来定义的。
#‰ 轴的个数(阶):例如,3D 张量有 3 个轴,矩阵有 2 个轴。这在 Numpy 等 Python 库中也叫张量的ndim。
#‰ 形状:这是一个整数元组,表示张量沿每个轴的维度大小(元素个数)。例如,前面矩阵示例的形状为(3, 5),3D 张量示例的形状为(3, 3, 5)。向量的形状只包含一个元素,比如(5,),而标量的形状为空,即()。
#‰ 数据类型(在 Python 库中通常叫作 dtype):这是张量中所包含数据的类型,例如,张量的类型可以是float32、uint8、float64 等。

#此段代码改写来自于Keras->datasets->mnist.py
#为了确保快速加载数据集,建议下载后从本地直接加载
def load_data(path='mnist.npz'):
    # 下载MNIST数据集 https://s3.amazonaws.com/img-datasets/mnist.npz
    # 通过本地目录加载MNIST数据集
    # 返回Numpy数组Tuple `(x_train, y_train), (x_test, y_test)`.
    path = 'D:/Python36/Coding/PycharmProjects/ttt/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_images 和train_labels 组成了训练集(training set),模型将从这些数据中进行学习。
#然后在测试集(test set,即test_images 和test_labels)上对模型进行测试。
(train_images, train_labels), (test_images, test_labels) = load_data()
printshape(train_images) #数据形状= (60000, 28, 28) 数据张量= 3 数据类型= uint8
printshape(test_images)  #数据形状= (10000, 28, 28) 数据张量= 3 数据类型= uint8
printshape(train_labels) #数据形状= (60000,) 数据张量= 1 数据类型= uint8
printshape(test_labels)  #数据形状= (10000,) 数据张量= 1 数据类型= uint8
import matplotlib.pyplot as plt
#通过matplotlib把数组还原会图片
#张量操作
digit = train_images[4]
printshape(digit)
my_slice = train_images[4:5]
printshape(my_slice)
my_slice = train_images[4:5, :, :]
printshape(my_slice)
my_slice = train_images[4:5, 0:28, 0:28]
printshape(my_slice)
my_slice = train_images[:, 14:, 14:]
printshape(my_slice)
my_slice = train_images[:, 7:-7, 7:-7]
printshape(my_slice)
#批量操作
#深度学习中所有数据张量的第一个轴(0 轴,因为索引从0 开始)都是样本轴(samples axis,有时也叫样本维度)
#深度学习模型不会同时处理整个数据集,而是将数据拆分成小批量。
# 具体来看,下面是MNIST 数据集的一个批量,批量大小为128。然后是下一个批量。
batch = train_images[:128]
batch = train_images[128:256]

# 向量数据:2D 张量,形状为 (samples, features)。
#   其中第一个轴是样本轴,第二个轴是特征轴
#   人口统计数据集,其中包括每个人的年龄、邮编和收入。每个人可以表示为包含 3 个值的向量,而整个数据集包含100 000 个人,因此可以存储在形状为(100000, 3) 的2D张量中。
#   文本文档数据集,我们将每个文档表示为每个单词在其中出现的次数,每个文档可以被编码为包含20 000 个值的向量
# 时间序列数据或序列数据:3D 张量,形状为 (samples, timesteps, features)。
#   股票价格数据集。每一分钟,我们将股票的当前价格、前一分钟的最高价格和前一分钟的最低价格保存下来。
#     因此每分钟被编码为一个3D 向量,整个交易日被编码为一个形状为(390, 3) 的2D 张量(一个交易日有390 分钟),
#     而250 天的数据则可以保存在一个形状为(250, 390, 3) 的3D 张量中。
#   推文数据集。我们将每条推文编码为 280 个字符组成的序列,而每个字符又来自于 128个字符组成的字母表。
#     在这种情况下,每个字符可以被编码为大小为128 的二进制向量,那么每条推文可以被编码为一个形状为(280, 128) 的2D 张量,
#     而包含100 万条推文的数据集则可以存储在一个形状为(1000000, 280, 128) 的张量中
# 图像:4D张量,形状为(samples, height, width, channels)或(samples, channels,height, width)。
#   图像通常具有三个维度:高度、宽度和颜色深度,灰度图像只有一个颜色通道
#     如果图像大小为256×256,那么128 张灰度图像组成的批量可以保存在一个形状为(128, 256, 256, 1) 的张量中,
#     而128 张彩色图像组成的批量则可以保存在一个形状为(128, 256, 256, 3) 的张量中。
# 视频:5D张量,形状为(samples, frames, height, width, channels)或(samples,frames, channels, height, width)。
#   视频可以看作一系列帧,每一帧都是一张彩色图像。
#     由于每一帧都可以保存在一个形状为(height, width, color_depth) 的3D 张量中,
#     因此一系列帧可以保存在一个形状为(frames, height, width,color_depth) 的4D 张量中,
#     而不同视频组成的批量则可以保存在一个5D 张量中,其形状为(samples, frames, height, width, color_depth)。

from keras.models import Input, Model, load_model
import keras
keras.layers.Dense(512, activation='relu', input_shape=(28 * 28,))
'''
keras.layers.core.Dense(
units,                               #代表该层的输出维度
activation=None,                     #激活函数.但是默认 liner
use_bias=True,                       #是否使用b
kernel_initializer='glorot_uniform', #初始化w权重,参见keras/initializers.py
bias_initializer='zeros',            #初始化b权重
kernel_regularizer=None,             #施加在权重w上的正则项,参见keras/regularizer.py
bias_regularizer=None,               #施加在偏置向量b上的正则项
activity_regularizer=None,           #施加在输出上的正则项
kernel_constraint=None,              #施加在权重w上的约束项
bias_constraint=None                 #施加在偏置b上的约束项
)
'''
# 所实现的运算是
#   output = activation(dot(input, kernel)+bias) 两者等同
#   output = activation(dot(W, input) + b)       两者等同
#   输入张量和张量W之间的点积运算(dot),kernel_initializer='glorot_uniform',标识初始化W权重
#   得到的2D 张量与向量bias 之间的加法运算(+),bias_initializer='zeros',标识初始化bias权重
#   最后的activation运算。
# kernel(等同于W) 是由网络层创建的权值矩阵,以及 bias(等同于b) 是其创建的偏置向量
# units=512 就是设置这一层的神经元的数量,即512个输出
# activation='relu'就是设置激活函数为relu
# 搭建第一层神经网络层的时候一定要添加input_shape

# 训练循环(training loop)具体过程。必要时一直重复这些步骤。
#(1) 抽取训练样本x 和对应目标y 组成的数据批量。
#(2) 在x 上运行网络[这一步叫作前向传播(forward pass)],得到预测值y_pred。
#(3) 计算网络在这批数据上的损失,用于衡量y_pred 和y 之间的距离。
#(4) 更新网络的所有权重,使网络在这批数据上的损失略微下降。

#梯度(gradient)是张量运算的导数。它是导数这一概念向多元函数导数的推广。多元函数是以张量作为输入的函数。
# 随机梯度下降,给定一个可微函数,理论上可以用解析法找到它的最小值:
#   函数的最小值是导数为0 的点,因此你只需找到所有导数为0 的点,然后计算函数在其中哪个点具有最小值。
#   将这一方法应用于神经网络,就是用解析法求出最小损失函数对应的所有权重值。
#   基于当前在随机数据批量上的损失,一点一点地对参数进行调节。
#   由于处理的是一个可微函数,你可以计算出它的梯度,从而有效地实现第四步。
#   沿着梯度的反方向更新权重,损失每次都会变小一点。
#   (1) 抽取训练样本x 和对应目标y 组成的数据批量。
#   (2) 在x 上运行网络,得到预测值y_pred。
#   (3) 计算网络在这批数据上的损失,用于衡量y_pred 和y 之间的距离。
#   (4) 计算损失相对于网络参数的梯度[一次反向传播(backward pass)]。
#   (5) 将参数沿着梯度的反方向移动一点,比如W -= step * gradient,从而使这批数据上的损失减小一点。
#小批量随机梯度下降(mini-batch stochastic gradient descent,又称为小批量SGD)。
# 术语随机(stochastic)是指每批数据都是随机抽取的(stochastic 是random在科学上的同义词a)
# 小批量SGD 算法的一个变体是每次迭代时只抽取一个样本和目标,而不是抽取一批数据。这叫作真SGD(有别于小批量SGD)。
# 还有另一种极端,每一次迭代都在所有数据上运行,这叫作批量SGD。
# SGD 还有多种变体,其区别在于计算下一次权重更新时还要考虑上一次权重更新,而不是仅仅考虑当前梯度值,比如带动量的SGD、Adagrad、RMSProp 等变体。
# 这些变体被称为优化方法(optimization method)或优化器(optimizer)。
# 其中动量的概念尤其值得关注,它在许多变体中都有应用。动量解决了SGD 的两个问题:收敛速度和局部极小点。
#链式求导:反向传播算法
#  根据微积分的知识,这种函数链可以利用下面这个恒等式进行求导,它称为链式法则(chainrule):(f(g(x)))' = f'(g(x)) * g'(x)。
#  将链式法则应用于神经网络梯度值的计算,得到的算法叫作反向传播(backpropagation,有时也叫反式微分,reverse-mode differentiation)。
#  反向传播从最终损失值开始,从最顶层反向作用至最底层,利用链式法则计算每个参数对损失值的贡献大小。

#学习是指找到一组模型参数,使得在给定的训练数据样本和对应目标值上的损失函数最小化。
#学习的过程:随机选取包含数据样本及其目标值的批量,并计算批量损失相对于网络参数的梯度。随后将网络参数沿着梯度的反方向稍稍移动(移动距离由学习率指定)。
#整个学习过程之所以能够实现,是因为神经网络是一系列可微分的张量运算,因此可以利用求导的链式法则来得到梯度函数,这个函数将当前参数和当前数据批量映射为一个梯度值。
#损失是在训练过程中需要最小化的量,因此,它应该能够衡量当前任务是否已成功解决。
#优化器是使用损失梯度更新参数的具体方式,比如 RMSProp 优化器、带动量的随机梯度下降(SGD)等。



#Display an image, i.e. data on a 2D regular raster.
#X : array-like or PIL image
#The image data. Supported array shapes are:
#(M, N): an image with scalar data. The data is visualized using a colormap.
#(M, N, 3): an image with RGB values (float or uint8).
#(M, N, 4): an image with RGBA values (float or uint8), i.e. including transparency.
#The first two dimensions (M, N) define the rows and columns of the image.
#plt.cm.binary(二值图)/plt.cm.gray(灰度图)/plt.cm.autumn(红-橙-黄)/plt.cm.hot(黑-红-黄-白)/plt.cm.viridis(蓝-绿-黄)
plt.imshow(digit, cmap=plt.cm.binary)
plt.show()
plt.imshow(digit, cmap=plt.cm.gray)
plt.show()
plt.imshow(digit, cmap=plt.cm.autumn)
plt.show()
plt.imshow(digit, cmap=plt.cm.hot)
plt.show()
plt.imshow(digit, cmap=plt.cm.viridis)
plt.show()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python与大数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 代码示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档