政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(六)—— 二元分类

news2024/11/15 12:01:08

政安晨的个人主页政安晨

欢迎 👍点赞✍评论⭐收藏

收录专栏政安晨的机器学习笔记

希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!

这篇文章咱们将深度学习应用到另一个常见任务中。


前言

在深度学习中,二元分类是一种常见的任务,旨在将输入数据分为两个类别之一这两个类别可以是任意两个互斥的类别,例如“正面”和“负面”,“真”和“假”,或者任何其他可以用于区分数据的两个标签。

二元分类问题的目标是训练一个模型,使其能够根据输入数据的特征来预测其所属的类别。深度学习通过构建深度神经网络来解决这个问题。通常,一个深度神经网络由多个隐藏层组成,每个隐藏层都包含多个神经元。这些神经元通过学习权重和偏差来逐渐调整模型,以最大限度地减少分类错误。

在深度学习中,常用的二元分类算法包括逻辑回归、支持向量机、决策树和随机森林等。这些算法在处理不同类型的数据和任务时表现不同,所以选择适合特定问题的算法是很重要的。

为了训练一个二元分类模型,需要准备一个标记好的训练数据集,其中包含了输入数据和对应的类别标签。然后,将数据输入到深度神经网络中,通过反向传播算法和梯度下降优化算法来调整模型的参数,以使模型能够更好地预测新的未见过的数据样本的类别。

在实际应用中,二元分类可以应用于很多领域,例如情感分析、垃圾邮件过滤、疾病诊断等。通过深度学习的技术,可以提高模型的准确性和泛化能力,使其在复杂的数据集上取得更好的性能。

到目前为止,我们在本系列的文章中已经学习了神经网络如何解决回归问题。现在我们将把神经网络应用到另一个常见的机器学习问题:分类。我们之前学到的大部分内容仍然适用。主要的区别在于我们使用的损失函数以及我们希望最后一层产生什么样的输出

二元分类 

将数据分为两个类别是一种常见的机器学习问题。你可能想预测一个客户是否有可能购买,一笔信用卡交易是否存在欺诈,深空信号是否显示出一颗新行星的证据,或者一项医学测试是否有疾病的证据。这些都是二元分类问题。

在原始数据中,类别可能由字符串表示,例如 "Yes" 和 "No",或者 "Dog" 和 "Cat"。在使用这些数据之前,我们将为其分配一个类别标签:一个类别将被赋值为 0,另一个类别将被赋值为 1将类别标签分配为数字将使数据能够被神经网络使用。

准确率和交叉熵

准确率是用于衡量分类问题成功程度的众多度量中的一种。准确率是正确预测数与总预测数的比值:准确率 = 正确预测数 / 总预测数。如果一个模型的预测始终正确,其准确率为1.0。其他条件相同的情况下,准确率是一个合理的度量指标,适用于数据集中的类别出现频率相近的情况。

准确率(以及大多数其他分类指标)的问题在于它不能用作损失函数。随机梯度下降(SGD)需要一个变化平滑的损失函数,但准确率作为一个计数比率,变化是“跳跃”的。因此,我们必须选择一个替代物来充当损失函数。这个替代物就是交叉熵函数。

现在,回想一下,损失函数定义了网络在训练过程中的目标。在回归中,我们的目标是最小化预期结果和预测结果之间的距离。我们选择了MAE来衡量这个距离。

对于分类任务,我们所希望的是概率之间的距离,而交叉熵提供了这种距离。交叉熵是一种衡量从一个概率分布到另一个概率分布的距离的方法。

交叉熵对错误的概率预测进行惩罚。

这个想法是我们希望我们的网络能以概率1.0预测出正确的类别。预测概率距离1.0越远,交叉熵损失就越大。

我们使用交叉熵的技术原因有点微妙,但从本节中要记住的主要事情就是:

对于分类损失,请使用交叉熵;

您可能关心的其他指标(如准确性)往往也会随之改善。

使用Sigmoid函数生成概率

交叉熵和准确率函数都需要概率作为输入,也就是0到1之间的数字。为了将密集层产生的实值输出转换为概率,我们需要使用一种新的激活函数,即sigmoid激活函数

Sigmoid函数将实数映射到区间[0,1]中。

为了得到最终的类别预测,我们定义了一个阈值概率。通常情况下,这个阈值概率是0.5,这样四舍五入就可以给出正确的类别预测:小于0.5表示标签为0的类别,大于等于0.5表示标签为1的类别。0.5阈值是Keras在默认情况下使用的准确度指标。

示例 — 二元分类

让我们尝试下面这个例子:

电离层数据集包含从地球大气层的电离层层面上获取的雷达信号特征。任务是确定信号是否显示出某个物体的存在,还是只是空气。

import pandas as pd
from IPython.display import display

ion = pd.read_csv('../input/dl-course-data/ion.csv', index_col=0)
display(ion.head())

df = ion.copy()
df['Class'] = df['Class'].map({'good': 0, 'bad': 1})

df_train = df.sample(frac=0.7, random_state=0)
df_valid = df.drop(df_train.index)

max_ = df_train.max(axis=0)
min_ = df_train.min(axis=0)

df_train = (df_train - min_) / (max_ - min_)
df_valid = (df_valid - min_) / (max_ - min_)
df_train.dropna(axis=1, inplace=True) # drop the empty feature in column 2
df_valid.dropna(axis=1, inplace=True)

X_train = df_train.drop('Class', axis=1)
X_valid = df_valid.drop('Class', axis=1)
y_train = df_train['Class']
y_valid = df_valid['Class']
V1V2V3V4V5V6V7V8V9V10...V26V27V28V29V30V31V32V33V34Class
1100.99539-0.058890.852430.023060.83398-0.377081.000000.03760...-0.511710.41078-0.461680.21266-0.340900.42267-0.544870.18641-0.45300good
2101.00000-0.188290.93035-0.36156-0.10868-0.935971.00000-0.04549...-0.26569-0.20468-0.18401-0.19040-0.11593-0.16626-0.06288-0.13738-0.02447bad
3101.00000-0.033651.000000.004851.00000-0.120620.889650.01198...-0.402200.58984-0.221450.43100-0.173650.60436-0.241800.56045-0.38238good
4101.00000-0.451611.000001.000000.71216-1.000000.000000.00000...0.906950.516131.000001.00000-0.200990.256821.00000-0.323821.00000bad
5101.00000-0.024010.941400.065310.92106-0.232550.77152-0.16399...-0.651580.13290-0.532060.02431-0.62197-0.05707-0.59573-0.04608-0.65697good

我们将和回归任务一样定义我们的模型,只有一个例外。在最后一层中包括一个'sigmoid'激活函数,以便模型能够产生类别概率。

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Dense(4, activation='relu', input_shape=[33]),
    layers.Dense(4, activation='relu'),    
    layers.Dense(1, activation='sigmoid'),
])

将交叉熵损失和准确度度量指标添加到模型中,并使用compile方法。

对于两类问题,请确保使用“binary”版本。(对于更多类别的问题会稍有不同。)Adam优化器在分类问题上效果很好,因此我们将继续使用它。

model.compile(
    optimizer='adam',
    loss='binary_crossentropy',
    metrics=['binary_accuracy'],
)

在这个特定问题中,模型可能需要很多个时期来完成训练,因此我们将包含一个提前停止的回调函数以方便操作。

early_stopping = keras.callbacks.EarlyStopping(
    patience=10,
    min_delta=0.001,
    restore_best_weights=True,
)

history = model.fit(
    X_train, y_train,
    validation_data=(X_valid, y_valid),
    batch_size=512,
    epochs=1000,
    callbacks=[early_stopping],
    verbose=0, # hide the output because we have so many epochs
)

我们将像往常一样查看学习曲线,还会检查在验证集上获得的损失和准确率的最佳值。(请记住,提前停止训练会恢复权重到获得这些值的状态。)

history_df = pd.DataFrame(history.history)
# Start the plot at epoch 5
history_df.loc[5:, ['loss', 'val_loss']].plot()
history_df.loc[5:, ['binary_accuracy', 'val_binary_accuracy']].plot()

print(("Best Validation Loss: {:0.4f}" +\
      "\nBest Validation Accuracy: {:0.4f}")\
      .format(history_df['val_loss'].min(), 
              history_df['val_binary_accuracy'].max()))

做个练习:二元分类

介绍

在这个练习中,你将使用一个二元分类器来预测酒店取消预订。

# Setup plotting
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
# Set Matplotlib defaults
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',
       titleweight='bold', titlesize=18, titlepad=10)
plt.rc('animation', html='html5')

# Setup feedback system
from learntools.core import binder
binder.bind(globals())
from learntools.deep_learning_intro.ex6 import *

首先,加载“酒店取消”数据集。

import pandas as pd

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.compose import make_column_transformer

hotel = pd.read_csv('../input/dl-course-data/hotel.csv')

X = hotel.copy()
y = X.pop('is_canceled')

X['arrival_date_month'] = \
    X['arrival_date_month'].map(
        {'January':1, 'February': 2, 'March':3,
         'April':4, 'May':5, 'June':6, 'July':7,
         'August':8, 'September':9, 'October':10,
         'November':11, 'December':12}
    )

features_num = [
    "lead_time", "arrival_date_week_number",
    "arrival_date_day_of_month", "stays_in_weekend_nights",
    "stays_in_week_nights", "adults", "children", "babies",
    "is_repeated_guest", "previous_cancellations",
    "previous_bookings_not_canceled", "required_car_parking_spaces",
    "total_of_special_requests", "adr",
]
features_cat = [
    "hotel", "arrival_date_month", "meal",
    "market_segment", "distribution_channel",
    "reserved_room_type", "deposit_type", "customer_type",
]

transformer_num = make_pipeline(
    SimpleImputer(strategy="constant"), # there are a few missing values
    StandardScaler(),
)
transformer_cat = make_pipeline(
    SimpleImputer(strategy="constant", fill_value="NA"),
    OneHotEncoder(handle_unknown='ignore'),
)

preprocessor = make_column_transformer(
    (transformer_num, features_num),
    (transformer_cat, features_cat),
)

# stratify - make sure classes are evenlly represented across splits
X_train, X_valid, y_train, y_valid = \
    train_test_split(X, y, stratify=y, train_size=0.75)

X_train = preprocessor.fit_transform(X_train)
X_valid = preprocessor.transform(X_valid)

input_shape = [X_train.shape[1]]

1. 定义模型

这次我们将使用的模型将包含批量归一化(batch normalization)和丢弃层(dropout)。

为了方便阅读,我们已将图表分成了几个块,但你可以按照通常的方式逐层定义它。

定义一个模型,其架构由以下图表给出:

二分类器的图示。

from tensorflow import keras
from tensorflow.keras import layers

# YOUR CODE HERE: define the model given in the diagram
model = ____

# Check your answer
q_1.check()

2. 添加优化器、损失函数和评估指标

现在使用Adam优化器和交叉熵损失函数和准确度指标的二进制版本来编译模型。

# YOUR CODE HERE
____

# Check your answer
q_2.check()
# Lines below will give you a hint or solution code
#q_2.hint()
#q_2.solution()

最后,运行这个单元格来训练模型并查看学习曲线。这可能需要大约60到70个epochs,可能需要一到两分钟。

early_stopping = keras.callbacks.EarlyStopping(
    patience=5,
    min_delta=0.001,
    restore_best_weights=True,
)
history = model.fit(
    X_train, y_train,
    validation_data=(X_valid, y_valid),
    batch_size=512,
    epochs=200,
    callbacks=[early_stopping],
)

history_df = pd.DataFrame(history.history)
history_df.loc[:, ['loss', 'val_loss']].plot(title="Cross-entropy")
history_df.loc[:, ['binary_accuracy', 'val_binary_accuracy']].plot(title="Accuracy")

3. 训练和评估

你对学习曲线有什么看法?模型是否欠拟合或过拟合?交叉熵损失是否是准确度的一个很好的替代指标?

结论

恭喜您,这是咱们这个系列的最后一篇文章,如果您都看完了,凭借您的新技能,您可以开始进行更高级的应用了,如计算机视觉和情感分类。您想下一步做什么呢?(呵呵)


本系列总共六篇文章,前五篇分别是:

【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(一)—— 单个神经元

【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(二)—— 深度神经网络

【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(三)—— 随机梯度下降

【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(四)—— 过拟合和欠拟合

【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(五)—— Dropout和批归一化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1539129.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Matlab的眼底图像血管分割,Matlab实现

博主简介: 专注、专一于Matlab图像处理学习、交流,matlab图像代码代做/项目合作可以联系(QQ:3249726188) 个人主页:Matlab_ImagePro-CSDN博客 原则:代码均由本人编写完成,非中介,提供…

前端应用开发实验:条件渲染和循环渲染

目录 实验目的相关知识点实验内容图片的隐藏和显示代码实现效果 电影票房排序代码实现效果 代办事项记录代码实现效果 实验目的 (1)熟练掌握v-on 指令的用法,学会使用v-on 指令监听DOM元素的事件,并通过该事件触发调用事件处理程序。 (2)掌握v-on指令修…

FFmepg--AVFilter过滤器使用以及yuv视频裁剪

文章目录 AVFilter 流程:api核心代码变量yuv视频裁剪AVFilter 流程: ⾸先使⽤split滤波器将input流分成两路流(main和tmp),然后分别对两路流进⾏处理。对于tmp流,先经过crop滤波器进⾏裁剪处理,再经过flip滤波器进⾏垂直⽅向上的翻转操作,输出的结果命名为flip流。再将…

【技术栈】Redis 中的事务及持久化方式

SueWakeup 个人主页: SueWakeup 系列专栏:学习技术栈 个性签名:保留赤子之心也许是种幸运吧 本文封面由 凯楠📸 友情提供 目录 相关传送门 1. Redis 中的事务 2. Redis 持久化 2.1 RDB 方式 2.1.1 RDB手动 2.1.2 RDB自动 2.…

百度地图的使用(js,vue2,vue3)

百度地图的使用 创建应用获取密钥ak ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key 一、原生js使用百度地图 引入<script type"text/javascript" src"https://api.map.baidu.com/api?v1.0&typewebgl&ak你的ak&…

后端系统开发之——功能完善

原文地址&#xff1a;https://blog.yiming1234.cn/?p830 下面是正文内容&#xff1a; 前言 通过SpringBoot开发用户模块的部分也就差不多要结束了&#xff0c;这一片文章就主要提一些在系统开发中需要注意到的细节部分和功能&#xff0c;也就是剩余的部分。 但是这个专栏只介…

一键掌控:Shell脚本自动化安装与管理Conda环境的艺术

前面写了个博客《conda&#xff1a;解决多项目开发环境配置的神器&#xff01;》简单介绍了 Conda 的安装和基本命令&#xff0c;在做开发时经常会使用 Conda 建立多个应用环境&#xff0c;Conda 的命令虽不复杂&#xff0c;但还是有时会弄混&#xff0c;所以就考虑写个脚本&am…

pyrealsense2获取保存点云

一、第一种实现代码 Python import sys import cv2 import pyrealsense2 as rs import numpy as np import keyboard import open3d as o3d import osif __name__ "__main__":output_folder output_data/os.makedirs(output_folder, exist_okTrue)pipeline rs.p…

Prometheus+Grafana 监控Tongweb嵌入式(by lqw)

文章目录 1.思路2.部署准备3.Grafana仪表盘json文件下载4.tw嵌入式jar包本地引入依赖并测试运行5.运行jmx_prometheus_javaagent-0.19.0.jar形式获取监控数据&#xff08;方法一&#xff09;6.使用Actuator 获取监听数据&#xff08;方法二&#xff09;7.Prometheus部署8.Prome…

项目配置之道:优化Scrapy参数提升爬虫效率

前言 在当今信息时代&#xff0c;数据是无处不在且无比重要的资源。为了获取有效数据&#xff0c;网络爬虫成为了一项至关重要的技术。Scrapy作为Python中最强大的网络爬虫框架之一&#xff0c;提供了丰富的功能和灵活的操作&#xff0c;让数据采集变得高效而简单。本文将以爬…

算法打卡day25|回溯法篇05|Leetcode 491.递增子序列、46.全排列、47.全排列 II

算法题 Leetcode 491.递增子序列 题目链接:491.递增子序列 大佬视频讲解&#xff1a;递增子序列视频讲解 个人思路 和昨天的子集2有点像&#xff0c;但昨天的题是通过排序&#xff0c;再加一个标记数组来达到去重的目的。 而本题求自增子序列&#xff0c;是不能对原数组进行…

Prometheus+Grafana 监控Tongweb7(by lqw)

文章目录 1.准备工作2.Tongweb7部署3.Prometheus部署4.上传jar包并配置Tongweb75.Prometheus配置6.安装和配置Grafana 1.准备工作 本次参考&#xff1a;Prometheus监控Tongweb容器 1.使用虚拟机ip&#xff1a;192.168.10.51&#xff08;tongweb&#xff09;&#xff0c;192.1…

oracle设置主键自增步骤

设置主键自增步骤&#xff1a; 每一张表都要设置序列&#xff0c;然后设置触发器。比mysql繁琐。 一、设置序列 选中表后&#xff0c;—》 文件—》新建—》其他—》序列. 设置如下四个值即可。 crtls保存。 给序列起个名字&#xff0c;一定要全大写字母。 二、设置触发器…

防火墙在解决方案及典型项目中的应用

防火墙在解决方案及典型项目中的应用 防火墙作为基础安全防护产品&#xff0c;在各种解决方案、业务场景中配套应用&#xff0c;本节给出各类方案资料链接方便查阅。 防火墙在华为网络解决方案中的应用 解决方案 文档 主要应用 CloudFabric云数据中心网解决方案 资料专区…

java设计模式(2)---六大原则

设计模式之六大原则 这篇博客非常有意义&#xff0c;希望自己能够理解的基础上&#xff0c;在实际开发中融入这些思想&#xff0c;运用里面的精髓。 先列出六大原则&#xff1a;单一职责原则、里氏替换原则、接口隔离原则、依赖倒置原则、迪米特原则、开闭原则。 一、单一职…

Java中调用由C/C++实现的本地库(JNI本地程序调用)

文章目录 背景介绍什么是JNI&#xff1f;什么是本地库&#xff1f;开发Java使用JNI本地库步骤 编写Java类实现JNI本地调用windows系统下编译动态链接库创建Java项目&#xff08;demo&#xff09;第一步&#xff1a;编写带有native的Java类第二步&#xff1a;javac生成NativeDem…

C++的缺省参数,函数重载,引用

目录 1、缺省参数&#xff08;不能在函数声明和定义中同时出现&#xff0c;若声明和定义是分开的&#xff0c;则缺省参数放在声明里面&#xff09; 1.1、缺省参数的概念 1.2、全缺省 1.3、半缺省 2、函数重载 2.1、特殊情况 2.2、特殊情况 2.3、为什么C支持函数重载而C语…

springboot+itextpdf+thymeleaf+ognl根据静态模版文件实现动态生成pdf文件并导出demo

第一步&#xff1a;导入maven依赖 <!-- 导出为PDF依赖包 --><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId></dependency><dependency><groupId>com.itextpdf</groupId><art…

网络安全慢速攻击

什么是低速缓慢攻击&#xff1f; 低速缓慢攻击是 DoS 或 DDoS 攻击的一种&#xff0c;依赖一小串非常慢的流量&#xff0c;可以针对应用程序或服务器资源发起攻击。与更传统的蛮力攻击不同&#xff0c;低速缓慢攻击所需的带宽非常小&#xff0c;并且难以防护&#xff0c;因为它…

Day60:WEB攻防-PHP反序列化POP链构造魔术方法流程漏洞触发条件属性修改

目录 PHP-DEMO1-序列化和反序列化 序列化操作 - 即类型转换 序列化案例 PHP-DEMO2-魔术方法触发规则 __construct(): //当对象new的时候会自动调用 __destruct()&#xff1a;//当对象被销毁时会被自动调用 __sleep(): //serialize()执行时被自动调用 __wakeup(): //uns…