-
自动驾驶系统。在行驶过程中,车辆需要实时地根据道路状况、交通信号、其他车辆的位置和速度等信息做出决策,以确保安全行驶。传统的基于规则或机器学习的方法往往难以处理如此复杂和实时性的决策问题。强化学习有可能为自动驾驶系统提供更有效的解决方案。
-
信用卡欺诈检测系统。在训练数据中,非欺诈交易的数量远远大于欺诈交易的数量。如果系统仅仅使用数量作为分类依据,它可能会将所有交易都归类为非欺诈交易,因为它更容易被正确分类。然而,这样的模型对于银行来说并没有太大的用处。因此,我们需要找到一种方法来处理不平衡数据集对分类算法的影响
-
在许多应用场景中,我们需要人工智能系统能够提供更详细的解释和透明的决策过程,以便用户可以理解并信任系统的输出结果。然而,目前的技术往往难以实现这一点。有什么好的建议和经验可以分享吗?
-
中奖结果公示感谢各位小伙伴参与本次活动,本次活动获奖名单如下:请各位获奖的伙伴在10月23日之前点击此处填写收货地址,如逾期未填写视为弃奖。再次感谢各位小伙伴参与本次活动,欢迎关注华为云DTSE Tech Talk 技术直播更多活动~直播简介【直播主题】华为云数字人赋能千行百业,共享AIGC新机遇【直播时间】2023年10月18日 16:30-18:00【直播专家】左雯 华为云媒体DTSE技术布道师【直播简介】数字人作为元宇宙中真人沉浸式体验的重要入口和AIGC的关键要素,伴随元宇宙和AIGC双轮产业进步,关注本期直播,告诉你数字人将如何带来千行百业的产业变革?直播链接:cid:link_1活动介绍【互动方式】直播前您可以在本帖留下您疑惑的问题,专家会在直播时为您解答。直播后您可以继续在本帖留言,与专家互动交流。我们会在全部活动结束后对参与互动的用户进行评选。【活动时间】即日起—2023年10月19日【奖励说明】评奖规则:活动1:直播期间在直播间提出与直播内容相关的问题,对专家评选为优质问题的开发者进行奖励。奖品:华为云定制U型按摩枕活动2:在本帖提出与直播内容相关的问题,由专家在所有互动贴中选出最优问题贴的开发者进行奖励。奖品:华为云定制POLO衫更多直播活动直播互动有礼:官网直播间发口令“华为云 DTSE”抽华为云定制短袖T恤、填写问卷抽华为云定制保温杯等好礼分享问卷有礼 :邀请5位朋友以上完成问卷即可获得华为云定制棒球帽。老观众专属福利:连续报名并观看DTT直播3期以上抽送华为云DTT定制T恤。【注意事项】1、所有参与活动的问题,如发现为复用他人内容,则取消获奖资格。2、为保证您顺利领取活动奖品,请您在活动公示奖项后2个工作日内私信提前填写奖品收货信息,如您没有填写,视为自动放弃奖励。3、活动奖项公示时间截止2023年10月20日,如未反馈邮寄信息视为弃奖。本次活动奖品将于奖项公示后30个工作日内统一发出,请您耐心等待。4、活动期间同类子活动每个ID(同一姓名/电话/收货地址)只能获奖一次,若重复则中奖资格顺延至下一位合格开发者,仅一次顺延。5、如活动奖品出现没有库存的情况,华为云工作人员将会替换等价值的奖品,获奖者不同意此规则视为放弃奖品。6、其他事宜请参考【华为云社区常规活动规则】。
-
一、PyTorch批训练1. 概述PyTorch提供了一种将数据包装起来进行批训练的工具——DataLoader。使用的时候,只需要将我们的数据首先转换为torch的tensor形式,再转换成torch可以识别的Dataset格式,然后将Dataset放入DataLoader中就可以啦。import torchimport torch.utils.data as Data torch.manual_seed(1) # 设定随机数种子 BATCH_SIZE = 5 x = torch.linspace(1, 10, 10)y = torch.linspace(0.5, 5, 10) # 将数据转换为torch的dataset格式torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y) # 将torch_dataset置入Dataloader中loader = Data.DataLoader( dataset=torch_dataset, batch_size=BATCH_SIZE, # 批大小 # 若dataset中的样本数不能被batch_size整除的话,最后剩余多少就使用多少 shuffle=True, # 是否随机打乱顺序 num_workers=2, # 多线程读取数据的线程数 ) for epoch in range(3): for step, (batch_x, batch_y) in enumerate(loader): print('Epoch:', epoch, '|Step:', step, '|batch_x:', batch_x.numpy(), '|batch_y', batch_y.numpy())'''''shuffle=TrueEpoch: 0 |Step: 0 |batch_x: [ 6. 7. 2. 3. 1.] |batch_y [ 3. 3.5 1. 1.5 0.5]Epoch: 0 |Step: 1 |batch_x: [ 9. 10. 4. 8. 5.] |batch_y [ 4.5 5. 2. 4. 2.5]Epoch: 1 |Step: 0 |batch_x: [ 3. 4. 2. 9. 10.] |batch_y [ 1.5 2. 1. 4.5 5. ]Epoch: 1 |Step: 1 |batch_x: [ 1. 7. 8. 5. 6.] |batch_y [ 0.5 3.5 4. 2.5 3. ]Epoch: 2 |Step: 0 |batch_x: [ 3. 9. 2. 6. 7.] |batch_y [ 1.5 4.5 1. 3. 3.5]Epoch: 2 |Step: 1 |batch_x: [ 10. 4. 8. 1. 5.] |batch_y [ 5. 2. 4. 0.5 2.5] shuffle=FalseEpoch: 0 |Step: 0 |batch_x: [ 1. 2. 3. 4. 5.] |batch_y [ 0.5 1. 1.5 2. 2.5]Epoch: 0 |Step: 1 |batch_x: [ 6. 7. 8. 9. 10.] |batch_y [ 3. 3.5 4. 4.5 5. ]Epoch: 1 |Step: 0 |batch_x: [ 1. 2. 3. 4. 5.] |batch_y [ 0.5 1. 1.5 2. 2.5]Epoch: 1 |Step: 1 |batch_x: [ 6. 7. 8. 9. 10.] |batch_y [ 3. 3.5 4. 4.5 5. ]Epoch: 2 |Step: 0 |batch_x: [ 1. 2. 3. 4. 5.] |batch_y [ 0.5 1. 1.5 2. 2.5]Epoch: 2 |Step: 1 |batch_x: [ 6. 7. 8. 9. 10.] |batch_y [ 3. 3.5 4. 4.5 5. ]'''2. TensorDatasetclasstorch.utils.data.TensorDataset(data_tensor, target_tensor)TensorDataset类用来将样本及其标签打包成torch的Dataset,data_tensor,和target_tensor都是tensor 3. DataLoader复制代码 代码如下:classtorch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,num_workers=0, collate_fn=<function default_collate>, pin_memory=False,drop_last=False)dataset就是Torch的Dataset格式的对象;batch_size即每批训练的样本数量,默认为;shuffle表示是否需要随机取样本;num_workers表示读取样本的线程数。二、PyTorch的Optimizer优化器本实验中,首先构造一组数据集,转换格式并置于DataLoader中,备用。定义一个固定结构的默认神经网络,然后为每个优化器构建一个神经网络,每个神经网络的区别仅仅是优化器不同。通过记录训练过程中的loss值,最后在图像上呈现得到各个优化器的优化过程。代码实现:import torchimport torch.utils.data as Dataimport torch.nn.functional as Ffrom torch.autograd import Variableimport matplotlib.pyplot as plttorch.manual_seed(1) # 设定随机数种子 # 定义超参数LR = 0.01 # 学习率BATCH_SIZE = 32 # 批大小EPOCH = 12 # 迭代次数 x = torch.unsqueeze(torch.linspace(-1, 1, 1000), dim=1)y = x.pow(2) + 0.1*torch.normal(torch.zeros(*x.size())) #plt.scatter(x.numpy(), y.numpy())#plt.show() # 将数据转换为torch的dataset格式torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)# 将torch_dataset置入Dataloader中loader = Data.DataLoader(dataset=torch_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=2) class Net(torch.nn.Module): def __init__(self): super(Net, self).__init__() self.hidden = torch.nn.Linear(1, 20) self.predict = torch.nn.Linear(20, 1) def forward(self, x): x = F.relu(self.hidden(x)) x = self.predict(x) return x # 为每个优化器创建一个Netnet_SGD = Net()net_Momentum = Net()net_RMSprop = Net()net_Adam = Net() nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam] # 初始化优化器opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99)) optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam] # 定义损失函数loss_function = torch.nn.MSELoss()losses_history = [[], [], [], []] # 记录training时不同神经网络的loss值 for epoch in range(EPOCH): print('Epoch:', epoch + 1, 'Training...') for step, (batch_x, batch_y) in enumerate(loader): b_x = Variable(batch_x) b_y = Variable(batch_y) for net, opt, l_his in zip(nets, optimizers, losses_history): output = net(b_x) loss = loss_function(output, b_y) opt.zero_grad() loss.backward() opt.step() l_his.append(loss.data[0]) labels = ['SGD', 'Momentum', 'RMSprop', 'Adam'] for i, l_his in enumerate(losses_history): plt.plot(l_his, label=labels[i])plt.legend(loc='best')plt.xlabel('Steps')plt.ylabel('Loss')plt.ylim((0, 0.2))plt.show()实验结果:由实验结果可见,SGD的优化效果是最差的,速度很慢;作为SGD的改良版本,Momentum表现就好许多;相比RMSprop和Adam的优化速度就非常好。实验中,针对不同的优化问题,比较各个优化器的效果再来决定使用哪个。三、其他补充1. Python的zip函数zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表。x = [1, 2, 3]y = [4, 5, 6]z = [7, 8, 9]xyz = zip(x, y, z)print xyz[(1, 4, 7), (2, 5, 8), (3, 6, 9)] x = [1, 2, 3]x = zip(x)print x[(1,), (2,), (3,)] x = [1, 2, 3]y = [4, 5, 6, 7]xy = zip(x, y)print xy[(1, 4), (2, 5), (3, 6)]torch.optim.SGD(params, lr=<object object>, momentum=0, dampening=0, weight_decay=0, nesterov=False)1 实现随机梯度下降算法( momentum 可选) Args: params(iterable): 待优化的迭代参数或者是定义了参数组的 dict eg: model.parameters() lr (float): 学习率 dampening(float, optional): 动量的抑制因子 (默认值: 0) weight_decay(float, optional): 权重衰减 (L2 正则化) (默认值: 0) nesterov (bool, optional): 使用 Nesterov 动量 (默认值: False)torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)实现 RMSprop 算法. Args: alpha(float, optional): 平滑常量 (default: 0.99) eps(float, optional): 为了增加数值计算的稳定性而加到分母里的项 (默认值: 1e-8) centered (bool, optional) : 如果为 True, 计算 RMSProp 的中值, 并且用它的方差预测值对梯度进行归一化torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)实现 Adamax 算法 ( Adam 的一种基于无穷范数的变种). Args: betas (Tuple[float, float], optional): 用来计算梯度和平方梯度的系数 参考链接:cid:link_0 cid:link_1
-
1.介绍之前的都是使用直接训练虽然它有它自己的优点但分批次训练也是一种重要的方法直接训练(full training)是指每次更新模型参数时,使用数据集中的所有样本,称为一个周期(epoch)。直接训练的优点是可以充分利用数据信息,更容易收敛到全局最优。直接训练的缺点是需要更多的内存空间,训练速度较慢,容易过拟合。分批次训练(batch training)是指每次更新模型参数时,只使用数据集中的一部分样本,称为一个批次(batch)。分批次训练的优点是可以减少内存消耗,加快训练速度,增加随机性,有利于模型的泛化。分批次训练的缺点是可能陷入局部最优,需要调整批次大小和学习率等超参数。2.实操使用的数据集依然是8个特征的糖尿病预测二分问题数据集的获取,见我之前文章(45条消息) pytorch-- 多维特征处理_小户爱的博客-CSDN博客首先是基础版本import torchimport torch.nn as nnimport numpy as npfrom torch.utils.data import Datasetfrom torch.utils.data import DataLoaderimport matplotlib.pyplot as pltclass DiabetesDataset(Dataset): def __init__(self, filepath): xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32, skiprows=1) self.len = xy.shape[0] self.x_data = torch.from_numpy(xy[:, :-1]) self.y_data = torch.from_numpy(xy[:, [-1]]) self.mean = torch.mean(self.x_data, dim=0) # 计算数据的均值 self.std = torch.std(self.x_data, dim=0) # 计算数据的标准差 def __getitem__(self, index): x = self.x_data[index] x = (x - self.mean) / self.std # 对数据进行归一化和标准化 y = self.y_data[index] return x, y def __len__(self): return self.lendataset = DiabetesDataset('diabetes.csv')train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2)class Model(nn.Module): def __init__(self): super(Model, self).__init__() self.linear1 = nn.Linear(8, 6) self.linear2 = nn.Linear(6, 4) self.linear3 = nn.Linear(4, 1) self.sigmoid = nn.Sigmoid() def forward(self, x): x = self.sigmoid(self.linear1(x)) x = self.sigmoid(self.linear2(x)) x = self.sigmoid(self.linear3(x)) return xmodel = Model()criterion = nn.BCELoss(reduction='mean')optimizer = torch.optim.SGD(model.parameters(), lr=0.01)epoch_list = []loss_list = []if __name__ == '__main__': for epoch in range(100): epoch_list.append(epoch) sum = 0 for i, data in enumerate(train_loader, 0): inputs, labels = data y_pred = model(inputs) loss = criterion(y_pred, labels) sum += loss.item() print(epoch, i, loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() loss_list.append(sum/24) plt.plot(epoch_list, loss_list, ls='-.', c='blue', label='DiabetesDataset') plt.xlabel('epoch') plt.ylabel('loss') plt.show()几点说明:a. class DiabetesDataset(Dataset):数据集的引入 因为要分批次所以要写几个魔法函数b.def __getitem__(self, index): x = self.x_data[index] y = self.y_data[index] return x, ydef __len__(self): return self.len他们两个是为了dataset = DiabetesDataset('diabetes.csv')train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2)这里面 dataset=dataset 就会自动调用def __getitem__(self, index): 来获取数据同时调用def __len__(self):来获取长度 从而正确的进行 分组batch_size=32 这个是分的批次大小 ,我这里选择每批次32,shuffle=True 是否随机打乱 num_workers=2 表示加载时使用多少个子进程这个根据自己的配置自行选择b. if __name__ == '__main__':这个是windows 系统要写上的不写会报错好奇为什么自己查吧c.for epoch in range(100): for i, data in enumerate(train_loader, 0): inputs, lables = data y_pred = model(inputs) loss = criterion(y_pred, lables) print(epoch, i, loss.item()) optimizer.zero_grad() loss.backward() optimizer.step()第一层循环每次运行到 for i, data in enumerate(train_loader, 0): 这里时由于之前选择了shuffle=True 因此会打乱索引充分批次 具体的批次分发如下:比如我们有12组数据 每批有2个 每32一个batchinputs, lables = data 这里的data 就是分批后一组的 x,y 的元组3. 最基本的优化:之前那种我们会发现运行的速度反而会较之前慢一些 因为还进行了分批次等操作 同时也没有特别好的运用 GPU并行能力,数据也不是很客观 可以尝试使用self.relu = nn.ReLU() # 使用ReLU激活函数,增加非线性self.dropout = nn.Dropout(0.2) # 使用Dropout层,防止过拟合self.batchnorm = nn.BatchNorm1d(6) # 使用BatchNorm层,加速收敛
-
导读一个step by step的指南,非常的实用。不要让你的神经网络变成这样让我们面对现实吧,你的模型可能还停留在石器时代。我敢打赌你仍然使用32位精度或GASP甚至只在一个GPU上训练。我明白,网上都是各种神经网络加速指南,但是一个checklist都没有(现在有了),使用这个清单,一步一步确保你能榨干你模型的所有性能。本指南从最简单的结构到最复杂的改动都有,可以使你的网络得到最大的好处。我会给你展示示例Pytorch代码以及可以在Pytorch- lightning Trainer中使用的相关flags,这样你可以不用自己编写这些代码!**这本指南是为谁准备的?**任何使用Pytorch进行深度学*模型研究的人,如研究人员、博士生、学者等,我们在这里谈论的模型可能需要你花费几天的训练,甚至是几周或几个月。我们会讲到:使用DataLoadersDataLoader中的workers数量Batch size梯度累计保留的计算图移动到单个16-bit 混合精度训练移动到多个GPUs中(模型复制)移动到多个GPU-nodes中 (8+GPUs)思考模型加速的技巧Pytorch-Lightning你可以在Pytorch的库Pytorch- lightning中找到我在这里讨论的每一个优化。Lightning是在Pytorch之上的一个封装,它可以自动训练,同时让研究人员完全控制关键的模型组件。Lightning 使用最新的最佳实践,并将你可能出错的地方最小化。我们为MNIST定义LightningModel并使用Trainer来训练模型。from pytorch_lightning import Trainermodel = LightningModule(…)trainer = Trainer()trainer.fit(model)1. DataLoaders这可能是最容易获得速度增益的地方。保存h5py或numpy文件以加速数据加载的时代已经一去不复返了,使用Pytorch dataloader加载图像数据很简单(对于NLP数据,请查看TorchText)。在lightning中,你不需要指定训练循环,只需要定义dataLoaders和Trainer就会在需要的时候调用它们。dataset = MNIST(root=self.hparams.data_root, train=train, download=True)loader = DataLoader(dataset, batch_size=32, shuffle=True)for batch in loader: x, y = batch model.training_step(x, y) ...2. DataLoaders 中的 workers 的数量另一个加速的神奇之处是允许批量并行加载。因此,您可以一次装载nb_workers个batch,而不是一次装载一个batch。# slowloader = DataLoader(dataset, batch_size=32, shuffle=True)# fast (use 10 workers)loader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=10)3. Batch size在开始下一个优化步骤之前,将batch size增大到CPU-RAM或GPU-RAM所允许的最大范围。下一节将重点介绍如何帮助减少内存占用,以便你可以继续增加batch size。记住,你可能需要再次更新你的学x率。一个好的经验法则是,如果batch size加倍,那么学x率就加倍。4. 梯度累加在你已经达到计算资源上限的情况下,你的batch size仍然太小(比如8),然后我们需要模拟一个更大的batch size来进行梯度下降,以提供一个良好的估计。假设我们想要达到128的batch size大小。我们需要以batch size为8执行16个前向传播和向后传播,然后再执行一次优化步骤。# clear last stepoptimizer.zero_grad()# 16 accumulated gradient stepsscaled_loss = 0for accumulated_step_i in range(16): out = model.forward() loss = some_loss(out,y) loss.backward() scaled_loss += loss.item() # update weights after 8 steps. effective batch = 8*16optimizer.step()# loss is now scaled up by the number of accumulated batchesactual_loss = scaled_loss / 16在lightning中,全部都给你做好了,只需要设置accumulate_grad_batches=16:trainer = Trainer(accumulate_grad_batches=16)trainer.fit(model)5. 保留的计算图一个最简单撑爆你的内存的方法是为了记录日志存储你的loss。losses = []...losses.append(loss)print(f current loss: {torch.mean(losses) })上面的问题是,loss仍然包含有整个图的副本。在这种情况下,调用.item()来释放它。# badlosses.append(loss)# goodlosses.append(loss.item())Lightning会非常小心,确保不会保留计算图的副本。6. 单个GPU训练一旦你已经完成了前面的步骤,是时候进入GPU训练了。在GPU上的训练将使多个GPU cores之间的数学计算并行化。你得到的加速取决于你所使用的GPU类型。我推荐个人用2080Ti,公司用V100。乍一看,这可能会让你不知所措,但你真的只需要做两件事:1)移动你的模型到GPU, 2)每当你运行数据通过它,把数据放到GPU上。# put model on GPUmodel.cuda(0)# put data on gpu (cuda on a variable returns a cuda copy)x = x.cuda(0)# runs on GPU nowmodel(x)如果你使用Lightning,你什么都不用做,只需要设置Trainer(gpus=1)。# ask lightning to use gpu 0 for trainingtrainer = Trainer(gpus=[0])trainer.fit(model)在GPU上进行训练时,要注意的主要事情是限制CPU和GPU之间的传输次数。# expensivex = x.cuda(0)# very expensivex = x.cpu()x = x.cuda(0)如果内存耗尽,不要将数据移回CPU以节省内存。在求助于GPU之前,尝试以其他方式优化你的代码或GPU之间的内存分布。另一件需要注意的事情是调用强制GPU同步的操作。清除内存缓存就是一个例子。# really bad idea. Stops all the GPUs until they all catch uptorch.cuda.empty_cache()但是,如果使用Lightning,惟一可能出现问题的地方是在定义Lightning Module时。Lightning会特别注意不去犯这类错误。7. 16-bit 精度16bit精度是将内存占用减半的惊人技术。大多数模型使用32bit精度数字进行训练。然而,最近的研究发现,16bit模型也可以工作得很好。混合精度意味着对某些内容使用16bit,但将权重等内容保持在32bit。要在Pytorch中使用16bit精度,请安装NVIDIA的apex库,并对你的模型进行这些更改。# enable 16-bit on the model and the optimizermodel, optimizers = amp.initialize(model, optimizers, opt_level= O2 )# when doing .backward, let amp do it so it can scale the losswith amp.scale_loss(loss, optimizer) as scaled_loss: scaled_loss.backward()amp包会处理好大部分事情。如果梯度爆炸或趋向于0,它甚至会缩放loss。在lightning中,启用16bit并不需要修改模型中的任何内容,也不需要执行我上面所写的操作。设置Trainer(precision=16)就可以了。trainer = Trainer(amp_level= O2 , use_amp=False)trainer.fit(model)8. 移动到多个GPUs中现在,事情变得非常有趣了。有3种(也许更多?)方法来进行多GPU训练。分batch训练A) 拷贝模型到每个GPU中,B) 给每个GPU一部分batch第一种方法被称为“分batch训练”。该策略将模型复制到每个GPU上,每个GPU获得batch的一部分。# copy model on each GPU and give a fourth of the batch to eachmodel = DataParallel(model, devices=[0, 1, 2 ,3])# out has 4 outputs (one for each gpu)out = model(x.cuda(0))在lightning中,你只需要增加GPUs的数量,然后告诉trainer,其他什么都不用做。# ask lightning to use 4 GPUs for trainingtrainer = Trainer(gpus=[0, 1, 2, 3])trainer.fit(model)模型分布训练将模型的不同部分放在不同的GPU上,batch按顺序移动有时你的模型可能太大不能完全放到内存中。例如,带有编码器和解码器的序列到序列模型在生成输出时可能会占用20GB RAM。在本例中,我们希望将编码器和解码器放在独立的GPU上。# each model is sooo big we can t fit both in memoryencoder_rnn.cuda(0)decoder_rnn.cuda(1)# run input through encoder on GPU 0encoder_out = encoder_rnn(x.cuda(0))# run output through decoder on the next GPUout = decoder_rnn(encoder_out.cuda(1))# normally we want to bring all outputs back to GPU 0out = out.cuda(0)对于这种类型的训练,在Lightning中不需要指定任何GPU,你应该把LightningModule中的模块放到正确的GPU上。class MyModule(LightningModule): def __init__(): self.encoder = RNN(...) self.decoder = RNN(...) def forward(x): # models won t be moved after the first forward because # they are already on the correct GPUs self.encoder.cuda(0) self.decoder.cuda(1) out = self.encoder(x) out = self.decoder(out.cuda(1)) # don t pass GPUs to trainermodel = MyModule()trainer = Trainer()trainer.fit(model)两者混合在上面的情况下,编码器和解码器仍然可以从并行化操作中获益。# change these linesself.encoder = RNN(...)self.decoder = RNN(...)# to these# now each RNN is based on a different gpu setself.encoder = DataParallel(self.encoder, devices=[0, 1, 2, 3])self.decoder = DataParallel(self.encoder, devices=[4, 5, 6, 7])# in forward...out = self.encoder(x.cuda(0))# notice inputs on first gpu in devicesout = self.decoder(out.cuda(4)) # <--- the 4 here使用多个GPU时要考虑的注意事项:如果模型已经在GPU上了,model.cuda()不会做任何事情。总是把输入放在设备列表中的第一个设备上。在设备之间传输数据是昂贵的,把它作为最后的手段。优化器和梯度会被保存在GPU 0上,因此,GPU 0上使用的内存可能会比其他GPU大得多。9. 多节点GPU训练每台机器上的每个GPU都有一个模型的副本。每台机器获得数据的一部分,并且只在那部分上训练。每台机器都能同步梯度。如果你已经做到了这一步,那么你现在可以在几分钟内训练Imagenet了!这并没有你想象的那么难,但是它可能需要你对计算集群的更多知识。这些说明假设你正在集群上使用SLURM。Pytorch允许多节点训练,通过在每个节点上复制每个GPU上的模型并同步梯度。所以,每个模型都是在每个GPU上独立初始化的,本质上独立地在数据的一个分区上训练,除了它们都从所有模型接收梯度更新。在高层次上:在每个GPU上初始化一个模型的副本(确保设置种子,让每个模型初始化到相同的权重,否则它会失败)。将数据集分割成子集(使用DistributedSampler)。每个GPU只在它自己的小子集上训练。在.backward()上,所有副本都接收到所有模型的梯度副本。这是模型之间唯一一次的通信。Pytorch有一个很好的抽象,叫做DistributedDataParallel,它可以帮你实现这个功能。要使用DDP,你需要做4的事情:def tng_dataloader(): d = MNIST() # 4: Add distributed sampler # sampler sends a portion of tng data to each machine dist_sampler = DistributedSampler(dataset) dataloader = DataLoader(d, shuffle=False, sampler=dist_sampler) def main_process_entrypoint(gpu_nb): # 2: set up connections between all gpus across all machines # all gpus connect to a single GPU "root" # the default uses env:// world = nb_gpus * nb_nodes dist.init_process_group("nccl", rank=gpu_nb, world_size=world) # 3: wrap model in DPP torch.cuda.set_device(gpu_nb) model.cuda(gpu_nb) model = DistributedDataParallel(model, device_ids=[gpu_nb]) # train your model now... if __name__ == __main__ : # 1: spawn number of processes # your cluster will call main for each machine mp.spawn(main_process_entrypoint, nprocs=8)然而,在Lightning中,只需设置节点数量,它就会为你处理其余的事情。# train on 1024 gpus across 128 nodestrainer = Trainer(nb_gpu_nodes=128, gpus=[0, 1, 2, 3, 4, 5, 6, 7])Lightning还附带了一个SlurmCluster管理器,可以方便地帮助你提交SLURM作业的正确详细信息。10. 福利!在单个节点上多GPU更快的训练事实证明,distributedDataParallel比DataParallel快得多,因为它只执行梯度同步的通信。所以,一个好的hack是使用distributedDataParallel替换DataParallel,即使是在单机上进行训练。在Lightning中,这很容易通过将distributed_backend设置为ddp和设置GPUs的数量来实现。# train on 4 gpus on the same machine MUCH faster than DataParalleltrainer = Trainer(distributed_backend= ddp , gpus=[0, 1, 2, 3])对模型加速的思考尽管本指南将为你提供了一系列提高网络速度的技巧,但我还是要给你解释一下如何通过查找瓶颈来思考问题。我将模型分成几个部分:首先,我要确保在数据加载中没有瓶颈。为此,我使用了我所描述的现有数据加载解决方案,但是如果没有一种解决方案满足你的需要,请考虑离线处理和缓存到高性能数据存储中,比如h5py。接下来看看你在训练步骤中要做什么。确保你的前向传播速度快,避免过多的计算以及最小化CPU和GPU之间的数据传输。最后,避免做一些会降低GPU速度的事情(本指南中有介绍)。接下来,我试图最大化我的batch size,这通常是受GPU内存大小的限制。现在,需要关注在使用大的batch size的时候如何在多个GPUs上分布并最小化延迟(比如,我可能会尝试着在多个gpu上使用8000 +的有效batch size)。然而,你需要小心大的batch size。针对你的具体问题,请查阅相关文献,看看人们都忽略了什么!—END—英文原文:https://towardsdatascience.com/9-tips-for-training-lightning-fast-neural-networks-in-pytorch-8e63a502f565
-
使用 PyTorch 训练数据分析模型项目2023/07/12本文内容定义神经网络模型参数网络是如何运作的?定义损失函数在本教程的前一阶段中,我们获取了将用于使用 PyTorch 训练数据分析模型的数据集。 现在,我们将使用这些数据。要使用 PyTorch 训练数据分析模型,需要完成以下步骤:加载数据。 如果已完成本教程的上一步,则已经完成了数据加载。定义神经网络。定义损失函数。使用训练数据训练模型。使用测试数据测试网络。定义神经网络在本教程中,你将构建带有 3 个线性层的基本神经网络模型。 模型的结构如下所示:Linear -> ReLU -> Linear -> ReLU -> Linear一个线性层对传入数据应用一个线性转换。 必须指定输入特征的数量和输出特征的数量,它们应与类的数量相对应。ReLU 层是一个激活函数,用于将所有传入特征定义为 0 或更大。 因此,应用此层时,任何小于 0 的数字都会更改为零,而其他数字则保持不变。 我们将在 2 个隐藏层上应用激活层,在最后一个线性层上不应用激活层。模型参数模型参数取决于我们的目标和训练数据。 输入大小取决于我们向模型馈送的特征数量,在本例中为 4 个。 输出大小是 3,因为有 3 种可能的鸢尾花类型。有 3 个线性层 (4,24) -> (24,24) -> (24,3),网络将具有 744 个权重 (96+576+72)。学习速率 (lr) 设置你根据损失梯度调整网络权重的程度控制。 速率越低,训练速度就越慢。 你将在本教程中将 lr 设置为 0.01。网络是如何运作的?在此处,我们将构建一个前馈网络。 在训练过程中,网络将处理所有层的输入,计算损失以了解图像的预测标签与正确标签相差多远,并将梯度传播回网络以更新层的权重。 通过迭代庞大的输入数据集,网络将“学习”设置其权重以获得最佳结果。前向函数计算损失函数的值,后向函数计算可学习参数的梯度 。 使用 PyTorch 创建神经网络时,只需定义前向函数。 后向函数会自动定义。将以下代码复制到 Visual Studio 中的 DataClassifier.py 文件中,来定义模型参数和神经网络。py# Define model parameters input_size = list(input.shape)[1] # = 4. The input depends on how many features we initially feed the model. In our case, there are 4 features for every predict value learning_rate = 0.01 output_size = len(labels) # The output is prediction results for three types of Irises. # Define neural network class Network(nn.Module): def __init__(self, input_size, output_size): super(Network, self).__init__() self.layer1 = nn.Linear(input_size, 24) self.layer2 = nn.Linear(24, 24) self.layer3 = nn.Linear(24, output_size) def forward(self, x): x1 = F.relu(self.layer1(x)) x2 = F.relu(self.layer2(x1)) x3 = self.layer3(x2) return x3 # Instantiate the model model = Network(input_size, output_size) 还需要根据电脑上的可用设备来定义执行设备。 PyTorch 没有用于 GPU 的专用库,但你可手动定义执行设备。 如果计算机上存在 Nvidia GPU,则该设备为 Nvidia GPU;如果没有,则为 CPU。复制以下代码来定义执行设备:py# Define your execution device device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print("The model will be running on", device, "device\n") model.to(device) # Convert model parameters and buffers to CPU or Cuda 最后一步是定义函数来保存模型:py# Function to save the model def saveModel(): path = "./NetModel.pth" torch.save(model.state_dict(), path) 备注想要详细了解如何使用 PyTorch 创建神经网络? 请查看 PyTorch 文档。定义损失函数损失函数计算一个值,该值可估计输出与目标之间的差距。 主要目标是通过神经网络中的反向传播改变权重向量值来减少损失函数的值。丢失值不同于模型准确性。 损失函数表示模型在每次训练集优化迭代后的表现。 模型的准确性基于测试数据进行计算,并显示正确预测的百分比。在 PyTorch 中,神经网络包包含各种损失函数,这些函数构成了深层神经网络的构建基块。 若想详细了解这些细节,请先查看上述说明。 在此处,我们将使用针对这种分类优化的现有函数,并使用分类交叉熵损失函数和 Adam 优化器。 在该优化器中,学习速率 (lr) 设置你根据损失梯度调整网络权重的程度控制。 此处需要将它设置为 0.001 - 值越低,训练速度越慢。将以下代码复制到 Visual Studio 中的 DataClassifier.py 文件中,以定义损失函数和优化器。py# Define the loss function with Classification Cross-Entropy loss and an optimizer with Adam optimizerloss_fn = nn.CrossEntropyLoss()optimizer = Adam(model.parameters(), lr=0.001, weight_decay=0.0001)使用训练数据训练模型。要训练模型,必须循环访问数据迭代器,将输入馈送到网络并进行优化。 只需在每次训练 epoch 后将预测得到的标签与验证数据集中的实际标签进行比较,即可验证结果。该程序将显示针对训练集的每个 epoch 或每个完整迭代的训练损失、验证损失和模型准确度。 它将以最高准确度保存模型,在 10 个 epoch 后,程序将显示最终的准确度。将以下代码添加到 DataClassifier.py 文件py# Training Function def train(num_epochs): best_accuracy = 0.0 print("Begin training...") for epoch in range(1, num_epochs+1): running_train_loss = 0.0 running_accuracy = 0.0 running_vall_loss = 0.0 total = 0 # Training Loop for data in train_loader: #for data in enumerate(train_loader, 0): inputs, outputs = data # get the input and real species as outputs; data is a list of [inputs, outputs] optimizer.zero_grad() # zero the parameter gradients predicted_outputs = model(inputs) # predict output from the model train_loss = loss_fn(predicted_outputs, outputs) # calculate loss for the predicted output train_loss.backward() # backpropagate the loss optimizer.step() # adjust parameters based on the calculated gradients running_train_loss +=train_loss.item() # track the loss value # Calculate training loss value train_loss_value = running_train_loss/len(train_loader) # Validation Loop with torch.no_grad(): model.eval() for data in validate_loader: inputs, outputs = data predicted_outputs = model(inputs) val_loss = loss_fn(predicted_outputs, outputs) # The label with the highest value will be our prediction _, predicted = torch.max(predicted_outputs, 1) running_vall_loss += val_loss.item() total += outputs.size(0) running_accuracy += (predicted == outputs).sum().item() # Calculate validation loss value val_loss_value = running_vall_loss/len(validate_loader) # Calculate accuracy as the number of correct predictions in the validation batch divided by the total number of predictions done. accuracy = (100 * running_accuracy / total) # Save the model if the accuracy is the best if accuracy > best_accuracy: saveModel() best_accuracy = accuracy # Print the statistics of the epoch print('Completed training batch', epoch, 'Training Loss is: %.4f' %train_loss_value, 'Validation Loss is: %.4f' %val_loss_value, 'Accuracy is %d %%' % (accuracy))使用测试数据测试模型。现在我们已经训练了模型,接下来可使用测试数据集来测试模型。我们将添加 2 个测试函数。 第一个函数测试你在上一部分保存的模型。 它将使用包含 45 个项的测试数据集来测试模型,并打印出模型的准确度。 第二个是可选函数,用于测试模型在预测三种鸢尾花品类的每一种时的可信度,用成功分类每个品种的概率表示。将以下代码添加到 DataClassifier.py 文件。py# Function to test the model def test(): # Load the model that we saved at the end of the training loop model = Network(input_size, output_size) path = "NetModel.pth" model.load_state_dict(torch.load(path)) running_accuracy = 0 total = 0 with torch.no_grad(): for data in test_loader: inputs, outputs = data outputs = outputs.to(torch.float32) predicted_outputs = model(inputs) _, predicted = torch.max(predicted_outputs, 1) total += outputs.size(0) running_accuracy += (predicted == outputs).sum().item() print('Accuracy of the model based on the test set of', test_split ,'inputs is: %d %%' % (100 * running_accuracy / total)) # Optional: Function to test which species were easier to predict def test_species(): # Load the model that we saved at the end of the training loop model = Network(input_size, output_size) path = "NetModel.pth" model.load_state_dict(torch.load(path)) labels_length = len(labels) # how many labels of Irises we have. = 3 in our database. labels_correct = list(0. for i in range(labels_length)) # list to calculate correct labels [how many correct setosa, how many correct versicolor, how many correct virginica] labels_total = list(0. for i in range(labels_length)) # list to keep the total # of labels per type [total setosa, total versicolor, total virginica] with torch.no_grad(): for data in test_loader: inputs, outputs = data predicted_outputs = model(inputs) _, predicted = torch.max(predicted_outputs, 1) label_correct_running = (predicted == outputs).squeeze() label = outputs[0] if label_correct_running.item(): labels_correct[label] += 1 labels_total[label] += 1 label_list = list(labels.keys()) for i in range(output_size): print('Accuracy to predict %5s : %2d %%' % (label_list[i], 100 * labels_correct[i] / labels_total[i])) 最后,让我们添加主代码。 这将启动模型训练、保存模型并在屏幕上显示结果。 我们将在训练集上仅运行两次迭代 [num_epochs = 25],因此训练过程不会花费太长时间。将以下代码添加到 DataClassifier.py 文件。pyif __name__ == "__main__": num_epochs = 10 train(num_epochs) print('Finished Training\n') test() test_species() 让我们运行测试! 确保顶部工具栏中的下拉菜单设置为 Debug。 如果设备是 64 位的,请将 Solution Platform 更改为 x64 以在本地计算机上运行项目;如果设备是 32 位的,请将其更改为 x86。要运行项目,请单击工具栏上的 Start Debugging 按钮,或者按 F5。这将弹出控制台窗口,你将看到训练过程。 如定义的一样,将对每个 epoch 打印丢失值。 预期是随着每次 epoch,损失值会变小。训练完成后,应会看到类似于下面的输出。 数字不会完全相同 - 训练取决于许多因素,并且不会总是返回相同的结果 - 但它们应该看起来相似。
-
本文内容定义卷积神经网络。神经网络如何工作?定义损失函数使用训练数据训练模型。在本教程的前一阶段中,我们获取了将用于使用 PyTorch 训练图像分类器的数据集。 现在,我们将使用这些数据。要使用 PyTorch 训练图像分类器,需要完成以下步骤:加载数据。 如果已完成本教程的上一步,则已经完成了数据加载。定义卷积神经网络。定义损失函数。使用训练数据训练模型。使用测试数据测试网络。定义卷积神经网络。若要使用 PyTorch 构建神经网络,你将使用 torch.nn 包。 该包包含模块、可扩展类和构建神经网络所需的全部组件。在本部分中,你将构建一个基本的卷积神经网络 (CNN) 来对 CIFAR10 数据集中的图像进行分类。CNN 是一类神经网络,定义为多层神经网络,旨在检测数据中的复杂特征。 它们最常用于计算机视觉应用程序。我们的网络将由以下 14 层构成:Conv -> BatchNorm -> ReLU -> Conv -> BatchNorm -> ReLU -> MaxPool -> Conv -> BatchNorm -> ReLU -> Conv -> BatchNorm -> ReLU -> Linear.卷积层卷积层是 CNN 的主要层,可帮助我们检测图像中的特征。 每个层都有多个通道来检测图像中的特定特征,还有多个内核来定义检测到的特征的大小。 因此,具有 64 个通道和 3 x 3 内核大小的卷积层将检测 64 个不同的特征,每个大小为 3 x 3。 定义卷积层时,需要提供输入通道数、输出通道数和内核大小。 该层中的输出通道数为下一层的输入通道数。例如:输入通道数为 3、输出通道数为 10、内核大小为 6 的卷积层将得到 RGB 图像(3 通道)作为输入,并对核大小为 6x6 的图像应用 10 个特征检测器。 较小的内核大小将缩短计算时间和权重共享。其他层我们的网络还涉及以下其他层:ReLU 层是一个激活函数,用于将所有传入特征定义为 0 或更大。 应用此层时,任何小于 0 的数字都会更改为零,而其他数字则保持不变。BatchNorm2d 层对输入应用规范化以获得零均值和单位方差并提高网络精度。MaxPool 层将帮助我们确保图像中对象的位置不会影响神经网络检测其特定特征的能力。Linear 层是网络中的最后一层,它计算每个类的分数。 在 CIFAR10 数据集中,有 10 类标签。 得分最高的标签将是模型预测的那一个。 在线性层中,必须指定输入特征的数量和输出特征的数量,它们应与类的数量相对应。神经网络如何工作?CNN 是一种前馈网络。 在训练过程中,网络将处理所有层的输入,计算损失以了解图像的预测标签与正确标签相差多远,并将梯度传播回网络以更新层的权重。 通过迭代庞大的输入数据集,网络将“学习”设置其权重以获得最佳结果。前向函数计算损失函数的值,后向函数计算可学习参数的梯度。 使用 PyTorch 创建神经网络时,只需定义前向函数。 后向函数会自动定义。将以下代码复制到 Visual Studio 中的 PyTorchTraining.py 文件以定义 CCN。pyimport torchimport torch.nn as nnimport torchvisionimport torch.nn.functional as F# Define a convolution neural networkclass Network(nn.Module): def __init__(self): super(Network, self).__init__() self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=1) self.bn1 = nn.BatchNorm2d(12) self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=1) self.bn2 = nn.BatchNorm2d(12) self.pool = nn.MaxPool2d(2,2) self.conv4 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=1) self.bn4 = nn.BatchNorm2d(24) self.conv5 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=1) self.bn5 = nn.BatchNorm2d(24) self.fc1 = nn.Linear(24*10*10, 10) def forward(self, input): output = F.relu(self.bn1(self.conv1(input))) output = F.relu(self.bn2(self.conv2(output))) output = self.pool(output) output = F.relu(self.bn4(self.conv4(output))) output = F.relu(self.bn5(self.conv5(output))) output = output.view(-1, 24*10*10) output = self.fc1(output) return output# Instantiate a neural network model model = Network()备注想要详细了解如何使用 PyTorch 创建神经网络? 请查看 PyTorch 文档定义损失函数损失函数计算一个值,该值可估计输出与目标之间的差距。 主要目标是通过神经网络中的反向传播改变权重向量值来减少损失函数的值。丢失值不同于模型准确性。 通过损失函数可了解模型在每次训练集优化迭代后的表现。 模型的准确性基于测试数据进行计算,并显示正确预测的百分比。在 PyTorch 中,神经网络包包含各种损失函数,这些函数构成了深层神经网络的构建基块。 在本教程中,你将先使用分类交叉熵损失定义损失函数和 Adam 优化器,然后再使用分类损失函数。 学习速率 (lr) 设置你根据损失梯度调整网络权重的程度控制。 请将其设置为 0.001。 速率越低,训练速度就越慢。将以下代码复制到 Visual Studio 中的 PyTorchTraining.py 文件中,以定义损失函数和优化器。pyfrom torch.optim import Adam # Define the loss function with Classification Cross-Entropy loss and an optimizer with Adam optimizerloss_fn = nn.CrossEntropyLoss()optimizer = Adam(model.parameters(), lr=0.001, weight_decay=0.0001)使用训练数据训练模型。要训练模型,必须循环访问数据迭代器,将输入馈送到网络并进行优化。 PyTorch 没有用于 GPU 的专用库,但你可以手动定义执行设备。 如果计算机上存在 Nvidia GPU,则该设备为 Nvidia GPU,如果没有,则为 CPU。将以下代码添加到 PyTorchTraining.py 文件pyfrom torch.autograd import Variable# Function to save the modeldef saveModel(): path = "./myFirstModel.pth" torch.save(model.state_dict(), path)# Function to test the model with the test dataset and print the accuracy for the test imagesdef testAccuracy(): model.eval() accuracy = 0.0 total = 0.0 with torch.no_grad(): for data in test_loader: images, labels = data # run the model on the test set to predict labels outputs = model(images) # the label with the highest energy will be our prediction _, predicted = torch.max(outputs.data, 1) total += labels.size(0) accuracy += (predicted == labels).sum().item() # compute the accuracy over all test images accuracy = (100 * accuracy / total) return(accuracy)# Training function. We simply have to loop over our data iterator and feed the inputs to the network and optimize.def train(num_epochs): best_accuracy = 0.0 # Define your execution device device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print("The model will be running on", device, "device") # Convert model parameters and buffers to CPU or Cuda model.to(device) for epoch in range(num_epochs): # loop over the dataset multiple times running_loss = 0.0 running_acc = 0.0 for i, (images, labels) in enumerate(train_loader, 0): # get the inputs images = Variable(images.to(device)) labels = Variable(labels.to(device)) # zero the parameter gradients optimizer.zero_grad() # predict classes using images from the training set outputs = model(images) # compute the loss based on model output and real labels loss = loss_fn(outputs, labels) # backpropagate the loss loss.backward() # adjust parameters based on the calculated gradients optimizer.step() # Let's print statistics for every 1,000 images running_loss += loss.item() # extract the loss value if i % 1000 == 999: # print every 1000 (twice per epoch) print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 1000)) # zero the loss running_loss = 0.0 # Compute and print the average accuracy fo this epoch when tested over all 10000 test images accuracy = testAccuracy() print('For epoch', epoch+1,'the test accuracy over the whole test set is %d %%' % (accuracy)) # we want to save the model if the accuracy is the best if accuracy > best_accuracy: saveModel() best_accuracy = accuracy使用测试数据测试模型。现在,可以使用测试集中的一批图像来测试模型。将以下代码添加到 PyTorchTraining.py 文件。pyimport matplotlib.pyplot as pltimport numpy as np# Function to show the imagesdef imageshow(img): img = img / 2 + 0.5 # unnormalize npimg = img.numpy() plt.imshow(np.transpose(npimg, (1, 2, 0))) plt.show()# Function to test the model with a batch of images and show the labels predictionsdef testBatch(): # get batch of images from the test DataLoader images, labels = next(iter(test_loader)) # show all images as one image grid imageshow(torchvision.utils.make_grid(images)) # Show the real labels on the screen print('Real labels: ', ' '.join('%5s' % classes[labels[j]] for j in range(batch_size))) # Let's see what if the model identifiers the labels of those example outputs = model(images) # We got the probability for every 10 labels. The highest (max) probability should be correct label _, predicted = torch.max(outputs, 1) # Let's show the predicted labels on the screen to compare with the real ones print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] for j in range(batch_size)))最后,让我们添加主代码。 这将启动模型训练、保存模型并在屏幕上显示结果。 我们将在训练集上仅运行两次迭代 [train(2)],因此训练过程不会花费太长时间。将以下代码添加到 PyTorchTraining.py 文件。pyif __name__ == "__main__": # Let's build our model train(5) print('Finished Training') # Test which classes performed well testModelAccuracy() # Let's load the model we just created and test the accuracy per label model = Network() path = "myFirstModel.pth" model.load_state_dict(torch.load(path)) # Test with batch of images testBatch()让我们运行测试! 确保顶部工具栏中的下拉菜单设置为“调试”。 将解决方案平台更改为 x64(如果使用 64 位设备)或 x86(如果使用 32 位设备)以在本地计算机上运行该项目。选择等于 2 ([train(2)]) 的时期数(完整通过训练数据集的次数)将导致对包含 10,000 个图像的整个测试数据集进行两次迭代。 在第 8 代 Intel CPU 上完成训练大约需要 20 分钟,该模型对 10 个标签的分类成功率应达到 65% 左右。要运行该项目,请单击工具栏上的开始调试按钮或按 F5 键。随即将弹出控制台窗口,你可以在其中看到训练过程。正如你所定义的那样,将每隔 1,000 批图像打印一次损失值,训练集的每次迭代打印五次。 你希望每个循环的损失值逐渐减少。还可以在每次迭代后查看模型的准确性。 模型准确性与损失值不同。 通过损失函数可了解模型在每次训练集优化迭代后的表现。 模型的准确性基于测试数据进行计算,并显示正确预测的百分比。 在本例中,它将指示模型在每次训练迭代后能够从 10,000 个图像测试集中正确分类的图像数量。训练完成后,应会看到类似于下面的输出。 数字不会完全相同 - 训练取决于许多因素,并且不会总是返回相同的结果 - 但它们应该看起来相似。仅运行 5 个时期后,模型成功率为 70%。 对于短期训练的基本模型来说,这是一个很好的结果!用一批图像进行测试,模型从该批次的 10 个图像中得出了 7 个正确的图像。 结果很不错,与模型成功率一致。可检查模型预测哪些类别的图像效果最佳。 只需添加并运行以下代码:可选 - 将以下 testClassess 函数添加到 PyTorchTraining.py 文件中,在主函数 __name__ == "__main__" 中添加此函数 testClassess() 的调用。py# Function to test what classes performed welldef testClassess(): class_correct = list(0. for i in range(number_of_labels)) class_total = list(0. for i in range(number_of_labels)) with torch.no_grad(): for data in test_loader: images, labels = data outputs = model(images) _, predicted = torch.max(outputs, 1) c = (predicted == labels).squeeze() for i in range(batch_size): label = labels[i] class_correct[label] += c[i].item() class_total[label] += 1 for i in range(number_of_labels): print('Accuracy of %5s : %2d %%' % ( classes[i], 100 * class_correct[i] / class_total[i]))输出如下所示:
-
前言 最近对大模型的微调时使用Pytorch-Lightning(一个基于pytorch高级封装的训练框架)非常方便地就实现大模型的分布式训练。前期自己也踩了一些坑,于是写一个笔记分享给有同样需求的后来者、避免踩坑。 PL框架在它的stratey模块中封装好了不同的分布式实现方式dp、ddp、deepspeed等 大部分情况下甚至不需额外的修改任何代码就能将实现从单机单卡到进行分布式(单机多卡、多机多卡)的训练。 少部分情况,目前只有在分布式训练模式为DP需要修改代码。虽然PL框架已经自动实现gather的过程,但如果你需要对模型训练逻辑中每一轮迭代、epoch结束时进行一些类似输出softmax()、评估验证mertic等额外操作时,还是需要手动在xxx_step_end()、xxx_epoch_end()中编码将不同GPU上所运行model返回的output、loss进行gather, 具体的编码可以看本文的第三部分。 如果想直接快速实现分布式训练、不纠结DP和DDP以及背后原理,可以跳过理论直接看第三部分,只需要记住一个结论: DDP比DP实际加速效果显著,在DP和DDP之间无脑的选择DDP。 分布式训练的理论 分布式训练顾名思义就是在相比之前只在一个机子一个显卡上训练,现在实现在多个机器多张显卡并行的进行训练。总的来说可以按照以下类别进行分类: 并行方式来分: 模型并行 vs 数据并行 更新方式来分: 同步更新 vs 异步更新 更新算法来分: Parameter Server 算法 vs AllReduce算法 物理机器分布来分:单机多卡 vs 多机单卡 vs 多机多卡 并行方式 模型并行: 将一个模型的不同部分放在不同GPU 上进行训练。使用这种方式训练时模型之间通信开销大,且规模伸缩性差。通常只有当模型大到一张GPU无法放下时才采用,大部分分布式训练采用是数据并行。 数据并行: 将全部数据分成独立部分并行运行在不同的GPU上,每个GPU上都有一个相同且完整的模型。 更新方式 对于数据并行的分布式训练,每轮迭代后需要对每个GPU上独立的模型去更新参数,根据更新方式可以划分同步和异步更新: 同步更新:每个batch所有GPU计算完成后再统一计算新权值(计算最快GPU等计算最慢的)然后等所有GPU更新参数后再进行下一轮batch的计算。 异步更新:每个GPU计算完梯度后,无需等待其他更新,立即更新整体权值并同步。异步更新GPU没有等待,但是涉及到更复杂的梯度过时,loss下降抖动大的问题。所以实践中,一般使用同步更新的方式。 更新算法 Parameter Server vs Ring-All-Reduce 在模型训练过程的同步更新中有两种常见的更新参数的算法, Parameter Server 和 Ring-All-Reduce。 Parameter Server: GPU:0 将数据分成五份分到各个GPU上(如下图所示),每张GPU负责自己的那一份mini-batch的训练,得到grad后,返回给GPU 0上做累积,得到更新的权重参数后,再分发给各个GPU。 输入图片说明 Parameter Server 的思想类似MapReduce,存在两个显著的缺点: 1.每一轮的训练迭代都需要所有卡都将数据同步完做一次Reduce才算结束,并行的卡很多的时候,木桶效应就会很严重,计算效率低。 2.所有的GPU卡需要和Reducer进行数据、梯度和参数的通信,当模型较大或者数据较大的时候,通信开销很大。 另外Parameter Server的开销和显卡有直接线性关系,显卡数越多,通信开销越大。 假设有 G 个GPU,通信一次完整的参数为 K ,使用PS架构后花费的通信成本为: T=2(G−1)K Ring AllReduce 如下图所示,5张GPU以环形相连,每张GPU都有左手GPU和右手GPU,一个负责接收,一个负责发送,整个过程5张GPU同时循环4次完成梯度累积,再循环4次做参数同步。整个过程主要涉及Scatter Reduce和All Gather两个步骤。 输入图片说明 Scatter Reduce过程:首先,我们将参数分为N份,相邻的GPU传递不同的参数,在传递N-1次之后,可以得到每一份参数的累积(在不同的GPU上)。 输入图片说明 All Gather过程:每个GPU得到每一份参数的累积之后,类似Scatter Reduce过程再通过一遍环状通信算法进行传递,将所有参数同步到所有的GPU上。 输入图片说明 根据这两个过程,所有GPU都会得到更新后的全部参数。 Parameter Service最大的问题就是通信成本和GPU的数量线性相关。而Ring AllReduce的通信成本与GPU数量无关。 同样类比PS架构,假设我们有 G 个GPU,将数据分成 N 份,全部参数一次通信的时间还是 K ,而这里每份参数通信只需要KN 时间,总共执行了两遍环形通信,一遍环形通信并行执行N-1次,因此All Reduce的通信总时间成本是: T=2(N−1)KN 可以看到通信成本 T 与GPU数量无关。同时所有GPU设备之间传递数据过程如上图所示,最终 G 个GPU上都拥有所有的参数,整个过程传递的数据量是 (G−1)∗N 。 因此更准确说:基于环状通信的集群通信算法执行时间几乎和设备数无关,但总通信量和设备数成正比。 单机多卡 vs 多机单卡 vs 多机多卡 根据实际分布式集群的部署方式可以区分: 单机多卡:单个机器内有多个GPU,成本来自单个机子内的多个GPU之间通信。 多机单卡:多个机器同时每个机器只有一个GPU,成本来自多个机器之间通信。 多机多卡:多个机器并且每个机器多个GPU,通信成本既有多个机器之间,也有单个机器内多个GPU之间。 这里多说一句,在集群测试不同分布式训练之间的(DDP)速度差异时,发现一个待验证的现象:相同总卡(GPU)数下,多机单卡方式比单机多卡、多机多卡都要快。 Pytorch的分布式DP, DDP Pytorch官方提供了两种分布式训练的实现方式:DP(DataParallel) 和DDP(DistributedDataParallel),它们都是采用数据并行的方式。API分别是torch.nn.DataParallel(DP)和torch.nn.DistributedDataParallel(DDP)。 它们差异: 在参数更新算法上,DP采用的是Parameter Server模式,梯度最后统一在device[0]上计算、更新参数。DDP采用的是Ring-all-reduce模式,通信传输的数据量更少,通信消耗的时间成本与节点数量无关。 DP是单进程多线程的实现,由于Python的GIL特性只能支持多进程,实际上DP在单进程控制GPU运行,同时主GPU进行梯度汇总和模型更新,负载不均衡。DDP是采用多进程控制多GPU的方式,并采用DistributedSampler加载数据,确保数据在各个进程之间没有重叠。DDP实现真正意义上能并发的并行训练。 DP只能支持单机多卡形式使用,DDP既能在单机多卡、也可用于多机多卡、多机单卡的形式。 总的来说,DP的优势仅在于只使用Pytorch的API实现时编码更容易,从性能(训练速度)上DDP完胜DP。 Pytorch-Lightning实现分布式训练 正如本文前言所说使用PL框架进行分布式训练非常简单,只需要通过修改 pl.Trainer()中的参数即可将单机单卡变成多机多卡的训练方式。 pl.Trainer()pytorch-lightning.readthedocs.io/en/latest/common/trainer.html?highlight=strategy#strategy 具体的通过修改参数gpus、num_nodes设置训练需要多少张GPU和所使用机器的数量,同时通过参数strategy指定分布式训练的模式。 单机多卡. 单机多卡时无需指定参数num_nodes: trainer = pl.Trainer(gpus=4, strategy="dp") # 使用4块GPU trainer = pl.Trainer(gpus=[0, 1, 2], strategy="dp") # 使用0,1,2号3块GPu 点击并拖拽以移动 多机多卡 trainer = pl.Trainer(gpus=4, num_nodes=3, strategy="ddp") # 使用3台机器,每个机器4块GPU,总共12张GPU 点击并拖拽以移动 另外PL不仅支持常见的dp、ddp、deepspeed等,甚至还可以通过DDPStrategy()自定义strategy,有更高级的需求可以查阅官方文档: https://pytorch-lightning.readthedocs.io/en/latest/accelerators/gpu_expert.htmlpytorch-lightning.readthedocs.io/en/latest/accelerators/gpu_expert.html DP模式:手动gather不同GPU的输出 DP模式是目前使用pl框架进行分布式训练时唯一遇到需要对代码进行修改情况。由于它在每轮迭代后都需要将梯度汇总到第一张GPU上进行计算,相对应在pl框架的设计中training_step()、valid_step()、test_step()等内执行的逻辑都是在各自GPU上,最终在xxx_step_end()、xxx_epoch_end()内执行将所有输出汇总在第一张GPU上进行计算和更新的逻辑 def training_step(self, batch, batch_idx): x, y = batch y_hat = self.model(x) loss = F.cross_entropy(y_hat, y) pred = ... return {"loss": loss, "pred": pred} def training_step_end(self, batch_parts): # predictions from each GPU predictions = batch_parts["pred"] # losses from each GPU losses = batch_parts["loss"] gpu_0_prediction = predictions[0] gpu_1_prediction = predictions[1] # 如果metric需要分开计算再汇总 # do something with both outputs # return (losses[0] + losses[1]) / 2 return torch.mean(losses) # 推荐这样写,无论多少张卡都适用 def training_epoch_end(self, training_step_outputs): for out in training_step_outputs: ... 点击并拖拽以移动 Training with DataParallelpytorch-lightning.readthedocs.io/en/stable/common/lightning_module.html?highlight=all_gather#training-with-dataparallel implement-your-own-distributed-ddp-trainingpytorch-lightning.readthedocs.io/en/latest/accelerators/gpu_intermediate.html?highlight=ddp#implement-your-own-distributed-ddp-training 多卡训练遇到坑 多卡训练,dp模式下batch_size是总共卡数,需要batch_size*gpu_num, ddp模式下batch_size是单个机子, 无需增大。 多卡训练learnring_rate调整,learning_rate 一般需要线性scale, 推荐采用增大sqrt()倍。 多卡训练在ddp模式开启sync_batchnorm=True, 提升模型精度。 训练加速技巧 只有当你的模型中所有参数都参与训练,可以开启find_unused_parameters=False,加快训练速度。在pl中你只需要设置stratyge=ddp_find_unused_parameters_false即可。 设置锁页内存,pl中通过设置trainer的参数pin_memory=True。 使用半精度训练,在pl中通过设置trainer的参数precison=16。 使用APEX加速,在pl中先通过设置amp_backbend='apex', 然后设置 amp_level=O1\O2\O3 。 冻结模型的部分层参数,在pl中通过设置model.parameter()的参数requires_grad=False,例如一些研究表明bert保留最后四层,效果不会下降太多。为了提升模型训练、推理速度可以冻结前几层的参数。 使用梯度累加,在pl中通过设置trainer的参数accumulate_grad_batches。
-
什么是图灵测试图灵测试是图灵提出的一个关于机器人的著名判断原则。1950年,图灵发表了具有里程碑意义的论文《电脑能思考吗?》,第一次提出“机器思维”的概念。所谓图灵测试是一种测试机器是不是具备人类智能的方法。被测试的有一个人,另一个是声称自己有人类智力的机器图灵测试的基本原理图灵测试的基本原理是一个测试者与一个计算机程序进行对话,如果测试者无法区分程序的回答是由人类还是计算机生成的,那么该计算机程序被认为通过了图灵测试。图灵测试是图灵提出的一个关于机器人的著名判断原则,其根本目的是判断机器能否具备与人类类似的"智能"。图灵测试是测试人(多人)在与被测试者(一个人和一台机器)隔开的情况下,通过一些装置(如键盘)向被测试者随意提问。问过一些问题后,如果测试人中超过30%的人不能根据答复确认被测试者哪个是人,哪个是机器,那么这台机器就通过了测试,并被认为具有人类智能。图灵测试的目的图灵测试的目的是判断机器能否具备与人类类似的 "智能"。图灵测试是现代计算机之父阿兰·图灵在1950年提出的,其根本目的是:机器是否能够思考,这也是目前检验强人工智能的最基本的方法。图灵测试是测试人(多人)在与被测试者(一个人和一台机器)隔开的情况下,通过一些装置(如键盘)向被测试者随意提问。问过一些问题后,如果测试人中超过30%的人不能根据答复确认被测试者哪个是人,哪个是机器,那么这台机器就通过了测试,并被认为具有人类智能。现状很不幸的是,目前还没有任何一个机器人或者人工智能通过了图灵测试。就连最近刚出不久的chatGPT也未能通过该测试
-
一 定义机器学*是一门从数据中研究算法的科学学科。机器学*直白来讲,是根据已有的数据,进行算法选择,并基于算法和数据构建模型,最终对未来进行预测。通过数据训练出一个模型->预测未知属性。理性认识输入: x ∈ X(属性值)输出: y ∈ Y(目标值 )获得一个目标函数(target function):f : X ∈ Y(理想的公式)输入数据:D = {(x1,y1),(x2,y2),…,(xn,yn)}(历史信息)最终具有最优性能的假设公式:g : X → Y(学*得到的最终公式 ){(Xn,Yn)} from f → ML → g目标函数f未知(无法得到)假设函数g类似函数f,但是可能和函数f不同机器学*中是无法找到一个完美的函数f机器学*从数据中获得一个假设的函数g,使其非常接近目标函数f的效果概念拟合:构建的算法符合给定数据的特征x(i) :表示第i个样本的x向量xi: x向量的第i维度的值鲁棒性:也就是健壮性、稳健性、强健性,是系统的健壮性;当存在异常数据的时候,算法也会拟合数据过拟合和欠拟合显示过拟合:算法太符合样本数据的特征,对于实际生产中的数据特征无法拟合–模型在这个数据集展示的特别好欠拟合:算法不太符合样本的数据特征–训练集不好(不存在函数或者假设不对)二 应用框架sciket-learn(Python)(小规模单机–为主)http://scikit-learn.org/stable/Mahout(Hadoop生态圈基于MapReduce)(大数据和机器学*的集合)http://mahout.apache.org/Spark MLlibhttp://spark.apache.org/个性化推荐:个性化指的是根据各种因素来改变用户体验和呈现给用户内容,这些因素可能包含用户的行为数据和外部因素;推荐常指系统向用户呈现一个用户可能感兴趣的物品列表。精准营销:从用户群众中找出特定的要求的营销对象。客户细分:试图将用户群体分为不同的组,根据给定的用户特征进行客户分组。预测建模及分析:根据已有的数据进行建模,并使用得到的模型预测未来。机器学*、数据分析、数据挖掘区别与联系数据分析:数据分析是指用适当的统计分析方法对收集的大量数据进行分析,并提取有用的信息,以及形成结论,从而对据进行详细的研究和概括过程。在实际工作中,数据分析可帮助人们做出判断;数据分析一般而言可以分为统计分析、探索性数据分析和验证性数据分析三大类。数据挖掘:一般指从大量的数据中通过算法搜索隐藏于其中的信息的过程。通常通过统计、检索、机器学*、模式匹配等诸多方法来实现这个过程。机器学*:是数据分析和数据挖掘的一种比较常用、比较好的手段机器学*分类学*分类标签==需要验证的值有监督学*:是从标签化训练数据集中推断出模型的机器学*任务。(标签化比较难)判别式模型(Discriminative Model):直接对条件概率p(y|x)进行建模,常见判别模型有:线性回归、决策树、支持向量机SVM、k近邻、神经网络等;生成式模型(Generative Model):对联合分布概率p(x,y)进行建模,常见生成式模型有:隐马尔可夫模型HMM、朴素贝叶斯模型、高斯混合模型GMM、LDA等;生成式模型更普适;判别式模型更直接,目标性更强生成式模型关注数据是如何产生的,寻找的是数据分布模型;判别式模型关注的数据的差异性,寻找的是分类面由生成式模型可以产生判别式模型,但是由判别式模式没法形成生成式模型无监督学*:推断出数据的一些内在结构。(相对有监督学*效果会差一些)无监督学*试图学*或者提取数据背后的数据特征,或者从数据中抽取出重要的特征信息,常见的算法有聚类、降维、文本处理(特征抽取)等。无监督学*一般是作为有监督学*的前期数据处理,功能是从原始数据中抽取出必要的标签信息。半监督学*:考虑如何利用少量的标注样本和大量的未标注样本进行训练和分类的问题,是有监督学*和无监督学*的结合主要考虑如何利用少量的标注样本和大量的未标注样本进行训练和分类的问题。半监督学*对于减少标注代价,提高学*机器性能具有非常重大的实际意义。SSL的成立依赖于模型假设,主要分为三大类:平滑假设、聚类假设、流行假设;其中流行假设更具有普片性。SSL类型的算法主要分为四大类:半监督分类、半监督回归、半监督聚类、半监督降维。缺点:抗干扰能力弱,仅适合于实验室环境,其现实意义还没有体现出来;未来的发展主要是聚焦于新模型假设的产生。做什么分类分类:给定信息的类别分类(有监督学*)聚类:未知类别划分为几个类别(无监督学*)回归:给出的答案是一个区间段(有监督学*)关联规则:提取数据和数据项之间的相互关系(无监督学*)算法Top10算法名称算法描述C4.5分类决策树算法,决策树的核心算法,ID3算法的改进算法。CART 分类与回归树(Classification and Regression Trees)kNNK近邻分类算法;如果一个样本在特征空间中的k个最相似的样本中大多数属于某一个类别,那么该样本也属于该类别(物以类聚)NaiveBayes贝叶斯分类模型;该模型比较适合属性相关性比较小的时候,如果属性相关性比较大的时候,决策树模型比贝叶斯分类模型效果好(原因:贝叶斯模型假设属性之间是互不影响的)SVM(应用广泛)支持向量机,一种有监督学*的统计学*方法,广泛应用于统计分类和回归分析中。EM最大期望算法,常用于机器学*和计算机视觉中的数据集聚领域(最大次元估计上的一个提升)Apriori关联规则挖掘算法K-Means聚类算法,功能是将n个对象根据属性特征分为k个分割(k<n); 属于无监督学*PageRankGoogle搜索重要算法之一(和机器学*关系不大)AdaBoost(思想特别重要)迭代算法;利用多个分类器进行数据分类(深度学*思想和他很像)人工智能 机器学* 深度学*之间的关系一般流程数据收集 → 数据清理 → 征程工程 → 数据建模数据收集与储存1.数据来源用户访问行为数据业务数据外部第三方数据(自己加或者爬虫)2.数据存储需要存储的数据:原始数据、预处理后数据、模型结果存储设施:mysql、HDFS、HBase、Solr、Elasticsearch、Kafka、Redis等3.数据收集方式Flume & Kafka (大数据)公开数据集http://archive.ics.uci.edu/ml/datasets.htmlhttps://aws.amazon.com/cn/public-datasets/https://www.kaggle.com/competitionshttp://www.kdnuggets.com/datasets/index.htmlhttp://www.sogou.com/labs/resource/list_pingce.phphttps://tianchi.aliyun.com/datalab/index.htmhttp://www.pkbigdata.com/common/cmptIndex.html数据清洗和转换(特征工程)工作量最大数据预处理:数据过滤 处理数据缺失 处理可能的异常、错误或者异常值 合并多个数据源数据 数据汇总处理方式将类别数据编码成为对应的数值表示(一般使用1-of-k方法)-dumy从文本数据中提取有用的数据(一般使用词袋法或者TF-IDF)处理图像或者音频数据(像素、声波、音频、振幅等<傅里叶变换>)数值数据转换为类别数据以减少变量的值,比如年龄分段对数值数据进行转换,比如对数转换对特征进行正则化、标准化,以保证同一模型的不同输入变量的值域相同对现有变量进行组合或转换以生成新特征,比如平均数 (做虚拟变量)不断尝试模型训练集测试将原始数据分为训练集和测试集(交叉验证)分类模型模型比较准确率(Accuracy)=提取出的正确样本数/总样本数召回率(Recall)=正确的正例样本数/样本中的正例样本数——覆盖率精准率(Precision)=正确的正例样本数/预测为正例的样本数F值=PrecisionRecall2 / (Precision+Recall) (即F值为正确率和召回率的调和平均值)ROCROC(Receiver Operating Characteristic)最初源于20世纪70年代的信号检测理论,描述的是分类混淆矩阵中FPR-TPR两个量之间的相对变化情况,ROC曲线的纵轴是**“真正例率”(True Positive Rate 简称TPR)**,横轴是“假正例率” (False Positive Rate 简称FPR)。如果二元分类器输出的是对正样本的一个分类概率值,当取不同阈值时会得到不同的混淆矩阵,对应于ROC曲线上的一个点。那么ROC曲线就反映了FPR与TPR之间权衡的情况,通俗地来说,即在TPR随着FPR递增的情况下,谁增长得更快,快多少的问题。TPR增长得越快,曲线越往上屈,AUC就越大,反映了模型的分类性能就越好。当正负样本不平衡时,这种模型评价方式比起一般的精确度评价方式的好处尤其显著。AUCAUC的值越大表达模型越好(分类模型AUC的值最小在0.7)AUC(Area Under Curve)被定义为ROC曲线下的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而AUC作为数值可以直观的评价分类器的好坏,值越大越好。AUC = 1,是完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。分类算法评估方式指标描述scikit-learn函数Precision精确度from sklearn.metrics import precision_scoreRecall召回率from sklearn.metrics import recall_scoreF1F1指标from sklearn.metrics import f1_scoreConfusion Matrix混淆矩阵from sklearn.metrics import confusion_matrixROCROC曲线from sklearn.metrics import rocAUCROC曲线下的面积from sklearn.metrics import auc回归模型回归模型度量explained_varicance_score:可解释方差的回归评分函数mean_absolute_error:平均绝对误差mean_squared_error:平均平方误差回归算法评估方式指标描述scikit-learn函数Mean Square Error(MSE, RMSE)平均方差 from sklearn.metrics import mean_squared_errorAbsolute Error(MAE, RAE)绝对误差from sklearn.metrics import mean_absolute_error,median_absolute_errorR-SquaredR平方值(准确率)from sklearn.metrics import r2_score
-
两者的区别PyTorch和TensorFlow都是流行的深度学习框架,以下是它们的一些比较:静态和动态:在TensorFlow中,图结构是静态的,先编译再运行,而在PyTorch中,图结构是动态的,可以即时(JIT)编译。可解释性:TensorFlow更可解释,因为它有更多的库和工具支持(如TensorBoard),而PyTorch更关注于研究,因为它的模型更容易构建和修改。社区支持:TensorFlow的社区更广泛,有很多开源项目和教程可以使用,而PyTorch的社区也很活跃,并且有很多针对特定任务的开源项目和教程。移动端支持:TensorFlow在移动端(Android、iOS)支持更好,因为TensorFlow Lite提供了移动端支持,而PyTorch也支持移动端,但需要使用ONNX格式进行模型转换。计算速度:在同等条件下,TensorFlow在CPU上运行速度比PyTorch快,但在GPU上运行速度两者差不多。数据加载:TensorFlow的数据加载API设计庞大但使用有技巧,PyTorch的数据加载API整体设计粗糙但使用友好。分布式计算:两个框架都能提供在单个/多个 CPU/GPU 上面进行计算的能力。pytorch 比起 tensorflow 优势PyTorch比起TensorFlow的优势有:灵活性:PyTorch基于Python,提供了灵活的编程环境,方便研究人员和开发人员实验和快速迭代。易用性:PyTorch的API设计简洁明了,易于学习和使用,它采用了动态图的方式,调试和可视化模型比较方便。社区支持:虽然TensorFlow的社区规模更大且广泛,但PyTorch的社区也非常活跃,提供了丰富的教程、文档和示例代码,开发人员可以从中获取支持和帮助。pytorch 比起 tensorflow 的劣势PyTorch比起TensorFlow的劣势可能在于以下几个方面:在生产中缺乏模型服务:虽然PyTorch在研究社区中变得越来越流行,但其他框架已更广泛地用于实际生产工作。因此,与其他框架相比,PyTorch的文档和开发人员社区较小。有限的监控和可视化接口:虽然TensorFlow带有用于构建模型图的功能强大的可视化工具(如TensorBoard),但PyTorch还没有这样的东西。因此,开发人员可以使用许多现有的Python数据可视化工具之一或从外部连接到TensorBoard。运行效率低:PyTorch是动态编程,运行效率比较低,没有静态图运行效率高。在工业界部署时比较麻烦,没有TensorFlow部署方便。如果神经网络中需要自定义功能,TensorFlow可能是更好的选择。python 这么慢,为啥拿来搞AIPython虽然运算速度相对较慢,但它仍然被广泛用于人工智能(AI)领域,原因如下:易读与易写:Python语言较为简洁且语法清晰,易于理解和编写,这使得Python成为许多AI和数据科学项目的首选语言。科学计算与可视化:Python拥有众多的科学计算和可视化库,如NumPy、Pandas和Matplotlib等,这些库使得Python成为进行数据分析、机器学习等AI相关工作的理想工具。动态类型:Python的动态类型系统使其更具灵活性和可扩展性,可以快速进行原型开发和小规模实验。社区支持与资源丰富:Python拥有庞大的开发者社区和丰富的第三方库,可以快速找到解决问题的方法和工具。跨平台兼容性:Python可以在多种操作系统中运行,包括Windows、Linux和Mac OS等,这使得Python在AI和数据科学领域的应用更为广泛。
-
前言八大神经网络是指常用的八种神经网络结构。下面对它们进行一个简单的介绍1.卷积神经网络(CNN):卷积神经网络是用于图像和空间数据处理的神经网络,通过卷积层和池化层来捕捉图像的局部特征,广泛应用于图像分类、物体检测等领域。2.循环神经网络(RNN):循环神经网络适用于处理序列数据,如时间序列和文本。通过引入时间维度,RNN可以考虑数据的上下文信息。LSTM和GRU等变体解决了传统RNN的梯度问题,广泛应用于语言模型、文本生成等任务。3.生成对抗网络(GAN):生成对抗网络由生成器和判别器组成,用于生成逼真的数据样本。生成器尝试生成与真实数据相似的样本,判别器努力区分真实和生成样本。GAN在图像生成、风格转换等领域创造了许多引人注目的成果。4.图神经网络(GNN):图神经网络专门用于处理图数据,可以学习节点和边的表示。它在社交网络分析、分子预测等任务中有应用,对节点分类、链接预测等任务有出色表现。5.长短时记忆网络(LSTM):长短时记忆网络是一种循环神经网络的变体,专门用于解决长序列任务。通过门控机制,LSTM能够更好地捕获序列中的长期依赖关系,适用于语音识别、自然语言生成等任务。6.人工神经网络(ANN):人工神经网络是神经网络的基本形式,由神经元、权重和激活函数组成。多层感知器(MLP)是其常见形式,用于各种任务,如图像识别、数据分类等。7.自编码器(Autoencoder):自编码器是一种用于学习数据表示的神经网络,通过编码和解码过程学习数据的压缩表示。它在数据降维、去噪、特征学习等方面有应用。8.变换器(Transformer):变换器是一种基于自注意力机制的神经网络,用于处理序列数据,如自然语言文本。它在NLP领域引起了革命,广泛用于翻译、生成、情感分析等任务。 每个神经网络都有其独特的设计和应用领域,通过了解它们,您可以更好地理解它们在不同领域中的价值和作用。
-
什么是chatGPTChatGPT(全名:Chat Generative Pre-trained Transformer),美国OpenAI研发的聊天机器人程序,于2022年11月30日发布。ChatGPT是人工智能技术驱动的自然语言处理工具,它能够通过理解和学习人类的语言来进行对话,还能根据聊天的上下文进行互动,真正像人类一样来聊天交流,甚至能完成撰写邮件、视频脚本、文案、翻译、代码,写论文等任务。chatGPT是怎么训练出来的ChatGPT的训练方法主要包括以下步骤:构建Prompt Dataset。包含大量提示文本,对GPT-3进行监督学习微调。 训练奖励模型。对第一步微调后的GPT-3进一步推理PromptDataset任务,获得多个结果,交给人工进行标注排序,用标注的结果训练一个奖励模型,用于接下来校正GPT-3的输出结果。采用PPO强化学习算法。持续优化奖励模型,让GPT-3持续自我进化,由机器自动检查自己的学习成果,并不断做出Fine-tuning微调策略。chatGPT与传统的NLP有啥区别,它为什么能突然间火起来ChatGPT与传统的NLP相比,有以下区别:语言处理能力:ChatGPT具有更强大的语言生成和语言理解能力,可以自动学习多种语言模式和知识,而传统的NLP技术通常只针对特定领域或任务进行训练,难以处理多领域的问题。对话交互能力:ChatGPT采用了基于Transformer的模型结构,可以高效地进行对话交互,而传统的NLP技术通常只关注文本的词性和句法结构等特征,难以实现自然流畅的对话交互。知识表示能力:ChatGPT可以更好地理解和记录复杂的知识,并更准确地回答问题,而传统的NLP技术通常只关注文本的语义和上下文信息等特征,难以表示和运用复杂的知识。ChatGPT之所以能突然间火起来,主要是因为其采用了最先进的自然语言处理技术,具有强大的处理能力和广泛的应用场景,可以应用于许多不同的领域,例如智能客服、智能翻译、自然语言生成等等,受到了许多企业和组织的广泛关注和支持。同时,ChatGPT还是一个开源项目,得到了来自全球开发者社区的支持和贡献,可以不断地更新和改进,使得其技术和应用更加完善和优化。补充说明虽然目前chatGPT貌似很强,但是大伙不必慌张,它目前还取代不了人工,只能说成为我们生活中一种更加便捷的工具。类似于小汽车这样的!
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签