C#基于ScottPlot进行可视化

前言

上一篇文章跟大家分享了用NumSharp实现简单的线性回归,但是没有进行可视化,可能对拟合的过程没有直观的感受,因此今天跟大家介绍一下使用C#基于Scottplot进行可视化,当然Python的代码,我也会同步进行可视化。

Python代码进行可视化

Python代码用matplotlib做了可视化,我就不具体介绍了。

修改之后的python代码如下:

#The optimal values of m and b can be actually calculated with way less effort than doing a linear regression. 
#this is just to demonstrate gradient descentimport numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation# y = mx + b
# m is slope, b is y-intercept
def compute_error_for_line_given_points(b, m, points):totalError = 0for i in range(0, len(points)):x = points[i, 0]y = points[i, 1]totalError += (y - (m * x + b)) ** 2return totalError / float(len(points))def step_gradient(b_current, m_current, points, learningRate):b_gradient = 0m_gradient = 0N = float(len(points))for i in range(0, len(points)):x = points[i, 0]y = points[i, 1]b_gradient += -(2/N) * (y - ((m_current * x) + b_current))m_gradient += -(2/N) * x * (y - ((m_current * x) + b_current))new_b = b_current - (learningRate * b_gradient)new_m = m_current - (learningRate * m_gradient)return [new_b, new_m]def gradient_descent_runner(points, starting_b, starting_m, learning_rate, num_iterations):b = starting_bm = starting_margs_data = []for i in range(num_iterations):b, m = step_gradient(b, m, np.array(points), learning_rate)args_data.append((b,m))return args_dataif __name__ == '__main__':points = np.genfromtxt("data.csv", delimiter=",")learning_rate = 0.0001initial_b = 0 # initial y-intercept guessinitial_m = 0 # initial slope guessnum_iterations = 10print ("Starting gradient descent at b = {0}, m = {1}, error = {2}".format(initial_b, initial_m, compute_error_for_line_given_points(initial_b, initial_m, points)))print ("Running...")args_data = gradient_descent_runner(points, initial_b, initial_m, learning_rate, num_iterations)b = args_data[-1][0]m = args_data[-1][1]print ("After {0} iterations b = {1}, m = {2}, error = {3}".format(num_iterations, b, m, compute_error_for_line_given_points(b, m, points)))data = np.array(points).reshape(100,2)x1 = data[:,0]y1 = data[:,1]x2 = np.linspace(20, 80, 100)y2 = initial_m * x2 + initial_bdata2 = np.array(args_data)b_every = data2[:,0]m_every = data2[:,1]# 创建图形和轴fig, ax = plt.subplots()line1, = ax.plot(x1, y1, 'ro')line2, = ax.plot(x2,y2)# 添加标签和标题plt.xlabel('x')plt.ylabel('y')plt.title('Graph of y = mx + b')# 添加网格plt.grid(True)# 定义更新函数def update(frame):line2.set_ydata(m_every[frame] * x2 + b_every[frame])ax.set_title(f'{frame} Graph of y = {m_every[frame]:.2f}x + {b_every[frame]:.2f}')# 创建动画
animation = FuncAnimation(fig, update, frames=len(data2), interval=500)# 显示动画
plt.show()

实现的效果如下所示:

python代码的可视化

image-20240113200232614

C#代码进行可视化

这是本文重点介绍的内容,本文的C#代码通过Scottplot进行可视化。

Scottplot简介

ScottPlot 是一个免费的开源绘图库,用于 .NET,可以轻松以交互方式显示大型数据集。

控制台程序可视化

首先我先介绍一下在控制台程序中进行可视化。

首先添加Scottplot包:

image-20240113201207374

将上篇文章中的C#代码修改如下:

using NumSharp;namespace LinearRegressionDemo
{internal class Program{    static void Main(string[] args){   //创建double类型的列表List<double> Array = new List<double>();List<double> ArgsList = new List<double>();// 指定CSV文件的路径string filePath = "你的data.csv路径";// 调用ReadCsv方法读取CSV文件数据Array = ReadCsv(filePath);var array = np.array(Array).reshape(100,2);double learning_rate = 0.0001;double initial_b = 0;double initial_m = 0;double num_iterations = 10;Console.WriteLine($"Starting gradient descent at b = {initial_b}, m = {initial_m}, error = {compute_error_for_line_given_points(initial_b, initial_m, array)}");Console.WriteLine("Running...");ArgsList = gradient_descent_runner(array, initial_b, initial_m, learning_rate, num_iterations);double b = ArgsList[ArgsList.Count - 2];double m = ArgsList[ArgsList.Count - 1];Console.WriteLine($"After {num_iterations} iterations b = {b}, m = {m}, error = {compute_error_for_line_given_points(b, m, array)}");Console.ReadLine();var x1 = array[$":", 0];var y1 = array[$":", 1];var y2 = m * x1 + b;ScottPlot.Plot myPlot = new(400, 300);myPlot.AddScatterPoints(x1.ToArray<double>(), y1.ToArray<double>(), markerSize: 5);myPlot.AddScatter(x1.ToArray<double>(), y2.ToArray<double>(), markerSize: 0);myPlot.Title($"y = {m:0.00}x + {b:0.00}");myPlot.SaveFig("图片.png");}static List<double> ReadCsv(string filePath){List<double> array = new List<double>();try{// 使用File.ReadAllLines读取CSV文件的所有行string[] lines = File.ReadAllLines(filePath);             // 遍历每一行数据foreach (string line in lines){// 使用逗号分隔符拆分每一行的数据string[] values = line.Split(',');// 打印每一行的数据foreach (string value in values){array.Add(Convert.ToDouble(value));}                  }}catch (Exception ex){Console.WriteLine("发生错误: " + ex.Message);}return array;}public static double compute_error_for_line_given_points(double b,double m,NDArray array){double totalError = 0;for(int i = 0;i < array.shape[0];i++){double x = array[i, 0];double y = array[i, 1];totalError += Math.Pow((y - (m*x+b)),2);}return totalError / array.shape[0];}public static double[] step_gradient(double b_current,double m_current,NDArray array,double learningRate){double[] args = new double[2];double b_gradient = 0;double m_gradient = 0;double N = array.shape[0];for (int i = 0; i < array.shape[0]; i++){double x = array[i, 0];double y = array[i, 1];b_gradient += -(2 / N) * (y - ((m_current * x) + b_current));m_gradient += -(2 / N) * x * (y - ((m_current * x) + b_current));}double new_b = b_current - (learningRate * b_gradient);double new_m = m_current - (learningRate * m_gradient);args[0] = new_b;args[1] = new_m;return args;}public static List<double> gradient_descent_runner(NDArray array, double starting_b, double starting_m, double learningRate,double num_iterations){double[] args = new double[2];List<double> argsList = new List<double>();args[0] = starting_b;args[1] = starting_m;for(int i = 0 ; i < num_iterations; i++) {args = step_gradient(args[0], args[1], array, learningRate);argsList.AddRange(args);}return argsList;}}
}

然后得到的图片如下所示:

image-20240113202345301

在以上代码中需要注意的地方:

  var x1 = array[$":", 0];var y1 = array[$":", 1];

是在使用NumSharp中的切片,x1表示所有行的第一列,y1表示所有行的第二列。

当然我们不满足于只是保存图片,在控制台应用程序中,再添加一个 ScottPlot.WinForms包:

image-20240113202751162

右键控制台项目选择属性,将目标OS改为Windows:

image-20240113212334704

将上述代码中的

  myPlot.SaveFig("图片.png");

修改为:

 var viewer = new ScottPlot.FormsPlotViewer(myPlot);viewer.ShowDialog();

再次运行结果如下:

image-20240113203022718

winform进行可视化

我也想像Python代码中那样画动图,因此做了个winform程序进行演示。

首先创建一个winform,添加ScottPlot.WinForms包,然后从工具箱中添加FormsPlot这个控件:

image-20240113205227384

有两种方法实现,第一种方法用了定时器:

using NumSharp;
namespace WinFormDemo
{public partial class Form1 : Form{System.Windows.Forms.Timer updateTimer = new System.Windows.Forms.Timer();int num_iterations;int count = 0;NDArray? x1, y1, b_each, m_each;public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){StartLinearRegression();}public void StartLinearRegression(){//创建double类型的列表List<double> Array = new List<double>();List<double> ArgsList = new List<double>();// 指定CSV文件的路径string filePath = "你的data.csv路径";// 调用ReadCsv方法读取CSV文件数据Array = ReadCsv(filePath);var array = np.array(Array).reshape(100, 2);double learning_rate = 0.0001;double initial_b = 0;double initial_m = 0;num_iterations = 10;ArgsList = gradient_descent_runner(array, initial_b, initial_m, learning_rate, num_iterations);x1 = array[$":", 0];y1 = array[$":", 1];var argsArr = np.array(ArgsList).reshape(num_iterations, 2);b_each = argsArr[$":", 0];m_each = argsArr[$":", 1];double b = b_each[-1];double m = m_each[-1];var y2 = m * x1 + b;formsPlot1.Plot.AddScatterPoints(x1.ToArray<double>(), y1.ToArray<double>(), markerSize: 5);//formsPlot1.Plot.AddScatter(x1.ToArray<double>(), y2.ToArray<double>(), markerSize: 0);formsPlot1.Render();}static List<double> ReadCsv(string filePath){List<double> array = new List<double>();try{// 使用File.ReadAllLines读取CSV文件的所有行string[] lines = File.ReadAllLines(filePath);// 遍历每一行数据foreach (string line in lines){// 使用逗号分隔符拆分每一行的数据string[] values = line.Split(',');// 打印每一行的数据foreach (string value in values){array.Add(Convert.ToDouble(value));}}}catch (Exception ex){Console.WriteLine("发生错误: " + ex.Message);}return array;}public static double compute_error_for_line_given_points(double b, double m, NDArray array){double totalError = 0;for (int i = 0; i < array.shape[0]; i++){double x = array[i, 0];double y = array[i, 1];totalError += Math.Pow((y - (m * x + b)), 2);}return totalError / array.shape[0];}public static double[] step_gradient(double b_current, double m_current, NDArray array, double learningRate){double[] args = new double[2];double b_gradient = 0;double m_gradient = 0;double N = array.shape[0];for (int i = 0; i < array.shape[0]; i++){double x = array[i, 0];double y = array[i, 1];b_gradient += -(2 / N) * (y - ((m_current * x) + b_current));m_gradient += -(2 / N) * x * (y - ((m_current * x) + b_current));}double new_b = b_current - (learningRate * b_gradient);double new_m = m_current - (learningRate * m_gradient);args[0] = new_b;args[1] = new_m;return args;}public static List<double> gradient_descent_runner(NDArray array, double starting_b, double starting_m, double learningRate, double num_iterations){double[] args = new double[2];List<double> argsList = new List<double>();args[0] = starting_b;args[1] = starting_m;for (int i = 0; i < num_iterations; i++){args = step_gradient(args[0], args[1], array, learningRate);argsList.AddRange(args);}return argsList;}private void button2_Click(object sender, EventArgs e){// 初始化定时器updateTimer.Interval = 1000; // 设置定时器触发间隔(毫秒)updateTimer.Tick += UpdateTimer_Tick;updateTimer.Start();}private void UpdateTimer_Tick(object? sender, EventArgs e){if (count >= num_iterations){updateTimer.Stop();}else{UpdatePlot(count);}count++;}public void UpdatePlot(int count){double b = b_each?[count];double m = m_each?[count];var y2 = m * x1 + b;formsPlot1.Plot.Clear();formsPlot1.Plot.AddScatterPoints(x1?.ToArray<double>(), y1?.ToArray<double>(), markerSize: 5);formsPlot1.Plot.AddScatter(x1?.ToArray<double>(), y2.ToArray<double>(), markerSize: 0);formsPlot1.Plot.Title($"第{count + 1}次迭代:y = {m:0.00}x + {b:0.00}");formsPlot1.Render();}private void button3_Click(object sender, EventArgs e){updateTimer.Stop();}private void Form1_Load(object sender, EventArgs e){}}
}

简单介绍一下思路,首先创建List<double> argsList用来保存每次迭代生成的参数b、m,然后用

           var argsArr = np.array(ArgsList).reshape(num_iterations, 2);  

argsList通过np.array()方法转化为NDArray,然后再调用reshape方法,转化成行数等于迭代次数,列数为2,即每一行对应一组参数值b、m。

            b_each = argsArr[$":", 0];m_each = argsArr[$":", 1];

argsArr[$":", 0]表示每一行中第一列的值,也就是每一个b,argsArr[$":", 1]表示每一行中第二列的值。

            double b = b_each[-1];double m = m_each[-1];

b_each[-1]用了NumSharp的功能表示b_each最后一个元素。

实现效果如下所示:

winform绘图效果1

另一种方法可以通过异步实现:

using NumSharp;namespace WinFormDemo
{public partial class Form2 : Form{      int num_iterations;NDArray? x1, y1, b_each, m_each;public Form2(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){StartLinearRegression();}public void StartLinearRegression(){//创建double类型的列表List<double> Array = new List<double>();List<double> ArgsList = new List<double>();// 指定CSV文件的路径string filePath = "你的data.csv路径";// 调用ReadCsv方法读取CSV文件数据Array = ReadCsv(filePath);var array = np.array(Array).reshape(100, 2);double learning_rate = 0.0001;double initial_b = 0;double initial_m = 0;num_iterations = 10;ArgsList = gradient_descent_runner(array, initial_b, initial_m, learning_rate, num_iterations);x1 = array[$":", 0];y1 = array[$":", 1];var argsArr = np.array(ArgsList).reshape(num_iterations, 2);b_each = argsArr[$":", 0];m_each = argsArr[$":", 1];double b = b_each[-1];double m = m_each[-1];var y2 = m * x1 + b;formsPlot1.Plot.AddScatterPoints(x1.ToArray<double>(), y1.ToArray<double>(), markerSize: 5);      formsPlot1.Render();}static List<double> ReadCsv(string filePath){List<double> array = new List<double>();try{// 使用File.ReadAllLines读取CSV文件的所有行string[] lines = File.ReadAllLines(filePath);// 遍历每一行数据foreach (string line in lines){// 使用逗号分隔符拆分每一行的数据string[] values = line.Split(',');// 打印每一行的数据foreach (string value in values){array.Add(Convert.ToDouble(value));}}}catch (Exception ex){Console.WriteLine("发生错误: " + ex.Message);}return array;}public static double compute_error_for_line_given_points(double b, double m, NDArray array){double totalError = 0;for (int i = 0; i < array.shape[0]; i++){double x = array[i, 0];double y = array[i, 1];totalError += Math.Pow((y - (m * x + b)), 2);}return totalError / array.shape[0];}public static double[] step_gradient(double b_current, double m_current, NDArray array, double learningRate){double[] args = new double[2];double b_gradient = 0;double m_gradient = 0;double N = array.shape[0];for (int i = 0; i < array.shape[0]; i++){double x = array[i, 0];double y = array[i, 1];b_gradient += -(2 / N) * (y - ((m_current * x) + b_current));m_gradient += -(2 / N) * x * (y - ((m_current * x) + b_current));}double new_b = b_current - (learningRate * b_gradient);double new_m = m_current - (learningRate * m_gradient);args[0] = new_b;args[1] = new_m;return args;}public static List<double> gradient_descent_runner(NDArray array, double starting_b, double starting_m, double learningRate, double num_iterations){double[] args = new double[2];List<double> argsList = new List<double>();args[0] = starting_b;args[1] = starting_m;for (int i = 0; i < num_iterations; i++){args = step_gradient(args[0], args[1], array, learningRate);argsList.AddRange(args);}return argsList;}private void Form2_Load(object sender, EventArgs e){}public async Task UpdateGraph(){for (int i = 0; i < num_iterations; i++){double b = b_each?[i];double m = m_each?[i];var y2 = m * x1 + b;formsPlot1.Plot.Clear();formsPlot1.Plot.AddScatterPoints(x1?.ToArray<double>(), y1?.ToArray<double>(), markerSize: 5);formsPlot1.Plot.AddScatter(x1?.ToArray<double>(), y2.ToArray<double>(), markerSize: 0);formsPlot1.Plot.Title($"第{i + 1}次迭代:y = {m:0.00}x + {b:0.00}");formsPlot1.Render();await Task.Delay(1000);}}private async void button2_Click(object sender, EventArgs e){await UpdateGraph();}}
}

点击更新按钮开始执行异步任务:

 private async void button2_Click(object sender, EventArgs e){await UpdateGraph();}
 public async Task UpdateGraph(){for (int i = 0; i < num_iterations; i++){double b = b_each?[i];double m = m_each?[i];var y2 = m * x1 + b;formsPlot1.Plot.Clear();formsPlot1.Plot.AddScatterPoints(x1?.ToArray<double>(), y1?.ToArray<double>(), markerSize: 5);formsPlot1.Plot.AddScatter(x1?.ToArray<double>(), y2.ToArray<double>(), markerSize: 0);formsPlot1.Plot.Title($"第{i + 1}次迭代:y = {m:0.00}x + {b:0.00}");formsPlot1.Render();await Task.Delay(1000);}

实现效果如下:

winform绘图效果2

image-20240113210320131

总结

本文以一个控制台应用与一个winform程序为例向大家介绍了C#如何基于ScottPlot进行数据可视化,并介绍了实现动态绘图的两种方式,一种是使用定时器,另一种是使用异步操作,希望对你有所帮助。

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

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

相关文章

从AAAI 2024看人工智能研究的最新热点

图 1 由AAAI 2024论文列表生成的词云 AAAI会议作为全球AI领域的顶级学术盛会&#xff0c;被中国计算机学会&#xff08;CCF&#xff09;评为A类会议。AAAI2024的会议论文投稿量达到了历史新高&#xff0c;主赛道收到了12100篇投稿论文&#xff0c;9862篇论文经过严格评审后共有…

imx6ull基于yocto工程的l汇编点亮ed

通过汇编点亮led 在裸机状态下通过汇编点亮led&#xff0c;即没有操作系统&#xff0c;(uboot kernel rootfs 都不需要实现&#xff09;。 led点亮原理 1.GPIO复用 根据原理图&#xff0c;找到led对应的引脚&#xff08;pin)&#xff0c;复用为GPIO&#xff08;只有GPIO才能…

一些硬件知识(三)

uint8_t, uint32_t, 和 uint16_t 是 C 和 C 语言中的数据类型&#xff0c;它们分别表示无符号的 8 位、32 位和 16 位整数。这些数据类型定义在标准库 <stdint.h>&#xff08;在 C 语言中&#xff09;或 <cstdint>&#xff08;在 C 中&#xff09;。 uint8_t&…

伴随矩阵定义和计算

一、伴随矩阵定义 1&#xff09;代数余子式 代数余子式也很好理解&#xff0c;在余子式的基础上多了一个-1的次方而已。 2)余子式 余子式很好理解&#xff0c;就是除了这个元素&#xff0c;出去该行该列剩下的行列式的值。 求每个元素的代数余子式&#xff0c;按行求&#xf…

QT基础篇(1)QT概述

1.什么是QT QT是一个跨平台的C应用程序开发框架。它提供了一套丰富的图形用户界面&#xff08;GUI&#xff09;和多媒体功能&#xff0c;可以用于开发各种类型的应用程序&#xff0c;包括桌面应用程序、移动应用程序和嵌入式系统。QT具有易于使用、可定制性强、性能高等特点&a…

uniapp 制作 wgt 包(用于 app 的热更新)

升级版本号 修改 manifest.json 的配置&#xff0c;应用版本名称和应用版本号 必须高于上一版的值。 制作 wgt 包 发布 wgt 包 打开 uni-admin 项目的升级中心 上传后会自动生成下载链接 app 的静默热更新 发布新版后&#xff0c;用户打开app&#xff0c;后台会自动下载 wgt…

pyenv虚拟环境安装和配合pipenv多版本创建

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、下载配置pyenv二、配置多版本虚拟环境总结 前言 最近公司编写了一个自动化用例编写软件&#xff0c;需要适配win7和win10系统&#xff0c;需要同时编译3.8…

基于SSM+vue的新生报到服务管理系统(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

C++算法学习心得五.二叉树(4)

1.二叉搜索树中的插入操作&#xff08;701题&#xff09; 题目描述&#xff1a;给定二叉搜索树&#xff08;BST&#xff09;的根节点和要插入树中的值&#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据保证&#xff0c;新值和原始二叉搜索树中的任意…

【Python机器学习】SVM——线性模型与非线性特征

SVM&#xff08;核支持向量机&#xff09;是一种监督学习模型&#xff0c;是可以推广到更复杂模型的扩展&#xff0c;这些模型无法被输入空间的超平面定义。 线模型在低维空间中可能非常受限&#xff0c;因为线和平面的灵活性有限&#xff0c;但是有一种方式可以让线性模型更加…

Linux系统中的IP地址、主机名、和域名解析

1.IP地址 每一台联网的电脑都会有一个地址&#xff0c;用于和其它计算机进行通讯 IP地址主要有2个版本&#xff0c;V4版本和V6版本&#xff08;V6很少用&#xff0c;暂不涉及&#xff09; IPv4版本的地址格式是&#xff1a;a.b.c.d&#xff0c;其中abcd表示0~255的数字&…

echarts x轴下增加一组数据的实现方法

实现效果&#xff1a; 关键代码 xAxis: [{type: category,axisTick:{show: false},axisLine:{show: false},axisLabel:{align:center,},data: [9-w2, 9-w3, 343,9-w2, 9-w3, 343]},{type: category,name: 排比变化,nameTextStyle: {verticalAlign: "left",padding:[…

迈入AI智能时代!ChatGPT国内版免费AI助手工具 peropure·AI正式上线 一个想法写一首歌?这事AI还真能干!

号外&#xff01;前几天推荐的Peropure.Ai迎来升级&#xff0c;现已支持联网模式&#xff0c;回答更新更准&#xff0c;欢迎注册体验&#xff1a; https://sourl.cn/5T74Hu 相信很多人都有过这样的想法&#xff0c;有没有一首歌能表达自己此时此刻的心情&#xff1a; 当你在深…

虚幻UE 特效-Niagara特效初识

虚幻的Niagara特效系统特别的强大&#xff0c;可以为开发者提供丰富的视觉效果&#xff01; 本篇笔记对Niagara系统进行初步的学习探索 文章目录 前言一、Niagara四大核心组件二、粒子发射器和粒子系统1、粒子发射器的创建2、粒子系统的创建3、Niagara系统的使用 总结 前言 在…

SpringBoot之优化高并发场景下的HttpClient并提升QPS

HttpClient优化思路 使用连接池&#xff08;简单粗暴&#xff09; 长连接优化&#xff08;特殊业务场景&#xff09; httpclient和httpget复用 合理的配置参数&#xff08;最大并发请求数&#xff0c;各种超时时间&#xff0c;重试次数&#xff09; 异步请求优化&#xff0…

个人博客教程(Typora官方免费版)

教程 链接&#xff1a;https://pan.baidu.com/s/1kVk3wxrcAPkIy8VrX7CK7g?pwdigiz 提取码&#xff1a;igiz 其实下面的教程都可以通过右键选择你想要的文本来实现&#xff0c;但是掌握基本的语法可以更快&#xff0c;如果看不懂我写的是什么东西可以查看非常简单的入门教程M…

解密Mybatis-Plus:优雅简化你的数据访问层!

目录 1、引言 2、什么是Mybatis-Plus 3、Mybatis-Plus的特点和优势 4、安装和配置Mybatis-Plus 5、使用Mybatis-Plus进行数据库操作 6、Mybatis-Plus的高级功能 7、Mybatis-Plus的扩展和插件 8、与Spring Boot集成 9、结语 1、引言 Mybatis-Plus是一个强大而优雅的Jav…

科研学习|论文解读——信息世界映射方法

题目&#xff1a;信息世界映射的下一步是什么&#xff1f;在情境中理解信息行为/实践的国际化和多学科方法&#xff08;What is next for information world mapping? International and multidisciplinary approaches to understanding information behaviors/ practices in …

Feature Fusion for Online Mutual KD

paper&#xff1a;Feature Fusion for Online Mutual Knowledge Distillation official implementation&#xff1a;https://github.com/Jangho-Kim/FFL-pytorch 本文的创新点 本文提出了一个名为特征融合学习&#xff08;Feature Fusion Learning, FFL&#xff09;的框架&…

进程的状态

进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型 中&#xff0c;进程状态分为三个基本状态&#xff0c;即就绪态&#xff0c;运行态&#xff0c;阻塞态。在五态模型中&#xff0c;进程分为新建态、就绪态&#xff0c;运行态&#x…