来 Azure 学习 OpenAI 三 - 用 Python 调用 Azure OpenAi API

news2024/11/29 4:52:19

大家好,我是微软学生大使 Jambo。在我们申请好 Azure 和 Azure OpenAI 之后,我们就可以开始使用 OpenAI 模型了。如果你还没有申请 Azure 和 Azure OpenAI,可以参考 注册 Azure 和申请 OpenAI。

本文将会以 Azure 提供的 Openai 端口为例,并使用 OpenAI 提供的 Python SDK 进行模型的调用。

创建工作区

进入 Azure 首页,在搜索栏中输入 OpenAI,点击进入 OpenAI 页面。

1

点击创建。

2

选择订阅,资源组,工作区名称,工作区地区,点击创建。这里我们地区选择 “美东” ,因为目前只有这个地区支持 chatgpt 对话模型。如果你不需要对话模型,可以选择其他模型种类更多的 “西欧”。

3

选择下一步,确认无误后点击创建。

4

等他创建完成后,点击 “探索” 进入工作区。

5

模型介绍

在使用模型之前,我们先来了解一下 Azure 提供了哪些 OpenAI 模型。Azure 提供的模型从功能上可以分为三大类:补全(completion)、对话(chat)、嵌入(embeddings)。

补全模型可以根据输入的文本,补全剩余的文本。这类模型顾名思义,就是根据前文续写后续的部分。他可以用来续写文章,补全程序代码。不仅如此,你其实也可以通过固定的文字格式来实现对话的效果。

对话模型相信有使用过 ChatGPT 的同学应该很熟悉。对话模型可以根据输入的文本,生成对话的回复。这类模型可以用来实现聊天机器人,也可以用来实现对话式的问答系统。在调用方面,对话模型与补全模型最主要的区别是:你需要一个列表来存储对话的历史记录。

没接触过过 NLP(自然语言处理) 的同学可能会对 “嵌入” 这个词感到疑惑。“嵌入” 实际上就是将文本转换为向量的操作,而这个向量可以用来表示文本的语义信息,这样就可以方便地比较语义的相似度。而嵌入模型就是用来实现这个操作的。

大部分模型拥有多个能力等级,能力越强能处理的文字也就越复杂,但相对的处理速度和使用成本也就越高。通常有 4 个等级:Davinci > Curie > Babbage > Ada ,其中 Davinci 最强而 Ada 是最快的(有兴趣的同学可以查一下这 4 位名人)。在使用模型时,你可以根据自己的需求选择合适的等级。

具体的模型介绍可以参考 Azure OpenAI 服务模型。

部署模型

在了解了模型的功能和等级之后,我们就可以开始使用模型了。在使用模型之前,我们需要先部署模型。在 Azure OpenAI 工作区中,进入 “部署” 页面。

6

选择模型,点击创建。这里我部署了一个补全模型和对话模型。

7

部署后你就可以用 API 调用模型了,当然你也可以现在 Playground 中测试一下。

8

API 参数

在 Playground 中测试模型时,我们可以看到 API 的参数。这里我们来介绍一下这些参数。具体的参数细节可以参考 API Reference。

  • model 指定使用的模型。
  • prompt 是输入给模型的文本。
  • temperature 控制了生成文本的随机程度,值越大,生成的文本越随机,值越小,生成的文本越稳定。这个值的范围在 0.0 到 2.0 之间(虽然在 Playground 中最高只能设为 1)。
  • top_ptemperature 类似,也是控制生成文本的随机程度。但这个参数简单的说是控制候选词的范围,值越大,候选词的范围越大,值越小,候选词的范围越小。这个值的范围在 0.0 到 1.0 之间。通常来说,这两个参数只需要设置一个就可以了。
  • max_tokens 是模型生成的文本的最大长度,这其中的 “token” 不是指字符长度,你可以把他理解为模型眼中的 “词”。Token 与我们所使用的词不一定是一一对应的。
  • stop 是生成文本的停止条件,当生成的文本中包含这个字符串时,生成过程就会停止,最终生成的文本中将不包含这个字符串。这个参数可以是一个 string,也可以是一个长度至多为 4 的 string 列表。
  • presence_penalty 控制生成文本的多样性。他会惩罚那些在生成文本中已经出现过的 token,以减小未来生成这些 token 的概率。这个值的范围在 -2.0 到 2.0 之间。如果设为负值,那么惩罚就会变为奖励,这样就会增加生成这些 token 的概率。
  • frequency_penaltypresence_penalty 类似,也是控制生成文本的多样性。但不同的是,presence_penalty 是一次性惩罚,而 frequency_penalty 累计惩罚。如果一个词在生成文本中出现了多次,那么这个词在未来生成的概率就会越来越小。这个值的范围同样在 -2.0 到 2.0 之间。

计算 Token

GPT 模型使用 token 来表示文本,而不是使用字符。模型能处理的文本长度是有限的,而这个长度指的是 token 的数量,而不是字符的数量,并且 OpenAI 使用模型的计费方式也是按照生成 token 的数量计算。因此为了能够更好地使用模型,我们需要知道生成的文本究竟有多少 token。

OpenAI 提供了一个 Python 库 tiktoken 来计算 token。

pip install tiktoken

导入 tiktoken 库。

import tiktoken

不同模型使用不同的编码来将文本转换为 token。

Encoding nameOpenAI models
cl100k_basegpt-4, gpt-3.5-turbo, text-embedding-ada-002
p50k_baseCodex models, text-davinci-002, text-davinci-003
r50k_base (or gpt2)GPT-3 models like davinci

我们可以使用 tiktoken.get_encoding() 来获取编码对象。也可以使用 tiktoken.encoding_for_model() 通过模型名自动获取编码对象。

encoding = tiktoken.get_encoding("cl100k_base")
encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")

然后用 .encode() 方法将文本 token 化。返回的 token 列表的长度,就是这段文本的 token 数量。

encoding.encode("tiktoken is great!")
[83, 1609, 5963, 374, 2294, 0]

我们还可以使用 .decode() 将 token 列表转换为文本。

encoding.decode([83, 1609, 5963, 374, 2294, 0])
'tiktoken is great!'

使用 Python SDK

我们首先需要到 Azure 的 “密钥” 页面获取密钥和终结点,两个密钥只要其中一个即可。

9

然后安装 openai 库。注意,Python 版本需要大于等于 3.7。我们这里使用官方提供的 Python SDK,其他语言的 SDK 可以在 OpenAI Libraries 找到。
另外,因为这个库没有专门的文档参考,所以我们需要查看库的源码和 API 参考。

pip3 install openai

更具先前获取的密钥和终结点初始化 SDK:

import openai

openai.api_key = "REPLACE_WITH_YOUR_API_KEY_HERE"    # Azure 的密钥
openai.api_base = "REPLACE_WITH_YOUR_ENDPOINT_HERE"  # Azure 的终结点
openai.api_type = "azure" 
openai.api_version = "2023-03-15-preview" # API 版本,未来可能会变
model = ""  # 模型的部署名

调用补全模型

补全模型使用的是 openai.Completion.create 方法,使用的参数在上面已经介绍过了,但因为我使用的是 Azure 的 API,所以指定模型的参数名是 engine。下面是一个简单的例子:

prompt = "1, 2, 3, 4, "
response = openai.Completion.create(
    engine=model, prompt=prompt, max_tokens=50, temperature=0.0
)
print(response)

它打印出的内容就是 API 返回的 json 结果。其中 text 就是模型生成的文本,可以看到它将数列续写下去。但他只停在 21,是因为我设置了 max_tokens=50,可以看到 usage 中的 completion_tokens 是 50,也就是说模型生成了 50 个 token,达到了最大值,而 finish_reasonlength,表示是因为达到了最大长度而停止的。如果是因为写完了而停止,那么 finish_reason 的值会是 stop

{
  "choices": [
    {
      "finish_reason": "length",
      "index": 0,
      "logprobs": null,
      "text": "5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,"
    }
  ],
  "created": 1680628906,
  "id": "cmpl-71edm7DMgHrynaiXONWi4ufSrXiL0",
  "model": "gpt-35-turbo",
  "object": "text_completion",
  "usage": {
    "completion_tokens": 50,
    "prompt_tokens": 12,
    "total_tokens": 62
  }
}

此外你或许有注意到,我使用的模型是 “gpt-35-turbo”。他虽然是对话模型,但他实际上也可以通过补全 API 使用。但同样是对话模型的 “gpt-4” 就只能通过对话 API 使用。

接下来我们在其中加个停止条件,让他数到 11 就停止:

prompt = "1, 2, 3, 4, "
response = openai.Completion.create(
    engine=model, prompt=prompt, temperature=0.0, stop=["11"]
)
print(response["choices"][0])

可以看到他确实是停在 11 之前,并且 finish_reason 的值是 stop

{
  "finish_reason": "stop",
  "index": 0,
  "logprobs": null,
  "text": "5, 6, 7, 8, 9, 10, "
}

但如果我们将 temperature 的值调高,它可能会生成意料之外的文本:

prompt = "1, 2, 3, 4, "
response = openai.Completion.create(
    engine=model, prompt=prompt, temperature=0.8, stop=["11"]
)
print(response["choices"][0])
{
  "finish_reason": "length",
  "index": 0,
  "logprobs": null,
  "text": "5, 6, 7, 8, 9, 10])) # 55\nprint(sum_list([0, 0, 0, 0, 0])) # 0\nprint(sum_list([1, -"
}

调用对话模型

对话模型使用的是 openai.ChatCompletion.create 方法,它的参数和补全模型的参数类似,但有一些不同:对话模型输入的是一个对话历史,而不是单个的文本。并且其参数名是 messages,而不是 prompt

对话历史是一个列表,列表中的每个元素都是一个对话,每个对话又是一个字典,字典中有两个键:rolecontentrole 是对话的角色,而 content 是对话的内容。下面是个简单的例子:

messages=[
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Knock knock."},
    {"role": "assistant", "content": "Who's there?"},
    {"role": "user", "content": "Orange."},
]

可以看到 role 的值有 systemuserassistantuser 就是指用户,assistant 代表的就是和你对话的 AI 模型,而 system 可以理解为 assistant 的设置、人设等等。当然 system 也可以省略。

接下来我们用此对话历史来调用对话模型:

response = openai.ChatCompletion.create(
    engine=model, messages=messages
)
response
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "Yes, many other Azure Cognitive Services do support the use of customer managed keys for encrypting and protecting data. In fact, most Azure services that handle sensitive data can be configured to use customer managed keys for enhanced security and compliance. Some examples of Azure Cognitive Services that support customer managed keys include Azure Cognitive Services Speech Services, Azure Cognitive Services Text Analytics, and Azure Cognitive Services Translator Text.",
        "role": "assistant"
      }
    }
  ],
  "created": 1680633366,
  "id": "chatcmpl-71fnivs89GKEMKpzwuCCxbH0MNP98",
  "model": "gpt-35-turbo",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 79,
    "prompt_tokens": 58,
    "total_tokens": 137
  }
}

我们可以维护一个对话历史,然后每次调用对话模型时,将新的对话加入到对话历史中,以此循环来实现一个对话系统:

conversation = [{"role": "system", "content": "You are a helpful assistant."}]
  
while True:
    user_input = input()
    conversation.append({"role": "user", "content": user_input})
  
    response = openai.ChatCompletion.create(
        engine=model,
        messages=conversation,
    )
  
    conversation.append(
        {"role": "assistant", "content": response["choices"][0]["message"]["content"]}
    )
    print("\n" + response["choices"][0]["message"]["content"] + "\n")

流式调用

所谓 “流式” ,就是服务器生成了什么内容就立即返回给客户端,而不是等全部都完成后再统一返回。最典型的例子就是各种视频网站,你在播放视频时,视频的内容是随着时间的推移而不断加载的,而不是等到视频加载完毕后再一次性播放。这样做的好处是可以让用户更快的看到内容。ChatGPT 那样像一个字一个字写出来的效果就是通过流式形成的。

但他的缺点是,服务器将不会帮你统计生成的 token,你需要自己统计。

以下是一个一般调用的例子:

response = openai.ChatCompletion.create(
    engine=model,
    messages=[
        {'role': 'user', 'content': "Count to 10. E.g. 1, 2, 3, 4, ..."},
    ],
    temperature=0,
)
  
print(response)
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "\n\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10.",
        "role": "assistant"
      }
    }
  ],
  "created": 1680709601,
  "id": "chatcmpl-71zdJtUaOIhfnVsAKLyD88RtGzgQb",
  "model": "gpt-35-turbo",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 31,
    "prompt_tokens": 28,
    "total_tokens": 59
  }
}

但我们只要将 stream 参数设置为 True ,就可以使用流式调用了:

response = openai.ChatCompletion.create(
    engine=model,
    messages=[
        {'role': 'user', 'content': "Count to 10. E.g. 1, 2, 3, 4, ..."},
    ],
    temperature=0,
    stream=True,
)
print(next(response))
for chunk in response:
    print(chunk['choices'])
{
  "choices": [
    {
      "delta": {
        "role": "assistant"
      },
      "finish_reason": null,
      "index": 0
    }
  ],
  "created": 1680710012,
  "id": "chatcmpl-71zjwZk3EB5fLgVup9S1BPZo73JUk",
  "model": "gpt-35-turbo",
  "object": "chat.completion.chunk",
  "usage": null
}
[<OpenAIObject at 0x1e2ba8fdc10> JSON: {
  "delta": {
    "content": "\n\n"
  },
  "finish_reason": null,
  "index": 0
}]
[<OpenAIObject at 0x1e2ba8fe870> JSON: {
  "delta": {
...
  "delta": {},
  "finish_reason": "stop",
  "index": 0
}]

因为长度原因,除了第一个块,其他都只打印了 choices 的内容,但其余的部分都是一样的,甚至是 id
可以看到,第一个块的 delta 里面只有 role ,而后面的块里面的 delta 里面有 content ,这就是服务器生成的内容。我们只要把这些内容拼接起来就可以了:

response = openai.ChatCompletion.create(
    engine=model,
    messages=[
        {"role": "user", "content": "Count to 10. E.g. 1, 2, 3, 4, ..."},
    ],
    temperature=0,
    stream=True,
)
  
message = next(response)["choices"][0]["delta"]
content = "".join(
    [chunk["choices"][0]["delta"].get("content", "") for chunk in response]
)
message["content"] = content
print(message)
{
  "content": "\n\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10.",
  "role": "assistant"
}

异步调用

在我们写诸如网站、爬虫之类的程序时,经常会遇到类似调用数据库、API 的情况,这些操作都是需要漫长的等待,在等待的过程中,程序会处于阻塞状态,无法继续执行后面的代码。可这些操作的瓶颈通常不在于程序本身,而是在于网络或者硬盘的速度,这时候我们就可以使用异步来解决这个问题。

异步可以让我们等待结果的同时,继续执行其他的代码,这样就不会阻塞程序的执行了。我们在这里就不多介绍 Python 的异步和其语法,这超出了本文的范围,有兴趣的同学可以自行学习。本文将着重于 SDK 的异步调用。

OpenAI SDK 的异步调用和同步调用的区别在于,异步调用需要使用 acreate 方法,而不是 create 方法。这里的 a 表示异步。acreate 方法的返回值是一个 coroutine 对象,而不是一个 OpenAIObject 对象,所以我们不能直接使用 print 来打印它,而是需要使用 await 来等待它的结果。

async def async_completion():
    response = await openai.ChatCompletion.acreate(
        engine=model,
        messages=[
            {"role": "user", "content": "Count to 10. E.g. 1, 2, 3, 4, ..."},
        ],
        temperature=0,
    )
    return response["choices"][0]["message"]
print(await async_completion())
{
  "content": "\n\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10.",
  "role": "assistant"
}

OpenAI SDK 的异步请求默认是使用 aiohttp 第三方异步请求库的 session。SDK 在每次请求时都会新建一个 session,这会造成一部分的开销,因此如果你的程序需要频繁的异步请求,那么你可以自己传入一个 aiohttp.ClientSession 对象,这样就可以复用 session 了。另外要注意的是,如果你使用了自己的 session,那么你需要在程序结束时手动关闭它,以免造成其他问题:

from aiohttp import ClientSession
  
openai.aiosession.set(ClientSession())
res = await asyncio.gather(*[async_completion() for _ in range(10)])
await openai.aiosession.get().close()

提示技巧

OpenAI 的模型基于你输入的文本,也就是提示(Prompt)来生成后续的文字,它可以做很多事情,正因如此,你需要明确的表达你想要什么。在一些时候,仅仅是描述是不够的,你还需要给模型展示出你想要的结果,比如列举几个例子。下面三点是创建提示的基本准则:

  • 展示和讲述。 通过指示、示例或两者结合,清楚地表明你的需求。
  • 提供优质数据。 如果您试图构建分类器或让模型遵循某种模式,请确保有足够的示例。。
  • 检查设置。 Temperaturetop_p 控制模型在生成响应时的确定性程度。如果你想要模型输出确定性的答案,将值设低一些;如果你想要模型输出更多的选择,将值设高一些。通常这两个值同时只需要调整一个就可以了。在生成文字时,你可能需要经常调整这些设置,以确保输出的正确性。

另外,虽然以下例子都是使用完成模型,但这些提示原则同样适用于聊天模型。

生成

产生文本和想法几乎是 OpenAI 的最基本功能,它可以用来生成代码、文章、故事、歌词、对话等等。在这里,我们将使用 Completion 类来完成这个任务。下面是个很简单的例子:

10

这虽然只是个非常简单的例子,但其中还是有些值得注意的细节:

  1. 我们首先描述了我们的意图,即生成一段关于 Python 优势的列表。
  2. 我们提供了一个示例,这样模型就知道我们想要的是一个列表。并且只是说明优势,而不用具体阐述。
  3. 我们留了一个 “2. ”,以此引导模型继续生成。

对话

生成模型在经过引导后也可以用于对话。当然,只是简单的提示可能不足以让模型理解你的意思,你可以给他提供一些示例对话,这样他就可以跟着对话续写下去:

12

为了避免让他生成过头,把我们的话也一起生成了,我们可以使用 stop 参数来进行限制。比如在这里,我把 stop 参数设置的是 “博士:”,这样当他生成到这个字符前,就会停止。

分类

下面的例子中,我在《巫师3》的评论区中选了 5 条,并让他分类为好评或差评:

11

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

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

相关文章

2023年4月广东省计算机软考中/高级备考班招生简章

软考是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资格考试。 系统集成…

VS Code 插件开发概览

VS Code 插件开发概览 前言 VS Code作为开发者的代码开发利器&#xff0c;越来越受开发者的喜爱。像我身边的前端&#xff0c;每天80%的开发工作都是在VS Code上完成的。随着人们对它的使用&#xff0c;不再满足简单的优雅&#xff0c;舒服写代码这一基本需求。有些人利用它进…

FA-PEG-MAL,叶酸-聚乙二醇-马来酰亚胺 实验用科研试剂;Folic acid PEG Maleimide

FA-PEG-MAL,叶酸-聚乙二醇-马来酰亚胺 中文名称&#xff1a;叶酸-聚乙二醇-马来酰亚胺 英文名称&#xff1a;Folic acid PEG Maleimide, FA-PEG-MAL 性状&#xff1a;固体或者粘稠液体&#xff0c;取决于分子量大小。 溶剂&#xff1a;溶于水、DMF、DMSO等常规有机溶剂 分…

Redis高级之IO多路复用和epoll(十二)

nginx 的反向代理也是采用了IO多路复用 1.是什么 I/O 网络 I/O 多路 多个客户端连接&#xff08;连接就是套接字描述符&#xff0c;即socket 或者 channel&#xff09;&#xff0c;指的是多条 TCP 连接 复用 用一个进程来处理多条的连接&#xff0c;使用单进程就能实现同时处…

【cmake学习】set_target_properties 常见属性以及获取target 属性

set_target_properties 的作用是设置目标的属性&#xff0c;可以是目标文件输出的名称或者目录、目标文件的版本号。与之对应的&#xff0c;我们可以使用 get_target_properties 来获取目标文件某一属性对应的值。 命令格式如下&#xff1a; set_target_properties(目标文件1…

凌恩生物美文分享|基于宏基因组的氮循环分析内容重磅升级!

元素循环是生物地球化学循环的重要环节&#xff0c;主要涉及碳、氮、磷、硫等元素的循环过程。凌恩生物强势推出基于宏基因组的氮循环研究方案&#xff0c;构建了完整的氮循环循环模式图&#xff0c;对宏基因组数据进行深入挖掘&#xff0c;各部分结果图可直接用于文章发表&…

NDK RTMP直播客户端三

在之前完成的实战项目【FFmpeg音视频播放器】属于拉流范畴&#xff0c;接下来将完成推流工作&#xff0c;通过RTMP实现推流&#xff0c;即直播客户端。简单的说&#xff0c;就是将手机采集的音频数据和视频数据&#xff0c;推到服务器端。 接下来的RTMP直播客户端系列&#xff…

Openssh 版本升级至8.4

目录 安装包下载地址 zlib包 openssl包 openssh 1、为了防止升级失败登陆不了&#xff0c;所以需要安装telnet 2、检查环境 2.1安装所需的相关组件 2.2备份原来的数据 2.3删除现有的安装sshd的相关软件包 3、下载所需的源码包 3.1编译安装sshd 3.2查看ssh命令的执…

XML文件检索技术:Xpath

纠正&#xff1a;上图中是通过根元素、父元素、子元素… Xpath检索方法及路径&#xff1a; 绝对路径代码示例&#xff1a; 47行&#xff1a;Xpath解析技术也是基于Dom4J的技术&#xff1b; 52行&#xff1a;List<Node> 创建Node类型的集合nameNodes&#xff0c;selec…

大数据应用开发--概述

大数据应用开发–概述 1. 大数据应用开发简介 1.1 数据分析的概念 数据分析就是利用数学、统计学理论相结合科学统计分析方法对数据库中的数据、Excel数据、收集的大量数据、网页抓取的数据进行分析&#xff0c;从中提取有价值的信息形成结论并进行展示的过程。 数据分析的目…

没想到大厂Adobe还有这些“猫腻”!

北京时间周四晚间&#xff0c;图像及视频生产力工具大厂Adobe发布公告&#xff0c;宣布旗下的视频创作应用Premiere Pro将喜提一系列新的AI功能。这也是Adobe上个月发布AIGC创作功能“萤火虫”后的最新动作。综合Adobe的官方公告和演示视频&#xff0c;最大亮点就是基于文字的视…

生存函数(Survival function)

文章目录1. 定义2. 生存函数的例子3. 参数生存函数3.1 指数生存函数&#xff08;Exponential survival function&#xff09;3.2 威布尔生存函数&#xff08;Weibull survival function&#xff09;3.3 其他参数生存函数4. 非参数生存函数5. 性质6. Kaplan–Meier estimator6.1…

总结824

学习目标&#xff1a; 4月&#xff08;复习完高数18讲内容&#xff0c;背诵21篇短文&#xff0c;熟词僻义300词基础词&#xff09; 学习内容&#xff1a; 英语&#xff1a;早上 读了《nasty place》&#xff0c;单词150个 高数&#xff1a;看了12讲二重积分的内容&#xff0…

算法设计与智能计算 || 专题六: 不可导凸函数的最优解搜索问题

不可导凸函数的最优解搜索问题 文章目录不可导凸函数的最优解搜索问题1. 次梯度下降方法1.1 基于次梯度的 Lasso 回归求解1.2 次梯度求解 Lasso 算法1.3 编程实现2. 软阈值方法2.1 软阈值求解Lasso回归1. 次梯度下降方法 如目标函数包含不可微分的部分&#xff0c;形如 E(w)1N…

计组2.3——浮点数的表示和运算

计组2.3 浮点数 #mermaid-svg-hwjyO2bt7hFXy1eD {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hwjyO2bt7hFXy1eD .error-icon{fill:#552222;}#mermaid-svg-hwjyO2bt7hFXy1eD .error-text{fill:#552222;stroke:#552…

视频美颜sdk的开发流程与注意事项

目前&#xff0c;视频美颜技术逐渐成为了人们关注的焦点。而视频美颜sdk作为实现视频美颜的重要工具&#xff0c;也因此备受关注。本文将从视频美颜sdk的开发流程和注意事项两个方面进行探讨。 一、视频美颜sdk的开发流程 1、确定需求 在进行视频美颜sdk的开发之前&#xff0…

Solon v2.2.10 发布,助力信创国产化

Solon 是一个高效的 Java 应用开发框架&#xff1a;更快、更小、更简单。它不是 Spring、没有使用 Servlet、JavaEE 接口&#xff0c;是一个有自己接口标准的开放生态。可以为应用软件国产化提供支持&#xff0c;助力信创建设。 150来个生态插件&#xff0c;覆盖各种不同的应用…

天猫数据分析:饮料市场头部份额下滑,无糖饮料占比40%

如今&#xff0c;全世界减糖、控糖的大趋势已经拉开帷幕。 根据沸点测评数据&#xff0c;今年所有在新加坡销售的饮料&#xff0c;必须在包装上注明A、B、C或D的营养等级标签&#xff0c;列明饮料含糖分和饱和脂肪的百分比&#xff0c;营养等级为D的饮品则会被禁止做广告营销。…

Tinymce富文本编辑器在vue项目中的使用;引入第三方插件和上传视频、图片等

先放张效果图第一步&#xff1a;安装依赖 npm install tinymce5.0.12第二步&#xff1a;在项目中的public文件夹中新建tinymce文件夹&#xff08;因为我的项目是脚手架创建的&#xff0c;所以公共文件夹是public&#xff09;&#xff1b;在node_modules中找到skins文件夹复制到…

插件化换肤原理—— 布局加载过程、View创建流程、Resources 浅析

作者&#xff1a;孙先森Blog 本文主要分析了 Android 布局加载流程 分析 一般的换肤功能大概是这样的&#xff1a;在 App 的皮肤商城内下载“皮肤包”&#xff0c;下载完成后点击更换界面上的 View 相关资源&#xff08;颜色、样式、图片、背景等&#xff09;发生改变&#xf…