.net 引用 其他文件类_在 Blazor WebAssembly 静态网站中部署ML.NET机器学习模型

news/2024/5/11 16:22:56/文章来源:https://blog.csdn.net/weixin_36485371/article/details/112731764

目前世面上有许多方法来部署机器学习模型。最常见的方法是通过 API 或 serverless functions 将模型公开为 Web 服务。将模型部署为 Web 服务时,其中一个注意事项是延迟和性能。使用模型基于 HTTP 进行预测的过程包括接受用户输入、从文件中加载模型的序列化版本、使用模型进行预测以及将预测返回给用户。由于模型通常只是静态文件,因此部署模型的另一种方法是作为 Web 上的静态资产,就像任何其他 HTML、CSS 或 JavaScript 文件一样。此部署方法与 TensorFlow.js 类似。以这种方式进行部署有几个优点。一是不再有 Web 服务只是为了为模型提供服务,从而使其更具成本效益。另一个是一旦模型下载到用户的 PC 上,此时使用的资源是用户 PC 的资源,而不是模型本来会托管的服务器。最后,由于模型是静态文件,因此可以通过 CDN 进行分发。

其中一个挑战是机器学习模型通常使用 JavaScript 以外的语言构建。这使得使用相同的代码/库构建模型变得困难或几乎不可能。WebAssembly 允许 Rust、C++、C# 和其他语言在浏览器中本机运行,从而改变了这一点。有了这种能力,加载模型和进行预测的代码/逻辑就更容易,几乎与本机平台的代码/逻辑相当。Blazor WebAssembly 为用户提供了在 C# 中完全创建基于组件的现代 Web 应用程序的能力。此外,Blazor WebAssembly 还允许用户以简单且经济高效的方式发布和部署其应用程序作为静态网站。ML.NET是一个开源的跨平台框架,允许开发人员使用 .NET 创建机器学习模型。在这篇文章中,我将演示如何训练一个多分类机器学习模型,预测鸢尾花种类。然后,我将采用该模型并将其与 Blazor WebAssembly 静态网站一起部署到 Azure 。此应用程序的完整代码可以在GitHub 上的 MLNETBlazorWASMSample 存储库中找到。

先决条件

这个项目是在Windows PC上构建的,但应该在Mac或Linux上执行以体现跨平台特性。

  • .NET 核心 SDK 3.1

  • Blazor WebAssembly模板

  • Azure 订阅

  • Azure 存储资源管理器

设置解决方案

本文中构建的解决方案包含三个项目:

  • SchemaLibrary:C# .NET 标准 2.0 类库,其中包含用于训练模型的数据的架构定义类以及模型生成的预测输出。

  • TrainingConsole:用于训练机器学习模型的 C# .NET Core 3.1 控制台应用程序。

  • BlazorWebApp:Blazor WebAssembly Web 应用程序,使用由TrainingConsole应用程序训练的机器学习模型进行预测。

安装Blazor WebAssembly模板

使用 .NET CLI 在命令提示符中运行以下命令:

dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.2.0-preview1.20073.1

创建解决方案

给命名MLNETBlazorWASMSample的解决方案创建新目录。

mkdir MLNETBlazorWASMSample

导航到新创建的解决方案目录并创建解决方案:

cd MLNETBlazorWASMSample
dotnet new sln

创建schema类库

模型输入和输出的数据架构在训练期间和进行预测时共享。要共享资源,请创建ConsoleTraining 和 BlazorWebApp 项目共享的类库。在解决方案目录中,输入以下命令:

dotnet new classlib -o SchemaLibrary

安装Microsoft.ML NuGet 包(此解决方案是使用版本 1.4.0 构建的)。整个解决方案都使用Microsoft.ML包。

dotnet add SchemaLibrary package Microsoft.ML

将库项目添加到解决方案。

dotnet sln add SchemaLibrary

创建训练控制台应用程序

控制台应用程序包含用于训练模型的一系列数据转换和算法。在解决方案目录中,创建新的控制台应用程序。

dotnet new console -o TrainingConsole

将控制台应用程序添加到解决方案。

dotnet sln add TrainingConsole

引用 SchemaLibrary 项目。

dotnet add TrainingConsole reference SchemaLibrary

创建 Blazor WebAssembly Web 应用程序

Web 应用程序包含一些输入元素,因此用户可以提供模型随后用于进行预测的新数据。在解决方案目录中,创建新的 Blazor WebAssembly 应用程序。

dotnet new blazorwasm -o BlazorWebApp

将 Web 应用程序项目添加到解决方案。

dotnet sln add BlazorWebApp

引用 SchemaLibrary 项目。

dotnet add BlazorWebApp reference SchemaLibrary

定义架构

了解数据

用于训练模型的数据来自iris dataset。它包含四个数值列,即花瓣和萼片的度量,最后一列为鸢尾花的种类。这是数据的示例。

Sepal length (cm)Sepal width (cm)Petal length (cm)Petal width (cm)Class (iris species)
5.13.51.40.2Iris-setosa
7.03.24.71.4Iris-versicolor
6.33.36.02.5Iris-virginica

定义模型输入架构

SchemaLibrary项目中,创建一个ModelInput类,用于数据建模并作为模型输入。 

ni ModelInput.cs

ModelInput类应如下所示:

using Microsoft.ML.Data;namespace SchemaLibrary
{public class ModelInput
{
[LoadColumn(0)]public float SepalLength { get; set; }
[LoadColumn(1)]public float SepalWidth { get; set; }
[LoadColumn(2)]public float PetalLength { get; set; }
[LoadColumn(3)]public float PetalWidth { get; set; }
[LoadColumn(4)]public string Label { get; set; }
}
}

请注意,该列现在是一个称为ClassLabel的属性。原因有二:

  1. 避免使用class关键字。

  2. 在ML.NET中,算法要预测的列的默认列名称为Label。

另请注意每个属性顶部的LoadColumn属性。这用于告诉加载程序列的索引,其中相应属性的数据所在的位置。

定义模型输出架构

与输入架构类似,有模型输出的架构。此解决方案中使用的模型类型是多类分类模型,因为鸢尾花种有两个以上类别可供选择。多分类模型输出称为一个列,该列包含预测类别的名称。在SchemaLibrary项目中,创建一个PredictedLabelModelOutput类,用于对模型所做的预测建模。 

ni ModelOutput.cs

ModelOutput类应如下所示:

namespace SchemaLibrary
{public class ModelOutput
{public string PredictedLabel { get; set; }
}
}

训练模型

现在是时候创建训练模型的应用程序了。

获取数据

下载数据并将其保存在TrainingConsole项目目录中。

curl https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data -o iris.data

定义数据准备和训练步骤

TrainingConsole项目中,打开Program.cs文件,并在顶部添加以下内容:

using System;using System.Linq;using Microsoft.ML;using SchemaLibrary;

然后,删除Main方法内的内容,并将其替换为以下内容。

// 1. Initialize MLContext
MLContext mlContext = new MLContext();// 2. Load the data
IDataView data = mlContext.Data.LoadFromTextFile("iris.data", separatorChar:',');// 3. Shuffle the data
IDataView shuffledData = mlContext.Data.ShuffleRows(data);// 3. Define the data preparation and training pipeline.
IEstimator pipeline =
mlContext.Transforms.Concatenate("Features","SepalLength","SepalWidth","PetalLength","PetalWidth")
.Append(mlContext.Transforms.NormalizeMinMax("Features"))
.Append(mlContext.Transforms.Conversion.MapValueToKey("Label"))
.Append(mlContext.MulticlassClassification.Trainers.NaiveBayes())
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));// 4. Train with cross-validationvar cvResults = mlContext.MulticlassClassification.CrossValidate(shuffledData, pipeline);// 5. Get the highest performing model and its accuracy
(ITransformer, double) model =
cvResults
.OrderByDescending(fold => fold.Metrics.MacroAccuracy)
.Select(fold => (fold.Model, fold.Metrics.MacroAccuracy))
.First();
Console.WriteLine($"Top performing model's macro-accuracy: {model.Item2}");// 6. Save the model
mlContext.Model.Save(model.Item1, data.Schema, "model.zip");
Console.WriteLine("Model trained");

训练应用程序从文件iris.data加载数据并应用一系列转换。首先,所有单独的数字列都合并到单个矢量中,并存储在称为Features的新列中。然后,该Features列需要预处理归一化,MapValueToKey转换用于将Label列中的文本转换为数字。然后,转换后的数据用于使用NaiveBayes算法训练模型。请注意,在撰写本文时,对于多分类问题,只有 Naive Bayes 已确认与 Blazor WebAssembly 合作。最后,将PredictedLabel存储为数字,以便必须将其转换回文本。

使用Fit方法,将数据应用于管道。由于数据集很小,因此使用称为交叉验证的技术来构建更健壮的模型。训练模型后,具有最高性能的模型将序列化并保存到名为model.zip的文件,以供以后在 Web 应用程序中使用。

最终Program.cs文件应类似于以下内容:

using System;using System.Linq;using Microsoft.ML;using SchemaLibrary;namespace TrainingConsole
{class Program
{static void Main(string[] args)
{// 1. Initialize MLContext
MLContext mlContext = new MLContext();// 2. Load the data
IDataView data = mlContext.Data.LoadFromTextFile("iris.data", separatorChar:',');// 3. Shuffle the data
IDataView shuffledData = mlContext.Data.ShuffleRows(data);// 3. Define the data preparation and training pipeline.
IEstimator pipeline =
mlContext.Transforms.Concatenate("Features","SepalLength","SepalWidth","PetalLength","PetalWidth")
.Append(mlContext.Transforms.NormalizeMinMax("Features"))
.Append(mlContext.Transforms.Conversion.MapValueToKey("Label"))
.Append(mlContext.MulticlassClassification.Trainers.NaiveBayes())
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));// 4. Train with cross-validationvar cvResults = mlContext.MulticlassClassification.CrossValidate(shuffledData, pipeline);// 5. Get the highest performing model and its accuracy
(ITransformer, double) model =
cvResults
.OrderByDescending(fold => fold.Metrics.MacroAccuracy)
.Select(fold => (fold.Model, fold.Metrics.MacroAccuracy))
.First();
Console.WriteLine($"Top performing model's macro-accuracy: {model.Item2}");// 6. Save the model
mlContext.Model.Save(model.Item1, data.Schema, "model.zip");
Console.WriteLine("Model trained");
}
}
}

运行应用程序

TrainConsole项目目录中,使用以下命令运行应用程序并训练模型:

dotnet run

托管模型

保存模型后,使用 Azure 门户创建 Azure 存储帐户。

6487933f7c45e4050c928b64ee9a6208.png

然后,导航到新创建的存储帐户资源,并创建名为models的 Blob 容器。

9254f07130f6b7a6468664ba162490a6.png

 创建容器后,导航到它并上传model.zip文件。

9cbd29dbdbbaf2a120224151361b4b42.png  

创建预测网页

要进行预测,请创建一个网页以获取用户输入。然后向模型提供用户输入,并将预测显示给用户。

设置导入

BlazorWebApp项目目录中,打开_Imports.razor文件。这包含应用程序中页面和组件的 using 语句。添加以下使用语句:

@using System.IO
@using Microsoft.ML
@using SchemaLibrary

创建用户输入页

BlazorWebApp项目中,在Pages目录中创建一个名为"Prediction.razor"的新razor页面。

ni Prediction.razor

向其中添加以下内容:

@page "/prediction"
@inject HttpClient _client<label>Sepal Length: label><input type="text" @bind="_sepalLength"><br><label>Sepal Width: label><input type="text" @bind="_sepalWidth"><br><label>Petal Length: label><input type="text" @bind="_petalLength"><br><label>Petal Width: label><input type="text" @bind="_petalWidth"><br><button @onclick="GetPrediction">Make predictionbutton>
@if(@ModelPrediction == null)
{<p>Enter data to get a predictionp>
} else
{<p>@ModelPredictionp>
}
@code {
private PredictionEngine<ModelInput,ModelOutput> _predictionEngine;
private string _sepalLength, _sepalWidth, _petalLength, _petalWidth, ModelPrediction;
protected override async Task OnInitializedAsync()
{
Stream savedModel = await _client.GetStreamAsync("<YOUR-MODEL-ENDPOINT>");
MLContext mlContext = new MLContext();
ITransformer _model = mlContext.Model.Load(savedModel,out DataViewSchema schema);
_predictionEngine = mlContext.Model.CreatePredictionEngine<ModelInput,ModelOutput>(_model);
}
private void GetPrediction()
{
ModelInput input = new ModelInput
{
SepalLength=float.Parse(_sepalLength),
SepalWidth=float.Parse(_sepalWidth),
PetalLength=float.Parse(_petalLength),
PetalWidth=float.Parse(_petalWidth)
};
ModelOutput prediction = _predictionEngine.Predict(input);
ModelPrediction = prediction.PredictedLabel;
}
}

Prediction.razor页包含模型原始训练的每个列的文本输入元素。初始化页面时,将从 Azure 存储加载模型并创建PredictionEngine。请确保将替换为包含模型的 blob 的 URL。PredictionEngine是进行单个预测的便利 API。传统上,当模型用作 Web 服务时,建议使用该PredictionEnginePool服务,因为它在多线程应用程序中具有线程安全且性能更高。但是,在这种情况下,由于模型被下载到单个用户的浏览器上,因此可以使用PredictionEngine。用户输入输入值并单击"创建预测"按钮后,该GetPrediction方法通过获取用户输入并使用PredictionEngine进行预测来执行。然后,预测将显示在浏览器中。

添加到导航菜单

BlazorWebApp项目中,在Shared目录中打开NavMenu.razor文件。

将以下列表项添加到元素。

<li class="nav-item px-3"><NavLink class="nav-link" href="prediction"><span class="oi oi-list-rich" aria-hidden="true">span> PredictionNavLink>li>

最终的NavMenu.razor页面应如下所示:

<div class="top-row pl-4 navbar navbar-dark"><a class="navbar-brand" href="">BlazorWebAppa><button class="navbar-toggler" @onclick="ToggleNavMenu"><span class="navbar-toggler-icon">span>button>div><div class="@NavMenuCssClass" @onclick="ToggleNavMenu"><ul class="nav flex-column"><li class="nav-item px-3"><NavLink class="nav-link" href="" Match="NavLinkMatch.All"><span class="oi oi-home" aria-hidden="true">span> HomeNavLink>li><li class="nav-item px-3"><NavLink class="nav-link" href="counter"><span class="oi oi-plus" aria-hidden="true">span> CounterNavLink>li><li class="nav-item px-3"><NavLink class="nav-link" href="fetchdata"><span class="oi oi-list-rich" aria-hidden="true">span> Fetch dataNavLink>li><li class="nav-item px-3"><NavLink class="nav-link" href="prediction"><span class="oi oi-list-rich" aria-hidden="true">span> PredictionNavLink>li>ul>div>
@code {
private bool collapseNavMenu = true;
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}

配置 Web 应用程序

Web 应用程序将作为 Azure 存储上的静态站点托管。

在 Azure 门户中,导航到托管模型的存储帐户资源。

启用静态网站

为存储帐户启用静态网站,并将索引文档名称和错误文档路径设置为index.html

a96980699af1f2639903f126e4ca0b98.png

 此时,在存储帐户中创建了名为$web的新容器。这是您网站的所有静态文件将驻留的位置。此外,还会创建一个主终结点。这是您将用于访问应用程序的 URL

配置 CORS

存储帐户具有一些默认的 CORS 设置。为了从应用程序下载和使用模型,您必须对其进行配置。

78d922e5f85f8108bce2a881135a1d18.png

对于"Allowed origins",请输入主终结点。

发布和部署 Web 应用程序

要发布应用程序,请运行以下命令:

dotnet publish -c Release

这将生成在BlazorWebApp项目的 bin/Release/netstandard2.1/publish/BlazorWebApp/dist 目录中所需的文件托管为Web 应用程序静态网站。

要部署应用程序,请使用 Azure 存储资源管理器将dist目录中的所有文件复制到 Azure 存储帐户的$web容器中。

841b5d6fe13c806601c66b008f2c8170.png

测试应用程序

在浏览器中,导航到静态网站的主终结点,然后选择"Prediction"页。输入数据并单击"Make prediction"。页面应如下所示。

d21bd57cc0953228689d55d6bcc41a01.png

您可能会注意到,Naive Bayes 在此数据集上的性能不是最好的,因此某些预测可能不太准确。我现在可以接受这一点,因为这是一个概念验证,以展示这些技术如何协同工作。也许使用更好的数据集可以产生更好的结果。

结论

在这篇文章中,我考虑如何将ML.NET多分类模型与 Blazor WebAssembly 静态网站一起部署到 Azure。虽然由于 WebAssembly 和 Blazor WebAssembly 的早期阶段,与其他部署方法相比,这一点更为有限,但这表明了这些技术的可能性。以这种方式部署可减少部署这些模型所需的资源量,并将处理从服务器或 Web 服务转移到客户端的浏览器,从而使机器学习模型的部署和分发更加高效、可扩展且更具成本效益。

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

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

相关文章

python下载网站视频_【python爬虫实战】批量下载网站视频

写在前面最近在学vue.js&#xff0c;看到一个网站上有很多视频教程&#xff0c;但在线观看不能倍速播放&#xff0c;就想着用python爬虫批量下载到本地。安装依赖pip3 install requests测试样例加上序言总共有16个视频&#xff0c;我们用python爬虫技术批量下载到本地。https:/…

大型网站架构体系的演变

文章出处来源摘自 微信--IT搬运工 地址&#xff1a;http://mp.weixin.qq.com/s?__bizMzAxNTI4NDAzNA&mid205960169&idx1&sn765e64eef36e5d459d69bbc11dd0c11d&keyc468684b929d2be2dea6dd3defba65255295bcd81d2374e6ab6b07547319d2760635b2617d8ccd8dcb448b446…

python如何爬取图片到指定文件夹_抓取某网站一分类下所有的图片(python小白登天日记)...

废话先不多说&#xff0c;先上代码&#xff1a;import requests from bs4 import BeautifulSoup import os,re import sys reload(sys) sys.setdefaultencoding(utf8) url http://www.bfpgf.com/yld user_agent Mozilla/4.0 (compatible; MSIE 5.5; Windows NT) headers { U…

网站三层架构学习之一 分层式结构

去年参加中软的面试&#xff0c;戴老师就说让好好研究一下petshop。可是今年来了以后&#xff0c;老师让做即墨公司的语音项目&#xff0c;一直进行的是windows编程&#xff0c;没有接触网站方面的。现在项目基本做完了&#xff0c;开始ASP.NET的学习了。 现在petshop的最新版本…

网站三层架构学习之二 整体架构

在上一篇中&#xff0c;我只是对微软的三层架构做了一下介绍&#xff0c;以后将主要结合两个项目&#xff1a;一个是ASP.NET网站模板中的个人网站初学者工具包和petshop 4.0. 因为昨天看的是petshop的&#xff0c;今天就主要说说petshop 4.0的整体架构。 根据三层架构&#xff…

18个优秀的在线图片编辑服务网站

说起编辑图片&#xff0c;可能大多数人都会马上想起强大的Photoshop。事实上&#xff0c;除了购买或下载盗版的PS之外&#xff0c;你还可以使用很多优秀在线图片编辑服务&#xff0c;这些网站大多数都是免费的。对于大部分的人来说&#xff0c;它们提供的功能已经足够强大了。在…

.NET开发人员必知的八个网站

当前全球有数百万的开发人员在使用微软的.NET技术。如果你是其中之一&#xff0c;或者想要成为其中之一的话&#xff0c;我下面将要列出的每一个站点都应该是你的最爱&#xff0c;都应该收藏到书签中去。 对于不熟悉.NET技术的朋友&#xff0c;需要说明一下&#xff0c;.NET提…

乐天酷网站用户体验

万众瞩目的电子商务平台--乐天酷上线了&#xff0c;怀着无比崇敬的心情&#xff0c;我浏览了网站的页面。 乐酷天-中国最大搜索引擎百度和日本最大购物网站乐天联手打造的超大型网络购物商城 看着这口号&#xff0c;两个最大产生出这么大的一个网站&#xff0c;整体色调以大红色…

手机网站重构经验分享(S60V3篇)

前言 做WEB重构的同学都应该知道,我们一般需要在一个操作系统 (Windows XP)和4种以上的浏览器(IE678,Firefox,Chrome,Opera等)上测试页面的兼容性。 相对而言,手机上的页面兼容性测试,相当痛苦!手机光操作系统都有S60V3,S60V5,MTK,Android,Windows Mobile等等,每个操作系统上除…

各位觉得哪个电子商务网站上的购物车做得好?

各位觉得哪个电子商务网站上的购物车做得好&#xff1f; 国内或者国外的都行&#xff0c;现在购物车设计感觉越来越同质化了。添加评论 分享 查看全部 2 个回答 段炼&#xff0c;交互设计 知乎用户 赞同 1. 购物车在首页上的界面和交互设计天猫 亚马逊京东淘宝 1号店 布 局…

我也要谈谈大型网站架构之系列(1)——纵观历史演变(上)

我们知道一个网站都是随着业务的发展&#xff0c;逐渐演变成几万服务器&#xff0c;几亿用户数的大型网站&#xff0c;经历了若干年&#xff0c;甚至上十年的 发展成为大型网站&#xff0c;然而真正亲身经历这个发展过程的人已经不多了&#xff0c;这种人也是拿着公司股票&…

网站性能优化-将Script放到HTML文件中尽量靠近尾部原理

在Yahoo的网站性能优化准则里&#xff0c;其中有一条是将Script放在页面底部&#xff0c; Put Scripts at the Bottom tag: javascript The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no…

Centos7下修改mysql5.6编码方式 解决网站中文显示问号

解决办法&#xff1a; 修改MySQL数据库字符编码为UTF-8&#xff0c;UTF-8包含全世界所有国家需要用到的字符&#xff0c;是国际编码。 具体操作&#xff1a; 1、进入MySQL控制台 mysql -u root -p 输入密码 查看当前mysql运行状态 mysql>status 后面四个编码是我在修改之后…

大型网站架构演变和知识体系

之前也有一些介绍大型网站架构演变的文章&#xff0c;例如LiveJournal的、ebay的&#xff0c;都是非常值得参考的&#xff0c;不过感觉他们讲的更多的是每次演变的结果&#xff0c;而没有很详细的讲为什么需要做这样的演变&#xff0c;再加上近来感觉有不少同学都很难明白为什么…

移动电子商务网站建设之概述

题外话 想做这次总结有一段时间了&#xff0c;但是总是这样那样的事情给耽搁。妈妈常说“不怕慢&#xff0c;就怕站”&#xff0c;我决定回来以后一定要把自己在手机当当网一年多以来的积累总结一下。 首先要感谢小白&#xff0c;放手让我处理占手机当当网60%的站点&#xff…

网站的活跃用户与流失用户见解分析

网站用户管理的目标是发掘新用户&#xff0c;保留老用户。但仅仅吸引新用户还不错&#xff0c;还需要保持新用户的活跃度&#xff0c;使其能持久地为网站创造价值&#xff1b;而一旦用户的活跃度下降&#xff0c;很可能用户就会渐渐地远离网站&#xff0c;进而流失。所以基于此…

使用cookie-free domains的方法优化网站性能

YSlow给如何提高网页效率和优化网站性能提供了22条建议&#xff0c;其中有一条是关于域名的&#xff1a;Use cookie-free domains。 使用 cookie-free domains 有什么好处呢&#xff1f;当用户浏览器发送一个静态文件&#xff0c;如图片image、CSS样式表文件时会同时发送同一个…

为何各大网站启用HTTPS?运营商做了“好事”

真的是好事&#xff0c;不加引号的好事。 你可能没有注意到&#xff0c;用百度搜索时&#xff0c;浏览器地址栏里的 http 已经成为永远的过去时&#xff0c;接棒的是更安全的 https。这家中国最大的搜索引擎&#xff0c;于2015年3月份做出了一个重要的决定——全站强制启用 htt…

外贸网站租用香港服务器有哪些好处

外贸网站租用香港服务器有哪些好处 互联网迅猛发展极大地加速经济全球化趋势&#xff0c;贸易、投资自由化己成为当代世界经济发展的潮流&#xff0c;国内外贸企业进军海外市场&#xff0c;由内销转出口已成为企业营销的潮流之举。对中小外贸企业来说&#xff0c;借助香港服务器…

专访 HackerOne COO 王宁:尊重规则是漏洞平台成功的秘诀,欢迎更多成人网站进驻 | 宅客...

本文作者史中&#xff0c;雷锋网主笔。关注网络安全&#xff0c;希望用简单地语言解释科技的一切。 HackerOne是美国著名的漏洞众测公司&#xff0c;它最早开创了一种模式&#xff1a;汇集众多的黑客&#xff0c;一起为企业找漏洞。 目前&#xff0c;全球致命的互联网公司 Yaho…