游戏AI的创造思路-技术基础-自然语言处理

自然语言处理-可以对游戏AI特别是RPG类、语言类游戏进行“附魔”,开发出“随机应变”和你聊天的“女友”、“队友”或者是根据你定义的文本库来用接近自然语言的生成“语言”,推动游戏情景在受控范围内前进

目录

1. 自然语言处理定义

2. 发展历史

3. 计算方法和计算公式

3.1. 隐马尔可夫模型(Hidden Markov ModelHMM)

3.1.1. 介绍

3.1.2.详细

3.1.3. python代码示例

3.2. 深度学习

4. 优缺点

5.游戏AI通过理解玩家语言输入并生成语音的全过程

5.1. 输入接收

5.2. 语音识别(针对语音输入)

5.3. 自然语言理解

5.4. 文本生成

5.5. 语音合成

5.6. 输出反馈

5.7. python代码示例

5.8. 小结


1. 自然语言处理定义

自然语言处理(Natural Language Processing, NLP)是人工智能(AI)的一个重要领域,它致力于创建能够理解、分析和生成人类语言(包括书面和口头语言)的软件系统。

在游戏领域,NLP使游戏AI能够解析玩家的语音或文本输入,理解其意图,并生成相应的文本回复或合成语音进行反馈,从而提升游戏的交互性和沉浸感。

2. 发展历史

自然语言处理的发展可以追溯到计算机科学诞生之初。早期的NLP方法主要基于规则和模板,但这种方法在处理复杂语言现象时显得力不从心。随着统计学习方法的发展,统计语言模型(SLM)开始被用于预测词汇序列,然而SLM在处理长序列时面临稀疏性和计算复杂性的问题。

随着深度学习的兴起,神经网络语言模型(NNLM)逐渐成为主流。NNLM通过学习词汇的连续表示(词向量)和使用神经网络计算序列概率,有效解决了SLM的问题。近年来,随着预训练和微调技术的引入,以及计算能力的提升和大量数据的可用性,NLP领域诞生了许多重要的模型,如BERT、GPT等,这些模型在游戏AI中的应用也变得越来越广泛。

3. 计算方法和计算公式

在游戏AI的NLP中,常用的计算方法包括隐马尔可夫模型(HMM)和深度学习。

3.1. 隐马尔可夫模型(Hidden Markov ModelHMM)

3.1.1. 介绍

HMM是一种概率模型,用于描述一个隐藏的马尔可夫链和观测序列之间的关系。在自然语言处理中,HMM可以用于文本生成和情感分析。其核心计算公式包括:


[P(O|H) = \prod_{t=1}^{T} P(o_t|h_t)]
[P(H) = \prod_{t=1}^{T} P(h_t|h_{t-1})]

其中,[P(O|H)]表示观测序列O在隐藏状态序列H下的条件概率,(h_t|h_{t-1})表示隐藏状态之间的转移概率,P(o_t|h_t)表示在隐藏状态h_{t}下观测到o_{t}的发射概率。

3.1.2.详细

隐马尔可夫模型(Hidden Markov Model,简称HMM)的状态转移概率矩阵是模型的一个重要组成部分,它描述了模型在不同状态之间转移的概率。状态转移概率矩阵的公式可以表示如下:

设状态集合为Q={q1​,q2​,...,qN​},其中N是可能的状态数。

状态转移概率矩阵记为A=a(i,j​)N×N​,其中 每个元素aij​表示在时刻t处于状态qi​的条件下,在时刻t+1转移到状态qj​的概率。

具体公式为:

[a_{ij} = P(i_{t+1} = q_j | i_t = q_i)]

这里,it​表示时刻t的状态,it+1​表示时刻t+1的状态。状态转移概率矩阵A中的每一行元素之和为1,即对于任意的i,有:

[\sum_{j=1}^{N} a_{ij} = 1]

这个性质保证了从任何一个状态出发,转移到所有可能状态的概率之和为1,符合概率分布的基本要求。

隐马尔可夫模型的状态转移概率矩阵是模型参数之一,它与观测概率矩阵和初始状态概率向量共同决定了模型的特性。

在实际应用中,这些参数通常需要通过训练数据来学习得到。

学习算法(如Baum-Welch算法)会根据给定的观测序列,调整模型参数,使得在该模型下观测序列出现的概率最大化。

3.1.3. python代码示例

Python中可以使用hmmlearn库来实现HMM。你需要安装hmmlearn库,可以使用pip进行安装:

pip install hmmlearn

接下来,我将展示一个简单的HMM实现,用于模拟一些数据并对其进行训练和预测:

import numpy as np  
from hmmlearn import hmm  
  
# 创建一个简单的数据集  
# 假设有两种隐藏状态,并且观测数据是从这两种状态产生的  
np.random.seed(42)  
states = ["Rainy", "Sunny"]  
n_states = len(states)  
  
observations = ["walk", "shop", "clean"]  
n_observations = len(observations)  
  
model = hmm.MultinomialHMM(n_components=n_states, random_state=42)  
  
# 训练数据,每一行是一个观测序列  
train_data = np.array([  
    [0, 1, 0],  # 在Rainy状态下可能更倾向于shop  
    [1, 0, 2],  # 在Sunny状态下可能更倾向于walk和clean  
    [0, 2, 1],  # 另一种Rainy状态的表现  
    [1, 0, 1],  # 另一种Sunny状态的表现  
    [2, 1, 0]   # 另一种观测序列  
])  
  
# 定义观测序列中每个数字对应的实际观测事件  
model.startprob_ = np.array([0.6, 0.4])  
model.transmat_ = np.array([  
    [0.7, 0.3],  
    [0.4, 0.6]  
])  
model.emissionprob_ = np.array([  
    [0.1, 0.4, 0.5],  
    [0.6, 0.3, 0.1]  
])  
  
# 训练模型  
model.fit(train_data)  
  
# 打印学习后的参数  
print("Start probability:", model.startprob_)  
print("Transition probability:\n", model.transmat_)  
print("Emission probability:\n", model.emissionprob_)  
  
# 预测观测序列的状态序列  
seen = np.array([[0, 1, 1]]).T  
logprob, boxes = model.decode(seen, algorithm="viterbi")  
print("The predicted boxes (state sequence) for observation sequence:", seen.T)  
print(boxes)

在这个例子中,我们创建了一个简单的数据集,然后定义了一个MultinomialHMM模型,包括初始状态概率、状态转移概率和发射概率。

之后,我们使用训练数据来训练模型,并打印出学习后的参数。

最后,我们使用模型来预测一个新的观测序列的隐藏状态序列。

3.2. 深度学习

深度学习在自然语言处理中常用于语音识别和语音合成。

其核心是神经网络模型,通过前向传播计算输入和输出之间的关系,并通过反向传播调整神经元的权重和偏置。

数学模型公式通常表示为:

[y = f(x; \theta)]

[\theta = \arg\min_{\theta} \sum_{i=1}^{N} L(y_i, \hat{y}_i)]

其中,y是输出,x是输入,θ是模型参数,f是神经网络的前向传播函数,L是损失函数。

深度学习的内容在前面已经进行了介绍,感兴趣可以参看前面文章

游戏AI的创造思路-技术基础-深度学习(1)-CSDN博客文章浏览阅读740次,点赞14次,收藏8次。深度学习(Deep Learning)是机器学习的一个子领域,它依赖于神经网络的结构。深度学习通过组合低层特征形成更加抽象的高层表示属性类别或特征,以发现数据的分布式特征表示。简单来说,深度学习是学习样本数据的内在规律和表示层次,这些学习过程中获得的信息对诸如文字,图像和声音等数据的解释有很大的帮助。它的最终目标是让机器能够识别和解释各种数据,如文字、图像和声音等,从而实现人工智能的目标。与传统的机器学习技术相比,深度学习可以自动提取数据的特征,而无需人工设计和选择特征。https://warghostwu.blog.csdn.net/article/details/139871952

4. 优缺点

优点

  1. 提升交互性:使游戏AI能够更自然地与玩家交流。
  2. 增强沉浸感:通过真实的对话体验,让玩家更容易沉浸在游戏世界中。
  3. 提高开发效率:自动生成大量对话内容,减少人工编写的工作量。

缺点

  1. 处理难度大:自然语言本身的复杂性和多样性增加了处理难度。
  2. 误识别率高:语言的模糊性和多义性容易导致误识别。
  3. 隐私安全问题:处理大量语言信息可能引发隐私泄露风险。

5.游戏AI通过理解玩家语言输入并生成语音的全过程

游戏AI通过自然语言处理(NLP)理解玩家语言输入(包括语音和文本输入),并生成对应文本进而合成语音的全过程,是一个涉及多个步骤和复杂技术的综合过程。以下是对这一过程的详细介绍:

5.1. 输入接收

  1. 语音输入:玩家通过麦克风等语音输入设备,向游戏系统发送语音指令或对话内容。
  2. 文本输入:玩家通过键盘或其他文本输入设备,在游戏聊天框中输入文字指令或对话内容。

5.2. 语音识别(针对语音输入)

对于语音输入,游戏AI首先需要进行语音识别,将语音信号转换为文本信息。这一过程通常包括以下步骤:

  1. 语音信号预处理:对输入的语音信号进行去噪、分帧、加窗等预处理操作,以便于后续处理。
  2. 特征提取:从预处理后的语音信号中提取出能够有效表征语音特征的信息,如梅尔频率倒谱系数(MFCC)等。
  3. 声学模型解码:利用训练好的声学模型对提取的特征进行解码,将语音信号转换为对应的音素或音节序列。
  4. 语言模型解码:结合语言模型,将音素或音节序列进一步转换为文本信息。语言模型能够考虑上下文信息,提高识别的准确率。

5.3. 自然语言理解

无论是语音输入还是文本输入,经过识别或接收后,游戏AI都需要对文本信息进行自然语言理解(NLU),以解析玩家的意图和上下文。这一过程通常包括:

  1. 分词:将文本信息分割成独立的词汇单元。
  2. 词性标注:为每个词汇标注其词性,如名词、动词等。
  3. 句法分析:分析词汇之间的句法关系,构建句法树或依存关系图。
  4. 语义理解:基于句法分析的结果,进一步理解文本中的语义信息,如实体识别、关系抽取等。

5.4. 文本生成

在理解了玩家的意图后,游戏AI需要根据上下文和游戏规则生成相应的回复文本。这一过程可能涉及复杂的对话管理策略和自然语言生成(NLG)技术,如:

  1. 对话管理:根据玩家的输入和当前的游戏状态,选择合适的对话策略。
  2. 文本生成:利用预训练的语言模型或模板生成符合语境的回复文本。

5.5. 语音合成

对于生成的文本回复,游戏AI可以通过语音合成技术将其转换为语音输出。语音合成过程通常包括:

  1. 文本预处理:对生成的文本进行必要的预处理,如分词、标点符号处理等。
  2. 语音编码:将文本转换为对应的音素或音节序列,并确定每个音素的发音特征。
  3. 声音合成:利用声码器或深度学习模型生成对应的声音波形。这一过程可能涉及波形拼接、参数合成或端到端的深度学习模型等方法。
  4. 后处理:对生成的声音波形进行滤波、音量调整等后处理操作,以提高语音的自然度和可懂度。

5.6. 输出反馈

最后,游戏AI将合成的语音输出给玩家,完成整个交互过程。玩家可以听到游戏角色的回复语音,并根据需要进行进一步的交互。

5.7. python代码示例

要实现一个完整的游戏AI系统,通过自然语言处理理解玩家语言输入并生成对应文本再合成语音,会涉及到多个复杂的组件和大量的代码。

由于这是一个庞大的项目,这里仅提供一个简化的框架和关键步骤的伪代码。

首先,确保你已经安装了nltkspaCy库。如果没有安装,可以通过pip安装:

pip install nltk spacy  
python -m spacy download zh_core_web_sm  # 下载中文模型,如果你需要处理中文文本

其次,确保你已经安装了gTTSpyttsx3库。如果没有安装,可以通过pip安装:

pip install gtts pyttsx3

以下是一个简化的Python代码框架,用于描述这个过程:

import speech_recognition as sr  
# 实际上你可能需要使用nltk, spaCy等
import nltk 
import spaCy
# 实际上你可能需要使用gTTS, pyttsx3等  
from gtts import gTTS
import pyttsx3

import os  
import tempfile 

#使用JSON串传递动作意图,当然,这个意图是以伪代码方式给出的
import json    
  
# 语音识别函数  
def recognize_speech(audio_data):  
    # 使用语音识别库将音频数据转换为文本  
    # 这里使用speech_recognition库作为示例  
    recognizer = sr.Recognizer()  
    try:  
        text = recognizer.recognize_google(audio_data, language='zh-CN')  
        return text  
    except sr.UnknownValueError:  
        return "无法识别语音"  
    except sr.RequestError as e:  
        return "无法从Google语音识别服务请求结果; {0}".format(e)  
  
# 自然语言理解函数  
def understand_text(text):  
    # 这是一个简化的示例,实际上你可能需要更复杂的逻辑来理解玩家意图   
    # 使用spaCy进行分词和词性标注  
    doc = nlp(text)  
      
    # 假设我们关注动词和它们的主语,以理解玩家的意图  
    intent = {  
        "verb": "",  
        "subject": "",  
        "object": ""  
    }  
      
    for token in doc:  
        if token.pos_ == "VERB":  
            intent["verb"] = token.text  
            # 尝试找到动词的主语  
            subject = [w for w in token.head.lefts if w.dep_ == 'nsubj']  
            if subject:  
                intent["subject"] = subject[0].text  
            # 尝试找到动词的宾语  
            object = [w for w in token.rights if w.dep_.endswith('obj')]  
            if object:  
                intent["object"] = object[0].text  
            break  # 只关注第一个动词  
      
    # 将意图转换为JSON串  
    return json.dumps(intent, ensure_ascii=False)
  
# 文本生成函数  
def generate_text(intent):  
    # 将JSON字符串解析为字典  
    intent = json.loads(intent)  
      
    # 根据意图生成回复文本  
    # 这里只是一个简单的示例,实际生成逻辑可能更复杂  
    if intent["verb"] == "打开":  
        reply = f"好的,我将为你打开{intent['object']}。"  
    elif intent["verb"] == "获取":  
        reply = f"你已经获得了{intent['object']}。"  
    else:  
        reply = "我无法理解你的意图,请重新表述。"  
      
    return reply


# 以下是使用两种库的语音生成  
# 使用gTTS生成语音的函数  
def generate_speech_with_gtts(text):  
    tts = gTTS(text=text, lang='zh-cn')  
    # 创建一个临时文件来保存语音  
    with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp:  
        tts.save(tmp.name)  
        return tmp.name  
  
# 使用pyttsx3生成语音的函数  
def generate_speech_with_pyttsx3(text):  
    engine = pyttsx3.init()  
    engine.setProperty('rate', 150)  # 设置语速  
    engine.setProperty('volume', 0.9)  # 设置音量  
    # 这里不直接返回wav对象,因为pyttsx3直接播放或保存到文件  
    with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp:  
        engine.save_to_file(text, tmp.name)  
        engine.runAndWait()  # 如果需要立即播放,可以调用这个函数  
        return tmp.name  
  
# 主函数  
def main(): 

    # 假设你已经下载了spaCy的中文模型  
    nlp = spacy.load("zh_core_web_sm") 
    
    # 接收语音输入  
    # 这里假设你已经有了音频数据audio_data  
    audio_data = b"玩家的语音数据"  
      
    # 语音识别  
    text = recognize_speech(audio_data)  
    print("识别的文本:", text)  
      
    # 自然语言理解  
    intent = understand_text(text)  
    print("理解的意图:", intent)  
      
    # 文本生成  
    reply_text = generate_text(intent)  
    print("生成的回复文本:", reply_text)  
      
    # 语音合成  
    # 使用gTTS生成语音  
    wav_file_gtts = generate_speech_with_gtts(reply_text)  
    print("gTTS生成的语音文件:", wav_file_gtts)  
      
    # 播放语音(使用系统默认播放器)  
    os.startfile(wav_file_gtts)  # Windows系统使用startfile  
    # 对于其他系统,你可能需要使用其他方法来播放wav文件  
  
    # 使用pyttsx3生成语音(这里不再次播放,只是生成文件)  
    wav_file_pyttsx3 = generate_speech_with_pyttsx3(reply_text)  
    print("pyttsx3生成的语音文件:", wav_file_pyttsx3)  
  
# 运行主函数  
if __name__ == "__main__":  
    main()

在这个代码中,generate_speech_with_gtts函数使用gTTS库生成语音,并将其保存到一个临时文件中。

然后,main函数中使用os.startfile来播放这个语音文件(这适用于Windows系统)。

对于其他操作系统,你可能需要使用不同的方法来播放WAV文件。

5.8. 小结

游戏AI通过自然语言处理理解玩家语言输入并生成对应文本进而合成语音的全过程是一个高度复杂和智能化的过程。它涉及语音识别、自然语言理解、文本生成和语音合成等多个技术环节,需要综合运用多种算法和模型来实现。随着人工智能技术的不断发展,这一过程将变得更加高效和自然,为玩家提供更加沉浸式的游戏体验。

通过以上过程,游戏AI能够实时、准确地理解玩家的语言输入,并生成相应的反馈,从而大大提升游戏的交互体验和沉浸感。

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

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

相关文章

k8s部署单节点redis

一、configmap # cat redis-configmap.yaml apiVersion: v1 kind: ConfigMap metadata:name: redis-single-confignamespace: redis data:redis.conf: |daemonize nobind 0.0.0.0port 6379tcp-backlog 511timeout 0tcp-keepalive 300pidfile /data/redis-server.pidlogfile /d…

高考服务系统

摘 要 每年有大批考生在进行填写高考志愿时并不很清楚自己的高考分数适合那些高校以及专业。高考考生面临着未被高校录取,被调剂专业,甚至可能复读的问题。若能让考生轻松查询到高校录取、高校专业、高校招生等相关信息,能减少很大一部分考生…

《后端程序猿 · Caffeine 本地缓存》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻一周,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…

SolrCloud Autoscaling 自动添加副本

SolrCloud Autoscaling 自动添加副本 前言 问题描述 起因是这样的,我在本地调试 Solr 源码(版本 7.7.3),用 IDEA 以 solrcloud 方式启动了 2 个 Solr 服务,如下所示: 上图的启动参数 VM Options 如下&am…

QT控制comboBox切换方法

目录 1. 效果2. 操作 1. 效果 如下图: 点击全切换雨天模式按钮 则 comboBox 文本显示为 “雨天模式”点击全切换正常模式按钮 则 comboBox 文本显示为 “雨天模式” 切换到 雨天模式 切换到 正常模式 2. 操作 使用 “setCurrentIndex” 方法,切换 combo…

vmware虚拟机增加磁盘容量

概述 当初始分配给虚拟机的磁盘空间不够时,需要从外部的主系统增加配给。 具体操作分为两步:一:通过虚拟机界面添加分配的磁盘配给;二:将新分配的配给给使用起来。 操作 添加磁盘配给 在虚拟机内部添加新分配的配给…

安装Intel Realsense D435i驱动与ROS包报错

1.下载安装realsense SDK 1.1 安装依赖 sudo apt install libudev-dev pkg-config libgtk-3-dev sudo apt install libusb-1.0-0-dev pkg-config sudo apt install libglfw3-dev sudo apt install libssl-dev1.2 权限 cd librealsense/ sudo cp config/99-realsense-libusb.…

独享代理VS共享代理,新手选择攻略

随着互联网的广泛普及和应用,涉及网络隐私、数据安全和网络访问控制的问题变得越来越重要。代理服务器作为一种常见的网络工具,可以在跨境电商、海外社媒、SEO投放、网页抓取等领域发挥作用,实现匿名访问并加强网络安全。在代理服务器类别中&…

GoLand 2024 for Mac GO语言集成开发工具环境

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件(适合自己的M芯片版或Intel芯片版),将其从左侧拖入右侧文件夹中,等待安装完毕2、应用程序显示软件图标,表示安装成功3、打开访达,点击【文…

哪个牌子的充电宝牌子便宜好用?2024年性价比高充电宝排行榜!

在 2024 年,充电宝市场依旧琳琅满目,让人眼花缭乱。大家都在寻找那个既便宜又好用的充电宝,可面对众多品牌和产品,常常感到无从下手。别担心!经过深入的市场调研和实际使用体验,我们为您精心整理出了 2024 …

掌握空投,预见未来:空投教程网,撸毛党的必备工具

随着区块链技术的发展,越来越多的人开始关注这一领域。对于很多人来说,如何有效地参与区块链项目,尤其是空投活动,成为了一个重要的问题。为了解决这一问题,“空投教程网”应运而生。作为一个专为撸毛党设计的工具&…

【高中数学/基本不等式】已知:x,y皆大于1,且x+2y=4 求:1/(x-1)+1/(y-1)的最小值为?

【问题来源】 https://www.ixigua.com/7025123539728466469?logTag1c2fd2e305d60e6277ab 之第一题 【问题】 已知:x,y皆大于1,且x2y4 求:1/(x-1)1/(y-1)的最小值为? 【解答】 解: 若将(x2y)/41代入目标式&…

【PostgreSQL】数据基石:PostgreSQL的数据类型与表结构设计

目录 核心数据类型深入探索 基础数值与文本类型 日期与时间类型 特殊与复合类型 JSON与HSTORE 表的创建、修改与管理 创建与修改表结构 索引与性能优化 约束与数据完整性 核心数据类型深入探索 PostgreSQL以其多样化的数据类型著称,不仅包括标准SQL数据类型…

昇思25天学习打卡营第04天 | 数据集 Dataset

昇思25天学习打卡营第04天 | 数据集 Dataset 文章目录 昇思25天学习打卡营第04天 | 数据集 Dataset数据集加载数据集迭代数据集的变换shufflemapbatch 自定义数据集可随机访问数据集对象可迭代数据集生成器 总结打卡 数据集Dataset对原始数据进行封装、变换,为神经网…

光照老化试验箱在化工产品暴晒测试中的应用

概述 光照老化试验箱是一种模拟自然光照条件下材料老化情况的实验设备,广泛应用于化工、建材、电子、汽车等行业中对材料的耐候性、耐光性能等进行测试。通过模拟日光中的紫外线和温度等环境因素,加速材料老化过程,以此评估材料在长期使用中…

C语言编程-基于单链表实现贪吃蛇游戏

基于单链表实现贪吃蛇游戏 1.定义结构体参数 蛇行走的方向 蛇行走的状态 蛇身节点类 维护蛇的结构体型 2.游戏运行前预备工作 定位光标位置 游戏欢迎界面 绘制游戏地图(边界) 初始化游戏中的蛇身 创建食物 3.游戏运行 下一个位置是食物,就吃掉…

阿里云 SAE 助力修正商城 3 周内提升系统承载能力 20 倍,轻松应对春晚流量

作者:赵世振、刘松伟、朱坪" 从了解阿里云 SAE 到使用 SAE 进行应用架构升级共经历 3 周,这 3 周我们系统能承载的 QPS 从 5000 增强到 10 万,提升 20 倍,轻松应对了春晚大促流量洪波。并且,SAE 还帮助我们降低了…

超详细:安装Linux系统、虚拟现实教程

文章目录 一、如何下载并使用VMware虚拟机1.百度搜索vmware2.进入官网点击Workstation Pro链接3.博通注册对应的账号4.博通填写用户名、密码后直接登录会跳转到博通登录页5.个人使用选择个人版 二、国内镜像网站下载(Centos版本)三、镜像系统的安装1.打开…

PCL小笔记

一、常用概念 1,过滤器Filters 消除噪音 2,特征Features 集合点属性:曲面的曲率估计和查询点的法线 通过k-neighborhood计算得到这两个属性作为特征 查找方法:KD-tress、八叉树等 3,关键点Keypoints 可以利用明确标…

Halcon支持向量机

一 支持向量机 1 支持向量机介绍: 支持向量机(Support Vector Machine,SVM)是Corinna Cortes和Vapnik于1995年首先提出的,它在解决小样本、非线性及高维模式识别表现出许多特有的优势。 2 支持向量机原理: 在n维空间中找到一个分类超平面…