多层神经网络

知识核心

  1. 多层神经网络构成是多个w的问题,如果有n个w,一个b的情况下,则有2^(n-1)个构成方式,比如有两个w的时候,函数公式可以是以下两种:y = xw1w2+b或者y = (xw1 + b)w2
  2. 多层神经网络会把训练速度降低
  3. 多层神经网络并不会对最终结果有过多影响,因为最终公式其实就是y = xw + b,只不过其中w被拆分成了多个条件而已
  4. 多层神经网络计算公式推导:如果y是三行四列的矩阵(3, 4),x是三行九列的举证(3,9)则,y = xw + b中w为九行四列(9,4),b为三行四列(3,4),这时候,把w拆为w1叉乘w2,那么可以为(9,N)叉乘(N,4)

代码

# 使用鸢尾花数据集
import tensorflow as tf
import numpy as np
from sklearn.datasets import load_iris

x_data = load_iris().data      # 返回iris数据集所有输入特征值
y_data = load_iris().target    # 返回iris数据集所有标签

# 因为x_data和y_data使用同样的随机种子,打乱顺序的算法是一样的,所以打乱后的特征和标签对应关系保持不变
np.random.seed(1024)           # 设置随机种子
np.random.shuffle(x_data)      # 按随机种子打乱数据顺序
np.random.seed(1024)           # 设置随机种子
np.random.shuffle(y_data)      # 按随机种子打乱数据顺序
tf.random.set_seed(1024)

# 取钱120条数据集作为训练集
x_train = x_data[:-30]
y_train = y_data[:-30]

# 取后30条数据集作为测试集
x_test = x_data[-30:]
y_test = y_data[-30:]

# 转变特征的数据类型(把numpy类型的数据转为Tensor类型的数据),否则后面矩阵叉乘时会因为数据类型不一致报语法错误
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)

# 配对特征和标签,每次未入神经网络一个batch
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)

# 定义神经网络中所有可训练参数
w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
w2 = tf.Variable(tf.random.truncated_normal([3, 3], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))
b2 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))

epoch = 5000   # 循环学习5000次,看实际情况,如果学习的知识太复杂可以增加学习轮数
lr = 0.2       # 定义学习率,也可以根据实际情况调整

"""
这个for迭代了5000次,每次学习一个batch组数据集(第一组batch:32个数据集;第二组batch:32个数据集;第三组batch:32个数据集;第四组batch:24个数据集)
"""
for epoch in range(epoch):
    # 下面的for迭代4次(train_db有4个元素,每个元素是一个batch)
    for step, (x_train, y_train) in enumerate(train_db):
        with tf.GradientTape() as tape:
            a = tf.matmul(x_train, w1) + b1   # 计算第一层神经网络
            y = tf.matmul(a, w2) + b2    # 计算第二层神经网络
            y = tf.nn.softmax(y)              # 使y符合概率分布并可以和独热码对比
            y_ = tf.one_hot(y_train, depth=3) # 将标签转换为独热码(3分类)
            loss = tf.reduce_mean((tf.square(y_ - y)))   # 损失函数
        grads = tape.gradient(loss, [w1, w2, b1])    # 让loss分别对w1,w2和b1求偏导
        w1.assign_sub(lr * grads[0])   # 更新w1(w1 = w1 - lr * w1_grad)
        w2.assign_sub(lr * grads[1])   # 更新w2(w1 = w2 - lr * w2_grad)
        b1.assign_sub((lr * grads[2])) # 更新b1(b1 = b1 - lr * b1_grad)
        b2.assign_sub((lr * grads[2])) # 更新b1(b2 = b2 - lr * b2_grad)
    print(f"轮数:{epoch}, loss值:{loss}")

print("-------------------------------------结果--------------------------------------------")
print("=======================================w1结果===============================================")
print(w1)
print("=======================================w2结果===============================================")
print(w2)
print("=======================================b1结果===============================================")
print(b1)
print("=======================================b2结果===============================================")
print(b2)


for x_test, y_test in test_db:     # 一次性未入30ge数据集的特征到神经网络,共喂入1次
    a = tf.matmul(x_test, w1)   # 用求出的w1和b1根据测试集中的特征预测结果
    y = tf.matmul(a, w2) + b1   # 用求出的w1和b1根据测试集中的特征预测结果
    y = tf.nn.softmax(y)             # 让y符合概率分布
    pred = tf.argmax(y, axis=1)      # 返回y中最大值的索引, 既预测的分类
    print("============================结果=================================")
    print(pred)         # 每个特征值预测的结果,本案例中,我们的神经网络根据30个特征预测的结果
    print(y_test)       # 测试集中的每个特征对应的标签, 测试集中的30个标签


posted @ 2023-10-11 15:37  影梦无痕  阅读(51)  评论(0)    收藏  举报