• [其他] 使用自定义算法构建模型(手写数字识别)
    本文为用户提供如何将本地的自定义算法通过简单的代码适配,实现在ModelArts上进行模型训练与部署的全流程指导。场景描述本案例用于指导用户使用PyTorch1.8实现手写数字图像识别,示例采用的数据集为MNIST官方数据集。通过学习本案例,您可以了解如何在ModelArts平台上训练作业、部署推理模型并预测的完整流程。操作流程开始使用如下样例前,请务必按前提条件指导完成必要操作。Step1 准备训练数据:下载MNIST数据集。Step2 准备训练文件和推理文件:编写训练与推理代码。Step3 创建OBS桶并上传文件:创建OBS桶和文件夹,并将数据集和训练脚本,推理脚本,推理配置文件上传到OBS中。Step4 创建训练作业:进行模型训练。Step5 推理部署:训练结束后,将生成的模型导入ModelArts用于创建 AI 应用,并将AI应用部署为在线服务。Step6 预测结果:上传一张手写数字图片,发起预测请求获取预测结果。Step7 清除资源:运行完成后,停止服务并删除OBS中的数据,避免不必要的扣费。前提条件已注册华为云帐号,且在使用ModelArts前检查帐号状态,帐号不能处于欠费或冻结状态。Step1 准备训练数据本案例使用的数据是MNIST数据集,您可以从MNIST官网下载数据集至本地,以下4个文件均要下载。“train-images-idx3-ubyte.gz”:训练集的压缩包文件。训练集,共包含60000个样本。“train-labels-idx1-ubyte.gz”:训练集标签的压缩包文件。训练集标签,共包含60000个样本的类别标签。“t10k-images-idx3-ubyte.gz”:验证集的压缩包文件。验证集,共包含10000个样本。“t10k-labels-idx1-ubyte.gz”:验证集标签的压缩包文件。验证集标签,共包含10000个样本的类别标签。Step2 准备训练文件和推理文件针对此案例,ModelArts提供了需使用的训练脚本、推理脚本和推理配置文件。请参考如下文件内容。训练脚本“train.py”内容如下:# base on https://github.com/pytorch/examples/blob/main/mnist/main.pyfrom __future__ import print_functionimport osimport gzipimport codecsimport argparsefrom typing import IO, Unionimport numpy as npimport torchimport torch.nn as nnimport torch.nn.functional as Fimport torch.optim as optimfrom torchvision import datasets, transforms from torch.optim.lr_scheduler import StepLRimport shutilclass Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 32, 3, 1) self.conv2 = nn.Conv2d(32, 64, 3, 1) self.dropout1 = nn.Dropout(0.25) self.dropout2 = nn.Dropout(0.5) self.fc1 = nn.Linear(9216, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): x = self.conv1(x) x = F.relu(x) x = self.conv2(x) x = F.relu(x) x = F.max_pool2d(x, 2) x = self.dropout1(x) x = torch.flatten(x, 1) x = self.fc1(x) x = F.relu(x) x = self.dropout2(x) x = self.fc2(x) output = F.log_softmax(x, dim=1) return output# 模型训练,设置模型为训练模式,加载训练数据,计算损失函数,执行梯度下降def train(args, model, device, train_loader, optimizer, epoch): model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() output = model(data) loss = F.nll_loss(output, target) loss.backward() optimizer.step() if batch_idx % args.log_interval == 0: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) if args.dry_run: break# 模型验证,设置模型为验证模式,加载验证数据,计算损失函数和准确率def test(model, device, test_loader): model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) output = model(data) test_loss += F.nll_loss(output, target, reduction='sum').item() pred = output.argmax(dim=1, keepdim=True) correct += pred.eq(target.view_as(pred)).sum().item() test_loss /= len(test_loader.dataset) print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format( test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset)))# pytorch mnist# https://github.com/pytorch/vision/blob/v0.9.0/torchvision/datasets/mnist.pydef get_int(b: bytes) -> int: return int(codecs.encode(b, 'hex'), 16)def open_maybe_compressed_file(path: Union[str, IO]) -> Union[IO, gzip.GzipFile]: """Return a file object that possibly decompresses 'path' on the fly. Decompression occurs when argument `path` is a string and ends with '.gz' or '.xz'. """ if not isinstance(path, torch._six.string_classes): return path if path.endswith('.gz'): return gzip.open(path, 'rb') if path.endswith('.xz'): return lzma.open(path, 'rb') return open(path, 'rb')SN3_PASCALVINCENT_TYPEMAP = { 8: (torch.uint8, np.uint8, np.uint8), 9: (torch.int8, np.int8, np.int8), 11: (torch.int16, np.dtype('>i2'), 'i2'), 12: (torch.int32, np.dtype('>i4'), 'i4'), 13: (torch.float32, np.dtype('>f4'), 'f4'), 14: (torch.float64, np.dtype('>f8'), 'f8')}def read_sn3_pascalvincent_tensor(path: Union[str, IO], strict: bool = True) -> torch.Tensor: """Read a SN3 file in "Pascal Vincent" format (Lush file 'libidx/idx-io.lsh'). Argument may be a filename, compressed filename, or file object. """ # read with open_maybe_compressed_file(path) as f: data = f.read() # parse magic = get_int(data[0:4]) nd = magic % 256 ty = magic // 256 assert 1 <= nd <= 3 assert 8 <= ty <= 14 m = SN3_PASCALVINCENT_TYPEMAP[ty] s = [get_int(data[4 * (i + 1): 4 * (i + 2)]) for i in range(nd)] parsed = np.frombuffer(data, dtype=m[1], offset=(4 * (nd + 1))) assert parsed.shape[0] == np.prod(s) or not strict return torch.from_numpy(parsed.astype(m[2], copy=False)).view(*s)def read_label_file(path: str) -> torch.Tensor: with open(path, 'rb') as f: x = read_sn3_pascalvincent_tensor(f, strict=False) assert(x.dtype == torch.uint8) assert(x.ndimension() == 1) return x.long()def read_image_file(path: str) -> torch.Tensor: with open(path, 'rb') as f: x = read_sn3_pascalvincent_tensor(f, strict=False) assert(x.dtype == torch.uint8) assert(x.ndimension() == 3) return xdef extract_archive(from_path, to_path): to_path = os.path.join(to_path, os.path.splitext(os.path.basename(from_path))[0]) with open(to_path, "wb") as out_f, gzip.GzipFile(from_path) as zip_f: out_f.write(zip_f.read())# --- pytorch mnist# --- end# raw mnist 数据处理def convert_raw_mnist_dataset_to_pytorch_mnist_dataset(data_url): """ raw {data_url}/ train-images-idx3-ubyte.gz train-labels-idx1-ubyte.gz t10k-images-idx3-ubyte.gz t10k-labels-idx1-ubyte.gz processed {data_url}/ train-images-idx3-ubyte.gz train-labels-idx1-ubyte.gz t10k-images-idx3-ubyte.gz t10k-labels-idx1-ubyte.gz MNIST/raw train-images-idx3-ubyte train-labels-idx1-ubyte t10k-images-idx3-ubyte t10k-labels-idx1-ubyte MNIST/processed training.pt test.pt """ resources = [ "train-images-idx3-ubyte.gz", "train-labels-idx1-ubyte.gz", "t10k-images-idx3-ubyte.gz", "t10k-labels-idx1-ubyte.gz" ] pytorch_mnist_dataset = os.path.join(data_url, 'MNIST') raw_folder = os.path.join(pytorch_mnist_dataset, 'raw') processed_folder = os.path.join(pytorch_mnist_dataset, 'processed') os.makedirs(raw_folder, exist_ok=True) os.makedirs(processed_folder, exist_ok=True) print('Processing...') for f in resources: extract_archive(os.path.join(data_url, f), raw_folder) training_set = ( read_image_file(os.path.join(raw_folder, 'train-images-idx3-ubyte')), read_label_file(os.path.join(raw_folder, 'train-labels-idx1-ubyte')) ) test_set = ( read_image_file(os.path.join(raw_folder, 't10k-images-idx3-ubyte')), read_label_file(os.path.join(raw_folder, 't10k-labels-idx1-ubyte')) ) with open(os.path.join(processed_folder, 'training.pt'), 'wb') as f: torch.save(training_set, f) with open(os.path.join(processed_folder, 'test.pt'), 'wb') as f: torch.save(test_set, f) print('Done!')def main(): # 定义可以接收的训练作业运行参数 parser = argparse.ArgumentParser(description='PyTorch MNIST Example') parser.add_argument('--data_url', type=str, default=False, help='mnist dataset path') parser.add_argument('--train_url', type=str, default=False, help='mnist model path') parser.add_argument('--batch-size', type=int, default=64, metavar='N', help='input batch size for training (default: 64)') parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N', help='input batch size for testing (default: 1000)') parser.add_argument('--epochs', type=int, default=14, metavar='N', help='number of epochs to train (default: 14)') parser.add_argument('--lr', type=float, default=1.0, metavar='LR', help='learning rate (default: 1.0)') parser.add_argument('--gamma', type=float, default=0.7, metavar='M', help='Learning rate step gamma (default: 0.7)') parser.add_argument('--no-cuda', action='store_true', default=False, help='disables CUDA training') parser.add_argument('--dry-run', action='store_true', default=False, help='quickly check a single pass') parser.add_argument('--seed', type=int, default=1, metavar='S', help='random seed (default: 1)') parser.add_argument('--log-interval', type=int, default=10, metavar='N', help='how many batches to wait before logging training status') parser.add_argument('--save-model', action='store_true', default=True, help='For Saving the current Model') args = parser.parse_args() use_cuda = not args.no_cuda and torch.cuda.is_available() torch.manual_seed(args.seed) # 设置使用 GPU 还是 CPU 来运行算法 device = torch.device("cuda" if use_cuda else "cpu") train_kwargs = {'batch_size': args.batch_size} test_kwargs = {'batch_size': args.test_batch_size} if use_cuda: cuda_kwargs = {'num_workers': 1, 'pin_memory': True, 'shuffle': True} train_kwargs.update(cuda_kwargs) test_kwargs.update(cuda_kwargs) # 定义数据预处理方法 transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) # 将 raw mnist 数据集转换为 pytorch mnist 数据集 convert_raw_mnist_dataset_to_pytorch_mnist_dataset(args.data_url) # 分别创建训练和验证数据集 dataset1 = datasets.MNIST(args.data_url, train=True, download=False, transform=transform) dataset2 = datasets.MNIST(args.data_url, train=False, download=False, transform=transform) # 分别构建训练和验证数据迭代器 train_loader = torch.utils.data.DataLoader(dataset1, **train_kwargs) test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs) # 初始化神经网络模型并拷贝模型到计算设备上 model = Net().to(device) # 定义训练优化器和学习率策略,用于梯度下降计算 optimizer = optim.Adadelta(model.parameters(), lr=args.lr) scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma) # 训练神经网络,每一轮进行一次验证 for epoch in range(1, args.epochs + 1): train(args, model, device, train_loader, optimizer, epoch) test(model, device, test_loader) scheduler.step() # 保存模型与适配 ModelArts 推理模型包规范 if args.save_model: # 在 train_url 训练参数对应的路径内创建 model 目录 model_path = os.path.join(args.train_url, 'model') os.makedirs(model_path, exist_ok = True) # 按 ModelArts 推理模型包规范,保存模型到 model 目录内 torch.save(model.state_dict(), os.path.join(model_path, 'mnist_cnn.pt')) # 拷贝推理代码与配置文件到 model 目录内 the_path_of_current_file = os.path.dirname(__file__) shutil.copyfile(os.path.join(the_path_of_current_file, 'infer/customize_service.py'), os.path.join(model_path, 'customize_service.py')) shutil.copyfile(os.path.join(the_path_of_current_file, 'infer/config.json'), os.path.join(model_path, 'config.json'))if __name__ == '__main__': main()推理配置文件“config.json”内容如下:{ "model_algorithm": "image_classification", "model_type": "PyTorch", "runtime": "pytorch_1.8.0-cuda_10.2-py_3.7-ubuntu_18.04-x86_64"}Step3 创建OBS桶并上传文件将训练使用的数据和代码文件、推理代码文件与推理配置文件,上传到OBS桶中。在 ModelArts 上运行训练作业时,需要从OBS桶中读取数据和代码文件。登录OBS管理控制台,按照如下示例创建OBS桶和文件夹。创建OBS桶和文件夹的操作指导请参见创建桶和新建文件夹。{OBS桶} # OBS对象桶,用户可以自定义名称,例如:test-modelarts-xx -{OBS文件夹} # OBS文件夹,自定义名称,此处举例为pytorch - mnist-data # OBS文件夹,用于存放训练数据集,可以自定义名称,此处举例为mnist-data - mnist-code # OBS文件夹,用于存放训练脚本train.py,可以自定义名称,此处举例为mnist-code - infer # OBS文件夹,用于存放推理脚本customize_service.py和配置文件config.json - mnist-output # OBS文件夹,用于存放训练输出模型,可以自定义名称,此处举例为mnist-output注意创建的OBS桶所在区域和后续使用ModelArts必须在同一个区域Region,否则会导致训练时找不到OBS桶。具体操作可参见如何查看查看OBS桶与ModelArts是否在同一区域。创建OBS桶时,桶的存储类别请勿选择“归档存储”,归档存储的OBS桶会导致模型训练失败。上传数据集到OBS中。上传文件至OBS的操作指导请参见上传文件上传训练脚本“train.py”到“mnist-code”文件夹中。上传推理脚本“customize_service.py”和推理配置文件“config.json”到“infer”文件中。Step4 创建训练作业登录ModelArts管理控制台,选择和OBS桶相同的区域。在“全局配置”中检查当前帐号是否已完成访问授权的配置。如未完成,请参考使用委托授权。针对之前使用访问密钥授权的用户,建议清空授权,然后使用委托进行授权。在左侧导航栏的“训练管理”-> “训练作业”中,单击“创建训练作业”。填写创建训练作业相关信息。“创建方式”:选择“自定义”,下拉框中选择PyTorch,pytorch_1.8.0-cuda_10.2-py_3.7-ubuntu_18.04-x86_64。“代码目录”:选择已创建的代码目录路径“/test-modelarts-xx/pytorch/mnist-code/”。“启动文件”:选择代码目录下上传的训练脚本“train.py”。“训练输入”:单击“添加”,设置训练输入的“参数名称”为“data_url”。设置数据存储位置为 “/test-modelarts-xx/pytorch/mnist-data/”。“训练输出”:单击“添加”,设置训练输出的“参数名称”为“train_url”。设置数据存储位置为 “/test-modelarts-xx/pytorch/mnist-output/”“资源类型”:选择 GPU 单卡的规格,如“GPU: 1*NVIDIA-V100(16GB) | CPU: 8 核 64GB 780GB”。单击“提交”,确认训练作业的参数信息,确认无误后单击“确定”。页面自动返回“训练作业”列表页,当训练作业状态变为“已完成”时,即完成了模型训练过程。单击训练作业名称,进入作业详情界面查看训练作业日志信息,观察日志是否有明显的Error信息,如果有则表示训练失败,请根据日志提示定位原因并解决。在训练详情页左下方单击训练输出路径,跳转到OBS目录,查看是否存在model文件夹,且model文件夹中是否有生成训练模型。如果未生成model文件夹或者训练模型,可能是训练输入数据不完整导致,请检查训练数据上传是否完整,并重新训练。Step5 推理部署模型训练完成后,可以创建AI应用,将AI应用部署为在线预测服务。在ModelArts管理控制台,单击左侧导航栏中的“AI应用管理>AI应用”,进入“我的AI应用”页面,单击“创建”。在“创建AI应用”页面,填写相关参数,然后单击“立即创建”。在“元模型来源”中,选择“从训练中选择>训练作业(New)”页签,选择Step4 创建训练作业中完成的训练作业,勾选“动态加载”。AI引擎的值是系统自动写入的,无需设置。在AI应用列表页面,当模型状态变为“正常”时,表示AI应用创建成功。单击AI应用名称左侧的小三角,打开此AI应用下的所有版本。在对应版本所在行,单击操作列“部署>在线服务”,将模型部署为在线服务。在“部署”页面,参考下图填写参数,然后根据界面提示完成在线服务创建。完成服务部署后,返回在线服务页面列表页,等待服务部署完成,当服务状态显示为“运行中”,表示服务已部署成功。Step6 预测结果在“在线服务”页面,单击在线服务名称,进入服务详情页面。单击“预测”页签,请求类型选择“multipart/form-data”,请求参数填写“image”,单击“上传”按钮上传示例图片,然后单击“预测”。预测完成后,预测结果显示区域将展示预测结果,根据预测结果内容,可识别出此图片的数字是“2”。Step7 清除资源如果不再需要使用此模型及在线服务,建议清除相关资源,避免产生不必要的费用。在“在线服务”页面,“停止”或“删除”刚创建的在线服务。在“AI应用管理”页面,“删除”刚创建的AI应用。在“训练作业New”页面,“删除”运行结束的训练作业。进入OBS,删除本示例使用的OBS 桶及文件夹,以及文件夹的文件。
  • [其他] 体验Stable Diffusion文字生成图像
    ModelArts 是面向开发者的一站式 AI 平台,为机器学习与深度学习提供海量数据预处理及交互式智能标注、大规模分布式训练、自动化模型生成,及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期 AI 工作流。点击Run in ModelArts,将会进入到ModelArts CodeLab中,这时需要你登录华为云账号,如果没有账号,则需要注册一个,且要进行实名认证,参考 https://developer.huaweicloud.com/develop/aigallery/article/detail?id=4ce709d6-eb25-4fa4-b214-e2e5d6b7919c 即可完成账号注册和实名认证。 登录之后,等待片刻,即可进入到CodeLab的运行环境Stable Diffusion文字生成图像 🎨Stable Diffusion 是由 CompVis、Stability AI 和 LAION 共同开发的一个文本转图像模型,它通过 LAION-5B 子集大量的 512x512 图文模型进行训练,我们只要简单的输入一段文本,Stable Diffusion 就可以迅速将其转换为图像,同样我们也可以置入图片或视频,配合文本对其进行处理Stable Diffusion Pipeline使用方法本案例可以使用GPU,也可以使用CPU来运行,GPU生成单张图片约20秒,CPU需6分钟
  • AI作诗
    finishjv'l'ri't'c'f'v't
  • [互动交流] 如何上传数据至OBS?
    如何上传数据至OBS?
  • [其他] AI绘画,一键成画,加油加油。
    1自己的第一次尝试,谢谢大家。
  • [互动交流] ACGAN-动漫头像自动生成—按照操作说明无法完成,请帮忙看看是什么问题
    RestraACGAN-动漫头像自动生成—按照操作说明无法完成,图片一直上传不成功,提示:Kernel Restarting​
  • [其他] 阳光海边
    海上的小屋一片平静,夏日太阳
  • [互动交流] 如何查看训练作业事件?
    如何查看训练作业事件?
  • AI绘画
    人人都是可以成为画家。
  • [互动交流] 自动学习训练后的模型怎么下载
    自动学习训练后的模型怎么下载
  • [互动交流] 在线服务预测时,怎么提高预测精度
    在线服务预测时,怎么提高预测精度?
  • [互动交流] 部署 GPU 服务支持的 Cuda 版本是多少?
    部署 GPU 服务支持的 Cuda 版本是多少?
  • [互动交流] notebook之间如何数据迁移
    我想把notebook里的数据拷到另外一个notebook中,应该怎么操作呀
  • [互动交流] 怎么将标注后的结果下载到本地
    怎么将ModelArts标注后的结果下载到本地
  • [互动交流] cartoongan 图像动漫化的案例训练中,总出现以下弹窗怎么回事呀?
    cartoongan 图像动漫化的案例训练中,总出现以下弹窗怎么回事呀?
总条数:3403 到第
上滑加载中