其他
利用TensorFlow构建前馈神经网络
本文作者:陈 鼎,中南财经政法大学统计与数学学院
本文编辑:王子一
技术总编:张馨月
爬虫俱乐部云端课程
为什么要引入深度学习
深度学习算法原理
基于TensorFlow的代码实现
(一) 为什么要引入深度学习
(二) 从一个简单的例子说起
1.回归问题&分类问题
2.MNIST数据集
图2 手写数据集
3.输入与输出
图4 relu函数
假设有三个"车间"用来加工数据,利用数学语言可以如下描述:
以上述数学公式为例,我们就能画出一个很简单的图示来表示模型:
图5 神经网络模型
输入“原材料”,即每张图片对应的表示矩阵,并将其竖直堆叠起来作为一层,称为神经网络的输入层(input);在最尾层输出预测类别,称为神经网络的输出层(out);中间的车间我们称之为隐藏层(hidden)。如图所示,参数w1,b1,w2,b2,w3,b3将不同的车间很好地连接了起来。
在设定的三层神经网络模型中,我们可以人为地指定中间隐藏层的参数维数。这里指定c个样本在通过第一个车间之后的维度变为了[c,256]维,在通过第二个车间之后的维度变成了[c,128]维,在通过第三个车间之后变成了[c,10]维。用直观的矩阵运算来表示一下上述模型的计算过程:
4.优化参数
小编使用的损失函数为常用的MSE(均方误差),它代表着预测值与真实值的欧氏距离:
梯度下降法的迭代公式如下:
其中lr为学习率(Learning Rate)。本模型中需要优化的参数共有6个,分别为w1,b1,w2,b2,w3,b3。
(三)实战演练
1.读取数据
tensorflow.keras
中的datasets
方法即可快速加载所需数据。首次加载数据时电脑会自动从Google上下载数据,这可能会花费一定的时间。调用该函数后会返回训练集样本与测试集样本,我们用x_train
,y_train
,x_test
,y_test
分别接收训练集的特征,训练集特征对应的类别,测试集特征,测试集特征所对应的类别。import tensorflow as tf
from tensorflow.keras import datasets
(x_train,y_train),(x_test,y_test) = datasets.mnist.load_data()
numpy.ndarray
格式)转换成张量(Tensor
格式),这一方面便于实现自动求导,另一方面有利于TensorFlow内部进行数值计算。tf.float32
格式。Datasets.from_tensor_slices
方法与map
函数实现。下面是一个简单的数据预处理过程:#加载数据集
def prepocessing_data(x,y):
'''
数据预处理
:param x: 特征
:param y: 类型
:return: x,y
'''
x = tf.cast(x,dtype=tf.float32)/255. #将特征数据转换成浮点型,并将输入数值等比例放缩到[0,1]区间上
y = tf.cast(y,dtype=tf.int32) #将分类结果转换成整型
return x,y
(x_train,y_train),(x_test,y_test) = datasets.mnist.load_data() #读取数据
train_datasets = tf.data.Dataset.from_tensor_slices((x_train,y_train))
train_datasets = train_datasets.map(prepocessing_data)
train_datasets = train_datasets.shuffle(10000).batch(128) #将训练数据随机打乱,并每次读取128个数据,返回训练样本的迭代器
test_datasets = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_datasets = test_datasets.map(prepocessing_data)
test_datasets = test_datasets.shuffle(10000).batch(128) #将测试集数据随机打乱,并每次读取128个数据,返回测试集样本的迭代器
2.参数随机初始化
w1,b1,w2,b2,w3,b3
。这里我们利用截断的正态分布(防止梯度消失或梯度爆炸)随机生成w矩阵,并将b随机初始化成一个元素全为0的向量。为了避免梯度爆炸对模型的学习产生影响,我们将正态分布的标准差设置为0.1,下面是代码实现过程:#随机初始化
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]))
lr = 1e-3 #指定学习率
3.模型训练
损失函数
来评估模型的精度,并使用损失函数分别对所有的参数进行求导来计算梯度
,进而完成对模型的优化。for epoch in range(200): #实现200次迭代
for step,(x,y) in enumerate(train_datasets): #输入测试数据,进行模型训练
x = tf.reshape(x,[-1,28*28]) #将输入数据展平
with tf.GradientTape() as tape: #开始记录变量梯度
a1 = tf.nn.relu(x@w1+b1) #第一层
a2 = tf.nn.relu(a1@w2+b2) #第二层
out = a2@w3+b3 #我们要计算损失函数,因此不需要再套用relu函数,只需要得出预测值即可
#计算损失函数
y_one_hot = tf.one_hot(y, depth=10) #将真实结果转换成one_hot编码
loss = tf.square(out - y_one_hot)
loss = tf.reduce_mean(loss) #计算MSE
#计算梯度
grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
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: #每进行100次训练,返回当前模型的损失值大小
print(epoch,step,"loss:",float(loss))
4.模型预测
(w1,w2,w3,b1,b2,b3)
。使用上述求解出来的这些参数,再进行一次前向传播操作,最后即可求解出预测结果的准确率。#利用测试集预测准确率
#注:如下代码应放入模型训练的第一层for循环中
total_correct_num,total_num = 0,0
for step,(x,y) in enumerate(test_datasets):
x = tf.reshape(x,[-1,28*28])
a1 = tf.nn.relu(x@w1+b1)
a2 = tf.nn.relu(a1@w2+b2)
out = tf.nn.relu(a2@w3 + b3)
# 获取最大的概率值
prob = tf.nn.softmax(out,axis=1) #将输出结果转换成概率
pred = tf.argmax(prob,axis=1) #获取数值最大的元素所对应的索引号(即返回预测的类别)
pred = tf.cast(pred,dtype=tf.float32)
y = tf.cast(y,dtype=tf.float32)
correct = tf.equal(pred,y) #判定预测值与真实值是否相等,返回一个Boolean类型的矩阵
correct = tf.cast(correct,dtype=tf.float32) #将Boolean类型的矩阵转换成元素为(0,1)的矩阵(True=1,False=0)
correct_num = tf.reduce_sum(correct) #求和,得到预测正确的个数值
total_correct_num += int(correct_num)
total_num += int(x.shape[0])
accuracy = total_correct_num/total_num #计算准确率
print("accuracy:",accuracy)
5.查看训练结果
图6 第一次训练模型返回的结果
图7 反复迭代200次后返回的结果
6.注意事项
推文合集(1)| Stata学习者必看的n篇推文!
Seminar | 诚信的价值
利用tushare获取股票数据及实现可视化
从Excel到Stata的“摆渡车”——import excel命令
光阴十载,见证了《经济研究》中的“高被引”
利用tushare获取股票数据
这些年,经管类C刊都在研究什么?
Seminar | 眼见为实吗?高管面部可信度、审计师任期与审计费用
Seminar | 恐怖袭击与CEO薪酬
代码补全,主题更换,Jupyter Notebook原来可以这样用?
【爬虫实战】“双十一”微博热搜实时跟进
Stata中的数值型变量分类神器--recode
fs命令——我们的小帮手【邀请函】听说你还在为处理表格头大?
用stack取代excel的数据重整操作吧Seminar | 委托贷款:打开中国影子银行的黑匣子
Seminar | 电话会议中的"non-answer"
Python 爬虫必杀技:XPath
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。