zoukankan      html  css  js  c++  java
  • 案例一:鸢尾花数据的分类

    一:准备数据

    1.1:读入数据集

    from sklearn.datasets import load_iris
    from sklearn import datasets
    import pandas
    import matplotlib.pyplot as plt
    
    x_data = datasets.load_iris().data
    y_data = datasets.load_iris().target
    print(x_data.shape)
    print(y_data.shape)
    

    1.2: 数据集乱序

    print(y_data)
    

    # seed()+shuffle
    import random
    
    seed=10
    random.seed(seed)
    random.shuffle(x_data)
    random.seed(seed)# 一定得重复在写一遍,和上面的seed要相同,不然y_batch和x_batch打乱顺序会不一样
    random.shuffle(y_data)
    
    print(y_data)
    

    1.3:生成训练集和测试集

    from sklearn.model_selection import train_test_split
    (X_train,X_test,y_train,y_test) = train_test_split(x_data, y_data, train_size=0.8, random_state=seed)
    print(X_train.shape)
    print(X_test.shape)
    print(y_train.shape)
    print(y_test.shape)
    

    1.4:(特征 - 标签)配对,且每次只读入一部分(batch)进行训练

    import tensorflow as tf
    # import tensorflow.compat.v1 as tf
    # tf.enable_eager_execution()
    
    train_data = tf.data.Dataset.from_tensor_slices((X_train, y_train)).batch(30)
    test_data = tf.data.Dataset.from_tensor_slices((X_test, y_test)).batch(30)
    

    batch(30):以每组30个的形式,喂入模型时以bacth为单位。一般选2的幂次。

    # DatasetV1Adapter类型
    train_data
    test_data
    

    二:搭建网络

    定义神经网络中所有可训练参数

    w1 = tf.Variable(tf.random.truncated_normal([4,3], stddev=0.1, seed=1, dtype=tf.float64))
    b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1, dtype=tf.float64))
    

    因为X的特征有4个,所以第一层有4个输入。
    且最终分类结果只有3个,所以最后一层输入为3
    又因为模型只有两层,所以第一层的输出 = 下一层的输入,为3。
    所以:

    • w1维度为:(4, 3)
    • b1维度为:(3, )
    lr = 0.1  # 学习率为0.1
    train_loss_results = []  # 将每轮的loss记录在此列表中,为后续画loss曲线提供数据
    test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
    epoch = 500  # 循环500轮
    loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和
    

    三:参数优化

    嵌套循环迭代,with结构更新参数,显示当前loss

    for epoch in range(epoch):# 数据集级别迭代
        for step,(x_train,y_train) in enumerate(train_data):# batch级别迭代
            with tf.GradientTape() as tape: # 记录梯度信息
                # 正向传播
                y = tf.matmul(x_train, w1) + b1 # 神经网络乘、加运算
                y = tf.nn.softmax(y) # 使分类输出转换成概率的形式,(注意:此操作后,与独热码同量级,可相减求loss)
                y_one_hot = tf.one_hot(y_train, depth=3, dtype=tf.float64)# 将标签值转换成独热码格式,方便计算loss和acc
                
                # 计算损失loss
                loss = tf.reduce_mean(tf.square(y_one_hot - y))
    #            # 这两句话的区别是 loss = tf.reduce_mean(tf.square(y_one_hot, y))
                loss_all += loss.numpy()
    
            # 计算loss对各个参数的梯度(导数)
            grads = tape.gradient(loss, [w1, b1])
            
            # 梯度自更新 w1 = w1 - lr*grads[0]; b1 = b1- lr*grads[1]
            w1.assign_sub(lr*grads[0])
            b1.assign_sub(lr*grads[1])  
        print("Epoch {}, loss: {}".format(epoch, loss_all/4))
        train_loss_results.append(loss_all / 4)
        loss_all = 0
        
        # 求模型的准确率
        total_correct, total_number = 0, 0
        for x_test, y_test in test_data:
            y = tf.matmul(x_test, w1)+b1 # 模型对三个分类的预测概率
            y = tf.nn.softmax(y) # 对y进行归一化
            pred = tf.argmax(y, axis=1) # 获取概率值最大的下标(也就是获取y的分类)
            pred = tf.cast(pred, dtype=y_test.dtype)
            # 若分类正确,则correct=1,否则为0
            correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
            total_correct += int(tf.reduce_sum(correct)) # 把一个批次的分类结果累加起来,保存到变量中
            total_number += x_test.shape[0]
    
        acc = total_correct / total_number
        test_acc.append(acc)
        print("Test acc: ", acc)
        print("-----------------------------------------------")
    

    这里的 y 相当于是 y_predict,y_test 相当于y_true。通过softmax将 y 转换成符合概率分布的概率值(不是很理解为什么要加这一步,不加好像也可以)。

    因为 y 的维度为[batch, 3],y_test 的维度为 [batch, 1]。采取的方法是将 y_test 转换成(三维)独热编码。

    损失函数 loss 即为两者的方差。

    acc/loss可视化

    plt.title("Loss Function Curve")
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    # 画出trian_loss_results曲线,且连线图标是Loss
    plt.plot(train_loss_results, label="$Loss$")
    # 画出曲线的图标(右上角)
    plt.legend()
    plt.show()
    

    plt.title("Acc Curve")
    plt.xlabel("Epoch")
    plt.ylabel("Acc")
    plt.plot(test_acc, label="$Accuracy$")# 连线图标是Accuracy
    plt.legend()
    plt.show()
    

  • 相关阅读:
    【洛谷3214】[HNOI2011] 卡农(思维)
    【洛谷2609】[ZJOI2012] 数列(高精度)
    【洛谷4501】[ZJOI2018] 胖(二分+RMQ)
    【洛谷4726】【模板】多项式指数函数(多项式 exp)
    uC/OS-II之入门与介绍20160525
    [转]Delphi 关键字详解
    [转]单元文件结构
    Delphi ComboBox的属性和事件、及几个鼠标事件的触发
    Delphi 用ToolButton和MonthCalendar实现DateTimePicker的功能
    Delphi 动态改变Rzsplitter的Orientation(方向)属性
  • 原文地址:https://www.cnblogs.com/linlk7571/p/13934010.html
Copyright © 2011-2022 走看看