【matlab】分类回归——智能优化算法极限学习机

目录

引言

基本原理

主要特点

应用领域

发展趋势

智能优化算法——蜣螂优化算法(DBO)

算法原理

 算法特点

应用前景

代码实现

ELM训练函数——elmtrain 函数

ELM预测函数——elmpredict 函数

适应度函数

主函数


引言

极限学习机(Extreme Learning Machine,ELM)是一种单隐层前馈神经网络(SLFNs)的学习算法,由黄广斌教授于2004年提出。ELM以其训练速度快、泛化能力强、易于实现等优点,在模式识别、回归预测、数据挖掘等领域得到了广泛的应用。

基本原理

ELM的基本原理是通过随机化选择输入层到隐层的连接权重(input weights)和隐层神经元的偏置(biases),并且这些参数在训练过程中保持不变。然后,通过求解一个线性系统来确定输出权重(output weights),从而使得网络的输出能够尽可能地逼近训练样本的标签或目标值。

推导过程参考:极限学习机(ELM)的原理和matlab代码实现-CSDN博客

主要特点
  1. 训练速度快:由于ELM的输入权重和偏置是随机生成的,并且在训练过程中保持不变,因此ELM的训练过程主要集中在求解输出权重上,这通常可以通过解一个线性方程组来高效完成。

  2. 泛化能力强:ELM的随机化特性使得它在训练过程中能够避免过拟合问题,因此具有较好的泛化能力。此外,ELM还可以通过调整隐层神经元的数量来平衡模型的复杂性和泛化能力。

  3. 易于实现:ELM算法简单易懂,实现起来相对容易。同时,由于ELM的训练过程不需要迭代调整参数,因此可以很容易地与其他算法进行结合使用。

应用领域

ELM已经成功应用于多个领域,包括:

  • 模式识别:如人脸识别、手写数字识别等。
  • 回归预测:如股票价格预测、气象预测等。
  • 数据挖掘:如聚类分析、异常检测等。
  • 生物信息学:如基因表达数据分析、蛋白质结构预测等。
发展趋势

随着深度学习、强化学习等技术的不断发展,ELM也在不断地进行改进和扩展。例如,一些研究者提出了基于ELM的深度学习模型,通过增加多个隐层来提高模型的表达能力和泛化能力。此外,还有一些研究者将ELM与其他优化算法相结合,如遗传算法、粒子群算法等,以进一步提高ELM的性能和稳定性。

总之,极限学习机作为一种高效、简单且泛化能力强的学习算法,在多个领域都有着广泛的应用前景。随着技术的不断发展,ELM的性能和应用范围也将得到进一步的提升和扩展。

蜣螂优化算法(Dung Beetle Optimizer, DBO)是一种新型的群智能优化算法,其灵感来源于蜣螂(俗称屎壳郎)的滚球、跳舞、觅食、偷窃和繁殖等自然行为。以下是关于蜣螂优化算法的详细介绍:

智能优化算法——蜣螂优化算法(DBO)

蜣螂优化算法由Jiankai Xue和Bo Shen在2022年提出,并发表在知名SCI期刊《THE JOURNAL OF SUPERCOMPUTING》上。该算法主要受到蜣螂的滚球、跳舞、觅食、偷窃和繁殖等行为的启发。

算法原理
  • 滚球行为:蜣螂在滚动过程中利用天体导航,滚动路径受环境影响。在算法中,蜣螂的位置变化模拟了这一过程,其中包含了光源强度、风等自然因素对蜣螂行进路线的影响。
  • 跳舞行为:当蜣螂遇到障碍物时,会通过跳舞来重新确定方向。在算法中,使用切线函数来模拟跳舞行为,以获取新的滚动方向。
  • 觅食行为:蜣螂在自然界中会寻找食物,并在安全区域产卵。算法中模拟了这一过程,包括建立最优觅食区域和引导小蜣螂觅食。
  • 偷窃行为:蜣螂之间会存在食物竞争,即偷窃行为。在算法中,通过更新偷窃蜣螂的位置来模拟这一过程。
  • 繁殖行为:雌性蜣螂会在安全区域产卵,并在孵化后引导小蜣螂觅食。算法中通过边界选择策略模拟了雌性蜣螂的产卵区域,并动态调整产卵区域和卵球的位置。
 算法特点

进化能力强:通过模拟蜣螂的自然行为,算法具有较强的进化能力,能够有效地解决复杂的寻优问题。

搜索速度快:算法中的五种主要操作(滚球、跳舞、觅食、偷窃和繁殖)模拟了蜣螂的生存行为,使得算法具有较快的搜索速度。

寻优能力强:算法同时考虑了全局探索和局部开发,具有收敛速度快和准确率高的特点。

应用前景
  • 蜣螂优化算法可以应用于更为广阔的场景,如无人机路径规划、神经网络参数优化等各类优化问题。
  • 尽管该算法具有寻优能力强、收敛速度快的特点,但也存在全局探索和局部开发能力不平衡的问题,未来可以通过改进方法进一步优化算法性能。

function [ bestX,fMin , Convergence_curve ] = DBO(pop, M,c,d,dim,fobj  )P_percent = 0.2;    % The population size of producers accounts for "P_percent" percent of the total population size       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pNum = round( pop *  P_percent );    % The population size of the producers   lb= c.*ones( 1,dim );    % Lower limit/bounds/     a vector
ub= d.*ones( 1,dim );    % Upper limit/bounds/     a vector
%Initialization
for i = 1 : popx( i, : ) = lb + (ub - lb) .* rand( 1, dim );  fit( i ) = fobj( x( i, : ) ) ;                       
endpFit = fit;                       
pX = x; XX=pX;    
[ fMin, bestI ] = min( fit );      % fMin denotes the global optimum fitness value
bestX = x( bestI, : );             % bestX denotes the global optimum position corresponding to fMin% Start updating the solutions.
for t = 1 : M    [fmax,B]=max(fit);worse= x(B,:);   r2=rand(1);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%for i = 1 : pNum    if(r2<0.9)r1=rand(1);a=rand(1,1);if (a>0.1)a=1;elsea=-1;endx( i , : ) =  pX(  i , :)+0.3*abs(pX(i , : )-worse)+a*0.1*(XX( i , :)); % Equation (1)elseaaa= randperm(180,1);if ( aaa==0 ||aaa==90 ||aaa==180 )x(  i , : ) = pX(  i , :);   endtheta= aaa*pi/180;   x(  i , : ) = pX(  i , :)+tan(theta).*abs(pX(i , : )-XX( i , :));    % Equation (2)      endx(  i , : ) = Bounds( x(i , : ), lb, ub );    fit(  i  ) = fobj( x(i , : ) );end [ fMMin, bestII ] = min( fit );      % fMin denotes the current optimum fitness valuebestXX = x( bestII, : );             % bestXX denotes the current optimum position R=1-t/M;                           %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Xnew1 = bestXX.*(1-R); Xnew2 =bestXX.*(1+R);                    %%% Equation (3)Xnew1= Bounds( Xnew1, lb, ub );Xnew2 = Bounds( Xnew2, lb, ub );%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Xnew11 = bestX.*(1-R); Xnew22 =bestX.*(1+R);                     %%% Equation (5)Xnew11= Bounds( Xnew11, lb, ub );Xnew22 = Bounds( Xnew22, lb, ub );
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  for i = ( pNum + 1 ) :12                  % Equation (4)x( i, : )=bestXX+((rand(1,dim)).*(pX( i , : )-Xnew1)+(rand(1,dim)).*(pX( i , : )-Xnew2));x(i, : ) = Bounds( x(i, : ), Xnew1, Xnew2 );fit(i ) = fobj(  x(i,:) ) ;endfor i = 13: 19                  % Equation (6)x( i, : )=pX( i , : )+((randn(1)).*(pX( i , : )-Xnew11)+((rand(1,dim)).*(pX( i , : )-Xnew22)));x(i, : ) = Bounds( x(i, : ),lb, ub);fit(i ) = fobj(  x(i,:) ) ;endfor j = 20 : pop                 % Equation (7)x( j,: )=bestX+randn(1,dim).*((abs(( pX(j,:  )-bestXX)))+(abs(( pX(j,:  )-bestX))))./2;x(j, : ) = Bounds( x(j, : ), lb, ub );fit(j ) = fobj(  x(j,:) ) ;end% Update the individual's best fitness vlaue and the global best fitness valueXX=pX;for i = 1 : pop if ( fit( i ) < pFit( i ) )pFit( i ) = fit( i );pX( i, : ) = x( i, : );endif( pFit( i ) < fMin )% fMin= pFit( i );fMin= pFit( i );bestX = pX( i, : );%  a(i)=fMin;endendConvergence_curve(t)=fMin;end% Application of simple limits/bounds
function s = Bounds( s, Lb, Ub)% Apply the lower bound vectortemp = s;I = temp < Lb;temp(I) = Lb(I);% Apply the upper bound vector J = temp > Ub;temp(J) = Ub(J);% Update this new move s = temp;
function S = Boundss( SS, LLb, UUb)% Apply the lower bound vectortemp = SS;I = temp < LLb;temp(I) = LLb(I);% Apply the upper bound vector J = temp > UUb;temp(J) = UUb(J);% Update this new move S = temp;

代码实现

ELM训练函数——elmtrain 函数

elmtrain 函数用于训练一个极端学习机模型。它接收以下输入参数:

  • P:训练集输入矩阵(大小为 R×Q)。
  • T:训练集输出矩阵(大小为 S×Q)。
  • N:隐藏层神经元的数量(默认为 Q)。
  • TF:激活函数(默认为 'sig' 代表 Sigmoid 函数)。
  • TYPE:指定任务是回归(0,默认)还是分类(1)。

它返回以下输出:

  • IW:输入权重矩阵(大小为 N×R)。
  • B:隐藏层偏置矩阵(大小为 N×1)。
  • LW:输出权重矩阵(大小为 N×S)。
  • TF:激活函数的名称。
  • TYPE:任务的类型(回归或分类)。
function [IW,B,LW,TF,TYPE] = elmtrain(P,T,N,TF,TYPE)
if nargin < 2error('ELM:Arguments','Not enough input arguments.');
end
if nargin < 3N = size(P,2);
end
if nargin < 4TF = 'sig';
end
if nargin < 5TYPE = 0;
end
if size(P,2) ~= size(T,2)error('ELM:Arguments','The columns of P and T must be same.');
end
[R,Q] = size(P);
if TYPE  == 1T  = ind2vec(T);
end
[S,Q] = size(T);
% Randomly Generate the Input Weight Matrix
IW = rand(N,R) * 2 - 1;
% Randomly Generate the Bias Matrix
B = rand(N,1);
BiasMatrix = repmat(B,1,Q);
% Calculate the Layer Output Matrix H
tempH = IW * P + BiasMatrix;
switch TFcase 'sig'H = 1 ./ (1 + exp(-tempH));case 'sin'H = sin(tempH);case 'hardlim'H = hardlim(tempH);
end
% Calculate the Output Weight Matrix
LW = pinv(H') * T';
ELM预测函数——elmpredict 函数

elmpredict 函数用于使用已训练的极端学习机模型进行预测。它接收以下输入参数:

  • P:测试集输入矩阵(大小为 R×Q)。
  • IW:输入权重矩阵(大小为 N×R)。
  • B:隐藏层偏置矩阵(大小为 N×1)。
  • LW:输出权重矩阵(大小为 N×S)。
  • TF:激活函数的名称。
  • TYPE:任务的类型(回归或分类)。

它返回以下输出:

  • Y:预测输出矩阵(大小为 S×Q)
function Y = elmpredict(P,IW,B,LW,TF,TYPE)if nargin < 6error('ELM:Arguments','Not enough input arguments.');
end
% Calculate the Layer Output Matrix H
Q = size(P,2);
BiasMatrix = repmat(B,1,Q);
tempH = IW * P + BiasMatrix;
switch TFcase 'sig'H = 1 ./ (1 + exp(-tempH));case 'sin'H = sin(tempH);case 'hardlim'H = hardlim(tempH);
end
% Calculate the Simulate Output
Y = (H' * LW)';
if TYPE == 1temp_Y = zeros(size(Y));for i = 1:size(Y,2)[max_Y,index] = max(Y(:,i));temp_Y(index,i) = 1;endY = vec2ind(temp_Y); 
end

适应度函数

以训练集的误差mse做为适应度值。

function [fitness,IW,B,LW,TF,TYPE] = fun(x,Pn_train,Tn_train,N)
R = size(Pn_train,1);
S = size(Tn_train,1);
IW = x(1:N*R);
B = x(N*R+1:N*R+N);
IW = reshape(IW,[N,R]);
B = reshape(B,N,1);
TYPE = 0;%回归
TF = 'sig';
[IW,B,LW,TF,TYPE] = elmtrainNew(Pn_train,Tn_train,N,TF,TYPE,IW,B);
%% ELM仿真测试
Tn_sim1 = elmpredict(Pn_train,IW,B,LW,TF,TYPE);
%计算误差
E1 = Tn_sim1 - Tn_train;
fitness = mse(E1);
end

主函数

clear all
clc%% 导入数据
load('data.mat'); % 加载数据文件%% 随机生成训练集和测试集
rng(42); % 设置随机种子,以确保结果可重复性% 计算样本数量
num_samples = size(input, 1);% 随机排列索引
k = randperm(num_samples);% 训练集——前 70% 的样本
train_samples = floor(0.7 * num_samples); % 70% 的样本作为训练集
P_train = input(k(1:train_samples), :)';
T_train = output(k(1:train_samples));% 测试集——后 30% 的样本
P_test = input(k(train_samples+1:end), :)';
T_test = output(k(train_samples+1:end));%% 归一化
% 使用 mapminmax 函数归一化训练集和测试集
[Pn_train, inputps] = mapminmax(P_train, -1, 1); % 归一化训练集,并记录参数
Pn_test = mapminmax('apply', P_test, inputps); % 应用训练集的归一化参数归一化测试集[Tn_train, outputps] = mapminmax(T_train', -1, 1); % 归一化训练集标签
Tn_train = Tn_train'; % 转置回原始维度
Tn_test = mapminmax('apply', T_test', outputps); % 归一化测试集标签,并转置回原始维度
Tn_test = Tn_test';% 训练数据相关尺寸
R = size(Pn_train, 1);
N = 70; % 隐含层神经元数量%% 定义优化参数并进行优化
pop = 30; % 种群数量
Max_iteration = 400; % 最大迭代次数
dim = N * R + N; % 维度,即权值与阈值的个数
lb = [-1 .* ones(1, N * R), zeros(1, N)]; % 下边界
ub = [ones(1, N * R), ones(1, N)]; % 上边界
fobj = @(x) fun(x, Pn_train, Tn_train, N);% 调用优化函数进行优化
[Best_pos, Best_score, DBO_curve] = DBO(pop, Max_iteration, lb, ub, dim, fobj);% 获取优化后的相关参数
[fitness, IW, B, LW, TF, TYPE] = fun(Best_pos, Pn_train, Tn_train, N);% 绘制收敛曲线
figure
plot(DBO_curve, 'linewidth', 1.5);
grid on
xlabel('迭代次数')
ylabel('适应度函数')
title('DBO-ELM收敛曲线')%% DBO-ELM仿真测试
Tn_sim = elmpredict(Pn_test, IW, B, LW, TF, TYPE);
% 反归一化
T_sim = mapminmax('reverse', Tn_sim, outputps);
% 均方误差
E = mse(T_sim - T_test);% 结果对比和R2
result = [T_test' T_sim'];
R2 = (60 * sum(T_sim .* T_test) - sum(T_sim) * sum(T_test))^2 / ((60 * sum(T_sim.^2)) - (sum(T_sim))^2 * (60 * sum(T_test.^2)) - (sum(T_test))^2);% 绘制测试集输出对比图
figure
plot(T_test, 'r*')
hold on
plot(T_sim, 'b:o')
xlabel('测试集样本编号')
ylabel('测试集输出')
title('ELM测试集输出')
grid on;
legend('期望输出', 'DBO-ELM预测输出')% 显示均方误差和R2分数
disp(['均方误差 (MSE): ', num2str(E)]);
disp(['R^2 分数: ', num2str(R2)]);

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

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

相关文章

ARM_Linux驱动开发——字符设备驱动开发(上)

目录 一、Linux驱动开发思维 二、Linux驱动开发分类 三、“ ARM_Linux驱动开发——字符设备驱动开发 ” 字符设备驱动简介 前言 在分享Linux驱动开发之前&#xff0c;我想带大家首先回顾一下裸机驱动开发和Linux驱动开发的区别。 1、运行环境和操作系统&#xff1a; 裸机驱…

CI脚本的python基础

CI脚本的python基础 基础python语法getopt.getopt(args, shortopts, longopts[])requests.requestjson.loads&#xff08;&#xff09;os.popensplit的用法os.path.existshutil.rmtree以及shutil家族shutil.make_archivetime.strftime计算Python zfill&#xff08;width&#x…

Spring Cloud Gateway报sun.misc.Unsafe.park(Native Method)

项目引入spring cloud gateway的jar报&#xff0c;启动的时候报&#xff1a; [2024-07-05 10:10:16.162][main][ERROR][org.springframework.boot.web.embedded.tomcat.TomcatStarter][61]:Error starting Tomcat context. Exception: org.springframework.beans.factory.Bean…

Apache Seata 高可用部署实践

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Apache Seata 高可用部署实践 Seata 高可用部署实践 使用配置中心和数据库来实现 Seata 的高…

使用Spring Boot和自定义缓存注解优化应用性能

在现代应用开发中&#xff0c;缓存是提高系统性能和响应速度的关键技术之一。Spring Boot提供了强大的缓存支持&#xff0c;但有时我们需要更灵活的缓存控制。本文将介绍如何使用Spring Boot和自定义缓存注解来优化应用性能。 1. 为什么需要自定义缓存注解&#xff1f; Sprin…

AI算力革命:GPU租赁与算力市场的未来趋势

在数字化和智能化的时代背景下&#xff0c;人工智能&#xff08;AI&#xff09;的快速发展已成为全球科技领域的焦点。AI算力作为支撑其发展的关键因素&#xff0c;正以前所未有的速度改变着我们的生活和工作方式。其中&#xff0c;GPU租赁模式的兴起&#xff0c;不仅解决了AI算…

IT学习之路:深耕技能,拥抱变化

高考&#xff0c;作为人生的重要转折点之一&#xff0c;为无数学子开启了通往梦想与未来的大门。对于众多选择投身IT行业的青年而言&#xff0c;这段旅程既是挑战也是机遇。IT行业以其快速的发展速度、广泛的应用领域和无限的创新潜力&#xff0c;成为了许多年轻人实现自我价值…

瀑布模型、渐增式开发、原型化开发、统一过程模型(RUP)都是软件开发生命周期中的重要模型和方法,他们的原理及他们的应用场景有哪些

软件开发生命周期中的不同模型和方法各有其独特的原理和应用场景。本文将详细分析瀑布模型、渐增式开发、原型化开发以及统一过程模型&#xff08;RUP&#xff09;的原理及其适用的应用场景。 瀑布模型 原理 瀑布模型是一种线性顺序的软件开发方法&#xff0c;其名称源于其流…

用SpringBoot打造坚固防线:轻松实现XSS攻击防御

在这篇博客中&#xff0c;我们将深入探讨如何使用SpringBoot有效防御XSS攻击。通过结合注解和过滤器的方式&#xff0c;我们可以为应用程序构建一个强大的安全屏障&#xff0c;确保用户数据不被恶意脚本所侵害。 目录 什么是XSS攻击&#xff1f;SpringBoot中的XSS防御策略使用…

ASP.NET Web应用中的 Razor Pages/MVC/Web API/Blazor

如果希望使用ASP.NET Core创建新的 Web 应用程序&#xff0c;应该选择哪种方法&#xff1f;Razor Pages还是 MVC&#xff08;模型-视图-控制器&#xff09;&#xff0c;又或者使用Web API Vue/React/......。 每种方法都有各自的优点和缺点。 什么是 MVC&#xff1f; 大多数服…

轻松设置:服务器域名配置全攻略

目录 前置条件 在阅读本篇内容之前&#xff0c;请先确保以下物料已准备好&#xff1a; 一台公网服务器&#xff0c;服务正常运行申请完成的域名&#xff0c;在对应域名服务商后台正常DNS解析域名备案完成可选条件&#xff1a;有https访问请求时&#xff0c;需要申请SSL证书 …

微信小程序的“小鱼在乎”日程计划系统-计算机毕业设计源码51307

摘要 本文介绍了一种基于微信小程序和Spring Boot后端服务的“小鱼在乎”日程计划系统。该系统结合了前端微信小程序的便捷交互与后端Spring Boot框架的稳健性能&#xff0c;为用户提供了一款功能全面、体验出色的日程管理工具。 “小鱼在乎”日程计划系统涵盖了多种功能&#…

DNS正向解析与反向解析实验

正向解析 安装bind软件 [rootlocalhost ~]# dnf install bind bind-utils -y修改主配置文件/etc/named.conf [rootlocalhost ~]# vim /etc/named.conf重启DNS服务&#xff08;named&#xff09; [rootlocalhost ~]# systemctl restart named编辑数据配置文件。在/var/named…

技术周总结 2024.07.01~07.07(Spark Scala)

文章目录 一、07.01 周一1.1&#xff09;问题01&#xff1a;scala怎么实现 一个变量作为函数的入参以及返回值1.2&#xff09;问题02&#xff1a;park中DataFrame使用 createView的用法1.3&#xff09;问题03&#xff1a;scala中三元运算符1.4) 问题04&#xff1a;伴生对象和伴…

vue 等待数据被定义后再执行v-for(ai生成)

在Vue中&#xff0c;如果你想确保在使用v-for循环之前数据已经被定义&#xff0c;你可以使用v-if指令来控制v-for的执行。有时使用axios异步请求数据时需延时&#xff08;比如500ms&#xff09;&#xff0c;才能获得被赋值的数据&#xff0c;v-if判断后再执行v-for。 <temp…

ubuntu20.04安装ros1

1、sudo apt-get install git 2、新建一个文件夹&#xff0c;进入该文件夹打开终端 git init git clone https://github.com/RocShi/rostaller.git 选择 1 3、进入下载后的文件夹 打开终端 chmod x run.sh ./run.sh 4、配置环境 echo "source /opt/ros/noetic/setup.…

000.动态规划题解目录

000.动态规划题解目录 奋力码字中

css如何设置文本第二行的文字多余部分变为省略号

在CSS中&#xff0c;直接设置一个元素中的文本最多有几行并不是原生的功能。但你可以使用一些技巧来实现类似的效果&#xff0c;特别是在固定高度的元素中。 以下是一些常用的方法&#xff1a; 使用line-height和height: 如果你知道文本的line-height&#xff0c;你可以通过…

Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制

文件的读取、显示、存取 cv2.imread(imagepath,IMREAD.xxx) 读取图像cv2.imshow(窗口名称,mat图片) 显示图像cv2.imwrite(保存的位置,img) 保存图像 # 1. 读取图像 原始图片路径&#xff0c;图片读取模式 cv2.imread(imagepath,IMREAD.xxx)cv2.IMREAD_COLOR 彩色模式读取 cv2…

Gemini for China 大更新,现已上架 Android APP!

官网&#xff1a;https://gemini.fostmar.online/ Android APP&#xff1a;https://gemini.fostmar.online/gemini_1.0.apk 一、Android APP 如果是 Android 设备&#xff0c;则会直接识别到并给下载链接。PC 直接对话即可。 二、聊天记录 现在 Gemini for China&#xff…