练习 - 上传数据
现在,可以上传用于训练机器学习模型的图像了。 可通过两种方式上传图像:
- 在自定义视觉门户中,选择“上传”,然后对图像进行标记。
- 在 Jupyter Notebook 之类的工具中,使用自定义视觉 SDK 中包含的图像。
如果要上传大量数据、图像类和标记,则使用自定义视觉 SDK 会更快。 不过,你可以选择下面几节所述的选项之一。 完成这些步骤,以最适合你的方式在数据集中上传图像。
选项 1:使用自定义视觉门户上传和标记图像
必须通过每个子文件夹单独上传和标记图像。 对于本练习,可能需要仅上传四到五个子文件夹中的图像,具体取决于上传速度。 请记住,训练机器学习模块时,更多不同的示例将产生更好的结果。
在自定义视觉门户中创建项目:
转到 https://www.customvision.ai/projects 并登录。 选择“新建项目”。
在“创建新项目”中:
在“名称”中,输入所选的项目名称。
在“描述”中,输入模型的短描述。
在“资源组”中,选择在 Azure 门户中创建的资源组。
在“项目类型”中,选择“分类”。
在“分类类型”中,选择“多类(一个图像一个标记)”。
在“域”中,选择“常规”。
选择“创建项目”。
注意
如果要导出模型以便在移动设备上、TensorFlow.js 中或 IoT 中部署,请在“域”下选择“精简”模型选项。 创建项目后,可以在设置中更改此选项。
为鸟类物种添加图像和标记:
在自定义视觉项目中,选择“添加图像”。
在“打开”中,转到从数据集 zip 文件中提取图像文件的 birds-photo 文件夹。
打开鸟类物种文件夹。
选择 Ctrl + A 来选择物种文件夹中的所有图像,然后选择“打开”。
在“图像上传”中,在“我的标记”中添加说明以表明照片中显示的鸟类物种。
选择“上传 <数量> 个文件”。
重复上述步骤,将每个鸟类物种文件夹中的照片上传到下载的数据集。
选项 2:使用 Python 和自定义视觉 SDK 上传和标记图像
自定义视觉 SDK 可用于以下编程语言:Python、.NET、Node.js、Go 和 Java。 我们将使用 Python。 如果尚未安装 Python,建议通过安装 Anaconda 来获取它。 下载 Anaconda 时,即可获得 Python。
如果选择从 GitHub 下载代码,可以使用以下命令克隆存储库:
git clone https://github.com/MicrosoftDocs/mslearn-cv-classify-bird-species.git
按照以下步骤创建虚拟环境并将代码粘贴到该环境中:
打开所选的 IDE。 然后运行以下命令,导入包:
!pip install azure-cognitiveservices-vision-customvision
导入运行脚本所需的包:
from azure.cognitiveservices.vision.customvision.training import CustomVisionTrainingClient from azure.cognitiveservices.vision.customvision.training.models import ImageFileCreateEntry from azure.cognitiveservices.vision.customvision.training.models import ImageFileCreateBatch from msrest.authentication import ApiKeyCredentials import numpy as np
现在,使用以下代码创建自定义视觉项目。 在运行代码之前,请将
<endpoint>
和<key>
占位符替换为自定义视觉资源的值。获取自定义视觉资源值:
在 Azure 门户中,转到自定义视觉资源。
在资源菜单的“资源管理”下,选择“键和终结点”。
从“终结点”框中复制值。 在代码中,将
<endpoint>
占位符替换为该值。对于“键 1”,请选择复制图标以复制该键。 在代码中,将
<key>
占位符替换为该值。
代码将如以下示例所示:
ENDPOINT = "<endpoint>" # Replace with a valid key training_key = "<key>" credentials = ApiKeyCredentials(in_headers={"Training-key": training_key}) publish_iteration_name = "classifyBirdModel" trainer = CustomVisionTrainingClient(ENDPOINT, credentials) # Create a new project print ("Creating project...") project = trainer.create_project("Bird Classification") print("Project created!")
将下载的 bird-photos.zip 文件解压缩到保存了 Jupyter Notebook 文件的相同目录。 将以下要更改的代码添加到项目中的鸟类照片目录。
# Change to the directory for the bird photos import os os.chdir('./bird-photos/custom-photos')
警告
仅运行此单元格中的代码一次。 如果尝试多次运行该单元格而不重新启动 Python 内核,则单元格运行将失败。
添加以下代码以获取鸟类标记的列表。 标记是基于 bird-photos/custom-photos 目录中的文件夹名称创建的:
# Create a tag list from folders in bird directory tags = [name for name in os.listdir('.') if os.path.isdir(name)] print(tags)
接下来,我们将创建三个在
for
循环中调用的函数:createTag
函数在自定义视觉项目中创建类标记。createImageList
函数使用标记名称和标记 ID 生成图像列表。image_list
函数从列表中成批上传图像。
创建三个函数:
在 Jupyter Notebook 文件中,添加
createTag
函数代码。 此函数在自定义视觉项目中创建一个图像名称标记。tag_id = createTag(tag) print(f"tag creation done with tag id {tag_id}") image_list = createImageList(tag, tag_id) print("image_list created with length " + str(len(image_list))) # Break list into lists of 25 and upload in batches for i in range(0, len(image_list), 25): batch = ImageFileCreateBatch(images=image_list[i:i + 25]) print(f'Upload started for batch {i} total items {len(image_list)} for tag {tag}...') uploadImageList(batch) print(f"Batch {i} Image upload completed. Total uploaded {len(image_list)} for tag {tag}")
接下来,添加
createImageList
函数代码。 该函数采用两个参数:文件夹名称列表中的tag
名称,以及在自定义视觉项目中创建的标记的tag_id
。 该函数使用base_image_url
值,将目录设置为包含我们根据文件夹名称创建的tag
的图像的文件夹。 然后将每个图像附加到列表,我们将使用该列表批量上传到创建的tag
:def createImageList(tag, tag_id): # Set directory to current tag. base_image_url = f"./{tag}/" photo_name_list = os.listdir(base_image_url) image_list = [] for file_name in photo_name_list: with open(base_image_url+file_name, "rb") as image_contents: image_list.append(ImageFileCreateEntry(name=base_image_url+file_name, contents=image_contents.read(), tag_ids=[tag_id])) return image_list
要添加的最后一个代码是创建
uploadImageList
函数。 我们传入从文件夹创建的image_list
,然后将该列表上传到tag
:def uploadImageList(image_list): upload_result = trainer.create_images_from_files(project_id=project.id, batch=image_list) if not upload_result.is_batch_successful: print("Image batch upload failed.") for image in upload_result.images: print("Image status: ", image.status) exit(-1)
现在,我们将为 main 方法添加代码。 对于每个标记,该方法都会调用创建的三个函数。 我们将循环遍历从 bird-photos/custom-photos 目录中的文件夹创建的
tags
集合中的每个标记(文件夹名称)。 下面是for
循环包含的步骤:调用前面创建的
createTag
函数在自定义视觉项目中创建tag
类。调用前面创建的
createImageList
函数,并使用自定义视觉返回的tag
名称和tag_id
值。 该函数返回要上传的图像列表。调用前面创建的
imageList
函数以分批上传image_list
中的图像(每批 25 张)。 我们将分批上传(每批 25 张),因为如果尝试同时上传整个数据集,自定义视觉将超时。for tag in tags: tag_id = createTag(tag) print(f"tag creation done with tag id {tag_id}") image_list = createImageList(tag, tag_id) print("image_list created with length " + str(len(image_list))) # Break list into lists of 25 and upload in batches. for i in range(0, len(image_list), 25): batch = ImageFileCreateBatch(images=image_list[i:i + 25]) print(f'Upload started for batch {i} total items {len (image_list)} for tag {tag}...') uploadImageList(batch) print(f"Batch {i} Image upload completed. Total uploaded {len(image_list)} for tag {tag}")
警告
仅运行此单元格中的代码一次。 如果尝试多次运行该单元格而不删除自定义视觉项目,则单元格运行将失败。