本文来自《AI实战90讲》——90个实战项目跑出你的AI竞争力。大家好欢迎来到专栏的第一个实战项目。一、项目简介说个实话我刚开始学深度学习的时候花了两周搭环境、读论文才跑通第一个模型。后来回头看其实没必要这么折腾。这个项目你只需要5分钟复制代码运行看到结果。不需要懂任何数学公式不需要训练任何模型。PyTorch已经帮我们把模型训练好了我们直接用就行。目标只有一个让你第一次看到AI在你自己的电脑上跑起来。二、数据集不需要下载任何数据集。我们要用的ResNet18模型已经在ImageNet数据集上训练好了。ImageNet是什么1400万张图片、1000个分类基本上日常见到的东西它都认识。代码会自动准备一张测试图片。如果网速慢也没关系程序会生成一张本地图片来演示效果。三、完整代码准备工作区导入工具先把要用到的工具包导入进来importtorchfromtorchvisionimporttransformsfromPILimportImage,ImageDrawimportrequestsfromioimportBytesIO核心5行代码下面这5行就是整个项目的灵魂。其余代码都是为了帮这5行跑起来# 核心5行开始 modeltorch.hub.load(pytorch/vision:v0.10.0,resnet18,pretrainedTrue)model.eval()withtorch.no_grad():outputmodel(input_tensor)_,predictedoutput.max(1)# 核心5行结束 你可能会问就这对就这。第一行加载模型第二行切换到评估模式后面三行把图片送进去、推理、拿到结果。辅助代码让核心5行能跑起来核心代码需要两样东西才能工作模型的分类标签告诉我们编号207对应Eskimo dog和一张输入图片。下面就是准备这些东西的代码# 下载1000个分类标签如果网络不通用编号代替try:urlhttps://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txtlabelsrequests.get(url,timeout5).text.strip().split(chr(10))except:labels[f类别{i}foriinrange(1000)]# 准备一张测试图片优先从网络下载失败则本地生成try:img_urlhttps://upload.wikimedia.org/wikipedia/commons/4/47/American_Eskimo_Dog.jpgresponserequests.get(img_url,timeout10)imgImage.open(BytesIO(response.content)).convert(RGB)except:print(在线图片下载失败自动生成本地测试图片)imgImage.new(RGB,(224,224),(180,140,100))drawImageDraw.Draw(img)draw.ellipse([50,50,174,174],fill(200,160,120))# 图片预处理缩放到224x224并进行标准化transformtransforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean[0.485,0.456,0.406],std[0.229,0.224,0.225]),])input_tensortransform(img).unsqueeze(0)# 执行核心推理withtorch.no_grad():outputmodel(input_tensor)probstorch.nn.functional.softmax(output,dim1)[0]_,predictedoutput.max(1)结果为print(f预测结果{labels[predicted.item()]})print(f置信度{probs[predicted.item()]:.4f})# 顺便看看Top-5备选top5torch.topk(probs,5)foriinrange(5):idxtop5.indices[i].item()print(f{i1}.{labels[idx]}:{top5.values[i].item():.3f})你可能注意到了预处理那一段为什么是224x224因为ResNet18训练的时候所有图片都缩成了224x224输入尺寸必须一致。为什么均值是[0.485, 0.456, 0.406]这些数字是ImageNet所有图片的RGB平均值标准化后模型才能正确识别。换别的值也行但准确率会下降——不信你可以试试改成[0,0,0]看效果。四、运行结果正常联网时运行可以看到预测结果Eskimo dog 置信度0.8352 Top-5备选 1. Eskimo dog: 0.835 2. Norwegian elkhound: 0.042 3. malamute: 0.031 4. Siberian husky: 0.015 5. Afghan hound: 0.008看到没Top-5里有4个是犬科。模型虽然没百分之百确定是哪一种狗但它很确定这是一条狗——这就是深度学习学到的东西不是死记硬背它是抓到了本质特征。网络不通时代码会自动用本地生成的图片进行测试。你只需要换掉img_url或改用Image.open()加载自己的图片就能识别任意照片。五、完整代码 项目025行代码跑通第一个AI项目 使用方法python code_02_first_ai_project.py 代码内置网络fallback国内网络环境也能正常运行。 import torch from torchvision import transforms from PIL import Image, ImageDraw import requests from io import BytesIO def load_image(): 加载测试图片网络失败时自动生成本地图片 # 尝试从网络下载 try: img_url https://upload.wikimedia.org/wikipedia/commons/4/47/American_Eskimo_Dog.jpg response requests.get(img_url, timeout10) img Image.open(BytesIO(response.content)).convert(RGB) print(使用在线测试图片爱斯基摩犬) return img except Exception as e: print(f在线图片下载失败: {e}) print(自动生成本地测试图片...) # 生成本地测试图片 img Image.new(RGB, (224, 224), (180, 140, 100)) draw ImageDraw.Draw(img) draw.ellipse([50, 50, 174, 174], fill(200, 160, 120)) draw.ellipse([90, 90, 134, 134], fill(50, 50, 50)) print(生成了包含椭圆形状的测试图片) return img def load_labels(): 下载ImageNet标签失败时使用编号替代 try: url https://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txt text requests.get(url, timeout5).text labels text.strip().split(\n) return labels except: print(提示标签文件下载失败使用编号代替类别名) return [f类别{i} for i in range(1000)] def main(): print(正在下载预训练模型首次运行约44MB...) model torch.hub.load(pytorch/vision:v0.10.0, resnet18, pretrainedTrue) model.eval() print(模型加载完成) labels load_labels() print(f标签数量{len(labels)}) img load_image() print(f图片大小{img.size}) # 图片预处理 transform transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ]) input_tensor transform(img).unsqueeze(0) # 推理 with torch.no_grad(): output model(input_tensor) probs torch.nn.functional.softmax(output, dim1)[0] _, predicted output.max(1) label labels[predicted.item()] confidence probs[predicted.item()].item() print(f\n预测结果{label}) print(f置信度{confidence:.4f}) # Top-5 top5 torch.topk(probs, 5) print(\nTop-5备选) for i in range(5): idx top5.indices[i].item() print(f {i1}. {labels[idx]}: {top5.values[i].item():.3f}) if __name__ __main__: main()5行核心代码加一些辅助工作你就跑通了一个图像分类项目。现在你可以试试用自己手机拍的照片来做预测——把img_url替换成Image.open(‘你的照片.jpg’)就行。试了哪些照片识别结果准不准在评论区告诉我我会回复每一条留言。下一期我们会上难度用猫狗图片数据集训练一个自己的分类模型。