目录

效果

生成图片特征

查找踢足球的人

测试图片

模型信息

image_model.onnx

text_model.onnx

项目

代码

Form1.cs

Clip.cs

下载


C# Onnx Chinese CLIP 通过一句话从图库中搜出来符合要求的图片

效果

生成图片特征

查找踢足球的人

测试图片

模型信息

image_model.onnx

Inputs
-------------------------
name:image
tensor:Float[1, 3, 224, 224]
---------------------------------------------------------------

Outputs
-------------------------
name:unnorm_image_features
tensor:Float[1, 512]
---------------------------------------------------------------

text_model.onnx

Inputs
-------------------------
name:text
tensor:Int64[1, 52]
---------------------------------------------------------------

Outputs
-------------------------
name:unnorm_text_features
tensor:Float[1, 512]
---------------------------------------------------------------

项目

代码

Form1.cs


using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Onnx_Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

Clip mynet = new Clip("model/image_model.onnx", "model/text_model.onnx", "model/myvocab.txt");

float[] imagedir_features;
        string image_dir = "test_img";
        StringBuilder sb = new StringBuilder();

private void button2_Click(object sender, EventArgs e)
        {
            //特征向量 可以存二进制文件或者向量数据库
            imagedir_features = mynet.generate_imagedir_features(image_dir);
            txtInfo.Text = "生成完成!";
            txtInfo.Text += "有" + mynet.imgnum + "张图片,特征向量长度=" + imagedir_features.Length;
        }

private void button3_Click(object sender, EventArgs e)
        {
            if (imagedir_features == null)
            {
                MessageBox.Show("请先生成图片特征!");
                return;
            }

sb.Clear();
            txtInfo.Text = "";
            lblInfo.Text = "";
            pictureBox1.Image = null;

string input_text = txt_input_text.Text;
            if (string.IsNullOrEmpty(input_text))
            {
                return;
            }
            List<Dictionary<string, float>> top5imglist = mynet.input_text_search_image(input_text, imagedir_features, mynet.imglist);

sb.AppendLine("top5:");
            foreach (var item in top5imglist)
            {
                sb.AppendLine(Path.GetFileName(item.Keys.First()) + "  相似度:" + item[item.Keys.First()].ToString("F2"));
            }

txtInfo.Text = sb.ToString();
            lblInfo.Text = Path.GetFileName(top5imglist[0].Keys.First());
            pictureBox1.Image = new Bitmap(top5imglist[0].Keys.First());

}

private void Form1_Load(object sender, EventArgs e)
        {

}
    }
}


using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Onnx_Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Clip mynet = new Clip("model/image_model.onnx", "model/text_model.onnx", "model/myvocab.txt");

        float[] imagedir_features;
        string image_dir = "test_img";
        StringBuilder sb = new StringBuilder();

        private void button2_Click(object sender, EventArgs e)
        {
            //特征向量 可以存二进制文件或者向量数据库
            imagedir_features = mynet.generate_imagedir_features(image_dir);
            txtInfo.Text = "生成完成!";
            txtInfo.Text += "有" + mynet.imgnum + "张图片,特征向量长度=" + imagedir_features.Length;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (imagedir_features == null)
            {
                MessageBox.Show("请先生成图片特征!");
                return;
            }

            sb.Clear();
            txtInfo.Text = "";
            lblInfo.Text = "";
            pictureBox1.Image = null;

            string input_text = txt_input_text.Text;
            if (string.IsNullOrEmpty(input_text))
            {
                return;
            }
            List<Dictionary<string, float>> top5imglist = mynet.input_text_search_image(input_text, imagedir_features, mynet.imglist);

            sb.AppendLine("top5:");
            foreach (var item in top5imglist)
            {
                sb.AppendLine(Path.GetFileName(item.Keys.First()) + "  相似度:" + item[item.Keys.First()].ToString("F2"));
            }

            txtInfo.Text = sb.ToString();
            lblInfo.Text = Path.GetFileName(top5imglist[0].Keys.First());
            pictureBox1.Image = new Bitmap(top5imglist[0].Keys.First());

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

Clip.cs

public class Clip
    {
        int inpWidth = 224;
        int inpHeight = 224;
        float[] mean = new float[] { 0.48145466f, 0.4578275f, 0.40821073f };
        float[] std = new float[] { 0.26862954f, 0.26130258f, 0.27577711f };

int context_length = 52;
        int len_text_feature = 512;

Net net;
        float[] image_features_input;

SessionOptions options;
        InferenceSession onnx_session;
        Tensor<long> input_tensor;
        List<NamedOnnxValue> input_container;
        IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;
        DisposableNamedOnnxValue[] results_onnxvalue;
        Tensor<float> result_tensors;

TokenizerBase tokenizer;

int[] text_tokens_input;
        float[,] text_features_input;

public int imgnum = 0;
        public List<string> imglist = new List<string>();

public Clip(string image_modelpath, string text_modelpath, string vocab_path)
        {
            net = CvDnn.ReadNetFromOnnx(image_modelpath);

// 创建输出会话,用于输出模型读取信息
            options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行
            // 创建推理模型类,读取本地模型文件
            onnx_session = new InferenceSession(text_modelpath, options);//model_path 为onnx模型文件的路径
            // 创建输入容器
            input_container = new List<NamedOnnxValue>();

load_tokenizer(vocab_path);

}

void load_tokenizer(string vocab_path)
        {

tokenizer = new TokenizerClipChinese();
            tokenizer.load_tokenize(vocab_path);
            text_tokens_input = new int[1024 * context_length];
        }

Mat normalize_(Mat src)
        {
            Cv2.CvtColor(src, src, ColorConversionCodes.BGR2RGB);

Mat[] bgr = src.Split();
            for (int i = 0; i < bgr.Length; ++i)
            {
                bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 / (255.0 * std[i]), (0.0 - mean[i]) / std[i]);
            }

Cv2.Merge(bgr, src);

foreach (Mat channel in bgr)
            {
                channel.Dispose();
            }

return src;
        }

unsafe void generate_image_feature(Mat srcimg)
        {
            Mat temp_image = new Mat();
            Cv2.Resize(srcimg, temp_image, new Size(inpWidth, inpHeight), 0, 0, InterpolationFlags.Cubic);
            Mat normalized_mat = normalize_(temp_image);
            Mat blob = CvDnn.BlobFromImage(normalized_mat);
            net.SetInput(blob);
            //模型推理,读取推理结果
            Mat[] outs = new Mat[1] { new Mat() };
            string[] outBlobNames = net.GetUnconnectedOutLayersNames().ToArray();
            net.Forward(outs, outBlobNames);
            float* ptr_feat = (float*)outs[0].Data;
            int len_image_feature = outs[0].Size(1);  //忽略第0维batchsize=1, len_image_feature是定值512,跟len_text_feature相等的, 也可以写死在类成员变量里
            image_features_input = new float[len_image_feature];
            float norm = 0.0f;
            for (int i = 0; i < len_image_feature; i++)
            {
                norm += ptr_feat[i] * ptr_feat[i];
            }
            norm = (float)Math.Sqrt(norm);
            for (int i = 0; i < len_image_feature; i++)
            {
                image_features_input[i] = ptr_feat[i] / norm;
            }
        }

unsafe void generate_text_feature(List<string> texts)
        {
            List<List<int>> text_token = new List<List<int>>(texts.Count);
            for (int i = 0; i < texts.Count; i++)
            {
                text_token.Add(new List<int>());
            }

for (int i = 0; i < texts.Count; i++)
            {
                tokenizer.encode_text(texts[i], text_token[i]);
            }

if (text_token.Count * context_length > text_tokens_input.Length)
            {
                text_tokens_input = new int[text_token.Count * context_length];
            }

foreach (int i in text_tokens_input) { text_tokens_input[i] = 0; }

for (int i = 0; i < text_token.Count; i++)
            {
                if (text_token[i].Count > context_length)
                {
                    Console.WriteLine("text_features index " + i + " ,bigger than " + context_length + "\n");
                    continue;
                }
                for (int j = 0; j < text_token[i].Count; j++)
                {
                    text_tokens_input[i * context_length + j] = text_token[i][j];
                }

}

int[] text_token_shape = new int[] { 1, context_length };

text_features_input = new float[text_token.Count, len_text_feature];

long[] text_tokens_input_64 = new long[texts.Count * context_length];
            for (int i = 0; i < text_tokens_input_64.Length; i++)
            {
                text_tokens_input_64[i] = text_tokens_input[i];
            }

for (int i = 0; i < text_token.Count; i++)
            {
                input_tensor = new DenseTensor<long>(text_tokens_input_64, new[] { 1, 52 });
                input_container.Clear();
                input_container.Add(NamedOnnxValue.CreateFromTensor("text", input_tensor));

//运行 Inference 并获取结果
                result_infer = onnx_session.Run(input_container);

// 将输出结果转为DisposableNamedOnnxValue数组
                results_onnxvalue = result_infer.ToArray();

// 读取第一个节点输出并转为Tensor数据
                result_tensors = results_onnxvalue[0].AsTensor<float>();

float[] text_feature_ptr = results_onnxvalue[0].AsTensor<float>().ToArray();

float norm = 0.0f;
                for (int j = 0; j < len_text_feature; j++)
                {
                    norm += text_feature_ptr[j] * text_feature_ptr[j];
                }
                norm = (float)Math.Sqrt(norm);
                for (int j = 0; j < len_text_feature; j++)
                {
                    text_features_input[i, j] = text_feature_ptr[j] / norm;
                }

}
        }

void softmax(float[] input)
        {
            int length = input.Length;
            float[] exp_x = new float[length];
            float maxVal = input.Max();
            float sum = 0;
            for (int i = 0; i < length; i++)
            {
                float expval = (float)Math.Exp(input[i] - maxVal);
                exp_x[i] = expval;
                sum += expval;
            }
            for (int i = 0; i < length; i++)
            {
                input[i] = exp_x[i] / sum;
            }
        }

int[] argsort_ascend(float[] array)
        {
            int array_len = array.Length;
            int[] array_index = new int[array_len];
            for (int i = 0; i < array_len; ++i)
            {
                array_index[i] = i;
            }

var temp = array_index.ToList();

temp.Sort((pos1, pos2) =>
             {

if (array[pos1] < array[pos2])
                 {
                     return -1;
                 }
                 else if (array[pos1] == array[pos2])
                 {
                     return 0;
                 }
                 else
                 {
                     return 0;
                 }

});

return temp.ToArray();
        }

public List<Dictionary<string, float>> input_text_search_image(string text, float[] image_features, List<string> imglist)
        {

int imgnum = imglist.Count;
            List<string> texts = new List<string> { text };

generate_text_feature(texts);

float[] logits_per_image = new float[imgnum];

for (int i = 0; i < imgnum; i++)
            {
                float sum = 0;
                for (int j = 0; j < len_text_feature; j++)
                {
                    sum += image_features[i * len_text_feature + j] * text_features_input[0, j]; //图片特征向量跟文本特征向量做内积
                }
                logits_per_image[i] = 100 * sum;
            }

softmax(logits_per_image);

int[] index = argsort_ascend(logits_per_image);

List<Dictionary<string, float>> top5imglist = new List<Dictionary<string, float>>(5);

for (int i = 0; i < 5; i++)
            {
                int ind = index[imgnum - 1 - i];
                Dictionary<string, float> result = new Dictionary<string, float>();
                result.Add(imglist[ind], logits_per_image[ind]);
                top5imglist.Add(result);
            }
            return top5imglist;
        }

public float[] generate_imagedir_features(string image_dir)
        {

imglist = Common.listdir(image_dir);
            imgnum = imglist.Count;
            Console.WriteLine("遍历到" + imgnum + "张图片");

float[] imagedir_features = new float[0];

for (int i = 0; i < imgnum; i++)
            {
                string imgpath = imglist[i];

Mat srcimg = Cv2.ImRead(imgpath);

generate_image_feature(srcimg);

imagedir_features = imagedir_features.Concat(image_features_input).ToArray();

srcimg.Dispose();
            }

return imagedir_features;

}

}

public class Clip
    {
        int inpWidth = 224;
        int inpHeight = 224;
        float[] mean = new float[] { 0.48145466f, 0.4578275f, 0.40821073f };
        float[] std = new float[] { 0.26862954f, 0.26130258f, 0.27577711f };

        int context_length = 52;
        int len_text_feature = 512;

        Net net;
        float[] image_features_input;

        SessionOptions options;
        InferenceSession onnx_session;
        Tensor<long> input_tensor;
        List<NamedOnnxValue> input_container;
        IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;
        DisposableNamedOnnxValue[] results_onnxvalue;
        Tensor<float> result_tensors;

        TokenizerBase tokenizer;

        int[] text_tokens_input;
        float[,] text_features_input;

        public int imgnum = 0;
        public List<string> imglist = new List<string>();

        public Clip(string image_modelpath, string text_modelpath, string vocab_path)
        {
            net = CvDnn.ReadNetFromOnnx(image_modelpath);

            // 创建输出会话,用于输出模型读取信息
            options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行
            // 创建推理模型类,读取本地模型文件
            onnx_session = new InferenceSession(text_modelpath, options);//model_path 为onnx模型文件的路径
            // 创建输入容器
            input_container = new List<NamedOnnxValue>();

            load_tokenizer(vocab_path);

        }

        void load_tokenizer(string vocab_path)
        {

            tokenizer = new TokenizerClipChinese();
            tokenizer.load_tokenize(vocab_path);
            text_tokens_input = new int[1024 * context_length];
        }

        Mat normalize_(Mat src)
        {
            Cv2.CvtColor(src, src, ColorConversionCodes.BGR2RGB);

            Mat[] bgr = src.Split();
            for (int i = 0; i < bgr.Length; ++i)
            {
                bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 / (255.0 * std[i]), (0.0 - mean[i]) / std[i]);
            }

            Cv2.Merge(bgr, src);

            foreach (Mat channel in bgr)
            {
                channel.Dispose();
            }

            return src;
        }

        unsafe void generate_image_feature(Mat srcimg)
        {
            Mat temp_image = new Mat();
            Cv2.Resize(srcimg, temp_image, new Size(inpWidth, inpHeight), 0, 0, InterpolationFlags.Cubic);
            Mat normalized_mat = normalize_(temp_image);
            Mat blob = CvDnn.BlobFromImage(normalized_mat);
            net.SetInput(blob);
            //模型推理,读取推理结果
            Mat[] outs = new Mat[1] { new Mat() };
            string[] outBlobNames = net.GetUnconnectedOutLayersNames().ToArray();
            net.Forward(outs, outBlobNames);
            float* ptr_feat = (float*)outs[0].Data;
            int len_image_feature = outs[0].Size(1);  //忽略第0维batchsize=1, len_image_feature是定值512,跟len_text_feature相等的, 也可以写死在类成员变量里
            image_features_input = new float[len_image_feature];
            float norm = 0.0f;
            for (int i = 0; i < len_image_feature; i++)
            {
                norm += ptr_feat[i] * ptr_feat[i];
            }
            norm = (float)Math.Sqrt(norm);
            for (int i = 0; i < len_image_feature; i++)
            {
                image_features_input[i] = ptr_feat[i] / norm;
            }
        }

        unsafe void generate_text_feature(List<string> texts)
        {
            List<List<int>> text_token = new List<List<int>>(texts.Count);
            for (int i = 0; i < texts.Count; i++)
            {
                text_token.Add(new List<int>());
            }

            for (int i = 0; i < texts.Count; i++)
            {
                tokenizer.encode_text(texts[i], text_token[i]);
            }

            if (text_token.Count * context_length > text_tokens_input.Length)
            {
                text_tokens_input = new int[text_token.Count * context_length];
            }

            foreach (int i in text_tokens_input) { text_tokens_input[i] = 0; }

            for (int i = 0; i < text_token.Count; i++)
            {
                if (text_token[i].Count > context_length)
                {
                    Console.WriteLine("text_features index " + i + " ,bigger than " + context_length + "\n");
                    continue;
                }
                for (int j = 0; j < text_token[i].Count; j++)
                {
                    text_tokens_input[i * context_length + j] = text_token[i][j];
                }

            }

            int[] text_token_shape = new int[] { 1, context_length };

            text_features_input = new float[text_token.Count, len_text_feature];

            long[] text_tokens_input_64 = new long[texts.Count * context_length];
            for (int i = 0; i < text_tokens_input_64.Length; i++)
            {
                text_tokens_input_64[i] = text_tokens_input[i];
            }

            for (int i = 0; i < text_token.Count; i++)
            {
                input_tensor = new DenseTensor<long>(text_tokens_input_64, new[] { 1, 52 });
                input_container.Clear();
                input_container.Add(NamedOnnxValue.CreateFromTensor("text", input_tensor));

                //运行 Inference 并获取结果
                result_infer = onnx_session.Run(input_container);

                // 将输出结果转为DisposableNamedOnnxValue数组
                results_onnxvalue = result_infer.ToArray();

                // 读取第一个节点输出并转为Tensor数据
                result_tensors = results_onnxvalue[0].AsTensor<float>();

                float[] text_feature_ptr = results_onnxvalue[0].AsTensor<float>().ToArray();

                float norm = 0.0f;
                for (int j = 0; j < len_text_feature; j++)
                {
                    norm += text_feature_ptr[j] * text_feature_ptr[j];
                }
                norm = (float)Math.Sqrt(norm);
                for (int j = 0; j < len_text_feature; j++)
                {
                    text_features_input[i, j] = text_feature_ptr[j] / norm;
                }

            }
        }

        void softmax(float[] input)
        {
            int length = input.Length;
            float[] exp_x = new float[length];
            float maxVal = input.Max();
            float sum = 0;
            for (int i = 0; i < length; i++)
            {
                float expval = (float)Math.Exp(input[i] - maxVal);
                exp_x[i] = expval;
                sum += expval;
            }
            for (int i = 0; i < length; i++)
            {
                input[i] = exp_x[i] / sum;
            }
        }

        int[] argsort_ascend(float[] array)
        {
            int array_len = array.Length;
            int[] array_index = new int[array_len];
            for (int i = 0; i < array_len; ++i)
            {
                array_index[i] = i;
            }

            var temp = array_index.ToList();

            temp.Sort((pos1, pos2) =>
             {

                 if (array[pos1] < array[pos2])
                 {
                     return -1;
                 }
                 else if (array[pos1] == array[pos2])
                 {
                     return 0;
                 }
                 else
                 {
                     return 0;
                 }

             });

            return temp.ToArray();
        }

        public List<Dictionary<string, float>> input_text_search_image(string text, float[] image_features, List<string> imglist)
        {

            int imgnum = imglist.Count;
            List<string> texts = new List<string> { text };

            generate_text_feature(texts);

            float[] logits_per_image = new float[imgnum];

            for (int i = 0; i < imgnum; i++)
            {
                float sum = 0;
                for (int j = 0; j < len_text_feature; j++)
                {
                    sum += image_features[i * len_text_feature + j] * text_features_input[0, j]; //图片特征向量跟文本特征向量做内积
                }
                logits_per_image[i] = 100 * sum;
            }

            softmax(logits_per_image);

            int[] index = argsort_ascend(logits_per_image);

            List<Dictionary<string, float>> top5imglist = new List<Dictionary<string, float>>(5);

            for (int i = 0; i < 5; i++)
            {
                int ind = index[imgnum - 1 - i];
                Dictionary<string, float> result = new Dictionary<string, float>();
                result.Add(imglist[ind], logits_per_image[ind]);
                top5imglist.Add(result);
            }
            return top5imglist;
        }

        public float[] generate_imagedir_features(string image_dir)
        {

            imglist = Common.listdir(image_dir);
            imgnum = imglist.Count;
            Console.WriteLine("遍历到" + imgnum + "张图片");

            float[] imagedir_features = new float[0];

            for (int i = 0; i < imgnum; i++)
            {
                string imgpath = imglist[i];

                Mat srcimg = Cv2.ImRead(imgpath);

                generate_image_feature(srcimg);

                imagedir_features = imagedir_features.Concat(image_features_input).ToArray();

                srcimg.Dispose();
            }

            return imagedir_features;

        }

    }

下载

源码下载

相关文章

一张图读懂人工智能

三、人工智能和多式联运 AI产品的发展趋势,以及语言模型的应急能力和广泛应用。视频探讨了人工智能和人类的优劣势,以及未来的发展方向。视频提出了一种积极的心态,认为人工智能可以成为我们的同事,帮助我们提高效率和能力。二、大型语言模型的训练过程和应用场景,包括文本到文本、图像到文本、语音转录等多个方面。同时也提到了不同模型的能力和成本。一、生成人工智能的概念和应用,以及如何使用大型语言模型进行聊天和创造原创内容。五、如何使用生成人工智能作为招聘公司的工具,以及如何有效地使用生成人工智能来制作有用结果的提示。

基于YOLOv8深度学习+Pyqt5的电动车头盔佩戴检测系统

该系统利用深度学习技术,通过训练YOLOv8模型来识别电动车骑行者是否佩戴头盔,并在检测到未佩戴头盔的情况下发出警报。因此,开发一种能够实时监测头盔佩戴情况的系统,对于提高骑行者的安全意识和减少交通事故具有重要作用。本文提出的基于YOLOv8的电动车头盔佩戴检测系统,能够有效地提高电动车骑行者的安全意识。YOLOv8是YOLO系列目标检测模型的最新版本,它在前代模型的基础上进行了优化,提高了检测速度和准确性。在不同的场景和光照条件下,模型均能稳定地识别出佩戴和未佩戴头盔的骑行者。wx供重浩:创享日记。

C# this关键字的作用

关键字在C#中主要用于引用当前对象,区分字段与局部变量,调用其他构造函数以及传递当前对象给其他方法或构造函数。

chatgpt的大致技术原理

在RLHF中,人类用户对模型生成的文本提供反馈(如打分或选择更喜欢的文本),然后模型根据这些反馈进行进一步的训练。预处理步骤包括分词(使用BPE算法将文本分解为更小的子单元,如单词或符号)、去除停用词(即那些对文本意义不大的词,如“的”、“了”等)以及其他可能的文本清洗工作。生成过程中,模型会考虑前文的上下文信息,以确保生成的文本是连贯和有意义的。通过收集大量的文本数据、建立深度学习模型、进行预训练和微调以及使用搜索算法和人类反馈强化学习等技术,ChatGPT能够生成高质量、连贯且有用的文本回复。

C# 如何实现一个事件总线

EventBus(事件总线)是一种用于在应用程序内部或跨应用程序组件之间进行事件通信的机制。它允许不同的组件通过发布和订阅事件来进行解耦和通信。在给定的代码片段中,我们可以看到一个使用C#实现的Event Bus。它定义了一些接口和类来实现事件的发布和订阅。IEvent和。IEvent是一个空接口,用于约束事件的类型。是一个泛型接口,用于约束事件处理程序的类型。它定义了处理事件的异步方法HandleAsync和处理异常的方法HandleException。

C# winfrom中excel文件导入导出

在C#交流群里,看到很多小伙伴在excel数据导入导出到C#界面上存在疑惑,所以今天专门做了这个主题,希望大家有所收获!环境:win10+vs2017界面:主要以演示为主,所以没有做优化,然后主界面上添加两个按钮,分别命名为ExportExcel和ImportExcel,添加两个dataGridView,分别是dataGridView1和dataGridView2然后在窗体加载程序中给dataGr...

C#中的浅度和深度复制(C#如何复制一个对象)

接着,我们修改了复制得到的对象及其引用类型字段的属性值,最后输出原始对象和复制对象的属性值。这意味着如果一个类包含引用类型成员,在执行深度复制时,不仅复制这些引用,还会递归地复制引用所指向的对象,直到所有的引用都指向全新的对象实例。当进行浅复制时,系统会创建一个新的对象实例,但这个新对象的字段将与原始对象中的值类型字段具有相同的值,而对于引用类型字段,则仅仅是复制了。也就是说,如果一个类中有引用类型的成员变量(比如数组、其他自定义类的对象等),那么浅复制后,新对象和原对象的这些引用类型成员仍然指向。

云计算与边缘计算:有什么区别?

云计算和边缘计算作为不同的计算范式,各自在特定场景中发挥着独特的作用。它们的区别体现在数据处理位置、延迟、可用性以及应用场景等方面。然而,随着数字化时代的发展,它们也逐渐形成了协同应用的趋势,充分发挥各自的优势,提供更灵活、高效的计算体系结构。未来,随着智能化、自动化和边缘计算的边界拓展,云计算和边缘计算将进一步推动数字化转型。同时,安全性、跨边缘计算标准和环境可持续性等问题也需要在未来的发展中得到更好的解决。

ChatGPT高效提问—prompt基础

​ 设计一个好的prompt对于获取理想的生成结果至关重要。通过选择合适的关键词、提供明确的上下文、设置特定的约束条件,可以引导模型生成符合预期的回复。例如,在对话中,可以使用明确的问题或陈述引导模型生成相关、具体的回答;在摘要生成中,可以提供需要摘要的文章段落作为prompt,以确保生成的摘要准确而精炼。

C# 实现微信自定义分享

在实际的应用中,我们可能不是简单的将该网页的链接直接分享出去,而是生成符合实际需要的URL,微信称其为自定义分享。

第5课 使用FFmpeg将rtmp流再转推到rtmp服务器

9.转码推流:循环读取输入文件的数据包,使用av_read_frame()函数读取数据包,然后使用avcodec_send_frame()函数发送数据包给编码器进行编码,再使用avcodec_receive_packet()函数接收编码后的数据包,最后使用av_interleaved_write_frame()函数将编码后的数据包写入输出流。5.添加输出流:根据输入文件的流信息,使用avformat_new_stream()函数创建输出流,并将其添加到输出上下文中。

C# 常用排序算法(冒泡排序 插入排序 选择排序 快速排序 归并排序 堆排序)

建堆阶段将无序列表转换为堆,排序阶段将堆的根节点依次取出,并调整堆,完成排序。它使用分治法的思想,通过选择一个基准元素,将列表分成两个子列表,并对每个子列表递归地进行排序。它重复地遍历要排序的列表,比较相邻的两个元素,并交换它们的位置,直到列表排序完成为止。每次遍历都会将最大的元素移动到列表的末尾。每次选择未排序部分的最小元素,并将其放到已排序部分的末尾,逐步构建有序序列。它将列表分成较小的子列表,对每个子列表进行排序,然后再将子列表合并成较大的有序列表,直到整个列表排序完成。

二维平面阵列波束赋形原理和Matlab仿真

阵面左下角天线位于坐标原点,将坐标原点阵元设为参考阵元,计算每个阵元相对于该参考阵元的入射波程差,从而来计算每个阵元接收的回波信号。实现波束赋形的最基本的方法是对各个天线阵元的信号进行适当延迟后相加,使目标方向的信号同相叠加得到增强,而其他方向均有不同程度的削弱,该方法通常用于模拟信号.根据上述理论推导可以仿真任意平面阵列的方向图,这里对两种典型的阵列(矩形平面阵列和圆形阵列)进行Matlab仿真,其余类型的阵列在此基础上修改即可。根据上述圆形阵列公式做仿真,得到下述的三维空间方向图。

人工智能与机器学习——开启智能时代的里程碑

人工智能是指使计算机系统表现出类似于人类智能的能力。其目标是实现机器具备感知、理解、学习、推理和决策等智能行为。人工智能的发展可以追溯到上世纪50年代,随着计算机技术和算法的不断进步,人工智能得以实现。机器学习是人工智能的一个重要分支,它通过让计算机从数据中学习和改进性能,而不需要明确的编程指令。机器学习可以分为监督学习、无监督学习和强化学习三种主要类型。

【.NET Core】深入理解任务并行库 (TPL)

是和空间中的一组公共类型和API。TPL的目的是通过简化将并行和并发添加到应用程序的过程来提高开发人员的工作效率。TPL动态缩放并发的程度以最有效地使用所有可用的处理器。此外,TPL还处理工作分区,ThreadPool上的线程调度、取消支持、状态管理以及其他低级别的细节操作。通过使用TPL,你可以在将精力集中于程序要完成的工作,同时最大程度地提高代码的性能。在.NET Framework4中,首选TPL编写多线程代码和并行代码。但是,并不是所有代码都适合并行化。

【GPU】深入理解GPU硬件架构及运行机制

GPU的基本底层构成,主要是以GPU计算核心 Cores,以及Memory以及控制单元,三大组成要素组成。Core是计算的基本单元,既可以用作简单的浮点运算,又可以做一些复杂的运算例如,tensor 或者ray tracing。多个core之间通讯的方式:在特定的应用场合多个core之间是不需要的通讯的,也就是各干各的(例如 图像缩放)。但是也有一些例子,多个core之间要相互通讯配合(例如上文谈到的数组求和问题),每个core之间都可以实现交互数据是非常昂贵的,

FluentValidation在C# WPF中的应用

1. 引言在.NET开发领域,FluentValidation以其优雅、易扩展的特性成为开发者进行属性验证的首选工具。它不仅适用于Web开发,如MVC、Web API和ASP.NET CORE,同样也能完美集成在WPF应用程序中,提供强大的数据验证功能。本文将深入探讨如何在C# WPF项目中运用FluentValidation进行属性验证,并展示如何通过MVVM模式实现这一功能。2. 功能概览我们的目标是构建一个WPF应用程序,它能够通过FluentValidation实现以下验证功能:验证Vie

RAG中的3个高级检索技巧

我们介绍的这些检索技术有助于提高文档的相关性。但是这方面的研究还正在进行,还有很多其他方法例如,利用真实反馈数据对嵌入模型进行微调;直接微调LLM以使其检索能力最大化(RA-DIT);探索更复杂的嵌入适配器使用深度神经网络而不是矩阵;深度和智能分块技术作者:Ahmed Besbes。

大数据深度学习卷积神经网络CNN:CNN结构、训练与优化一文全解

卷积神经网络是一种前馈神经网络,它的人工神经元可以响应周围单元的局部区域,从而能够识别视觉空间的部分结构特征。卷积层: 通过卷积操作检测图像的局部特征。激活函数: 引入非线性,增加模型的表达能力。池化层: 减少特征维度,增加模型的鲁棒性。全连接层: 在处理空间特征后,全连接层用于进行分类或回归。卷积神经网络的这些组件协同工作,使得CNN能够从原始像素中自动学习有意义的特征层次结构。随着深度增加,这些特征从基本形状和纹理逐渐抽象为复杂的对象和场景表现。

【.NET Core】Lazy<T> 实现延迟加载详解

延迟初始化是一种将对象的创建延迟到第一次需要用时的技术。简而言之,就是对象的初始化发生在第一次需要调用的时候执行。通常所说的延迟初始化和延迟实例化的意思是相同。通过使用延迟基础,可以避免应用程序不必要的计算和内存消耗。从.NET 4.0开始,可以使用Lazy来实现对象的延迟初始化,从而优化系统的性能。延迟初始化就是将对象的初始化延迟到第一次使用该对象时。延迟初始化是我们优化程序性能的一种方式。如创建一个对象时需要花费很大的开销,而这一对象在系统运行过程中不一定会用到。

从虚拟到现实:数字孪生驱动智慧城市可持续发展

同时,我们也需要不断探索和创新数字孪生技术的应用场景和发展方向,为智慧城市的可持续发展提供更加全面和深入的支持。“方案365”2023年全新整理智慧城市、数字孪生、乡村振兴、智慧乡村、元宇宙、数据中台、智慧园区、智慧社区、智慧矿山、城市生命线、智慧水利、智慧应急、智慧校园、智慧工地、智慧农业、智慧文旅、智慧交通等300+行业全套解决方案。通过智能电表和能源管理系统,数字孪生技术可以实现对家庭、企业等各个层面的能源使用情况进行监测和优化,提高能源利用效率,推动城市的绿色发展。

如何使用人工智能优化 DevOps?

DevOps 和人工智能密不可分,影响着各种业务。DevOps 可以加快产品开发速度并简化现有部署的维护,而 AI 则可以改变整个系统的功能。DevOps团队可以依靠人工智能和机器学习来进行数据集成、测试、评估和发布系统。更重要的是,人工智能和机器学习可以以高效、快速、安全的方式改进 DevOps 驱动的流程。从开发人员实用性和业务支持的角度来看, 评估AI和ML在 DevOps 中的重要性对于企业来说是有益的。

人工智能有哪些领域?

像京东自主研发的无人仓采用大量智能物流机器人进行协同与配合,通过人工智能、深度学习、图像智能识别、大数据应用等技术,让工业机器人可以进行自主的判断和行为,完成各种复杂的任务,在商品分拣、运输、出库等环节实现自动化。人工智能在金融领域的应用主要有:智能获客、身份识别、大数据风控、智能投顾、智能客服、金融云等,该行业也是人工智能渗透最早、最全面的行业。目前,我国在ITS方面的应用主要是通过对交通中的车辆流量、行车速度进行采集和分析,可以对交通进行实施监控和调度,有效提高通行能力、简化交通管理、降低环境污染等。
返回
顶部