会员可以在此提问,百战程序员老师有问必答
对大家有帮助的问答会被标记为“推荐”
看完课程过来浏览一下别人提的问题,会帮你学得更全面
截止目前,同学们一共提了 132358个问题

基于tensorflow1.X的版本,图片中在模型网络定义完成后,在定义相关的评价指标过程中所做的事情:image.png

1. 定义损失函数(交叉熵损失函数)

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y * tf.log(y_pred), reduction_indices=[1]))

  • 目的:计算模型预测值与真实标签之间的差距。

  • 具体操作

    • y * tf.log(y_pred):逐元素计算真实标签 y 与预测值 ypred 的对数的乘积。

    • tf.reduce_sum(..., reduction_indices=[1]):对每个样本的损失值求和(沿类别维度)。

    • -tf.reduce_mean(...):对所有样本的损失值取平均,得到最终的标量损失值。

  • 结果cross_entropy 是一个标量值,表示当前批次数据的平均交叉熵损失。

  • (每一个批次求一个平均损失值,以批次为单位去校正模型的训练和评价模型)


2. 定义优化器

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
  • 目的:通过梯度下降法更新模型参数,以最小化损失函数。

  • 具体操作

    • tf.train.GradientDescentOptimizer(0.01):使用学习率为 0.01 的梯度下降优化器。

    • .minimize(cross_entropy):最小化交叉熵损失函数。

  • 结果train_step 是一个操作节点,执行时会更新模型参数。


3. 定义评价指标(准确率)

correct_prediction = tf.equal(tf.argmax(y_pred, 1), tf.argmax(y, 1))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
  • 目的:评估模型的分类准确率。

  • 具体操作

    • tf.argmax(y_pred, 1):获取每个样本预测概率最大的类别索引。

    • tf.argmax(y, 1):获取每个样本真实标签的类别索引。

    • tf.equal(...):比较预测类别和真实类别是否相等,返回 布尔值 。

    • tf.cast(..., tf.float32):将布尔值转换为浮点数(True -> 1.0,False -> 0.0)。

    • tf.reduce_mean(...):计算所有样本的准确率平均值。

  • 结果accuracy 是一个标量值,表示当前批次数据的分类准确率。


4. 初始化变量

with tf.Session() as sess:
    tf.global_variables_initializer().run()
  • 目的:初始化 TensorFlow 计算图中的所有变量。

  • 具体操作

    • tf.global_variables_initializer():创建一个初始化所有全局变量的操作。

    • .run():在会话中执行初始化操作。

  • 结果:所有变量(如权重、偏置等)被初始化为默认值或指定值。


5. 训练模型

for __ in range(10000):
  • 目的:通过多次迭代训练模型。

  • 具体操作

    • 在循环中,每次迭代会执行 train_step 操作,更新模型参数。

    • 可以使用 sess.run([train_step, cross_entropy, accuracy], feed_dict={...}) 来同时计算损失值和准确率。

  • 结果:模型参数逐渐优化,损失值减小,准确率提高。


人工智能/第十一阶段:深度学习-原理和进阶/TensorFlow深度学习工具 256楼

交叉熵损失函数:

image.png

比喻:猜谜游戏

想象你在玩一个猜谜游戏,游戏中有多个选项(类别),每个选项都有一个正确的概率(真实分布),而你需要根据提示(模型预测)选择一个最可能的答案。交叉熵的作用就是衡量你的猜测(预测分布)与正确答案(真实分布)之间的“距离”。


过程:

  1. 真实分布:每个类别都有一个真实标签(比如正确答案是“猫”),真实分布是一个“独热编码”(one-hot)向量,只有正确答案的概率是 1,其他都是 0。

  2. 预测分布:模型会输出一个概率分布(比如“猫”概率 0.7,“狗”概率 0.2,“鸟”概率 0.1),表示模型对每个类别的预测信心。

  3. 计算差距:交叉熵通过比较真实分布和预测分布,计算两者之间的“差距”。如果模型预测的概率分布与真实分布越接近,交叉熵的值越小;反之,差距越大,交叉熵的值越大。


直观理解:

  • 惩罚错误:交叉熵会重点惩罚那些模型预测错误的地方。比如,如果真实答案是“猫”,但模型给“猫”的概率很低(比如 0.1),交叉熵会给出一个很大的损失值,提醒模型“你错了,要改正”。

  • 鼓励正确:如果模型预测的概率分布与真实分布一致(比如“猫”概率 1,其他概率 0),交叉熵的值会很小,甚至为 0,表示模型预测完全正确。


结果:

交叉熵损失函数的作用是指导模型不断调整参数,使得预测分布越来越接近真实分布。通过最小化交叉熵,模型可以逐渐学会更准确地分类。


总结:

交叉熵就像一位严格的老师,它会根据模型的预测结果打分:

  • 如果模型猜对了,老师会表扬(损失值小);

  • 如果模型猜错了,老师会批评(损失值大),并告诉模型如何改进。


image.png

对于结果的输出,结合softmax和交叉熵损失函数去理解:

模型训练的过程上:

1. 模型预测

首先,模型会对输入数据 X 进行处理,通常通过一系列线性变换和非线性激活函数(如Softmax)生成预测概率分布 ypred。假设我们有 k 个类别,那么 ypred 将是一个 m×k 的矩阵,其中每一行表示一个样本的预测概率分布。

2. 真实标签

真实标签 ytrue 通常是一个 m×k 的独热编码矩阵,其中每一行表示一个样本的真实类别。如果样本的真实类别是第 j 个类别,那么该行的第 j 个元素为 1,其余元素为 0。

3. 计算交叉熵

交叉熵损失函数的计算公式为:

Cross-Entropy=i=1mj=1kytrue,ijlog(ypred,ij)

其中:

  • ytrue,ij 是真实标签矩阵中第 i 个样本的第 j 个类别的值(0 或 1)。

  • ypred,ij 是预测概率矩阵中第 i 个样本的第 j 个类别的概率。

4. 维度转换

  • 对于每个样本 i,计算其交叉熵损失:

    Lossi=j=1kytrue,ijlog(ypred,ij)

    这一步会得到一个标量值,表示第 i 个样本的损失。

  • 对所有 m 个样本重复上述计算,最终得到一个 m×1 的损失值矩阵,其中每个元素表示对应样本的交叉熵损失。

5. 总结

  • 输入数据 X 是 m×n 的矩阵。

  • 模型预测 ypred 是 m×k 的矩阵。

  • 真实标签 ytrue 是 m×k 的矩阵。

  • 交叉熵损失函数通过逐样本计算损失,最终得到一个 m×1 的损失值矩阵


小结:

  • Softmax 的作用是将神经网络输出的 logits Zm×k)转换为概率分布 ypredm×k),即对每个样本的 logits 进行归一化,得到每个类别的预测概率。

  • 交叉熵损失函数 的作用是基于每个样本的预测概率分布 ypred,i 和真实分布 ytrue,i,计算一个标量损失值。最终,所有样本的损失值组成一个 m×1 的损失矩阵。


人工智能/第十一阶段:深度学习-原理和进阶/TensorFlow深度学习工具 257楼

image.png

softmax回归用于将n维度在特征拟合成m类别的多分类问题

image.png

截距项b的数量取决于下一层的节点数量(b -- 全连接的关系)


W = tf.Variable(tf.random_uniform([784,10])) -- 参数W矩阵 784维的特征

b = tf.Variable(tf.zeros([10])) -- 截距项b 一维的向量

这里定义了一个浅层简单的神经网络,中间没有隐藏层,b的形状代表输出层的输出类别数量

初始化时,W参数集合一般初始化为较小的但不能为0的数,b可以初始化为0(b做的是加法,不是乘法)

image.png

Z的维度是[m,10],(W*X:[m,784]*[784,10] -- [m,10](矩阵乘法) ; b广播机制 -- Z:[m,10])


! softmax:

image.png

比喻:投票与权重

想象一下,你有一群朋友(每个朋友代表一个类别),他们一起决定去哪里吃饭。每个朋友都有一个“影响力分数”(模型的原始输出分数),分数越高,说明这个朋友的影响力越大。Softmax 的作用就是根据这些分数,计算出每个朋友的“投票权重”,最终决定去哪里吃饭的概率。

过程:

  1. 原始分数:每个类别(朋友)都有一个原始分数,这个分数可能来自模型的输出(比如神经网络的最后一层)。

  2. 指数放大:Softmax 首先对这些分数进行指数运算。指数函数的特点是,分数越高,放大得越多;分数越低,放大得越少。这就像给影响力大的朋友更多的“话语权”。

  3. 归一化:接下来,Softmax 将所有放大后的分数加在一起,得到总和。然后,每个类别的放大分数除以这个总和,得到每个类别的概率。这个过程就像把所有朋友的投票权重归一化,确保总和为 1(即 100% 的概率)。

结果:

最终,Softmax 输出的是一组概率值,每个值代表该类别的“获胜概率”。概率最大的类别就是模型预测的结果。

直观理解:

  • 高分更突出:Softmax 会放大高分,抑制低分,使得高分对应的类别概率更大。

  • 概率分布:输出的概率值总和为 1,符合概率的基本性质。



人工智能/第十一阶段:深度学习-原理和进阶/TensorFlow深度学习工具 258楼
Python 全系列/第十五阶段:Python 爬虫开发/Python爬虫基础与应用 260楼
Python 全系列/第一阶段:Python入门/序列 261楼
人工智能/第二阶段:人工智能基础-Python基础/更多Python技巧与实战 263楼

image.png

1. 标准化的过程

标准化的公式为:

z=xμσ

其中:

    • x 是原始数据。

    • μ 是数据的均值。

    • σ 是数据的标准差。

    • z 是标准化后的数据。

标准化后的数据具有以下特性:

    • 均值为 0。

    • 标准差为 1。


2. 代码解释

标准化过程:

image.png

(1)scaler = StandardScaler().fit(X_train)

  • fit 方法计算训练集 X_train 的均值和标准差,并将这些统计量存储在 scaler 对象中。

  • 这一步是为了获取训练集的统计信息,而不是直接对数据进行转换。

(2)X_train = scaler.transform(X_train)

  • transform 方法使用 scaler 中存储的均值和标准差,对训练集 X_train 进行标准化。

  • 这一步将训练集转换为均值为 0、标准差为 1 的分布。

(3)X_test = scaler.transform(X_test)

  • 对测试集 X_test 使用相同的 scaler 进行标准化。

  • 注意:测试集的标准化必须使用训练集的均值和标准差,而不是重新计算。这是为了确保训练集和测试集在同一尺度上。


3. 为什么不能写成 scaler = StandardScaler().fit_transform(X_train)

虽然 fit_transform 是一个方便的方法,但它不适合在训练集和测试集上分别使用。原因如下:

(1)fit_transform 的作用

  • fit_transform 是 fit 和 transform 的组合方法。

  • 它会先计算数据的统计量(fit),然后对数据进行转换(transform)。

(2)问题所在

  • 如果对训练集和测试集分别调用 fit_transform,会导致:

    • 训练集和测试集使用不同的均值和标准差进行标准化。

    • 这会破坏数据的一致性,导致模型在测试集上的性能下降。

(3)正确做法

  • 对训练集调用 fit,然后对训练集和测试集分别调用 transform

  • 这样可以确保训练集和测试集使用相同的均值和标准差进行标准化。


4. 代码改进

image.png


5. 总结

  • 标准化是将数据转换为均值为 0、标准差为 1 的分布。

  • 在训练集上调用 fit,在训练集和测试集上调用 transform,以确保数据一致性。

  • 不能对训练集和测试集分别调用 fit_transform,否则会导致数据尺度(均值、标准差 -- 数据的分布)不一致,影响模型性能。

  • 值得注意的是,代码中在fit时用的是X_train,原因是训练集的数据量一般大于测试集,用训练集的均值和标准差会更有泛化性,transform时对训练集和测试集分别去做转换,但用的都是训练集的均值和标准差。


人工智能/第十一阶段:深度学习-原理和进阶/TensorFlow深度学习工具 264楼

image.png

1. Scikit-learn 的使用场景

Scikit-learn 是一个经典的机器学习框架,专注于传统的机器学习算法。它适用于以下场景:

(1)数据规模较小

  • Scikit-learn 适合处理中小规模的数据集(通常数据量在 GB 级别以下)。

  • 如果数据可以完全加载到内存中,Scikit-learn 是一个高效的选择。

(2)传统机器学习任务

  • Scikit-learn 提供了丰富的传统机器学习算法,包括:

    • 分类(如 SVM、决策树、随机森林、KNN)

    • 回归(如线性回归、岭回归、Lasso)

    • 聚类(如 K-Means、DBSCAN)

    • 降维(如 PCA、t-SNE)

    • 特征选择(如 SelectKBest、RFE)

  • 如果你的任务是传统的监督学习或无监督学习,Scikit-learn 是首选。

(3)快速原型开发

  • Scikit-learn 的 API 设计非常简洁一致,易于上手。

  • 对于快速验证想法或构建原型,Scikit-learn 的开发效率非常高。

(4)不需要 GPU 加速

  • Scikit-learn 主要基于 CPU 计算,不支持 GPU 加速。

  • 如果你的任务不需要大规模并行计算,Scikit-learn 是一个轻量级的选择。

(5)特征工程和模型评估

  • Scikit-learn 提供了丰富的工具用于特征工程(如 StandardScalerOneHotEncoder)和模型评估(如交叉验证、网格搜索、分类报告)。

  • 如果你的任务需要大量的特征处理或模型调优,Scikit-learn 是一个强大的工具。


2. TensorFlow 的使用场景

TensorFlow 是一个深度学习框架,专注于构建和训练神经网络模型。它适用于以下场景:

(1)大规模数据集

  • TensorFlow 支持分布式计算和 GPU/TPU 加速,适合处理大规模数据集(如 TB 级别的数据)。

  • 如果数据无法完全加载到内存中,TensorFlow 的数据管道(如 tf.data)可以高效地处理数据流。

(2)深度学习任务

  • TensorFlow 适用于需要深度神经网络的复杂任务,例如:

    • 图像分类、目标检测(如 CNN)

    • 自然语言处理(如 RNN、Transformer)

    • 生成模型(如 GAN、VAE)

    • 强化学习(如 DQN、PPO)

  • 如果你的任务需要非线性建模能力或处理高维数据(如图像、文本、音频),TensorFlow 是更好的选择。

(3)自定义模型

  • TensorFlow 提供了灵活的低级 API(如 tf.Tensortf.GradientTape),允许用户自定义模型结构和训练流程。

  • 如果你需要实现复杂的模型(如自定义损失函数、自定义层),TensorFlow 提供了更大的自由度。

(4)GPU/TPU 加速

  • TensorFlow 支持 GPU 和 TPU 加速,适合需要大规模并行计算的任务。

  • 如果你的任务需要训练深度神经网络(如 ResNet、BERT),TensorFlow 可以利用硬件加速显著提升训练速度。

(5)生产环境部署

  • TensorFlow 提供了完整的工具链,支持模型的生产环境部署(如 TensorFlow Serving、TensorFlow Lite)。

  • 如果你需要将模型部署到移动端、嵌入式设备或云端,TensorFlow 是一个成熟的选择。


3. Scikit-learn 和 TensorFlow 的对比

特性Scikit-learnTensorFlow
适用任务传统机器学习任务深度学习任务
数据规模中小规模数据集大规模数据集
模型复杂度简单模型(如线性模型、树模型)复杂模型(如深度神经网络)
硬件支持CPUGPU/TPU
开发效率高(API 简洁,适合快速原型开发)中(需要更多代码,适合复杂任务)
自定义能力有限(固定算法,不支持自定义模型)高(支持自定义模型和训练流程)
部署支持有限(依赖其他工具)完整(支持多种部署场景)

4. 实际项目中的选择依据

(1)任务类型

  • 如果是传统的分类、回归、聚类任务,优先选择 Scikit-learn。

  • 如果是图像、文本、音频等复杂任务,优先选择 TensorFlow。

(2)数据规模

  • 如果数据规模较小(GB 级别以下),优先选择 Scikit-learn。

  • 如果数据规模较大(TB 级别),优先选择 TensorFlow。

(3)模型复杂度

  • 如果模型较简单(如线性模型、树模型),优先选择 Scikit-learn。

  • 如果模型较复杂(如深度神经网络),优先选择 TensorFlow。

(4)硬件资源

  • 如果没有 GPU/TPU,优先选择 Scikit-learn。

  • 如果有 GPU/TPU,优先选择 TensorFlow。

(5)开发效率 vs. 灵活性

  • 如果需要快速验证想法,优先选择 Scikit-learn。

  • 如果需要高度自定义模型,优先选择 TensorFlow。


5. 结合使用的场景

在实际项目中,Scikit-learn 和 TensorFlow 可以结合使用。例如:

  • 使用 Scikit-learn 进行数据预处理和特征工程。

  • 使用 TensorFlow 构建和训练深度神经网络。

  • 使用 Scikit-learn 的模型评估工具评估 TensorFlow 模型的性能。


人工智能/第十一阶段:深度学习-原理和进阶/TensorFlow深度学习工具 265楼

image.png

tensorflow提供的自动微分功能(计算梯度)

前面需要定义好mse、theta

gradients = tf.gradients(mse, [theta])[0]

1. 自动微分的流程

(1)定义计算图

TensorFlow 使用计算图来表示数学运算。你需要先定义好损失函数(如均方误差 mse)和变量(如 theta),然后 TensorFlow 会自动构建计算图。

image.png

(2)计算梯度

使用 tf.gradients 计算损失函数 mse 对变量 theta 的梯度:

gradients = tf.gradients(mse, [theta])[0]
  • tf.gradients(mse, [theta]):计算 mse 对 theta 的梯度。

  • [theta]:表示要对 theta 求梯度。如果有多个变量,可以传入一个列表,例如 [theta1, theta2]

  • gradients:返回的是一个列表,包含每个变量的梯度。

(3)运行计算图

在 TensorFlow 中,计算图需要在一个会话(Session)中运行:

# 创建会话with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())  # 初始化变量
    grad_value = sess.run(gradients)  # 计算梯度
    print("梯度值:", grad_value)

2. [0] 的含义

tf.gradients(mse, [theta]) 返回的是一个列表,列表中的每个元素是对应变量的梯度。例如:

  • 如果传入 [theta],返回的列表长度为 1,包含 theta 的梯度。

  • 如果传入 [theta1, theta2],返回的列表长度为 2,包含 theta1 和 theta2 的梯度。

[0] 的作用是从返回的列表中提取第一个梯度值。例如:

gradients = tf.gradients(mse, [theta])[0]
  • tf.gradients(mse, [theta]) 返回的是一个列表 [grad_theta]

  • [0] 提取列表中的第一个元素 grad_theta


补充:

1.为什么需要 [0]

当你只对一个变量(如 theta)计算梯度时,tf.gradients 仍然会返回一个列表。例如:

gradients = tf.gradients(mse, [theta])

返回的 gradients 是一个列表 [grad_theta],其中 grad_theta 是 mse 对 theta 的梯度。

为了提取这个梯度值(而不是一个包含单个元素的列表),你需要使用 [0] 来访问列表中的第一个元素:

grad_theta = gradients[0]

2.实际意义

(1)统一返回值格式

tf.gradients 的设计是为了支持同时对多个变量计算梯度。无论你传入一个变量还是多个变量,它都返回一个列表。这种设计保持了函数行为的统一性。

(2)方便扩展

如果你以后需要对多个变量计算梯度,代码可以很容易地扩展。例

gradients = tf.gradients(mse, [theta1, theta2])grad_theta1 = gradients[0]grad_theta2 = gradients[1]

(3)避免混淆

通过返回列表,tf.gradients 明确表示它可以处理多个变量。如果你只对一个变量计算梯度,返回的列表长度为 1,你可以通过 [0] 提取梯度值。


人工智能/第十一阶段:深度学习-原理和进阶/TensorFlow深度学习工具 266楼
Python 全系列/第一阶段:Python入门/Python入门(动画版) 267楼
人工智能/第十二阶段:深度学习-图像识别原理/卷积神经网络优化 269楼

课程分类

百战程序员微信公众号

百战程序员微信小程序

©2014-2025百战汇智(北京)科技有限公司 All Rights Reserved 北京亦庄经济开发区科创十四街 赛蒂国际工业园
网站维护:百战汇智(北京)科技有限公司
京公网安备 11011402011233号    京ICP备18060230号-3    营业执照    经营许可证:京B2-20212637