Pytorch速成教程(一)整体流程

article/2025/10/19 18:25:38

目录

0 简介

1 张量的概念和生成

2 自动微分

2.1 Tensor类

2.2 梯度

3 神经网络

 3.1 定义网络

3.2 查看模型参数

3.3 测试网络

3.4 损失函数更新权重

4 训练分类器

4.1 数据处理生成Dataload

4.2 定义卷积网络

4.3 定义损失函数

4.4 遍历DataLoader进行训练

4.5 测试

5 GPU训练


0 简介

跟numpy功能一样,但可以GPU加速,和numpy可以相互转化。

1 张量的概念和生成

张量是torch里的多维数组,和numpy中的ndarrays相似

生成张量的方法:

  • 空张量
# 这个是用来生成一个为未初始化的5*3的张量,切记不是全零
x = torch.empty(5, 3
  • 随机化0-1张量
# 这个是生成一个均匀分布的初始化的,每个元素从0~1的张量,与第一个要区别开,另外,还有其它的随机张量生成函数,如torch.randn()、torch.normal()、torch.linespace(),分别是标准正态分布,离散正态分布,线性间距向量
x = torch.rand(5, 3)
  • 全0张量
# 这个是初始化一个全零张量,可以指定每个元素的类型。
x = torch.zeros(5, 3, dtype=torch.long)
  • 已有矩阵转化为张量
x = torch.tensor([5.5, 3])
  • size函数来看它的shape
print(x.size())
  • 张量加法
print(torch.add(x, y))
  • 张量的大小
print(x.item())
  • torch转numpy

在使用Cpu的情况下,张量和array将共享他们的物理位置,改变其中一个的值,另一个也会随之变化。

a = torch.ones(5)
b = a.numpy()
  • numpy转torch
a = np.ones(5)
b = torch.from_numpy(a)
  • GPU下转化
if torch.cuda.is_available():device = torch.device("cuda")          # a CUDA device objecty = torch.ones_like(x, device=device)  # directly create a tensor on GPUx = x.to(device)                       # or just use strings ``.to("cuda")``z = x + y

2 自动微分

在pytorch中,神经网络的核心是自动微分

2.1 Tensor类

orch.Tensor 是这个包的核心类。如果它的属性requires_grad是True,那么PyTorch就会追踪所有与之相关的operation。当完成(正向)计算之后, 我们可以调用backward(),PyTorch会自动的把所有的梯度都计算好。与这个tensor相关的梯度都会累加到它的grad属性里。

如果不想计算这个tensor的梯度,我们可以调用detach(),这样它就不会参与梯度的计算了。为了阻止PyTorch记录用于梯度计算相关的信息(从而节约内存),我们可以使用 with torch.no_grad()。这在模型的预测时非常有用,因为预测的时候我们不需要计算梯度,否则我们就得一个个的修改Tensor的requires_grad属性,这会非常麻烦。

关于autograd的实现还有一个很重要的Function类。Tensor和Function相互连接从而形成一个有向无环图, 这个图记录了计算的完整历史。每个tensor有一个grad_fn属性来引用创建这个tensor的Function(用户直接创建的Tensor,这些Tensor的grad_fn是None)。

如果你想计算梯度,可以对一个Tensor调用它的backward()方法。如果这个Tensor是一个scalar(只有一个数),那么调用时不需要传任何参数。如果Tensor多于一个数,那么需要传入和它的shape一样的参数,表示反向传播过来的梯度。

创建tensor时设置属性requires_grad=True,PyTorch就会记录用于反向梯度计算的信息:

    x = torch.ones(2, 2, requires_grad=True)print(x)

然后我们通过operation产生新的tensor:

y = x + 2
print(y)

是通过operation产生的tensor,因此它的grad_fn不是None。

    print(y.grad_fn)# <AddBackward0 object at 0x7f35409a68d0>

再通过y得到z和out 

    z = y * y * 3out = z.mean()print(z, out)# z = tensor([[ 27.,  27.],[ 27.,  27.]]) # out = tensor(27.)

requires_grad_()函数会修改一个Tensor的requires_grad。

a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)
输出:FalseTrue<SumBackward0 object at 0x7f35766827f0>

2.2 梯度

现在我们里反向计算梯度。因为out是一个scalar,因此out.backward()等价于out.backward(torch.tensor(1))。

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)print(x.grad) #数量的梯度,即各个方向的导数的集合
"""
tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])
"""
#停止计算微分
print(x.requires_grad)
print((x ** 2).requires_grad)with torch.no_grad():print((x ** 2).requires_grad)
"""
True
True
False
"""

3 神经网络

神经网络定义过程

  • 定义神经网络及其参数;
  • 在数据集上多次迭代循环;
  • 通过神经网络处理数据集;
  • 计算损失(输出和正确的结果之间相差的距离);
  • 用梯度对参数反向影响;
  • 更新神经网络的权重,weight = weight - rate * gradient;

 3.1 定义网络

import torch
import torch.nn as nn
import torch.nn.functional as F# 汉字均为我个人理解,英文为原文标注。
class Net(nn.Module):#1、初始化定义  def __init__(self):# 继承原有模型super(Net, self).__init__()# 1 input image channel, 6 output channels, 5x5 square convolution# kernel# 定义了两个卷积层# 第一层是输入1维的(说明是单通道,灰色的图片)图片,输出6维的的卷积层(说明用到了6个卷积核,而每个卷积核是5*5的)。self.conv1 = nn.Conv2d(1, 6, 5)# 第一层是输入1维的(说明是单通道,灰色的图片)图片,输出6维的的卷积层(说明用到了6个卷积核,而每个卷积核是5*5的)。self.conv2 = nn.Conv2d(6, 16, 5)# an affine operation: y = Wx + b# 定义了三个全连接层,即fc1与conv2相连,将16张5*5的卷积网络一维化,并输出120个节点。self.fc1 = nn.Linear(16 * 5 * 5, 120)# 将120个节点转化为84个。self.fc2 = nn.Linear(120, 84)# 将84个节点输出为10个,即有10个分类结果。self.fc3 = nn.Linear(84, 10)#2、搭建网络   我们只需要定义forward函数,而backward函数会自动通过autograd创建。def forward(self, x):# Max pooling over a (2, 2) window# 用relu激活函数作为一个池化层,池化的窗口大小是2*2,这个也与上文的16*5*5的计算结果相符(一开始我没弄懂为什么fc1的输入点数是16*5*5,后来发现,这个例子是建立在lenet5上的)。# 这句整体的意思是,先用conv1卷积,然后激活,激活的窗口是2*2。x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))# If the size is a square you can only specify a single number# 作用同上,然后有个需要注意的地方是在窗口是正方形的时候,2的写法等同于(2,2)。# 这句整体的意思是,先用conv2卷积,然后激活,激活的窗口是2*2。x = F.max_pool2d(F.relu(self.conv2(x)), 2)# 实际上view()类似于reshape()的用法,将张量重新规划格式 -1代表待定x = x.view(-1, self.num_flat_features(x)) #一维化# 用一下全连接层fc1,然后做一个激活。x = F.relu(self.fc1(x))# 用一下全连接层fc2,然后做一个激活。x = F.relu(self.fc2(x))# 用一下全连接层fc3。x = self.fc3(x)return xdef num_flat_features(self, x):# 承接上文的引用,这里需要注意的是,由于pytorch只接受图片集的输入方式(原文的单词是batch),所以第一个代表个数的维度被忽略。size = x.size()[1:]  # all dimensions except the batch dimensionnum_features = 1for s in size:num_features *= sreturn num_featuresnet = Net()
print(net)"""
Net((conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))(fc1): Linear(in_features=400, out_features=120, bias=True)(fc2): Linear(in_features=120, out_features=84, bias=True)(fc3): Linear(in_features=84, out_features=10, bias=True)
)
"""

3.2 查看模型参数

# 现在我们已经构建好模型了,但是还没有开始用bp呢,如果你对前面的内容有一些印象的话,你就会想起来不需要我们自己去搭建,我们只需要用某一个属性就可以了,autograd。# 现在我们需要来看一看我们的模型,下列语句可以帮助你看一下这个模型的一些具体情况。params = list(net.parameters())
print(len(params))
print(params[0].size())  # conv1's .weight"""
10
torch.Size([6, 1, 5, 5])
"""

3.3 测试网络

input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)
# tensor([[-0.0198,  0.0438,  0.0930, -0.0267, -0.0344,  0.0330,  0.0664,
0.1244, -0.0379,  0.0890]])#默认的梯度会累加,因此我们通常在backward之前清除掉之前的梯度值:
net.zero_grad()
out.backward(torch.randn(1, 10))

3.4 损失函数更新权重

1、计算损失
# 这一部分是来搞定损失函数
output = net(input)
target = torch.randn(10)  # a dummy target, for example
target = target.view(1, -1)  # make it the same shape as output
criterion = nn.MSELoss()
loss = criterion(output, target)
print(loss)2、查看结果
print(loss.grad_fn)  # MSELoss
print(loss.grad_fn.next_functions[0][0])  # Linear
print(loss.grad_fn.next_functions[0][0].next_functions[0][0])  # ReLU3、计算梯度
#在调用loss.backward()之前,我们需要清除掉tensor里之前的梯度,否则会累加进去。
net.zero_grad() 
loss.backward()4、更新权重 (梯度下降)
learning_rate = 0.01
for f in net.parameters():f.data.sub_(f.grad.data * learning_rate)
  • 使用优化包即使用optimizer,我们也需要清零梯度。但是我们不需要一个个的清除,而是用optimizer.zero_grad()一次清除所有。
import torch.optim as optim# 创建optimizer,需要传入参数和learning rate
optimizer = optim.SGD(net.parameters(), lr=0.01)# 清除梯度
optimizer.zero_grad()  
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # optimizer会自动帮我们更新参数

4 训练分类器

4.1 数据处理生成Dataload

特别是对于视觉领域,我们写了一个叫做torchvision的包,他可以将很多知名数据的数据即涵盖在内。并且,通过torchvision.datasets 和 torch.utils.data.DataLoader 进行数据的转化。在本里中我们将会使用 CIFAR10 数据集,它有以下各类: ‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’。在这个数据集中的图像尺寸都是33232的。

import torch
import torchvision
import torchvision.transforms as transforms#数据归一化
transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
#训练集
trainset = torchvision.datasets.CIFAR10(root='/path/to/data', train=True,download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,shuffle=True, num_workers=2)
#测试集
testset = torchvision.datasets.CIFAR10(root='/path/to/data', train=False,download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,shuffle=False, num_workers=2)
# 标签
classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')

4.2 定义卷积网络

import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(3, 6, 5)self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, 5)self.fc1 = nn.Linear(16 * 5 * 5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):x = self.pool(F.relu(self.conv1(x)))x = self.pool(F.relu(self.conv2(x)))x = x.view(-1, 16 * 5 * 5)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return x
net = Net()

4.3 定义损失函数

import torch.optim as optim
#这里使用交叉熵损失函数,Optimizer使用带冲量的SGD。     
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

4.4 遍历DataLoader进行训练

for epoch in range(2):  # 这里只迭代2个epoch,实际应该进行更多次训练 running_loss = 0.0#enumerate将其组成一个索引序列,利用它可以同时获得索引和值for i, data in enumerate(trainloader, 0):# 得到输入inputs, labels = data# 梯度清零 optimizer.zero_grad()# forward + backward + optimizeoutputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# 定义统计信息running_loss += loss.item()if i % 2000 == 1999:print('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 2000))running_loss = 0.0print('Finished Training')

4.5 测试

  • 取样测试
#next() 返回迭代器的下一个项目。
#next() 函数要和生成迭代器的iter() 函数一起使用。# 1 选取图片
dataiter = iter(testloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))
# 2 预测结果
outputs = net(images)
_, predicted = torch.max(outputs, 1)
print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]for j in range(4)))
  • 测试集一类测试
correct = 0
total = 0
with torch.no_grad():
for data in testloader:images, labels = dataoutputs = net(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))
  • 每类的测试
class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():for data in testloader:images, labels = dataoutputs = net(images)_, predicted = torch.max(outputs, 1)c = (predicted == labels).squeeze()for i in range(4):label = labels[i]class_correct[label] += c[i].item()class_total[label] += 1for i in range(10):print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))Accuracy of plane : 52 %
Accuracy of   car : 66 %
Accuracy of  bird : 49 %
Accuracy of   cat : 34 %
Accuracy of  deer : 30 %
Accuracy of   dog : 45 %
Accuracy of  frog : 72 %
Accuracy of horse : 71 %
Accuracy of  ship : 76 %
Accuracy of truck : 55 %

5 GPU训练

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
# cuda:0
class Net2(nn.Module):
def __init__(self):
super(Net2, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5).to(device)
self.pool = nn.MaxPool2d(2, 2).to(device)
self.conv2 = nn.Conv2d(6, 16, 5).to(device)
self.fc1 = nn.Linear(16 * 5 * 5, 120).to(device)
self.fc2 = nn.Linear(120, 84).to(device)
self.fc3 = nn.Linear(84, 10).to(device)def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return xnet = Net2()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)for epoch in range(20):running_loss = 0.0for i, data in enumerate(trainloader, 0):# 得到输入inputs, labels = data inputs, labels = inputs.to(device), labels.to(device) # 梯度清零 optimizer.zero_grad()# forward + backward + optimizeoutputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# 定义统计信息running_loss += loss.item()if i % 2000 == 1999:print('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 2000))running_loss = 0.0print('Finished Training')


http://chatgpt.dhexx.cn/article/pfsgJiSC.shtml

相关文章

PyTorch详细教程

一、参考资料 PyTorch中文文档 PyTorch官方文档 PyTorch官方源码&#xff1a;GitHub - pytorch/pytorch: Tensors and Dynamic neural networks in Python with strong GPU acceleration PyTorch 中文教程 & 文档 二、分布式训练 pytorch set_epoch()方法 在分布式模…

PyTorch深度学习快速入门教程(绝对通俗易懂!!!)

文章目录 一、PyTorch环境的配置及安装二、Pycharm、jupyter的安装1. Pycharm2.jupyter 三、Python学习中的两大法宝函数&#xff08;help、dir&#xff09;四、加载数据&#xff08;Dataset&#xff09;五、TensorBorad的使用六、Transformer1.compose2.toTensor3.Normalize4.…

Python安装Pytorch教程(图文详解)

最近人工智能等多门课需要复现论文&#xff0c;近两年的论文很多都是基于Pytorch环境做的实验&#xff0c;所以&#xff0c;这里总结一下Pytorch的安装教程&#xff0c;做好最快、最简单、最好地完成安装。 本机环境Win101050TiPython3.7 1、查看本机的CUDA版本 cmd命令行输…

Pytorch入门教程

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;大数据专业硕士在读&#xff0c;CSDN人工智能领域博客专家&#xff0c;阿里云专家博主&#xff0c;专注大数据与人工智能知识分享&#xff0c;公众号&#xff1a;GoAI的学习小屋&#xff0c;免费分享书籍、简历、导图等资料&a…

【Pytorch】2022 Pytorch基础入门教程(完整详细版)

一、Pytorch 1.1 简介 Pytorch是torch的python版本&#xff0c;是由Facebook开源的神经网络框架&#xff0c;专门针对 GPU 加速的深度神经网络&#xff08;DNN&#xff09;编程。Torch 是一个经典的对多维矩阵数据进行操作的张量&#xff08;tensor &#xff09;库&#xff0…

MacOS Ventura 13.4 (22F66) 带 OC 引导双分区黑苹果镜像

苹果今日向 Mac 电脑用户推送了 macOS 13.4 更新&#xff08;内部版本号&#xff1a;22F66&#xff09;&#xff0c;本次更新距离上次发布隔了 41 天&#xff0c;主要解决了与Apple Watch自动解锁、蓝牙键盘、屏幕使用时间和VoiceOver相关的问题&#xff0c;推荐大家安装升级。…

装完黑苹果怎么装windows_苹果都说双系统好 黑苹果装windows教程

【IT168 应用】苹果官网上有段广告词——“妈妈总是说&#xff1a;“要和别人好好相处啊。”你的电脑也要这样。借助 OS X&#xff0c;你可以使用 Microsoft Office、与大多数打印机和摄像机相连、加入 PC 网络、甚至还可以运行 Windows。”。 可见苹果也将支持安装windows系统…

打造黑苹果(二)制作黑mac系统安装U盘

打造黑苹果&#xff08;二&#xff09;制作黑mac系统安装U盘 前言 在上一篇打造黑苹果&#xff08;一&#xff09;组装硬件的选择与组装 中&#xff0c;我们已经给大家在硬件上有了一个建议。如果你已经购买了硬件了&#xff0c;或者你原来的硬件就已经满足了黑MAC的需求&…

MacOS Ventura 13.4.1 (22F82) 带 OC 引导双分区黑苹果镜像

苹果今日向 Mac 电脑用户推送了 macOS 13.4.1 更新&#xff08;内部版本号&#xff1a;22F82&#xff09;&#xff0c;根据Apple的发布说明&#xff0c;该更新提供了重要的安全修复&#xff0c;并建议所有用户进行更新。Apple还为无法运行Ventura的用户发布了macOS 11.7.8和mac…

小新Pro13成功安装黑苹果超详细教程,小白也会安装双系统!

前言 最近买了台小新pro13&#xff08;i5版本&#xff09;&#xff0c;发现可以安装黑苹果&#xff0c;于是请教了很多大神&#xff0c;折腾了两天成功装上了黑苹果。 由于有人指导所以没走多少弯路&#xff0c;在这里感谢指导我安装的大神。因此&#xff0c;我决定把过程步骤…

可能是最详细的Win10+黑苹果双系统安装教程(For Dell 7580)

目录 1 前期准备1.1 工具和软件1.2 硬盘分区1.3 制作黑苹果安装U盘 2 正式安装2.1 黑苹果系统安装2.2 转移CLOVER文件2.3 添加CLOVER启动项 3 故障排查3.1 扬声器问题3.2 重启直接进win103.3 不显示U盘启动项3.4 应用程序副本已损坏3.5 黑苹果和Win10系统时间不一致 4 恢复Win1…

win10+黑苹果双系统教程教程

很多时候用macos系统都需要买苹果的笔记本&#xff0c;但我们可以模仿苹果的efi输入mac系统就可以完美运行了 首先我们需要知道我们的电脑能不能装黑苹果 最简单的方法就是去淘宝问一下&#xff0c;他说能装&#xff0c;就肯定可以干&#xff0c;然后去找对应的efi&#xff0…

黑苹果双系统安装教程macOS High Sierra 10.13.x

摘 要&#xff1a;今天小编给大家准备了一份最新的黑苹果10.13u盘安装黑苹果双系统安装教程&#xff0c;所有的黑苹果安装教程基本上都差不多&#xff0c;但是还有很多童鞋通过QQ联系我&#xff0c;问我如何安装黑苹...教程前言今天小编给大家准备了一份最新的黑苹果10.13u盘安…

win10+黑苹果 单硬盘 双系统 超简单安装 一看就会

注意&#xff1a;此教程全机型通用 &#xff0c;只需要替换相关的efi文件即可。安装黑苹果的教程已经很多了&#xff0c;本人学的皮毛只适合跟我配置差不多的笔记本电脑&#xff0c;比如神州系列啥的。如果本文出现任何问题请及时指正&#xff0c;谢谢。 电脑型号 Notebook …

电脑win10黑苹果双系统

装黑苹果系统无可避免地要用到U盘&#xff0c;这里楼主安利一个不用U盘就可以安装黑苹果的方法 首先&#xff0c;一个电脑如果只有一个磁盘还要安装双系统&#xff0c;就要用到磁盘分区工具。这里我们用到的是diskgenius。 如果你的硬盘是512g的&#xff0c;这里建议你分一个1…

win10笔记本电脑双系统 安装黑苹果系统macOS 小白黑苹果乐园下载资源简便安装黑苹果方式,非常详细,还有资源!

马上就要考研咯&#xff0c;今天还是作死研究安装了下黑苹果&#xff0c;罪恶感啊 言归正传&#xff0c;接下来将献上我的黑苹果教程 首先呢第一步下载你所需要的macOS系统&#xff0c;地址如下 https://imac.hk/category/macos/ 这里也有我的几个保存在百度网盘里的黑苹…

win10+黑苹果 单硬盘的双系统引导配置

搜了多篇win10黑苹果双系统&#xff0c;按照步骤进行安装过程发现引导分区会误导&#xff0c;导致多分了一个引导分区&#xff0c;基本第一步就是直接让分200M左右的FAT32的分区作为引导分区。 首先需要知道的是引导分区的作用是什么&#xff1f;请看度娘的解释https://baike.b…

安装win10+黑苹果双系统零基础教程

经常有人留言或者私信我 我这边不能及时回复 一、准备工作 准备8g以上的U盘 安装TransMac 安装Hasleo EasyUEFI 安装DiskGenius 系统镜像,格式注意是.dmg,我示范的版本为mac 10.13.3 目前最新版镜像已经是10.15.4的版本了 镜像链接迅雷资源https://mirrors.d…

【电脑配置】开发人员必备,黑苹果双系统安装教程

首先把我自己的电脑配置贴出来供大家参考&#xff1a; CPU&#xff1a;Intel i7-8086k 主板&#xff1a;技嘉Z370 AORUS ULTRA GAMING WIFI 内存&#xff1a;海盗船 铂金统治者 3000C15 白光 8G*2 套条 改为酷兽DDR4 3200 8G*4&#xff0c;海力士颗粒。 显卡&#xff1a;镭…

最新最简单的黑苹果Mac Windows双系统教程(单双系统通用)

最新最简单的黑苹果Mac Windows双系统教程&#xff08;单双系统通用&#xff09; 关于抹盘“MediaKit报告设备上的空间不足以执行请求的操作”报错的处理关于双系统加引导 黑苹果Mac Windows双系统教程&#xff08;单双系统通用&#xff09; B站视频链接 如何自己配EFI教程 个人…