深度学习之tensorflow学习记录(二)
第二章 鸢尾花分类入门
0、引言
通过搭建简单的神经网络,利用tensorflow框架,对鸢尾花数据集进行分类。
一、引入相关库
import pandas as pd
from sklearn import datasets
import numpy as np
import tensorflow as tf
from matplotlib import pyplot as plt
二、数据准备
代码如下(示例):
1.读入数据
data = datasets.load_iris()
x = data.data #加载特征部分,数据包括:['花萼长度','花萼宽度','花瓣长度','花瓣宽度']
y = data.target #加载标签部分
2.数据处理:打乱、划分训练集及测试集、数据配对
代码如下(示例):
np.random.seed(116) #生成随机种子,保证打乱之后的特征-标签值一一对应
np.random.shuffle(x)
np.random.seed(116)
np.random.shuffle(y)
tf.random.set_seed(116)
#分割出训练集和测试集
train_x = x[:-30]
train_y = y[:-30]
test_x = x[-30:]
test_y = y[-30:]
train_x = tf.cast(train_x, dtype = tf.float32) #数据类型转换
test_x = tf.cast(test_x, dtype = tf.float32)
#将数据配为 特征/标签 对
train_db = tf.data.Dataset.from_tensor_slices((train_x, train_y)).batch(32) #每次喂入batch个数据对(每32个数据打包成一个batch)
test_db = tf.data.Dataset.from_tensor_slices((test_x, test_y)).batch(32)
三、配置神经网络
代码如下(示例):
#假设只有输入层和输出层,则输入层为四个神经网络节点(因为每个数据有四个特征),输出层为三个神经网络节点(分别是对三种分类的预测概率)
#定义神经网络中的所有可训练参数,将所有参数都定义为可更新参数,即tf.Variable()
w1 = tf.Variable(tf.random.truncated_normal([4,3], stddev = 0.1, seed = 1)) #输入特征为四维,假设没有隐藏层,输出特征为3维,所以是 4 * 3
b1 = tf.Variable(tf.random.truncated_normal([3], stddev = 0.1, seed = 1)) #bi的维度 要与 wi 的第二个维度一致
#定义超参数
epoch = 500 #迭代次数
lr = 0.1 #learning_rate
train_loss_result = [] #记录每次迭代的loss, 便于后续画loss图
test_acc = [] #记录每次测试的准确率,便于后续画acc图
loss_all = 0
#嵌套循环迭代,with结构更新参数,显示当前loss
for epoch in range(epoch): #对整个数据集进行迭代,迭代次数为epoch
for step, (train_x, train_y) in enumerate(train_db): #batch 级别的迭代
with tf.GradientTape() as tape: #记录梯度信息
#前向传播过程计算y
y = tf.matmul(train_x, w1) + b1
y = tf.nn.softmax(y) #使输出的数据符合概率分布
y_ = tf.one_hot(train_y, depth = 3) #将标签值转换成one-hot编码
#记录总loss
loss = tf.reduce_mean(tf.square(y_ - y))
loss_all += loss.numpy()
grads = tape.gradient(loss, [w1, b1])
w1.assign_sub(lr * grads[0]) #更新参数w1
b1.assign_sub(lr * grads[1]) #更新参数b1
print("epoch:{}, loss:{}".format(epoch, loss_all/4)) #此处因为对batch迭代了四次(即一个epoch里面有4个batch),因此求loss的均值
train_loss_result.append(loss_all/4)
loss_all = 0
# 计算当前参数传播的准确率
total_correct = 0
total_num = 0
for test_x, test_y in test_db: #batch级别的迭代(每次迭代32个测试用例)
y = tf.matmul(test_x, w1) + b1 #输出的y应该为30行,3列,(因为有30个测试集,预测类别共有三类)
y = tf.nn.softmax(y) #使 y 的值符合概率分布
pred = tf.argmax(y, axis = 1) #返回输出的 y 的每一行的最大索引,即最终的预测结果 , 输出的pred应该为30行, 1列,(有三十个测试集,每个测试数据对应一个最终的预测类别)
pred = tf.cast(pred, dtype = test_y.dtype) #调整数据类别与原始标签类别一致
correct = tf.cast(tf.equal(pred, test_y), dtype = tf.int32) #比较结果,并将结果的true/false 转换为 1/0 的数据类型
correct = tf.reduce_sum(correct) #对所有元素求和,求和大小即为预测准确的测试用例个数
total_correct += int(correct) #将本次batch的32组数据的正确的数量计入总数
total_num += test_x.shape[0] #将本次batch的32组数据的个数计入总数
acc = total_correct/total_num
test_acc.append(acc)
print("acc : ", acc)
4.画图
代码如下(示例):
#画图
plt.title("Loss")
plt.xlabel("epoch")
plt.ylabel("loss")
plt.plot(train_loss_result, label = "&loss")
plt.legend()
plt.show()
#画图
plt.title("acc")
plt.xlabel("epoch")
plt.ylabel("acc")
plt.plot(test_acc, label = "&acc")
plt.legend()
plt.show()
总结
以上就是今天学习的内容,本文仅仅简单介绍了神经网络分类鸢尾花数据,简单的介绍了输出输出层之间数据的前向传播以及反向传播(即w1, b1的更新过程),并未涉及到隐藏层的概念,后续会陆续更新更加准确的神经网络分类。