医学数据分析实训 项目十 基于深度残差神经网络的皮肤癌检测

news2024/9/20 11:51:24

文章目录

    • 综合实践三 基于深度残差神经网络的皮肤癌检测
      • 实现步骤1:图像数据预处理
      • 实现步骤2:模型构建
      • 实现步骤3:性能度量
      • 提交要求
    • 1 基于深度残差神经网络的皮肤癌检测代码
    • 2 结果分析

综合实践三 基于深度残差神经网络的皮肤癌检测

皮肤镜图像是检查皮肤癌黑色素瘤的主要手段。本实践项目通过构建深度残差神经网络提取皮肤镜图像的高维特征,使用残差学习防止网络梯度退化,降低网络训练的难度,实现黑色素瘤的有效识别。

实践项目所使用的数据集由多名患者的皮肤癌组织纤维图像组成,分为训练集和预测集,每部分包含良性(benign,标签定义为1)和恶性(malignant,标签定义为0)两种。

请将皮肤癌组织显微图像进行预处理,并在处理后的数据集基础上,运用基于深度残差神经网络模型对训练集进行训练,并对测试集进行预测。

实现步骤1:图像数据预处理

  1. 安装 Pillownumpyscikit-learnkerastensorflowmatplotlib 库;
  2. 对图像数据进行归一化和格式转换。将“jpg”图像传输到数组 IMG,并将所有数据转换成矩阵形式;
  3. 定义标签,良性定义标签为 1,恶性定义标签为 0;
  4. 分别合并训练集和测试集中的良性肿瘤数据和恶性肿瘤数据;

实现步骤2:模型构建

  1. 使用 Keras 库中的 ImageDataGenerator() 函数进行数据增强;
  2. 读取预处理后的图像,划分训练集和测试集;
  3. 使用 Sequential() 建立模型,并进行模型训练;
  4. 使用测试数据对模型进行测试;
  5. 对模型进行评估;

实现步骤3:性能度量

  1. 绘制模型精度折线图,查看训练效果;
  2. 输出显示恶性的预测结果前 8 个图像;
  3. 输出显示良性的预测结果前 8 个图像;

提交要求

  1. 提交实现本实践任务的所有代码(可执行,非.doc、.txt 等文本格式);
  2. 提交综合实践任务书(word 格式),包括小组成员分工、分析目的、数据预处理、算法介绍、结果分析等内容;
  3. 提交“四、性能度量”中 2 和 3 输出的图像;

1 基于深度残差神经网络的皮肤癌检测代码

在虚拟环境下进行该任务--基于深度残差神经网络的皮肤癌检测
anaconda下的虚拟环境,python版本是3.10
我的虚拟环境路径: D:\envs\miniconda\envs\cancer_detection

conda create -n cancer_detection python=3.10

conda activate cancer_detection

conda deactivate

安装要使用的包

pip install Pillow numpy scikit-learn keras tensorflow matplotlib



import time

from keras.src.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras import Sequential, Input
import os
from PIL import Image
import numpy as np
from sklearn.model_selection import train_test_split
from keras.src.optimizers import Adam
from keras.src.legacy.preprocessing.image import ImageDataGenerator
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
import matplotlib.pyplot as plt
# 显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
# 显示负号
plt.rcParams['axes.unicode_minus'] = False


# 从指定的文件夹中加载图像
def load_images_from_folder(folder, class_name):
    jpg_path = os.path.join(folder, class_name)  #data/train/benign
    images = []
    # 添加计数器
    count = 0  
    #遍历指定路径下的所有文件名
    for filename in os.listdir(jpg_path): 
        img = Image.open(os.path.join(jpg_path, filename))  #224*224
        if img is not None:
            img = np.array(img) / 255.0  # 归一化,将图像像素值归一化到0-1
            images.append(img)
            count += 1  # 更新计数器
    return images, count


# 训练集文件夹路径 测试集文件夹路径
train_folder = "data/train"
test_folder = "data/test"
# 第一个类别名称 # 第二个类别名称
class1_name = "benign"
class2_name = "malignant"

train_class1_images, train_class1_count = load_images_from_folder(train_folder, class1_name)
train_class2_images, train_class2_count = load_images_from_folder(train_folder, class2_name)
test_class1_images, test_class1_count = load_images_from_folder(test_folder, class1_name)
test_class2_images, test_class2_count = load_images_from_folder(test_folder, class2_name)

print("类别 {} 的训练集图像数目: {}".format(class1_name, train_class1_count))
print("类别 {} 的训练集图像数目: {}".format(class2_name, train_class2_count))
print("类别 {} 的测试集图像数目: {}".format(class1_name, test_class1_count))
print("类别 {} 的测试集图像数目: {}".format(class2_name, test_class2_count))

类别 benign 的训练集图像数目: 1440
类别 malignant 的训练集图像数目: 1197
类别 benign 的测试集图像数目: 360
类别 malignant 的测试集图像数目: 300

# 定义标签
train_class1_labels = np.ones(len(train_class1_images))
train_class2_labels = np.zeros(len(train_class2_images))
test_class1_labels = np.ones(len(test_class1_images))
test_class2_labels = np.zeros(len(test_class2_images))

# 合并训练集和测试集的图片和标签
benign_images = np.concatenate((train_class1_images, test_class1_images))  #训练集和验证集中的良性图片
benign_labels = np.concatenate((train_class1_labels, test_class1_labels))
malignant_images = np.concatenate((train_class2_images, test_class2_images))   #训练集和验证集中的恶性图片
malignant_labels = np.concatenate((train_class2_labels, test_class2_labels))
#查看合并后的图像数量
total_benign_images = benign_images.shape[0]
total_malignant_images = malignant_images.shape[0]
print("合并后的良性图片数量:", total_benign_images)
print("合并后的恶性图片数量:", total_malignant_images)
print("benign_labels的数量:", benign_labels.shape[0])
print("malignant_labels的数量:", malignant_labels.shape[0])


合并后的良性图片数量: 1800
合并后的恶性图片数量: 1497
benign_labels的数量: 1800
malignant_labels的数量: 1497

# 划分训练集和测试集
X = np.concatenate((benign_images, malignant_images))
y = np.concatenate((benign_labels, malignant_labels))
# 输出X的数量
print("X的数量:", X.shape[0])
# 输出y的数据量
print("y的数据量:", y.shape[0])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

X的数量: 3297
y的数据量: 3297


# 开始计时
start_time = time.time()

#简单的卷积神经网络(CNN)模型
input_shape = (224, 224, 3)
model = Sequential()
model.add(Input(shape=input_shape))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dense(10, activation='softmax'))
input_data = np.random.rand(1, 224, 224, 3)
output = model(input_data)

# 编译模型,Adam优化器的默认学习率通常是0.001
model.compile(optimizer=Adam(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])

#使用Adam优化器、稀疏类别交叉熵损失函数和准确率评估指标来编译模型
# 定义数据增强操作
datagen = ImageDataGenerator(
    rotation_range=20,       # 随机旋转角度范围(0~20度)
    width_shift_range=0.1,   # 水平平移范围(相对于总宽度的比例)
    height_shift_range=0.1,  # 垂直平移范围(相对于总高度的比例)
    horizontal_flip=True,    # 随机水平翻转
)

# 使用数据增强生成器对训练数据进行增强,并设置批量大小为32
train_generator = datagen.flow(X_train, y_train, batch_size=32) #32

# 使用增强后的数据训练模型,共进行10个周期的训练
history = model.fit(train_generator, epochs=10)

# # 使用测试数据对模型进行测试
y_pred = model.predict(X_test)
#每一行代表一个样本的预测概率分布,沿着每一行(即每个样本)寻找最大值的索引
y_pred_classes = np.argmax(y_pred, axis=1)

# 结束计时
end_time = time.time()

# 计算和输出所花费的时间
elapsed_time = end_time - start_time
print(f"进程完成所需时间: {elapsed_time:.2f} 秒")

83/83 ━━━━━━━━━━━━━━━━━━━━ 39s 421ms/step - accuracy: 0.5926 - loss: 12.5544
Epoch 2/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 34s 383ms/step - accuracy: 0.7577 - loss: 0.4838
Epoch 3/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 33s 383ms/step - accuracy: 0.7646 - loss: 0.4563
Epoch 4/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 32s 364ms/step - accuracy: 0.7697 - loss: 0.4524
Epoch 5/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 32s 369ms/step - accuracy: 0.7690 - loss: 0.4457
Epoch 6/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 32s 374ms/step - accuracy: 0.7890 - loss: 0.4195
Epoch 7/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 32s 368ms/step - accuracy: 0.7764 - loss: 0.4321
Epoch 8/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 32s 369ms/step - accuracy: 0.7921 - loss: 0.4323
Epoch 9/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 37s 428ms/step - accuracy: 0.7821 - loss: 0.4326
Epoch 10/10
83/83 ━━━━━━━━━━━━━━━━━━━━ 34s 391ms/step - accuracy: 0.7929 - loss: 0.4186
21/21 ━━━━━━━━━━━━━━━━━━━━ 1s 49ms/step
进程完成所需时间: 349.87 秒

# 计算评估指标
accuracy = accuracy_score(y_test, y_pred_classes)
precision = precision_score(y_test, y_pred_classes, average='weighted') #计算加权平均值
recall = recall_score(y_test, y_pred_classes, average='weighted')
f1 = f1_score(y_test, y_pred_classes, average='weighted')
confusion = confusion_matrix(y_test, y_pred_classes)

print('Accuracy:', accuracy)
print('Precision:', precision)
print('Recall:', recall)
print('F1 Score:', f1)
print('Confusion Matrix:', confusion)
# 保存数据
if not os.path.exists('./结果分析'):
    os.makedirs('./结果分析')
with open('./结果分析/计算评估指标.txt', 'a') as f:
    f.write('计算评估指标\n')
    f.write(f'Accuracy: {accuracy}\n')
    f.write(f'Precision: {precision}\n')
    f.write(f'Recall: {recall}\n')
    f.write(f'F1 Score: {f1}\n')
    f.write(f'Confusion Matrix: {confusion}\n')

Accuracy: 0.8106060606060606
Precision: 0.8103019434437978
Recall: 0.8106060606060606
F1 Score: 0.8094419197353939
Confusion Matrix: [[211 74]
[ 51 324]]

# 提取训练精度和验证精度数据
train_accuracy = history.history['accuracy']
loss = history.history['loss']
# 绘制精度折线图
plt.plot(train_accuracy, label='Training Accuracy')
plt.plot(loss, label='loss')
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.ylim(0, 1)
plt.legend()
plt.savefig('./结果分析/Model Accuracy.png')
plt.show()

在这里插入图片描述

# 预测结果数组 y_pred_classes 中找出所有预测为恶性(值为0)的索引,然后取前8个索引。
malignant_pred_indices = np.where(y_pred_classes == 0)[0][:8]
# 使用这些索引从测试数据集 X_test 中提取对应的图像数据
malignant_pred_images = X_test[malignant_pred_indices]
# 在一个2x4的子图网格中显示恶性预测图像。
for i, image in enumerate(malignant_pred_images):  # 遍历恶性预测图像列表,同时获取每个图像及其索引。
    plt.subplot(2, 4, i + 1)  #创建一个2行4列的子图网格,并将当前图像放置在子图中
    plt.imshow(image.squeeze(), cmap='gray')   #灰度颜色映射显示图像,移除单维度条目,确保图像数据的形状正确
    plt.axis('off')
    plt.title(f'Malignant {i + 1}')  #为当前子图设置标题

plt.savefig('./结果分析/恶性预测结果.png') 
plt.show()

在这里插入图片描述

# 获取良性预测结果前8个图像的索引
benign_pred_indices = np.where(y_pred_classes == 1)[0][:8]
# 获取良性预测结果前8个图像
benign_pred_images = X_test[benign_pred_indices]
# 显示良性预测结果前8个图像
for i, image in enumerate(benign_pred_images):
    plt.subplot(2, 4, i + 1)
    plt.imshow(image.squeeze(), cmap='gray')
    plt.axis('off')
    plt.title(f'Benign {i + 1}')
plt.savefig('./结果分析/良性预测结果.png')
plt.show()

在这里插入图片描述

2 结果分析

1.任务分工

2.分析目的
通过构建神经网络提取皮肤镜图像的高维特征,实现黑色素瘤的有效识别。

3.数据预处理
(1)格式转换
使用np.array(img),将“jpg” 图像传输到阵列 IMG,并将所有数据转换成矩阵形式

(2)对图像数据进行归一化
使用np.array(img) / 255.0,将每个像素值除以255.0,可以将像素值缩放到0到1之间的范围,实现归一化

(3)定义标签, 良性定义标签为 1, 恶性定义标签为 0;
train_class1_labels = np.ones(len(train_class1_images))
创建一个长度为与良性类别图像数目等同的数组,数组中的所有元素都为1。这表示良性肿瘤数据中的所有图像都属于类别1,良性定义标签为 1;
train_class2_labels = np.zeros(len(train_class2_images))
创建一个长度为与恶性类别图像数目等同的数组,数组中的所有元素都为0。这表示恶性肿瘤数据中的所有图像都属于类别0,恶性定义标签为 0。

(4)分别合并训练集和测试集中的良性肿瘤数据和恶性肿瘤数据

benign_images = np.concatenate((train_class1_images, test_class1_images))
benign_labels = np.concatenate((train_class1_labels, test_class1_labels))

将原数据集中分别属于训练集和测试集的同类别数据进行组合,即两个数组按照它们的第一个维度(通常是行)进行拼接,得到完整的良性肿瘤数据集和恶性肿瘤数据集,其对应标签同样方式进行组合,保证图片与标签的类别对应关系。
4.算法介绍
建立一个简单的卷积神经网络模型,其中包括:

  • 输入层:input_shape = (224, 224, 3)定义了输入图像的形状,其中224x224是图像的宽度和高度,3是图像的通道数(通常对应于RGB三个颜色通道)。
  • 模型构建:使用Sequential()创建了一个序列化的模型,然后通过.add()方法依次添加各个层。
  • Conv2D(32, (3, 3), activation=‘relu’):添加了一个卷积层,有32个过滤器,每个过滤器的大小为3x3,激活函数为ReLU。
  • MaxPooling2D((2, 2)):添加了一个最大池化层,池化窗口大小为2x2。
  • Flatten():将多维的卷积层输出展平为一维,以便连接到全连接层。
  • Dense (64, activation=‘relu’):添加了一个全连接层,有64个神经元,激活函数为ReLU。
  • Dense(2, activation=‘softmax’):添加了另一个全连接层,作为输出层,有2个神经元(对应于2个类别),激活函数为softmax,用于多分类任务。

5.结果分析
(1)模型精度折线图
见上图

模型采用Adam优化器,sparse_categorical_crossentropy损失函数,训练10轮,根据图像可以看出模型损失函数逐渐下降,准确率逐渐上升。

(2)评价指标结果

  • 准确率(Accuracy):0.8257575757575758,表示模型预测正确的样本占总样本的比例为82.58%。这是一个相对较高的准确率,说明模型在大多数情况下能够正确预测。
  • 精确率(Precision):0.8256871986269648,表示模型预测为正例的样本中真正为正例的比例为82.57%。精确率关注的是模型预测为正例的准确性,较高的精确率意味着模型预测出的正例中错误的可能性较低。
  • 召回率(Recall):0.8257575757575758,表示实际为正例的样本中被模型正确预测为正例的比例为82.58%。召回率关注的是模型能够找出所有正例的能力,较高的召回率意味着模型能够识别出更多的真实正例。
  • F1 Score:0.8257204698469889,F1 Score是精确率和召回率的调和平均值,用于综合评价模型的性能。较高的F1 Score意味着模型在精确率和召回率之间取得了较好的平衡

(3)混淆矩阵
Confusion Matrix: [[256 29]
[ 87 289]]
含义如下:

  • 第一行第一列(256):表示实际为正类且被模型正确预测为正类的数量。
  • 第一行第二列(29):表示实际为正类但被模型错误预测为负类的数量(即假阴性,Type I错误)。
  • 第二行第一列(87):表示实际为负类但被模型错误预测为正类的数量(即假阳性,Type II错误)。
  • 第二行第二列(289):表示实际为负类且被模型正确预测为负类的数量。

每次运行会有小差异

计算评估指标
Accuracy: 0.8257575757575758
Precision: 0.8395988183724034
Recall: 0.8257575757575758
F1 Score: 0.8265118719664174
Confusion Matrix: [[256  29]
 [ 86 289]]
计算评估指标
Accuracy: 0.8106060606060606
Precision: 0.8103019434437978
Recall: 0.8106060606060606
F1 Score: 0.8094419197353939
Confusion Matrix: [[211  74]
 [ 51 324]]

(4)输出显示恶性的预测结果前 8 个图像
见上文

(5)输出显示良性的预测结果前 8 个图像
见上文

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

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

相关文章

Games101学习 - 着色

本文主要讲述Games101中的着色部分。 文中将使用UE的UTexture2D接口,若不了解可以看这篇: https://blog.csdn.net/grayrail/article/details/142165442 1.面积比计算三角形坐标 通过三角形面积比可以得到三角形的坐标alpha、beta、gamma从而进行插值&a…

MATLAB画图,曲线图如何绘制美观,曲线图10种美化方法

曲线图是比较常用的图形,本文以二维曲线图为例,展示曲线的图的不同美化方法,如图1所示,是一个标准的曲线图,横坐标为x,纵坐标为y, 图1 标准曲线图 调整方法1 首先可以通过改变线的颜色,不同…

react + antDesign封装图片预览组件(支持多张图片)

需求场景:最近在开发后台系统时经常遇到图片预览问题,如果一个一个的引用antDesign的图片预览组件就有点繁琐了,于是在antDesign图片预览组件的基础上二次封装了一下,避免重复无用代码的出现 效果 公共预览组件代码 import React…

Python安装不再难!全平台保姆级教程带你轻松搞定!

Python介绍 Python是一种功能强大且灵活的编程语言,被广泛应用于各个领域。以下是Python在不同应用领域的一些常见用途: 网络开发 Python提供了丰富的库和框架,使其成为网络开发的理想选择。诸如Django、Flask和Pyramid等框架可以帮助开发人员…

从 HDFS 迁移到 MinIO 企业对象存储

云原生、面向 Kubernetes 、基于微服务的架构推动了对 MinIO 等网络存储的需求。在云原生环境中,对象存储的优势很多 - 它允许独立于存储硬件对计算硬件进行弹性扩展。它使应用程序无状态,因为状态是通过网络存储的,并且通过降低操作复杂性&a…

Vue使用组件需要加前缀而React使用组件库的区别

Vue 写在模版中的内容最终会被render&#xff0c;render时会区分标签与组件。 通过-短横线命名法 或 大驼峰命名法使用组件 <a-button><a-button/> <MyComponent></MyComponent>但是-短横线命名法容易引起歧义&#xff0c;比如组件名是一个单词(无法…

learn C++ NO.17——继承

什么是继承&#xff1f; 用冒号 : 后跟基类名称来声明一个类是从某个基类继承而来的。继承方式可以是 public、protected 或 private&#xff0c;这决定了基类成员在子类中的访问权限。 下面通过代码简单进行一下演示. 派生类Student即子类&#xff0c;而基类Person是它的父…

浏览器恢复历史记录应该怎么操作?简单几步轻松搞定

浏览器的历史记录是用户上网过程中产生的所有浏览活动的记录。这些历史记录对于查找之前访问过的网站、恢复误关闭的页面&#xff0c;以及跟踪浏览活动有很大的帮助。当然有时候我们可能会不小心将浏览器历史记录给删除了&#xff0c;那浏览器清除的历史记录可以恢复吗&#xf…

Linux 信号的产生

1. 概念 在Linux系统中&#xff0c;信号是一种进程间通信的机制&#xff0c;它允许操作系统或其他进程向特定进程发送异步通知。我们可以通过命令 kill -l来查看信号的种类&#xff1a; Linux系统中的信号可以分为两大类&#xff1a;传统信号和实时信号。从上图可以看出它们分…

代码随想录算法训练营第40天 动态规划part07| 题目: 198.打家劫舍 、 213.打家劫舍II 、 337.打家劫舍III

代码随想录算法训练营第40天 动态规划part07| 题目&#xff1a; 198.打家劫舍 、 213.打家劫舍II 、37.打家劫舍III 文章来源&#xff1a;代码随想录 题目名称&#xff1a;198.打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff…

【随手笔记】485

1. 基础知识 2线&#xff0c;半双工&#xff0c;多点通信 电压差传递信号 逻辑 1&#xff1a; 两线间电压差为 2V ~ 6V 逻辑0 &#xff1a; 两线间电压差为-2V ~ -6V 10米最高速率达 35Mbps 1200米 速率达100Kbps 抗共模干扰能力强 一般支持32个节点 推荐使用点对点线型 总线…

IDEA开发HelloWorld程序

IDEA管理Java程序的结构 project&#xff08;项目、工程&#xff09;---project中可以创建多个modulemodule&#xff08;模块&#xff09;---module中可以创建多个packagepackage&#xff08;包&#xff09;---package中可以创建多个classclass&#xff08;类&#xff09;---c…

木牛科技PMO总监关沨受邀为第四届中国项目经理大会演讲嘉宾

全国项目经理专业人士年度盛会 北京木牛领航科技有限公司PMO总监关沨女士受邀为PMO评论主办的全国项目经理专业人士年度盛会——2024第四届中国项目经理大会演讲嘉宾&#xff0c;演讲议题为“如何培养能打胜仗的项目经理”。大会将于10月26-27日在北京举办&#xff0c;主题为&a…

图神经网络在推荐系统中的应用综述

1 研究计划 了解推荐系统的研究背景和发展历程了解为什么推荐系统需要GNN了解基于GNN的推荐的关键挑战了解基于GNN的推荐的现有方法 2 完成情况 2.1推荐系统的研究背景和发展历程 随着各种服务和平台(如电子商务、短视频等)上信息的快速爆炸&#xff0c;推荐系统在缓解信息…

UWA支持鸿蒙HarmonyOS NEXT

华为在开发者大会上&#xff0c;宣布了鸿蒙HarmonyOS NEXT将仅支持鸿蒙内核和鸿蒙系统的应用&#xff0c;不再兼容安卓应用&#xff0c;这意味着它将构建一个全新且完全独立的生态系统。 为此&#xff0c;UWA也将在最新版的UWA SDK v2.5.0中支持鸿蒙HarmonyOS NEXT&#xff0c…

NLP三天入门大模型,我领先你好几个版本了

大模型时代下&#xff0c;nlp初学者需要怎么入门? 入门姿势简单粗暴:打一些必要的基础就跑步进入Transformera 大模型时代&#xff0c;传统的算法&#xff0c;像分词、词性标注&#xff0c;被替代得非常厉害&#xff0c;在入门阶段没必要花费太多精力在传统算法上面。 数学和…

强弱电的基本知识和区别

什么是弱电&#xff1a; 弱电一般是指直流电路或音频、视频线路、网络线路、电话线路&#xff0c;直流电压一般在36V以内。家用电器中的电话、电脑、电视机的信号输入&#xff08;有线电视线路&#xff09;、音响设备&#xff08;输出端线路&#xff09;等用电器均为弱电电气设…

IDEA Cody 插件实现原理

近年来&#xff0c;智能编程助手 在开发者日常工作中变得越来越重要。IDEA Cody 插件是 JetBrains 生态中一个重要的插件&#xff0c;它可以帮助开发者 快速生成代码、自动补全、并提供智能提示&#xff0c;从而大大提升开发效率。今天我们将深入探讨 Cody 插件的实现原理&…

Facebook隐私设置指南:如何更好地保护个人信息

在数字化时代&#xff0c;隐私保护成为了每个互联网用户面临的重要课题。Facebook&#xff0c;作为全球最大的社交网络平台之一&#xff0c;拥有庞大的用户基础和丰富的个人数据。因此&#xff0c;了解和管理Facebook的隐私设置对保护个人信息至关重要。本文将为您提供一份详细…

RTX 4090/RTX 4090D停产,为RTX 5090扫平“障碍”

原文转载修改自&#xff08;更多互联网新闻/搞机小知识&#xff09;&#xff1a; RTX 4090/4090D或于10月停产&#xff0c;为RTX 5090“登基”铺路 作为网络人均一代旗舰的RTX 4090至今也已发售近两年&#xff0c;说实在的&#xff0c;按老黄一贯的手法&#xff0c;也到了该落…