游戏AI的创造思路-技术基础-tanh函数详解

又来搞事情,总想着把sigmoid函数替换成其他函数作为激活函数,或者找到更合适某一段训练的函数,所以今天来聊聊tanh函数(谁让咱当年差点去了数学系,结果还是在数学系转过去计算机的)

目录

3.9. tanh函数详解

3.9.1. 定义

3.9.2. 发展历史

3.9.3. 公式

3.9.4. 优缺点

3.9.5. 对比sigmoid函数的优势和劣势

3.9.6. 梯度消失的处理方法

3.9.6.1. 梯度消失的原因

3.9.6.2. 处理方法

3.9.7. 死节点(dead neurons)问题

3.9.7.1. 死节点问题来源

3.9.7.2. 解决方法

3.9.8. 在游戏AI应用方面的方法

3.9.8.1. 概述

3.9.8.2. 实践

3.9.8.3. 练它

3.9.8.4. 小结

3.9.9. 总结下


3.9. tanh函数详解

3.9.1. 定义

tanh函数,全称双曲正切函数(hyperbolic tangent function),是深度学习中常用的一种激活函数。它的数学定义是:

[\tanh(x) = \frac{ex - e{-x}}{ex + e{-x}}]

其中,e代表自然对数的底数。tanh函数的输出值被映射到-1和1之间,这使得它特别适用于需要将输出值中心化到0的情况。

3.9.2. 发展历史

tanh函数作为激活函数的历史可以追溯到早期神经网络的研究中。尽管其具体的提出时间可能难以精确追溯,但tanh函数因其良好的数学性质和实际应用效果,在神经网络的发展过程中逐渐得到了广泛应用。特别是在多层感知机(MLP)和循环神经网络(RNN)等结构中,tanh函数因其输出范围的优势而被频繁使用。

3.9.3. 公式

tanh函数的公式已在上文定义部分给出,即:

[\tanh(x) = \frac{ex - e{-x}}{ex + e{-x}}]

这个公式展示了tanh函数如何通过指数运算将输入值x映射到输出范围[−1,1]内。

Python实现代码

在Python中,可以使用多种库来实现tanh函数。以下是使用NumPy和math库的实现示例:

使用NumPy库

import numpy as np  
  
x = np.array([0, 1, -1, 2, -2])  
y = np.tanh(x)  
print(y)

使用math库(手动实现)

虽然math库直接提供了tanh函数,但为了展示其计算过程,可以手动实现:

import math  
  
def tanh(x):  
    return (math.exp(x) - math.exp(-x)) / (math.exp(x) + math.exp(-x))  
  
x = 0.5  
y = tanh(x)  
print(y)

3.9.4. 优缺点

优点

  1. 输出值中心化:tanh函数的输出值在-1和1之间,且关于原点对称,这有助于缓解梯度消失问题,特别是在训练深层网络时。
  2. 导数连续且可微:tanh函数的导数连续且易于计算,有利于使用梯度下降等优化算法进行训练。
  3. 非线性特性:tanh函数保留了非线性特性,使得神经网络能够学习复杂的模式。

缺点

  1. 计算复杂度:由于tanh函数涉及指数运算,因此在处理大规模数据时计算复杂度较高。
  2. 梯度消失问题:虽然比sigmoid函数有所改善,但当输入值非常大或非常小时,tanh函数的梯度仍然可能接近于0,导致梯度消失问题。

3.9.5. 对比sigmoid函数的优势和劣势

优势

  1. 输出范围:tanh函数的输出范围在-1和1之间,比sigmoid函数的[0,1]范围更广,这有助于模型学习到更丰富的特征表示。
  2. 梯度特性:tanh函数在0附近的梯度比sigmoid函数更陡峭,这有助于在训练初期加快收敛速度。

劣势

在深度学习的实际应用中,tanh函数和sigmoid函数都面临着梯度消失的问题。尽管tanh函数在输出范围和梯度特性上有所改进,但在处理深层网络时仍可能遇到挑战。

3.9.6. 梯度消失的处理方法

3.9.6.1. 梯度消失的原因

梯度消失通常发生在深度神经网络中,尤其是在使用sigmoid或tanh等饱和型激活函数时。

这些函数在输入值较大较小时,其导数(梯度)会接近于0

在反向传播过程中,这些微小的梯度经过多层网络逐层传递时,会不断被乘以权重矩阵(权重通常小于1),进一步导致梯度值缩小,直至几乎消失。

这种现象会严重影响网络的训练效果,使得深层网络的参数无法得到有效更新。

对于tanh函数来说,当输入值x的绝对值很大时,tanh(x)会迅速接近-1或1,此时{tanh}'(x)会迅速趋近于0,即梯度几乎消失。

这是tanh函数面临梯度消失问题的主要原因。

3.9.6.2. 处理方法

为了缓解tanh函数带来的梯度消失问题,可以采取以下几种策略:

  1. 使用非饱和型激活函数
    尽管tanh函数相对于sigmoid函数在梯度消失问题上有所改善,但使用ReLU、LeakyReLU、ELU等非饱和型激活函数可以更有效地避免梯度消失。这些函数在输入值较大时梯度不会趋于0,从而保证了梯度在网络中的稳定传播。

  2. 批标准化(Batch Normalization)
    批标准化技术可以确保每一层的输入分布接近标准正态分布,从而缓解梯度消失并加速收敛。通过对每一层的输出进行归一化处理,批标准化可以减少内部协变量偏移(Internal Covariate Shift),使得激活函数的输入值保持在敏感区域,有助于避免梯度消失。

  3. 残差连接(Residual Connections)
    残差连接通过引入跳跃连接允许信息直接从输入层传递到输出层,绕过了可能的梯度消失路径。这种方法在深度网络中尤其有效,如ResNet等网络结构就通过添加残差块来保留层之间的信息流,从而缓解梯度消失问题。

  4. 适当的权重初始化
    使用适当的权重初始化方法如Xavier初始化、He初始化等,可以使得网络的权重在初始化时不会过大或过小,有助于控制梯度的大小并缓解梯度消失问题。

  5. 降低学习率
    适当降低学习率可以减少权重更新的步长,避免在训练初期由于学习率过大导致的梯度爆炸或梯度消失问题。随着训练的进行,可以逐步调整学习率以获得更好的训练效果。

  6. 使用正则化方法
    如L1、L2正则化等正则化方法可以减少网络的复杂度并限制权重的增长范围,有助于缓解梯度消失问题并提高模型的泛化能力。

综上所述,虽然tanh函数本身受梯度消失问题的影响,但通过采取上述策略可以有效地缓解这一问题并提高深度神经网络的训练效果。

在实际应用中,需要根据具体任务和网络结构选择合适的激活函数、初始化方法、优化算法等策略来构建高效稳定的深度学习模型。

3.9.7. 死节点(dead neurons)问题

3.9.7.1. 死节点问题来源

tanh函数作为深度学习的激活函数时,虽然在一定程度上缓解了sigmoid函数输出非零中心化导致的梯度消失问题,但它仍然可能面临梯度饱和导致的训练难题,包括死节点(dead neurons)问题。

死节点问题指的是在训练过程中,某些神经元的输出长时间保持为0,导致其权重无法得到有效更新。

3.9.7.2. 解决方法

针对tanh函数可能遇到的死节点问题,可以采取以下几种解决方法:

  • 使用非饱和激活函数

ReLU及其变体:ReLU(Rectified Linear Unit)函数在输入为正时梯度恒为1,有效缓解了梯度消失问题,并且计算效率高。然而,ReLU在输入为负时输出为0,可能导致死节点。为了解决这一问题,可以使用Leaky ReLU、PReLU(Parametric ReLU)、RReLU(Randomized ReLU)等变体,这些变体在输入为负时给予一个小的非零梯度,从而避免死节点。

  • 优化学习率

合理设置学习率对于避免死节点至关重要。学习率过大会导致权重更新步长过大,可能跳过最优解甚至导致梯度爆炸;学习率过小则可能导致训练过程缓慢,且容易陷入局部最小值。通过动态调整学习率(如使用Adam、RMSprop等优化器)或使用学习率衰减策略,可以在一定程度上避免死节点问题。

  • 权重初始化

适当的权重初始化方法可以减少训练初期死节点的发生。例如,使用He初始化或Xavier初始化等方法,可以根据网络的层数和激活函数的特点来设置初始权重的大小,使得在训练初期各层的激活值和梯度保持在合理的范围内。

  • 批标准化(Batch Normalization)

批标准化通过规范化每一层的输入分布,使得激活函数的输入值保持在敏感区域内,从而减少了梯度消失或爆炸的可能性。同时,批标准化还具有一定的正则化效果,有助于提升模型的泛化能力。

  • 正则化技术

使用L1或L2正则化等技术可以对模型的权重进行约束,防止权重过大导致梯度消失或爆炸。此外,Dropout技术通过在训练过程中随机丢弃一部分神经元及其连接,可以减少神经元之间的共适应性,从而在一定程度上避免死节点问题。

  • 数据预处理和特征缩放

对输入数据进行适当的预处理和特征缩放,使得输入数据的分布更加合理,有助于提升模型的训练效率和稳定性。例如,对于tanh函数来说,由于其输出范围在-1到1之间,因此将输入数据缩放到一个合适的范围内(如-1到1)可能有助于减少死节点问题的发生。

3.9.8. 在游戏AI应用方面的方法

3.9.8.1. 概述

在游戏AI中,tanh函数和sigmoid函数等激活函数常用于神经网络模型的构建。通过引入这些激活函数,神经网络能够学习到复杂的非线性关系,从而在游戏中实现更智能的决策和行为。

具体来说,游戏AI可能会使用多层感知机(MLP)或循环神经网络(RNN)等结构来处理游戏状态信息(如玩家位置、敌人位置、资源分布等),并使用tanh函数作为激活函数来引入非线性特性。

3.9.8.2. 实践

在游戏AI中,使用tanh函数作为深度学习模型的激活函数是一种常见的做法,特别是在处理3D环境下的运动时。以下是一个简单的Python示例,展示了如何在一个简单的神经网络中使用tanh激活函数来控制3D环境中的运动。

我们将使用PyTorch库,它是一个流行的深度学习框架,提供了构建和训练神经网络所需的工具和预训练模型。

第一步,确保你已经安装了PyTorch(没安装的话就打屁屁)。如果还没有安装,可以通过以下命令安装:

pip install torch

然后,你可以使用以下代码来创建一个简单的神经网络,该网络使用tanh激活函数来控制3D环境中的运动:

import torch  
import torch.nn as nn  
  
# 定义一个简单的神经网络类  
class SimpleMotionNetwork(nn.Module):  
    def __init__(self):  
        super(SimpleMotionNetwork, self).__init__()  
        # 假设输入特征数量为10,输出控制参数数量为3(例如,3D空间中的x, y, z坐标)  
        self.fc1 = nn.Linear(10, 64)  
        self.fc2 = nn.Linear(64, 32)  
        self.fc3 = nn.Linear(32, 3)  
        # 使用tanh作为激活函数  
        self.activation = nn.Tanh()  
  
    def forward(self, x):  
        x = self.activation(self.fc1(x))  
        x = self.activation(self.fc2(x))  
        x = self.fc3(x)  # 输出层通常不使用激活函数,直接输出控制参数  
        return x  
  
# 创建网络实例  
network = SimpleMotionNetwork()  
  
# 创建一个随机输入张量来模拟3D环境下的运动控制输入  
input_tensor = torch.randn(1, 10)  
  
# 通过网络传递输入并获取输出  
output = network(input_tensor)  
  
print("输出控制参数:", output)

在这个例子中,我们定义了一个名为SimpleMotionNetwork的神经网络类,它有三个全连接层(fc1fc2fc3),并使用tanh作为激活函数。网络的输入特征数量为10,输出控制参数数量为3,可以解释为3D空间中的x, y, z坐标。我们创建了一个网络实例,并使用一个随机生成的输入张量来模拟3D环境下的运动控制输入。最后,我们通过网络传递输入并打印输出控制参数。

3.9.8.3. 练它

训练上述定义的SimpleMotionNetwork模型通常涉及以下几个步骤:

准备数据集、定义损失函数、选择优化器、进行训练循环以及评估模型性能。

以下是一个简化的训练流程示例:

  • 准备数据集

首先,你需要一个包含输入特征和对应输出标签的数据集。在游戏AI的上下文中,输入特征可能包括游戏状态(如玩家位置、敌人位置、道具位置等),而输出标签则可能是控制参数(如速度、方向等),这些参数将用于控制游戏中的角色或对象在3D环境中的运动。

由于这个示例是简化的,我们将不会具体实现数据集的加载和预处理步骤,但你需要确保你的数据集已经准备好,并且可以被你的模型以适当的方式读取。

  • 定义损失函数

损失函数用于评估模型的预测值与真实标签之间的差异。对于回归问题(如控制参数的预测),常用的损失函数包括均方误差(MSE)或平均绝对误差(MAE)。

在PyTorch中,你可以使用torch.nn.MSELosstorch.nn.L1Loss来定义损失函数。

criterion = nn.MSELoss()  # 使用均方误差作为损失函数
  • 选择优化器

优化器用于根据损失函数的梯度来更新模型的权重。在深度学习中,常用的优化器包括SGD(随机梯度下降)、Adam等。

optimizer = torch.optim.Adam(network.parameters(), lr=0.001)  # 使用Adam优化器,学习率为0.001
  • 进行训练循环

训练循环通常包括多个epoch(训练周期),每个epoch中模型会遍历整个数据集。在每个批次(batch)中,模型会进行前向传播以计算预测值,然后进行反向传播以计算梯度,并使用优化器更新权重。

以下是一个简化的训练循环示例:

# 假设dataloader已经定义好,用于按批次加载数据  
for epoch in range(num_epochs):  
    for inputs, targets in dataloader:  
        # 前向传播  
        outputs = network(inputs)  
        loss = criterion(outputs, targets)  
          
        # 反向传播和优化  
        optimizer.zero_grad()  # 清除之前的梯度  
        loss.backward()        # 反向传播计算梯度  
        optimizer.step()       # 使用优化器更新权重  
          
    # 可选:在每个epoch结束时打印损失或验证模型性能  
    print(f'Epoch {epoch+1}, Loss: {loss.item()}')

请注意,上面的代码示例假设dataloader已经定义好,并且以(inputs, targets)元组的形式返回每个批次的数据。在实际应用中,你需要根据自己的数据集来定义dataloader

  • 评估模型性能

在训练过程中或训练完成后,你需要评估模型的性能。这通常涉及在验证集或测试集上运行模型,并计算性能指标(如损失值、准确率等)。

由于你的模型是用于预测3D环境中的运动控制参数,因此你可能需要定义一些与游戏环境相关的性能指标来评估模型的实际效果。

上述训练流程是一个高度简化的示例。在实际应用中,你可能还需要考虑更多的因素,如学习率调整、早停法(early stopping)、权重衰减(weight decay)、梯度裁剪(gradient clipping)等,以进一步提高模型的性能和稳定性。

通过训练这些网络模型,游戏AI可以学习到如何在不同游戏状态下做出最优决策。

3.9.8.4. 小结

此外,随着深度学习技术的不断发展,越来越多的游戏AI开始采用更复杂的网络结构和优化算法来提高性能和准确性。

例如,强化学习技术可以允许游戏AI通过试错学习来不断优化其决策策略;而注意力机制等新技术则可以帮助游戏AI更好地处理复杂的游戏环境和多任务场景。

3.9.9. 总结下

总的来说tanh函数作为激活函数,还是有一战之力,但需要注意其x接近0时的情况,长时间出现x为0时会造成“死节点”问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

让采购和工程师们既爱又恨的任务——BOM

在项目研发与生产过程中,有一个常常让采购经理和工程师们既爱又恨的任务,那就是整理BBOMB。BOM作为连接设计与制造的桥梁,其重要性不言而喻,它详细列出了产品构成所需的所有零部件、材料及其规格、数量,是成本估算、采…

如何选择品牌推广公司?哪家好?收费标准及评价!

不管是什么品牌,推广对公司的成败起了很关键的作用。然而,面对市面上琳琅满目的品牌推广公司,如何选择一家既熟悉又靠谱的公司,成为许多企业主面临的难题。 作为一家手工酸奶品牌的创始人,目前全国也复制了100多家门店…

超简洁Django个人博客系统(适合初学者)

一、环境介绍 Django4.2.13Markdown3.3.4PyMySQL1.1.1Python3.8PyCharm 2023.1.2 (Professional Edition) 二、功能简介 用户登录 通过在pycharm终端执行以下命令创建超级管理员。python manage.py create createsuperuser 创建完成后再通过新建的超级管理员账号进行登录 …

Java的日期类常用方法

Java_Date 第一代日期类 获取当前时间 Date date new Date(); System.out.printf("当前时间" date); 格式化时间信息 SimpleDateFormat simpleDateFormat new SimpleDateFormat("yyyy-mm-dd hh:mm:ss E); System.out.printf("格式化后时间" si…

【Arduino】小飞鱼通达二开实验ESP32使用激光传感器(图文)

激光在我们的生活中应用很多,比如激光雷达、激光焊接、激光笔等等,今天我们来实验一下这个激光传感器模块。 这个模块的使用非常的简单,模块一共有3个针脚,正负极针脚和一个信号输入S针脚,当给到S针脚一个高电平时即可…

动手RAG: ocr调研

对于rag应用来说,文档是第一步,对于部分扫描件的文件来讲,主要就需要OCR. OCR tesseractppocrmmocr OCR包含几类, 自然场景中的文字识别,文档中的文字识别pipeline: 文本检测,文本识别,文…

武汉星起航:无锡跨境电商加速“出海”,物流升级助品牌全球布局

随着全球化的不断深入,跨境电商作为数字外贸的新业态,正逐渐成为无锡企业拓展海外市场的重要渠道。武汉星起航关注到,近年来,无锡市通过积极推进国际物流枢纽建设,完善海外仓布局,以及各特色产业带的积极参…

19184 传球游戏

这是一个经典的动态规划问题,我们可以定义一个二维数组dp[i][j],其中i表示传球的次数,j表示球当前在哪个同学手里。我们需要找到的是dp[m][1],即球传了m次后又回到1号同学手里的方法数。 我们可以从1次开始,逐次计算每…

老师怎样一键发布期末考试成绩?

期末考试的钟声一响,老师们便开始了紧张的阅卷工作。成绩出来后,他们又面临着一项繁琐的任务——将成绩单逐一私信给每位学生的家长。这不仅耗费了大量时间,也让老师们在繁忙的期末工作中倍感压力。期末老师的工作已经够多够繁琐,…

10款优秀的企业防泄密软件推荐 (干货必看)

在当今日益数字化的商业环境中,企业数据的安全性和保密性显得尤为重要。随着网络攻击和数据泄露事件的频发,越来越多的企业开始关注并投入资源于防泄密软件的使用。本文旨在为读者推荐10款优秀的企业防泄密软件,帮助企业在保护敏感信息方面做…

LabVIEW风机跑合监控系统

开发了一种基于LabVIEW的风机跑合监控系统,提高风机测试的效率和安全性。系统通过自动控制风机的启停、实时监控电流和功率数据,并具有过流保护功能,有效减少了人工操作和安全隐患,提升了工业设备测试的自动化和智能化水平。 项目…

轻松创建对象——简单工厂模式(Python实现)

1. 引言 大家好,又见面了!今天我们要聊的是设计模式中的“万能钥匙”——简单工厂模式。想象一下,如果每次你都得亲自动手创建各种对象,不仅累得像个陀螺,还可能搞得一团糟。别怕,简单工厂模式来拯救你&am…

SciencePub学术刊源 | 7月SCI/SSCI/EI/CNKI刊源表已更新!(内含TOP及CCF推荐)

【SciencePub学术】我处SciencePub学术2024年7月SCI/SSCI/EI/CNKI刊源表已更新!内含多本中科院TOP、CCF推荐以及进展超顺的优质期刊,最快1-3个月录用! 计算机领域重点SCI 环境地质化学领域重点SCI 生物医学领域重点SCI 数学材料领域重点SCI 各…

grpc学习golang版( 二、入门示例 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、环境二、编写protobuf文件三、编写server服务端四、编写Clie…

不用找了!这个软件自带各行业话术,客服效率飞跃

有一款客服工具软件,不但能吸附聊天窗口,实现图文视频话术的一键发送,还内置了多行业的优质客服话术模板,允许用户直接下载使用,快速构建起适合自身企业的专业客服知识库。 前言 在今天的快节奏商业环境中&#xff0c…

同星TTS系列产品全新亮相:让开发测试变得更简单!

TTS系列产品 如果需要完整地测试 ECU,不仅需要将通信网络连接到测试系统,还需要连接 I/O 接口。同星的TTS测试系统将连接 I/O 通道所需的所有电路组件集成在一个模块中,可以极大地简化测试台架和HIL测试系统的设置,提高搭建和测试…

使用工业自动化的功能块实现大语言模型应用

大语言模型无所不能? 以chatGPT为代表的大语言模型横空出世,在世界范围内掀起了一场AI革命。给人的感觉似乎大模型语言无所不能。它不仅能够生成文章,图片和视频,能够翻译文章,分析科学和医疗数据,甚至可以…

当下环境下如何提升自己以拥抱未来的机会-程序员的自我提升

一、前言 看看今年的行情,无论是国内还是国外,仿佛都没有什么活力,经济下行压力越来越大,企业经营越来越困难。对于程序员的工作机会越来越少。这可能是现阶段乃至几年内的现象。现在是现金为王,拥有其他资产仿佛没有多大的增值空间,经济一片惨淡,消费不活跃,我看到的…

nextTick实现原理及使用场景

1.定义: nextTick是一个在Vue.js中常见的异步更新DOM的机制,它利用JavaScript的事件循环机制以及浏览器的渲染流程来实现延迟执行DOM更新操作。nextTick方法能够将回调函数延迟到下一个DOM更新循环之后执行,确保在DOM更新完成后执行某些操作…

为什么要学习大模型应用开发?原因80%的人都不知道

0 prompt engineer 就是prompt工程师它的底层透视。 1 学习大模型的重要性 底层逻辑 人工智能大潮已来,不加入就可能被淘汰。就好像现在职场里谁不会用PPT和excel一样,基本上你见不到。你问任何一个人问他会不会用PPT,他都会说会用&#x…