一个人可以建设网站吗,网站开发liucheng,做的时间长的网站制作公司,微信网站建设方案深度学习基本概念
人工智能是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。人工智能的目的 就是让计算机能够像人一样思考。 强人工智能#xff1a;就是要使机器学习人的理解、学习和执行任务的能力。 弱人工智能#xff1a;指用…深度学习基本概念
人工智能是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。人工智能的目的 就是让计算机能够像人一样思考。 强人工智能就是要使机器学习人的理解、学习和执行任务的能力。 弱人工智能指用于自动化特定任务的软件。机器学习的广义概念是指从已知数据中获得规律并利用规律对未知数据进行预测的方法。机器学习是一种统计学习方法机器人和计算机等机器需要使用大量数据进行学习从而提取出所需的信息。深度学习 就是一种利用深度人工神经网络来进行自动分类、预测和学习的技术。人工智能机器学习深度学习 TensorFlow
TensorFlow 是一款用于数值计算的强大的开源软件库特别适用于大规模机器学习的微调。
MNIST数据读取、建模、编译、训练、测试
import tensorflow as tf
# 载入数据
mnist tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) mnist.load_data()
x_train, x_test x_train / 255.0, x_test / 255.0
# 建模
model tf.keras.models.Sequential([tf.keras.layers.Flatten(input_shape(28, 28)), # 将输入“压平”即把多维的输入一维化只有第一层有输入数据的形状tf.keras.layers.Dense(128, activationrelu), # 该层的输出维度或神经元个数和激活函数tf.keras.layers.Dropout(0.2),tf.keras.layers.Dense(10, activationsoftmax)
])
# 编译优化器、损失和评价
model.compile(optimizeradam,losssparse_categorical_crossentropy,metrics[accuracy])
# 训练训练和验证数据不一样
model.fit(x_train, y_train, epochs5)
# 验证
model.evaluate(x_test, y_test, verbose2)
优化器 tf.optimizers SGD 随机梯度下降优化器
tf.keras.optimizers.SGD( learning_rate0.01, momentum0.0,nesterovFalse, nameSGD, **kwargs)
学习率、动量、是否使用nesterov震荡Adam优化器 tf.keras.optimizers.Adam(learning_rate0.001)
损失函数均方根误差MSEMeanSquaredError、二值交叉熵BinaryCrossentropy; metrics sparse_categorical_crossentropy多分类损失函数metrics评价函数 “accuracy” :真实值(y_)和预测值(y) 都是数值; “sparse_accuracy”:y_和y都是以独热码和概率分布表示; “sparse_categorical_accuracy”:y_是以数值形式给出y是以独热码给出数据结构 1Rank维度 2Shape每个维度数据的个数 3Data typebool、int、float、string、complex、Truncated float、Quantized int 4Variables与Constant : 变量和常数
常用函数
数据类型转换 import tensorflow as tf
import tensorflow.compat.v1 as tf1
string 12.3
n1 tf1.string_to_number(string, out_typeNone, nameNone) #字符串转为数字
x 12.3
d1 tf1.to_double(x, nameToDouble)#转为64位浮点类型float64
f1 tf1.to_float(x, nameToFloat) #转为32位浮点类型float32
i1 tf1.to_int32(x, nameToInt32) #转为32位整型int32
i2 tf1.to_int64(x, nameToInt64) #转为64位整型–int64
a [1.8, 2.2]
i3 tf.cast(a, tf.int32) # 将a或者a.values转换为dtype形状操作
t [ [[1, 1, 1], [2, 2, 2]] , [[3, 3, 3], [4, 4, 4]] ]
tf.shape(t) #返回维度中数据的个数
tf.size(t) #返回数据的元素数量
tf.rank(t) #返回数据维度
t [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(tf.shape(t))
t2 tf.reshape(t, [3, 3]) #改变tensor的形状
print(tf.shape(t2))
t3 tf.reshape(t, [3, -1])
print(t3)其它操作函数
t [2,3] #插⼊维度1进⼊⼀个tensor中
t1 tf.shape(tf.expand_dims(t, 0)) [1,2]
t2 tf.shape(tf.expand_dims(t, 1)) [2,1]
t3 tf.shape(tf.expand_dims(t, -1)) [2,1]
t4 tf.ones([2,3,5]) #用数字1填充所有维度
t6 tf.shape(tf.expand_dims(t4, 2)) shape【2315】
t [[[1, 1, 1], [2, 2, 2]],[[3, 3, 3], [4, 4, 4]],[[5, 5, 5], [6, 6, 6]]]
#对tensor进⾏切⽚操作
t1 tf.slice(t, [1, 0, 0], [1, 1, 3])
t2 tf.slice(t, [1, 0, 0], [1, 2, 3])
t3 tf.slice(t, [1, 0, 0], [2, 1, 3])t tf.ones([5,30])
t1, t2, t3 tf.split(t,3,1) #沿着某⼀维度将tensor分离
print(tf.shape(t1))
print(tf.shape(t2))
print(tf.shape(t3))t1 [[1, 2, 3], [4, 5, 6]]
t2 [[7, 8, 9], [10, 11, 12]]
t3 tf.concat([t1, t2], 0) #沿着某⼀维度连结tensor
t4 tf.concat([t1, t2], 1)x [1, 4] y [2, 5] z [3, 6]
t1 tf.stack([x, y, z]) #沿着第⼀维stack [[1 4] [2 5] [3 6]]
t2 tf.stack([x, y, z], axis1) #axis取0时表示按x轴叠加取1时表示按y轴叠加#[[1 2 3] [4 5 6]]t [[ [[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]], [[12, 13, 14, 15],[16, 17, 18, 19],[20, 21, 22, 23]] ]] # shape(1,2,3,4),dims [3]
t1 tf.reverse(t, dims) #沿着某维度进⾏序列反转dims [1]
t2 tf.reverse(t, dims) #dims [2]
t3 tf.reverse(t, dims) [[ [[ 8 9 10 11] [ 4 5 6 7] [ 0 1 2 3]] [[20 21 22 23] [16 17 18 19] [12 13 14 15]] ]]t [[1, 2, 3],[4, 5, 6]]
t1 tf.transpose(t) #调换tensor的维度顺序
t2 tf.transpose(t, perm[1, 0]) # [[1 4] [2 5] [3 6]]indices [0, 1, 2] depth 3
t1 tf.one_hot(indices, depth) #
indices [0, 2, -1, 1] depth 3
t2 tf.one_hot(indices, depth,on_value5.0, off_value0.0,axis-1)
indices [[0, 2], [1, -1]] depth 3
t3 tf.one_hot(indices, depth,on_value1.0, off_value0.0,axis-1) # [ [[1. 0. 0.][0. 0. 1.]]
[[0. 1. 0.][0. 0. 0.]] ]
t [1, 1, 2, 4, 4, 4, 7, 8, 8]
y, idx tf.unique(t)
print(y) #t的所有唯一元素
print(idx) #y中每个值的索引tf.math.ceil([-1.7,-1.5,-0.2,0.2,1.5,1.7,2.0]) #向上取整函数
tf.gather(params,indices,axis0 ) 从params的axis维根据indices的参数值获取切片运算
tf.diag(diagonal) 根据主对角线元素生成矩阵
tf.trace(x, nameNone)求二维tensor对角值之和
tf.matrix_determinant(input, nameNone)求方阵行列式
tf.matrix_inverse(input, adjointNone,nameNone)求逆矩阵
tf.matmul(a,b,transpose_aFalse,transpose_bFalse,a_is_sparseFalse,b_is_sparseFalse,nameNone)矩阵相乘
tf.complex(real, imag, nameNone) 将两实数转换为复数形式
tf.complex_abs(x, nameNone) 计算复数的绝对值即⻓度。
tf.conj(input, nameNone) 计算共轭复数
tf.imag(input, nameNone)
tf.real(input, nameNone)
tf.eye(num_rows,num_columnsNone)生成单位阵
tf.fill(dims,value,nameNone) fill([2, 3], 9) [[9, 9, 9][9, 9, 9]]
tf.ones(shape,dtypetf.dtypes.float32,nameNone)
数据生成
⽣成随机张量
tf.random_normal(shape, mean0.0, stddev1.0, dtypetf.float32, seedNone)
从“服从指定正态分布的序列”中随机取出指定个数的值shape: 输出张量的形状mean: 正态分布的均值stddev: 正态分布的标准差dtype: 输出的类型seed: 随机数种子是一个整数当设置之后每次生成的随机数都一样tf.truncated_normal(shape, mean, stddev)
产生截断正态分布随机数取值范围为 [ mean - 2 * stddev, mean 2 * stddev ]tf.random_uniform(shapeminval0, maxvalNone, dtypetf.float32, seedNone)
生成的值在 [minval, maxval) 范围内遵循均匀分布.tf.random_shuffle() 随机地将张量沿其第一维度打乱变量
biases tf.Variable(tf.zeros([200]),name“var) 生成一组变量没有初始化
const tf.constant(1.0,nameconstant) 创建常量名称作用域
在TensorFlow 应用程序中可能会有数以千计的计算节点。如此多节点汇集在一起难以分析甚至无法用标准的图表工具来展示。为解决这个问题一个有效方法就是为Op/Tensor 划定名称范围。在TensorFlow 中这个机制叫名称作用域(name scope)tf.variable_scope() 管理变量命名空间可以创建同名变量。在tf.variable_scope 中创建的变量,名称. name 中名称前面会加入命名空间的名称并通过“/” 来分隔命名空间名和变量名。tf.get_variable(namefoo/bar, shape[1]) 可以通过带命名空间名称的变量名来获取其命名空间下的变量。如果变量存在则使用以前创建的变量如果不存在则新创建一个变量。不能创建同名变量。Pytorch
概念Pytorch是一个基于python的科学计算包主要用途为
作为Numpy的替代品可以利用GPU的性能进行高效计算作为高灵活性速度快的深度学习平台
测试
torch.cuda.is_available()
x torch.rand(5,3) print(x)
print(x)基本元素 张量Tensor、变量Variable、神经网络模块nn.Module
张量(Tensor)张量是PyTorch中最基本的元素相当于numpy.ndarray。Tensor是PyTorch中numpy.ndarray的替代品。变量(Variable)搭建神经⽹络时需要variable来构建计算图。Variable是对tensor的封装是⼀个存放会变化的值tensor的物理位置。variable有3个属性 variable.data: variable中tensor的值variable.grad: variable中tensor的梯度;variable.gradfn: 指向Function对象⽤于反向传播的梯度计算之⽤
nn.Module
神经⽹络模块nn.Module神经⽹络的接⼝。定义⾃⼰的神经⽹络时需继承 nn.Module类
(1) Liner模块
torch.nn.Linear(in_features, out_features, biasTrue) ⽹络中的全连接层全连接层输⼊与输出都是⼆维张量输⼊形状为[batch_size, size]。 in_features指的是输入的二维张量的大小。 out_features指的是输出的二维张量的大小即输出的二维张量的形状为[batch_sizeoutput_size]也代表该全连接层的神经元个数。
(2) Conv2d模块
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, biasTrue) kernel_size:卷积核的⼤⼩⽤(H,W)表示HxW的输出H表示H*H⼤⼩的输出。 stride卷积步幅卷积核每次挪动间距 padding:填充操作控制padding_mode的数⽬。默认为Zero-padding。 dilation:扩张操作控制kernel点卷积核点的间距默认为1。 group:控制分组卷积默认不分组。 (对输入feature map进行分组然后每组分别卷积。) bias:是否添加偏置如为真则在输出中添加⼀个可学习的偏差默认为True。 Linear和Conv2d连接Conv2d的输出为四维张量转换为⼆维张量之后才能作为全连接层的输⼊。 (3)⼆维批量归⼀化模块
torch.nn.BatchNorm2d(num_features, eps1e-05, momentum0.1, affineTrue) num_features特征数C (4)最⼤池化模块
torch.nn.MaxPool2d(kernel_size, strideNone, padding0, dilation1) 输⼊: (N,C,H_in,W_in) 输出: (N,C,H_out,W_out) (5)平均池化模块
torch.nn.AvgPool2d(kernel_size, strideNone, padding0, ceil_modeFalse) ceil_mode:如果为True则在计算输出形状时使⽤ceil函数替代floor (6)⾃适应平均池化模块:
torch.nn.AdaptiveAvgPool2d(output_size) output_size: 输出信号的尺⼨ Adaptive Pooling特殊性在于输出张量的⼤⼩是给定的output_size。对于任何输⼊⼤⼩的输⼊可以将输出尺⼨指定为H*W但是输⼊和输出特征的数⽬不会变化。
nn.function
位置torch.nn.functional 例torch.nn.functional.adaptive_avg_pool2d(input, output_size)torch.nn.ReLU(inplaceFalse) inplace:选择是否进⾏原位运算即x x1Sigmoid:
m nn.Sigmoid()
input torch.randn(2)
output m(input)
input, output
(tensor([-0.8425, 0.7383]), tensor([0.3010, 0.6766]))4.Tanh:
m nn.Tanh()
input torch.randn(2)
output m(input)
input, output
(tensor([1.3372, 0.6170]), tensor([0.8710, 0.5490])) RNN
函数torch.nn.RNN(input_size, hidden_size, num_layers)
hidden_size隐含层神经元个数,也是输出的维度因为rnn输出为各时间步上的隐藏状态;num_layers隐含层的层数
RNN的输出包含两部分输出值Y即output和 最后⼀个时刻隐含层的输出 h n h_n hn
前向预测:
x[seq_len, batch, feature_len],是⼀次性将所有时刻特征输⼊的不需要每次输⼊当前时刻的xt;h0是第⼀个初始时刻所有层的记忆单元的Tensor理解成每⼀层中每个句⼦的隐藏输出; 例输⼊⼀段中⽂输出⼀段英⽂。每个中⽂字符⽤100维数据进⾏编码每个隐含层的维度是20有4个隐含层。所以input_size 100hidden_size 20num_layers 4。设模型已经训练好了现在有个1个⻓度为10的句⼦做输⼊那seq_len 10 batch_size 1。 import torch
import torch.nn as nn
input_size 100 # 输⼊数据编码的维度
hidden_size 20 # 隐含层维度
num_layers 4 # 隐含层层数
rnn nn.RNN(input_sizeinput_size,hidden_sizehidden_size,num_layersnum_layers)
print(rnn:,rnn)
seq_len 10 # 句⼦⻓度
batch_size 1 x torch.randn(seq_len,batch_size,input_size) # 输⼊数据x
h0 torch.zeros(num_layers,batch_size,hidden_size) # 输⼊数据h0 out, h rnn(x, h0) # 输出数据 print(out.shape:,out.shape)
print(h.shape:,h.shape)RNNCell模块: (1)区别nn.RNN是⼀次性将所有时刻特征输⼊⽹络的。nn.RNNCell将序列上的‘每个时刻的数据’分开来处理 (2)前向预测: h t f o r w a r d ( x t , h t − 1 ) h_t forward(x_t, h_{t-1}) htforward(xt,ht−1) 例如如果要处理3个句⼦每个句⼦10个单词每个单词⽤100维的嵌⼊向量表示 nn.RNN传⼊的Tensor的shape是[10,3,100] nn.RNNCell传⼊的Tensor的shape是[3,100]将此计算单元运⾏10次 LSTM模块 函数torch.nn.LSTM(input_size, hidden_size, num_layers) 输⼊及输出格式out, (h_t, c_t) lstm(x, [h_t0, c_t0])LSTMCell模块 h_t, c_t lstmcell(x_t, [h_t-1, c_t-1]) xt[batch, feature_len]表示t时刻的输⼊ht−1,ct−1[batch, hidden_len]t−1时刻本层的隐藏单元和记忆单元
nn.LSTM是⼀次性将所有时刻特征输⼊⽹络的。 nn.LSTMCell将序列上的‘每个时刻的数据’分开来处理 CNN
前馈型神经网络的学习主要采用误差修正法如BP算法计算过程比较慢收敛速度也较慢而反馈型神经网络主要采用Hebb学习规则计算收敛速度很快。
CNN使用部分连接层三个思想为局部性、相同性、不变性
卷积层
第一层神经元只连接输入图像中位于他感知区域中的像素 专注图像的低级特征第二层神经元仅连接到位于第一层中感知区域内的神经元 高级特征
过滤器Filters、卷积核 卷积操作 设定参数 1滤波器的长宽高 HWC 2步长(Stride) 3边界填充 注经过滤器处理后的图像称为特征图特征图中所有神经元共享相同参数权重、偏差顷
基本结构输入层卷积层提取特征池化层压缩特征 全连接层非线性输出
输⼊图像的表示3D张量 [⾼度宽度通道]⼩批量表示4D张量 [⼩批量⾼度宽度通道]
卷积层的权重表示4D张量 [ fh,fw,fn,fn′]
fh为当前层过滤器高度 fw为当前层过滤器宽度fn为当前层过滤器数量 fn’为上一层特征图数量
卷积层的偏置项表示1D张量 [fn]
计算一个具有5×5过滤器的卷积层输出尺寸为150×100的200个特征图带有步幅1和SAME填充。
参数数量若输入是150×100 RGB图像三通道则参数的数量5×5×31*20015,200200个特征图每一个都包含150×100个神经元每个都需要计算其5×5×375个输入的加权和总共有75*150*100*2002.25亿次浮点乘法。若用32位浮点数表示特征图卷积层输出将占200×150×100×3296百万位约11.4 MB内存关于padding
写代码时要注意padding有两个模式分别是 ‘same’ 和 ‘valid’
paddingsame表示进行填充填充的值由算法内部根据卷积核大小计算目的是让输出尺寸和输入相等 paddingvalid表示不进行填充即是 padding0只使用有效的窗口位置这是默认的选项。
填充的值 (b - 1) / 2 填充的值b的值就是卷积核的尺寸这里就是为什么卷积核尺寸通常选择奇数的原因
举例子 问题1. 一个尺寸 55 的特征图经过 33 的卷积层步幅stride1想要输出尺寸和输入尺寸相等填充padding的值应该等于多少 答填充的值(3 - 1)/2 1即每一边填充1层
问题2. 一个尺寸 224224 的特征图经过 77 的卷积层步幅stride2想要输出尺寸和输入尺寸相等填充padding的值应该等于多少 答填充的值(7 - 1)/2 3即每一边填充3层
paddingsame’目的是让输出尺寸和输入尺寸相等但前提是步幅1步幅若不是1那么输出尺寸跟输入尺寸肯定是不一样。
对于 padding 的 same 和 valid 模式两种直白的理解就是要么不填充要么填充就让输出尺寸和输入尺寸相等 padding 的值不会乱取就两种情况要么padding0 要么padding(b - 1)/2。 池化层
1⽬标对输⼊图像进⾏⼆次采样即缩⼩以减少计算量、内存占⽤和参数数量减少过拟合⻛险 2特点池化层中的每个神经元都和前⼀层神经元的输出相连位于⼀个⼩的矩形感受区内。但池化神经元没有权重它⽤聚合函数如max_pool()或avg_pool()聚合输⼊。 3作用特征降维避免过拟合空间不变性减少参数降低训练难度
4代码实现⼀个2x2内核的池化层keras实现
keras.layers.MaxPool2D( pool_size(2,2), stridesNone, #默认值和pool_size相等
paddingvalid, data_formatNone)keras.layers.AvgPool2D(pool_size(2,2),strides None, # 默认值和pool_size相等
paddingvalid, data_formatNone)keras.layers.GlobalAveragePooling2D(data_formatNone)设计一个对MNIST处理的CNN网络结构和参数如下每次MaxPooling后添加系数为0.25的Dropout. import os
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D,
import numpy as np(X_tarin, y_train), (X_test, y_test) mnist.load_data()
X_train4D X_tarin.reshape(X_tarin.shape[0], 28, 28, 1).astype(float32)
X_test4D X_test.reshape(X_test.shape[0], 28, 28, 1).astype(float32)# 归⼀化
X_train4D_Normalize X_train4D / 255
X_test4D_Normalize X_test4D / 255
# 标签onehot编码
y_trainOnehot to_categorical(y_train)
y_testOnehot to_categorical(y_test)# 建⽴模型
model Sequential()
model.add(Conv2D(filters16,kernel_size(5, 5),paddingSAME, input_shape(28, 28, 1),activationrelu))
model.add(MaxPool2D(pool_size(2, 2)))
model.add(Dropout(0.25))# ⼆层卷积
model.add(Conv2D(filters32,kernel_size(5, 5), paddingSAME, activationrelu))
model.add(MaxPool2D(pool_size(2, 2)))
model.add(Dropout(0.25))#三、四层卷积
model.add(Conv2D(filters64, kernel_size(5, 5), paddingsame, activationrelu))
model.add(MaxPool2D(pool_size(2, 2)))
model.add(Dropout(0.25))model.add(Conv2D(filters128, kernel_size(5, 5), paddingsame, activationrelu))
model.add(MaxPool2D(pool_size(2, 2)))
model.add(Dropout(0.25))
# 全连接层
model.add(Flatten())
model.add(Dense(128, activationrelu))
model.add(Dropout(0.25)) model.add(Dense(10, activationsoftmax))
model.summary()
# 编译模型
model.compile(losscategorical_crossentropy,optimizeradam,metrics[accuracy])
#训练模型
train_history model.fit(xX_train4D_Normalize,yy_trainOnehot,validation_split0.2,batch_size300,epochs10,verbose2)
#评估模型
model.evaluate(X_test4D_Normalize, y_testOnehot)[1]
#预测
prediction model.predict_classes(X_test4D_Normalize)RNN
概念⼀类⽤于处理序列数据的神经⽹络⼀个序列当前的输出与前⾯的输出有关。具体的表现形式为:⽹络会对前⾯的信息进⾏记忆并应⽤于当前输出的计算中即隐藏层之间的节点是有连接的并且隐藏层的输⼊不仅包括输⼊层的输出还包括上⼀时刻隐藏层的输出。 结构
参数3组权重
U(输⼊x和节点间的计算)W(节点随时间转换计算)V:(节点x和输出节点间计算)St为时刻t隐层的状态 s t f ( U x t W s t − 1 ) s_t f(U_{x_t} W_{s_t−1}) stf(UxtWst−1)
激励函数 ⼀般为tanh或ReLU o t o_t ot为时刻t的输出。 o t s o f t m a x ( V s t ) o_t softmax(V_{s_t}) otsoftmax(Vst) 分类
按输⼊和输出序列的结构One to One、One to Many向量到序列、Many to One序列到向量、Many to Many 、Encoder-Decoder模型Seq2Seq模型按内部结构传统RNN、LSTM、Bi-LSTM、GRU、Bi-GRU
简单RNN缺点在预测⻓序列上表现不佳⾯临不稳定梯度问题易发生梯度消失或爆炸且当 RNN 处理⻓序列时会逐渐忘掉序列的第⼀个输⼊
简易RNN
np.random.seed(42)
tf.random.set_seed(42)model keras.models.Sequential([
keras.layers.SimpleRNN(1, input_shape[None, 1]) ])optimizer keras.optimizers.Adam(learning_rate0.005)model.compile(lossmse, optimizeroptimizer)
history model.fit(X_train, y_train, epochs20,validation_data(X_valid, y_valid))model.evaluate(X_valid, y_valid)
y_pred model.predict(X_valid)深度RNN
np.random.seed(42)
tf.random.set_seed(42)
model keras.models.Sequential([keras.layers.SimpleRNN(20, return_sequencesTrue,input_shape[None, 1]),keras.layers.SimpleRNN(20, return_sequencesTrue),keras.layers.SimpleRNN(1)
])
model.compile(lossmse, optimizeradam)
history model.fit(X_train, y_train, epochs20,validation_data(X_valid, y_valid))
model.evaluate(X_valid, y_valid)
y_pred model.predict(X_valid)np.random.seed(42)
tf.random.set_seed(42)model keras.models.Sequential([
keras.layers.SimpleRNN(20, return_sequencesTrue, input_shape[None, 1])
keras.layers.BatchNormalization(),
keras.layers.SimpleRNN(20, return_sequencesTrue),
keras.layers.BatchNormalization(), 批量归一化
keras.layers.TimeDistributed(keras.layers.Dense(10)) 时间步
每⼀步都预测10个值即在时刻0会预测1到10时刻1预测2到11.
])
model.summary()
model.compile(lossmse, optimizeradam, metrics[last_time_step_mse])
history model.fit(X_train, Y_train, epochs20, validation_data(X_valid, Y_valid))
model.evaluate(X_valid, Y_valid)LSTM LSTM 单元的状态h[t]短期记忆状态c[t]⻓期记忆状态
c[t−1]先经遗忘⻔丢弃⼀些记忆后经添加操作增加⼀些记忆从输⼊⻔中选 择⼀些最后不经转换直接输出。添加操作之后⻓时状态复制后经tanh 激活函数后结果被输出⻔过滤得到短时状态h[t]。h[t]即为这⼀时间步的单元输出y[t]。
短期记忆状态 h [ t − 1 ] h[t−1] h[t−1]和输⼊向量 x [ t ] x[t] x[t]经4个不同的全连接层 g [ t ] g[t] g[t]层为主要层将最重要的部分保存在⻓期状态中tanh为激活函数其它三个全连接层(FC)是⻔控制器Logistic作为激活函数
权重计算 W x i W x f W x o W x g W_{xi}W_{xf} W_{xo}W_{xg} WxiWxfWxoWxg是四个全连接层连接输⼊向量x(t)的权重 W h i W h f W h o W h g W_{hi}W_{hf} W_{ho}W_{hg} WhiWhfWhoWhg是四个全连接层连接h(t−1)的权重 b i b f b o b g b_ib_f b_ob_g bibfbobg是全连接层的四个偏置项。 W x i W x f W x o W x g W_{xi}W_{xf} W_{xo}W_{xg} WxiWxfWxoWxg 权重数量 输入参数数量×隐层参数数量隐层参数数量 ×隐层参数数量 偏置数量隐层参数数量
np.random.seed(42)
tf.random.set_seed(42)
model keras.models.Sequential([
keras.layers.LSTM(20, return_sequencesTrue, input_shape[None, 1]),
keras.layers.LSTM(20, return_sequencesTrue),
keras.layers.TimeDistributed(keras.layers.Dense(10))
])model.summary()
model.compile(lossmse, optimizeradam, metrics[last_time_step_mse])
history model.fit(X_train, Y_train, epochs20, validation_data(X_valid, Y_valid))
model.evaluate(X_valid, Y_valid)GRU ⻓时状态和短时状态合并为⼀个向量h(t)。⽤⼀个⻔控制器z(t)(重置门)控制遗忘⻔和输⼊⻔
若⻔控制器输出1则遗忘⻔打开 1输⼊⻔关闭1 - 1 0。若输出0则做相反操作取消输出⻔每个时间步输出全态向量。
增加⼀个控制门r(t)更新门来控制前⼀状态的哪些部分呈现给主层g(t) 注尽管它们相⽐于简单RNN可处理更⻓的序列了还是有⼀定程度的短时记忆。
应对⽅法之⼀是将输⼊序列缩短例如使⽤ 1D 卷积层。1D 卷积层在序列上滑动⼏个核每个核可以产⽣⼀个 1D 特征映射。 每个核能学到⼀个⾮常短序列模式不会超过核的⼤⼩
np.random.seed(42)
tf.random.set_seed(42)model keras.models.Sequential([
keras.layers.GRU(20, return_sequencesTrue, input_shape[None, 1]),
keras.layers.GRU(20, return_sequencesTrue),
keras.layers.TimeDistributed(keras.layers.Dense(10))
])
model.summary()
model.compile(lossmse, optimizeradam, metrics[last_time_step_mse])
history model.fit(X_train, Y_train, epochs20, validation_data(X_valid, Y_valid))实现RNN对数据集MNIST的分类任务
import torch
import torch.nn as nn
import torchvision.datasets as ds
import torchvision.transforms as transforms
from torch.autograd import Variablesequence_length 28 , input_size 28 , hidden_size 128
num_layers 2, num_classes 10 , batch_size 100 , num_epochs 2
learning_rate 0.003#加载MNIST数据集
train_dataset ds.MNIST(root.\data,trainTrue,transformtransforms.ToTensor(),downloadTrue)
test_dataset ds.MNIST(root.\data,trainFalse,transformtransforms.ToTensor())
train_loader torch.utils.data.DataLoader(datasettrain_dataset,batch_sizebatch_size,shuffleTrue)
test_loader torch.utils.data.DataLoader(datasettest_dataset,batch_sizebatch_size,shuffleFalse)#定义多对⼀双向RNN模型
class BiRNN(nn.Module):def __init__(self, input_size, hidden_size, num_layers, num_classes):super(BiRNN, self).__init__()self.hidden_size hidden_sizeself.num_layers num_layersself.lstm nn.LSTM(input_size, hidden_size, num_layers,batch_firstTrue, bidirectionalTrue)self.fc nn.Linear(hidden_size * 2, num_classes) def forward(self, x):h0 Variable(torch.zeros(self.num_layers * 2, x.size(0),self.hidden_size)) # 设置初始状态c0 Variable(torch.zeros(self.num_layers * 2, x.size(0),self.hidden_size)) out, _ self.lstm(x, (h0, c0)) #前向传播out self.fc(out[:, -1, :]) # 上一时间步隐藏状态输出return out#定义模型
rnn BiRNN(input_size, hidden_size, num_layers, num_classes)
criterion nn.CrossEntropyLoss()
optimizer torch.optim.Adam(rnn.parameters(), lrlearning_rate)#训练模型
for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader):images Variable(images.view(-1, sequence_length, input_size)) labels Variable(labels) optimizer.zero_grad()#前向后向优化器outputs rnn(images)loss criterion(outputs, labels)loss.backward()optimizer.step()if (i 1) % 100 0:print(Epoch [%d/%d], Step [%d/%d], Loss: %.4f% (epoch1,num_epochs,i 1, len(train_dataset)// batch_size, loss.item()))# 测试模型
correct 0
total 0
for images, labels in test_loader:images Variable(images.view(-1, sequence_length, input_size))outputs rnn(images)_, predicted torch.max(outputs.data, 1)total labels.size(0)correct (predicted.cpu() labels).sum()print(Test Accuracy of the model on test images: %d %% % (100 * correct / total))AE
特征 自动编码器通常具有比输入数据低得多的维度使其可以实现降维目的。 自动编码器还可以应⽤于降噪场合。 自动编码器还可以作为强⼤的特征检测器它们可以⽤于⽆监督的深度神经⽹络预训练。 ⼀些自动编码器是生成式模型能够随机生成与训练数据⾮常相似的新数据。自动编码器由两部分组成 识别⽹络: 将输⼊转换为潜在表征的编码器 ⽣成⽹络: 将潜在表征转换为输出的解码器数据的潜在空间表示包含表示原始数据点所需的所有重要信息。该表示必须表示原始数据的特征。换句话说该模型学习数据特征并简化其表示从⽽使其更易于分析。输出层中的神经元数量必须等于输⼊数量。⾃动编码器试图重构输⼊所以输出通常被称为重建并且损失函数包含重建损失当重建与输⼊不同时重建损失会对模型进⾏惩罚。
X_train np.random.rand(100,3)
encoder Sequential([Dense(2, input_shape[3])])
decoder Sequential([Dense(3)])autoencoder Sequential([encoder, decoder])
autoencoder.compile(lossmse, optimizerSGD(lr0.1))history autoencoder.fit(X_train, X_train, epochs20)
codings encoder.predict(X_train)自动编码器被迫学习输⼊数据中最重要的特征并且要删除不重要的特征。借助PCA如果⾃动编码器仅使⽤线性激活并且损失函数是均⽅误差MSE最终其实是做了主成分分析PCA
深度自动编码器
⾃动编码器可以有多个隐藏层称为深度⾃动编码器。 添加更多层有助于⾃动编码器学习更复杂的编码。 但不要让⾃动编码器功能太强⼤。 如果⼀个编码器太强⼤就会导致过拟合问题 这样的⾃动编码器将完美地重构训练数据但它不会在过程中学习到任何有⽤的数据表征并且它不可能很好地泛化到新的实例。
import utils.mnist_reader
X_train, y_train utils.mnist_reader.load_mnist(./data/, kindtrain)
X_valid, y_valid utils.mnist_reader.load_mnist(./data/, kindt10k)
X_train X_train.reshape(X_train.shape[0],28,28).astype(float32)
X_valid X_valid.reshape(X_valid.shape[0],28,28).astype(float32)stacked_encoder Sequential([
Flatten(input_shape[28, 28]),
Dense(100, activationselu),
Dense(30, activationselu),
])stacked_decoder Sequential([
Dense(100, activationselu, input_shape[30]),
Dense(28 * 28, activationsigmoid),
Reshape([28, 28])
])stacked_ae Sequential([stacked_encoder, stacked_decoder])
stacked_ae.compile( lossbinary_crossentropy, optimizerSGD(lr1.5))
history stacked_ae.fit(X_train,X_train,epochs10,validation_data[X_valid])卷积自动编码
卷积⾃动编码器通常会降低输⼊的空间维度即⾼和宽同时增加深度即特征映射的数量。⽽解码器的⼯作相反即放⼤图⽚压缩深度。可以通过转置卷积层实现。也可以将上采样层和卷积层合并。
conv_encoder Sequential([
Reshape([28, 28, 1], input_shape[28, 28]),
Conv2D(16, kernel_size3, paddingsame, activationselu),
MaxPool2D(pool_size2),
Conv2D(32, kernel_size3, paddingsame, activationselu),
MaxPool2D(pool_size2),
Conv2D(64, kernel_size3, paddingsame, activationselu),
MaxPool2D(pool_size2)
])conv_decoder Sequential([
Conv2DTranspose(32, kernel_size3, strides2, paddingvalid,
activationselu, input_shape[3, 3, 64]),
Conv2DTranspose(16, kernel_size3, strides2, paddingsame,
activationselu),
Conv2DTranspose(1, kernel_size3, strides2, paddingsame,
activationsigmoid),
Reshape([28, 28])
])conv_ae Sequential([conv_encoder, conv_decoder])反卷积 ⼀种⽤于扩⼤图像的尺⼨的⽅法称为逆卷积或反卷积。 例如输⼊特征图3 ∗ 3 输⼊卷积核kernel3 ∗ 3, stride2padding1 输出特征图3 * 3 - 3 2 * 1 1 5 循环自动编码器 循环⾃动编码器中的编码器是⼀个序列到向量的 RNN⽽解码器是向量到序列的 RNN。
recurrent_encoder Sequential([LSTM(100, return_sequencesTrue, input_shape[None, 28]),LSTM(30)
])
recurrent_decoder Sequential([RepeatVector(28, input_shape[30]), 将输⼊重复28次LSTM(100, return_sequencesTrue),TimeDistributed(Dense(28, activationsigmoid))将Dense层应⽤于输⼊的每个时间⽚对输入的每个向量进行一次Dense操作。
])
recurrent_ae Sequential([recurrent_encoder, recurrent_decoder])VAE变分自编码
损失函数
重建损失推动⾃动编码器重现其输⼊。潜在损失推动⾃动编码器使编码看起来像是从简单的⾼斯分布中采样 使⽤⽬标分布⾼斯分布与编码实际分布之间的 KL散度
变分⾃动编码器不是直接为给定的输⼊⽣成编码编码器产⽣平均编码μ和标准差σ 然后从平均值μ和标准差σ的⾼斯分布随机采样实现编码。之后解码器正常解码采样的编码。
通过随机采样可以将之前离散的潜在属性空间变为连续、平滑的潜在空间。 RL
Agent智能体也就是机器人你的代码。 Environment环境也就是游戏本身openai gym提供了多款游戏也就是提供了多个游戏环境。 Action行动比如玩超级玛丽向上向下等动作。 State状态每次智能体做出行动环境会相应地做出反应返回一个状态和奖励。 Reward奖励根据游戏规则的得分。智能体不知道怎么才能得分它通过不断地尝试来理解游戏规则比如它在这个状态做出向上的动作得分那么下一次它处于这个环境状态就倾向于做出向上的动作。
在强化学习中智能体(Agent)在环境Environment中观察Observation状态State并且做出决策Action随后它会得到奖励Reward。
智能体的目标是去学习如何行动能最大化期望奖励。 gym的核心接口是统一的环境EnvEnv包含下面几个核心方法
1、reset(self):重置环境的状态返回观察值 observation 。 2、step(self,action):推进一个时间步长返回[observationrewarddoneinfo] 3、render(self,modehuman, closeFalse): 重绘环境的一帧。默认模式一般比较友好如弹出一个窗口。 4、info(dict)用于调试的诊断信息。 5、observation(object):返回一个特定环境的对象描述对环境的观察。比如来自相机的像素数 据机器人的关节角度和关节速度或棋盘游戏中 的棋盘状态。 6、reward(float)返回之前动作收获的总的奖 励值。 7、done(boolean)返回是否应该重新设置 reset环境。大多数游戏任务分为多个环节 episode当donetrue的时候表示这个环节结束了。
对于 CartPole 环境每个观测是包含四个浮点的 1D Numpy 向量 1.小车的水平位置0 为中心 2.小车的速度 3.杆的角度垂直 4.杆的角速度
CartPole-v0示例
env gym.make(CartPole-v0) # 初始化环境
for i_episode in range(20): # 外层循环obs env.reset() 返回观察值for t in range(100): # 内层循环env.render() 重绘环境的一帧。action env.action_space.sample() 随机选取动作obs, re, done, info env.step(action)print(obs)if done:print(done True : %d % (t1))break
env.close()深度强化学习
策略搜索
在强化学习中被智能体(Agent)使用去改变它行为的算法叫做策略(Policy)。例如策略可以是一个把观测(Observations)当输入行为(Actions)当做输出的神经网络。
搜寻策略方法 1)随机策略这个策略可以是你能想到的任何算法 2)尝试策略可以通过尝试来搜索即通过大量实验来选择参数的最佳组合 3)遗传算法通过遗传算法来搜索最佳参数 4)策略梯度(PG)使用优化技术通过评估奖励关于策略参数的梯度然后通过跟随梯度向更高的奖励(梯度上升)调整这些参数 5)神经网络策略神经网络将把观察作为输入输出要执行的动作。它将估计每个动作的概率然后我们将根据估计的概率随机地选择一个动作。
Q为什么根据神经网络给出的概率来选择随机的动作而不是选择最高分数的动作? A这种方法使智能体在探索新的行为和选择可行的行动之间找到平衡。
评价行为信用分配问题
在强化学习中智能体获得的指导的唯一途径是通过奖励奖励通常是稀疏的和有延迟的。
信用分配问题当智能体得到奖励时如何知道哪些行为应该被信任或责备。
解决策略是基于这个动作后得分的总和来评估这个动作通常在每个步骤中应用衰减率r。如果衰减率接近0那么与即时奖励相比未来的奖励不会有多大意义。相反如果衰减率接近1那么对未来的奖励几乎等于即时回报。
如果一个智能体决定连续三次向右在第一步之后得到 10 奖励第二步后得到 0第三步之后得到 -50衰减率r0.8那么第一个动作将得到 10 r × 0 r 2 × ( − 50 ) 10 0.8 × 0 0. 8 2 × ( − 50 ) − 22 10 r ×0 r^2 ×(−50) 100.8×00.8^2 ×(−50)−22 10r×0r2×(−50)100.8×00.82×(−50)−22的分数。
Q-Learning
马尔科夫链 包含N个状态从某个状态到其它状态的转移概率Transition Probability是确定的且不取决于过去的状态系统没有记忆。将来的状态分布只取决于现在跟过去无关。所有状态之间的转移概率关系可以用一个矩阵表示称为转移矩阵Transition Matrix。马尔可夫决策过程(MDP) 1)在每个步骤中agent 可以选择几种可能的动作中的一个并且转移概率取决于所选择的动作。一些状态转换会返回一些奖励正面或负面而agent的目标是找到一种能够随着时间的推移最大化回报的策略。 2)一种估算任何状态s的最佳状态值的方法记为V*(s)
T(s,a,s’)是agent 选择了动作a时从状态s到状态s’的转换概率。R(s,a,s’)是agent选择了动作a时从状态s到状态s’时获得的奖励。γ是折扣率。
Q值迭代算法
动态规划的一个例子它将一个复杂的问题分解为易处理的子问题并且可以通过迭代解决。
原理将状态-动作值 (s,a) 称为Q值记为Q(s,a),它将返回在该状态下执行该动作的未来奖励期望。状态-动作(s,a)的最佳Q值记为Q*(s,a)。
工作原理首先将所有Q值估算值初始化为零然后使用Q值迭代算法更新它们。
Q-Learning算法是Q值迭代算法适应转移概率和奖励未知的情况。
对于每个状态 - 动作对sa算法跟踪agent 在离开状态s时采取动作a的奖励的运行平均值以及预期稍后获得的奖励。由于目标策略将采取最优行动因此我们对下一个状态采取最大Q值估计。 估值Q-Learning Q-Learning的主要问题是它不能很好地扩展到具有许多状态和动作的大型、中型MDP问题。找到一个使用参数数量可管理的函数来近似Q值称为估值Q-Learning
用于估计Q值的DNN称为深度Q网络DQN。使用DQN进行近似Q学习称为深度Q学习DQL。
Q-learning 示例 用一个简单的例子介绍Q-Learning算法的执行过程。在一幢建筑里有6个房间房间用编号0-5表示房间之间通过门相连。房间5是建筑外围空间可以看作是一个大的房间。首先将Agent置于建筑中任意一个房间其1目标是从那个房间开始走到房间5。 初始化初始化Q,R,γ Q-Learning算法 Step 1 给定参数 和R矩阵Q0.
Step 2 循环执行Step3,4
Step 3 随机选择一个初始状态s
Step 4 循环执行1.判断s是否是目标状态如否则执行下列步骤,如是则结束Step 4.2.在当前状态s的所有可能行动中选取一个动作a3.利用选定的动作a得到下一个状态s~4.利用公式计算Q(s,a)5.令ss~执行过程 循环1令初始状态为1。状态不为5则在R矩阵中选择状态1的可能动作3或5。选择状态5得到下一个状态为5。利用公式计算Q(1,5)Q矩阵更新为当前状态为5所以下次循环判断后即可结束循环2回到Step 3, 重新选择一个初始状态。选择初始状态为3.找出状态3的可能动作1,2,4选择状态1对应2个可能的动作3或5利用公式计算Q(3,1)Q矩阵更新为现在的当前状态变成了状态1因为状态1不是目标状态因此从状态1 的可能动作选择一个3或5。选择状态5其动作有3个可能1,4或5利用公式计算Q(1,5)继续循环继续执行多次后将得到矩阵Q一旦Q接近收敛状态就可以指导Agent进行最佳路径选择。如假定Agent从状态2出发可到到下列路径1. Q矩阵中状态2的最大元素值为320选择状态32. 状态3的最大元素值为400 状态为1或4选择状态43. 状态4的最大元素值为500即状态5到达目标。因此最佳路径为2-3-4-5