2023夏季英特尔oneAPI校园黑客松竞赛——工业品组装缺陷检测
缺陷检测项目
问题陈述
提供:若干张组装后的工业品图片,每张图片中只有一个物体。
要求:学生使用图像分类的AI算法,识别合格和不合格物品。基于训练好的深度学习模型,建立WEB 服务。提供上传图片,同时识别图片中物品是否有缺陷的功能。
评测标准:
- 在INTEL X86服务器/PC上实现WEB服务,具备上传图片和识别图片的功能。
- 图片的识别正确率。
- 图片识别速度。
项目介绍
通过比赛提供的工业品数据,使用图像分类的深度学习算法,识别合格与不合格工业品。并且建立web服务,结合手机拍照为用户提供上传图片途径,快速检测图片中是否有缺陷。
- 照片数据清洗,预处理和标签的标注以及图片格式的转化。
- 根据问题和提供的数据集,选择图片分类的深度学习模型,创建深度学习训练环境。能够具有较好的推理精度正确识别大部分图片。
- 创建基于web的工业品图片检测服务,使用深度学习模型对图片进行识别,并且返回结果和运行时间。
关键技术
flask框架
Flask是一个轻量级的Python Web框架。它是一个微型框架,具有灵活性和可扩展性。Flask使用Python语言编写,它是一个开源框架,使得它可以自由地使用和修改。
它被称为微框架(microframework),“微”并不是意味着把整个Web应用放入到一个Python文件,微框架中的“微”是指Flask旨在保持代码简洁且易于扩展,Flask框架的主要特征是核心构成比较简单,但具有很强的扩展性和兼容性,程序员可以使用Python语言快速实现一个网站或Web服务。
pytorch和torchvision
PyTorch是一个开源的Python机器学习库,基于Torch,用于自然语言处理等应用程序。PyTorch既可以看作加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络。
PyTorch是相当简洁且高效快速的框架,设计追求最少的封装
,设计符合人类思维,它让用户尽可能地专注于实现自己的想法,与google的Tensorflow类似,FAIR的支持足以确保PyTorch获得。
torchvision是pytorch的一个图形库,它服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。
models:提供了很多常用的训练好的网络模型,我们可以直接加载并使用,如Alexnet、ResNet等。
transforms:提供了一些常用的图像转换处理操作,主要针对Tensor或PIL Image进行操作。
迁移学习
迁移学习允许我们采用另一个模型从另一个问题中学到的模式,并将它们用于我们自己的问题。例如,我们可以采用计算机视觉模型,它是从 ImageNet等数据集中学习的模式,并使用它们为FoodVision Mini 模型提供动力。
1.可以利用现有的模型,已经证明可以解决与我们类似的问题。
2.可以利用学习到的模式,这样用较少的自定。
数据集的划分
根据数据图片的情况,划分为三类:合格、不合格、图片不完整。其中图片中工业品完整且四颗螺丝完整,工业品标记为合格;图片中工业品完整且螺丝有缺失,工业品标记为不合格;图片中工业品不完整,标记为图片不完整。
同时数据集按照8:2划分训练集和测试集。
图片类别 | 标签 |
---|---|
合格 | 16 |
不合格 | 16 |
图片不完整 | 85 |
总计 | 117 |
合格图像
不合格图像(四颗螺丝有不同程度缺少)
图片不完整
数据格式转化
在数据集划分的同时,将图片转换成224*224尺寸的图片并且使用transforms.ToTensor()将图片数据转换成tensor格式。
transformer = transforms.Compose([
torchvision.transforms.Resize((224, 224)),
transforms.ToTensor(),
])
使用torch.save()将转换后的训练集和测试集数据保存为pt结尾的文件,方便后面模型训练时数据调用。
torch.save(train_images_tensor, 'train_images_tensor2.pt')
torch.save(test_images_tensor, 'test_images_tensor2.pt')
torch.save(train_labels_tensor, 'train_labels_tensor2.pt')
torch.save(test_labels_tensor, 'test_labels_tensor2.pt')
tensor格式数据加载
# 加载tensor文件
train_images_tensor = torch.load('./train_images_tensor2.pt')
test_images_tensor = torch.load('./test_images_tensor2.pt')
train_labels_tensor = torch.load('./train_labels_tensor2.pt')
test_labels_tensor = torch.load('./test_labels_tensor2.pt')
train_datas_tensor = torch.stack(train_images_tensor)
train_labels_tensor = torch.stack(train_labels_tensor)
test_datas_tensor = torch.stack(test_images_tensor)
test_labels_tensor = torch.stack(test_labels_tensor)
train_dataset = TensorDataset(train_datas_tensor,train_labels_tensor)
train_dataloader = DataLoader(train_dataset,batch_size=8,shuffle=True)
test_dataset = TensorDataset(test_datas_tensor,test_labels_tensor)
test_dataloader = DataLoader(test_dataset,batch_size=8,shuffle=True)
数据增强
数据增强主要是为了减少网络的过拟合现象,通过对训练图片进行变换可以得到泛化能力更强的网络,更好的适应应用场景。本身比赛提供的图片数据仅有117条,相对较少,在使用深度学习模型时容易出现过拟合的情况,所以数据增强相当重要。
本次数据增强主要使用了torchvision.transforms针对图片进行了六种数据增强操作,主要包括:水平翻转、竖直翻转、对比度提高、对比度降低、加入高斯噪声和椒盐噪声。将图片数据扩充了七倍。
处理后的各个类别数据条数如下:
图片类别 | 标签 |
---|---|
合格 | 112 |
不合格 | 112 |
图片不完整 | 595 |
总计 | 819 |
模型训练
在模型训练上,使用了英特尔® oneAPI AI分析工具套件(Intel® AI Analytics Toolkits)中的intel extension for pytorch部署模型。
主要调用torchvision.models中vgg16模型,启用了pretrained参数获取了预训练参数并冻结了部分特征提取层参数。同时修改了全连接层的输入和输出特征数,重新搭建分类器。
其中网络最后两层全连接层修的输出特征参数修改为2048和3。
模型训练结果
数据集 | 精度 |
---|---|
训练集 | 85.71% |
测试集 | 99.07% |
correct = 0
total = 0
with torch.no_grad():
for data in test_dataloader:
images, labels = data[0],data[1]
outputs = vgg16(images)
_,predicted = torch.max(outputs.data,1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy on test set: {100*correct/total:.2f}%')
# print(f'correct:'+str(correct))
# print(f'total:'+str(total))
correct = 0
total = 0
with torch.no_grad():
for data in train_dataloader:
images, labels = data[0],data[1]
outputs = vgg16(images)
_,predicted = torch.max(outputs.data,1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy on train set: {100*correct/total:.2f}%')
web页面搭建
主要使用Flask框架进行搭建,Flask框架可以用于构建任何类型的Web应用程序,包括单页面应用程序、企业应用程序、博客、社交媒体应用程序等等。它提供了一个简洁的API,使得开发者能够快速上手并构建出高效的Web应用。Flask允许开发者根据自己的需求进行定制。
网页效果展示
web部分端代码
@app.route('/', methods=['POST', 'GET'])
def upload():
if request.method == 'POST':
f = request.files['file']
if not (f and allowed_file(f.filename)):
return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于png、PNG、jpg、JPG、bmp"})
user_input = request.form.get("name")
basepath = os.path.dirname(__file__)
upload_path = os.path.join(basepath, 'static/images', secure_filename(f.filename))
f.save(upload_path)
image = Image.open(upload_path)
transformer = transforms.Compose([
torchvision.transforms.Resize((224, 224)),
transforms.ToTensor(),
])
start_time = time.time()
tensor = transformer(image).type(torch.float32).reshape(1,3,224,224)
with torch.no_grad():
outputs = vgg16(tensor)
_,predicted = torch.max(outputs.data,1)
if predicted.item()==0:
result ='产品合格'
elif predicted.item()==1:
result ='图片不完整,无法判断'
else:
result ='产品不合格'
end_time = time.time()
time1 = end_time-start_time
return render_template('upload_ok.html',userinput=user_input,prediction='图片识别为:{}'.format(result),val1='推理时间:{:.3f}s'.format(time1))
return render_template('upload.html')
总结
通过本次学习与实践,我初步了解到了oneAPI的架构与使用方式。但是还是有很多地方可以优化的地方,希望后续可以完成使用oneAP中Intel Neural Compressor模块I进行模型的优化。不断地熟悉oneAPI的使用,争取在更多的地方应用oneAPI组件。