小熊飞桨练习册-02眼疾识别,本项目开发和测试均在 Ubuntu 20.04 系统下进行。
项目最新代码查看主页:小熊飞桨练习册
百度飞桨 AI Studio 主页:小熊飞桨练习册-02眼疾识别
Ubuntu 系统安装 CUDA 参考:Ubuntu 百度飞桨和 CUDA 的安装
| 文件 | 说明 |
|---|---|
| train.py | 训练程序 |
| test.py | 测试程序 |
| test-gtk.py | 测试程序 GTK 界面 |
| report.py | 报表程序 |
| onekey.sh | 一键获取数据到 dataset 目录下 |
| get-data.sh | 获取数据到 dataset 目录下 |
| check-data.sh | 检查 dataset 目录下的数据是否存在 |
| mod/alexnet.py | AlexNet 网络模型 |
| mod/dataset.py | ImageClass 图像分类数据集解析 |
| mod/utils.py | 杂项 |
| mod/config.py | 配置 |
| mod/report.py | 结果报表 |
| dataset | 数据集目录 |
| params | 模型参数保存目录 |
| log | VisualDL 日志保存目录 |
数据集来源于百度飞桨公共数据集:眼疾识别数据集iChallenge-整理版
如果运行在本地计算机,下载完数据,文件放到 dataset 目录下,在项目目录下运行下面脚本。
如果运行在百度 AI Studio 环境,查看 data 目录是否有数据,在项目目录下运行下面脚本。
bash onekey.sh
如果运行在本地计算机,下载完数据,文件放到 dataset 目录下,在项目目录下运行下面脚本。
如果运行在百度 AI Studio 环境,查看 data 目录是否有数据,在项目目录下运行下面脚本。
bash get-data.sh
获取数据完毕后,在项目目录下运行下面脚本,检查 dataset 目录下的数据是否存在。
bash check-data.sh
网络模型使用 AlexNet 网络模型 来源百度飞桨教程和网络。
AlexNet 网络模型 参考: 百度飞桨教程
import paddle
import paddle.nn as nn
import paddle.nn.functional as F
# AlexNet 网络模型
class AlexNet(nn.Layer):
"""
AlexNet 网络模型
输入图像大小为 224 x 224
池化层 kernel_size = 2, 第一层卷积层填充 paddling = 2
"""
def __init__(self, num_classes=10, pool_kernel_size=2, conv1_paddling=2, fc1_in_features=9216):
"""
AlexNet 网络模型
Args:
num_classes (int, optional): 分类数量, 默认 10
pool_kernel_size (int, optional): 池化层核大小, 默认 2
conv1_paddling (int, optional): 第一层卷积层填充, 默认 2,
输入图像大小为 224 x 224 填充 2
fc1_in_features (int, optional): 第一层全连接层输入特征数量, 默认 9216,
根据 max_pool3 输出结果, 计算得出 256*6*6 = 9216
Raises:
Exception: 分类数量 num_classes 必须大于等于 2
"""
super(AlexNet, self).__init__()
if num_classes < 2:
raise Exception("分类数量 num_classes 必须大于等于 2: {}".format(num_classes))
self.num_classes = num_classes
self.pool_kernel_size = pool_kernel_size
self.fc1_in_features = fc1_in_features
self.conv1 = nn.Conv2D(
in_channels=3, out_channels=96, kernel_size=11, stride=4, padding=conv1_paddling)
self.max_pool1 = nn.MaxPool2D(kernel_size=pool_kernel_size, stride=2)
self.conv2 = nn.Conv2D(
in_channels=96, out_channels=256, kernel_size=5, stride=1, padding=2)
self.max_pool2 = nn.MaxPool2D(kernel_size=pool_kernel_size, stride=2)
self.conv3 = nn.Conv2D(
in_channels=256, out_channels=384, kernel_size=3, stride=1, padding=1)
self.conv4 = nn.Conv2D(
in_channels=384, out_channels=384, kernel_size=3, stride=1, padding=1)
self.conv5 = nn.Conv2D(
in_channels=384, out_channels=256, kernel_size=3, stride=1, padding=1)
self.max_pool3 = nn.MaxPool2D(kernel_size=pool_kernel_size, stride=2)
# in_features 9216 = max_pool3 输出 256*6*6
self.fc1 = nn.Linear(in_features=fc1_in_features, out_features=4096)
self.drop_ratio1 = 0.5
self.drop1 = nn.Dropout(self.drop_ratio1)
self.fc2 = nn.Linear(in_features=4096, out_features=4096)
self.drop_ratio2 = 0.5
self.drop2 = nn.Dropout(self.drop_ratio2)
self.fc3 = nn.Linear(in_features=4096, out_features=num_classes)
def forward(self, x):
x = self.conv1(x)
x = F.relu(x)
x = self.max_pool1(x)
x = self.conv2(x)
x = F.relu(x)
x = self.max_pool2(x)
x = self.conv3(x)
x = F.relu(x)
x = self.conv4(x)
x = F.relu(x)
x = self.conv5(x)
x = F.relu(x)
x = self.max_pool3(x)
# flatten 根据给定的 start_axis 和 stop_axis 将连续的维度展平
x = paddle.flatten(x, start_axis=1, stop_axis=-1)
x = self.fc1(x)
x = F.relu(x)
# 在全连接之后使用 dropout 抑制过拟合
x = self.drop1(x)
x = self.fc2(x)
x = F.relu(x)
# 在全连接之后使用 dropout 抑制过拟合
x = self.drop2(x)
x = self.fc3(x)
return x
数据集解析,主要是解析 图像路径和标签的文本 ,然后根据图像路径读取图像和标签。
import paddle
import os
import random
import numpy as np
from PIL import Image
import paddle.vision as ppvs
class ImageClass(paddle.io.Dataset):
"""
ImageClass 图像分类数据集解析, 继承 paddle.io.Dataset 类
"""
def __init__(self,
dataset_path: str,
images_labels_txt_path: str,
transform=None,
shuffle=True
):
"""
构造函数,定义数据集
Args:
dataset_path (str): 数据集路径
images_labels_txt_path (str): 图像和标签的文本路径
transform (Compose, optional): 转换数据的操作组合, 默认 None
shuffle (bool, True): 随机打乱数据, 默认 True
"""
super(ImageClass, self).__init__()
self.dataset_path = dataset_path
self.images_labels_txt_path = images_labels_txt_path
self._check_path(dataset_path, "数据集路径错误")
self._check_path(images_labels_txt_path, "图像和标签的文本路径错误")
self.transform = transform
self.image_paths, self.labels = self.parse_dataset(
dataset_path, images_labels_txt_path, shuffle)
def __getitem__(self, idx):
"""
获取单个数据和标签
Args:
idx (Any): 索引
Returns:
image (float32): 图像
label (int): 标签
"""
image_path, label = self.image_paths[idx], self.labels[idx]
return self.get_item(image_path, label, self.transform)
@staticmethod
def get_item(image_path: str, label: int, transform=None):
"""
获取单个数据和标签
Args:
image_path (str): 图像路径
label (int): 标签
transform (Compose, optional): 转换数据的操作组合, 默认 None
Returns:
image (float32): 图像
label (int): 标签
"""
if not os.path.exists(image_path):
raise Exception("{}: {}".format("图像路径错误", image_path))
ppvs.set_image_backend("pil")
# 统一转为 3 通道, png 是 4通道
image = Image.open(image_path).convert("RGB")
if transform is not None:
image = transform(image)
# 转换图像 HWC 转为 CHW
# image = np.transpose(image, (2, 0, 1))
return image.astype("float32"), label
def __len__(self):
"""
数据数量
Returns:
int: 数据数量
"""
return len(self.labels)
def _check_path(self, path: str, msg: str):
"""
检查路径是否存在
Args:
path (str): 路径
msg (str, optional): 异常消息
Raises:
Exception: 路径错误, 异常
"""
if not os.path.exists(path):
raise Exception("{}: {}".format(msg, path))
@staticmethod
def parse_dataset(dataset_path: str, images_labels_txt_path: str, shuffle: bool):
"""
数据集解析
Args:
dataset_path (str): 数据集路径
images_labels_txt_path (str): 图像和标签的文本路径
Returns:
image_paths: 图像路径集
labels: 分类标签集
"""
lines = []
image_paths = []
labels = []
with open(images_labels_txt_path, "r") as f:
lines = f.readlines()
# 随机打乱数据
if (shuffle):
random.shuffle(lines)
for i in lines:
data = i.split(" ")
if (len(data) < 2):
raise Exception("数据集解析错误,数据少于 2")
image_paths.append(os.path.join(dataset_path, data[0]))
labels.append(int(data[1]))
return image_paths, labels
可以查看修改 mod/config.py 文件,有详细的说明
运行 train.py 文件,查看命令行参数加 -h
python3 train.py
--cpu 是否使用 cpu 计算,默认使用 CUDA
--learning-rate 学习率,默认 0.001
--epochs 训练几轮,默认 2 轮
--batch-size 一批次数量,默认 2
--num-workers 线程数量,默认 2
--no-save 是否保存模型参数,默认保存, 选择后不保存模型参数
--load-dir 读取模型参数,读取 params 目录下的子文件夹, 默认不读取
--log 是否输出 VisualDL 日志,默认不输出
--summary 输出网络模型信息,默认不输出,选择后只输出信息,不会开启训练
运行 test.py 文件,查看命令行参数加 -h
python3 test.py
--cpu 是否使用 cpu 计算,默认使用 CUDA
--batch-size 一批次数量,默认 2
--num-workers 线程数量,默认 2
--load-dir 读取模型参数,读取 params 目录下的子文件夹, 默认 best 目录
运行 test-gtk.py 文件,此程序依赖 GTK 库,只能运行在本地计算机。
python3 test-gtk.py
python3 -m pip install pygobject
运行 report.py 文件,可以显示 params 目录下所有子目录的 report.json。
加参数 --best 根据 loss 最小的模型参数保存在 best 子目录下。
python3 report.py
| 键名 | 说明 |
|---|---|
| id | 根据时间生成的字符串 ID |
| loss | 本次训练的 loss 值 |
| acc | 本次训练的 acc 值 |
| epochs | 本次训练的 epochs 值 |
| batch_size | 本次训练的 batch_size 值 |
| learning_rate | 本次训练的 learning_rate 值 |
visualdl --logdir ./log
导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri
之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在
1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析: 在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1: print(k)k=k/2A.1000 B.10C.11D.9解析: 按照题意每次循环K/2,直到K值小于等
在我让另一个人重做我的前端UI之前,我的Rails应用程序运行平稳。我已经尝试解决此错误3天了。这是错误:Nosuchfileordirectory-identifyExtractedsource(aroundline#59):575859606162@post=Post.find(params[:id])authorize@postif@post.update_attributes(post_params)flash[:notice]="Postwasupdated."redirect_to[@topic,@post]else{"utf8"=>"✓","_method"=>"patc
如果我们有一个数组array=[1,1,0,0,2,3,0,0,0,3,3,3]我们如何识别给定数字的运行(具有相同值的连续数字的数量)?例如:run_pattern_for(array,0)->2run_pattern_for(array,3)->1run_pattern_for(array,1)->1run_pattern_for(array,2)->0没有2的运行,因为没有连续出现2。3有一个运行,因为只有一个幻影以树为连续数字。 最佳答案 尝试:classArraydefcount_runs(element)chunk{|n
技术选型1,前端小程序原生MINA框架cssJavaScriptWxml2,管理后台云开发Cms内容管理系统web网页3,数据后台小程序云开发云函数云开发数据库(基于MongoDB)云存储4,人脸识别算法基于百度智能云实现人脸识别一,用户端效果图预览老规矩我们先来看效果图,如果效果图符合你的需求,就继续往下看,如果不符合你的需求,可以跳过。1-1,登录注册页可以看到登录页有注册入口,注册页如下我们的注册,需要管理员审核,审核通过后才可以正常登录使用小程序1-2,个人中心页登录成功以后,我们会进入个人中心页我们在个人中心页可以注册人脸,因为我们做人脸识别签到,需要先注册人脸才可以进行人脸比对,进
当尝试创建一个heroku应用程序并通过git推送到它时,我收到以下错误:$herokucreate'"C:\ProgramFiles\ruby-1.9.2\bin\ruby.exe"isnotrecognizedasaninternalorexternalcommand,operableprogramorbatchfile.但是,$ruby-vruby1.9.3p125[i386-mingw32]我已经检查了PATH环境,它肯定包含“C:\ProgramFiles(x86)\ruby-1.9.2\bin”。同样有趣的是,当导航到该目录时,它实际上并不包含名为ruby.exe的文件
本文章承接《基于Python的人脸识别课堂考勤系统(毕设)》,填坑上篇文章遗留的代码部分。因为项目分的模块比较多,再加上本人能力有限,所以代码过于臃肿还存在许多优化的地方。同样本篇文章也仅适用于小白,零基础人群。PS:每个文件之中代码都已经区分开来,可以对照左侧目录部分实现快速预览! 由于代码过于多我这里分成上,下两个部分来发布吧!一、主文件importosimportsysimportrandomimportpymysqlimportcv2importnumpyasnpfrommathimportpifrommatplotlibimportpyplotaspltfromPILimpor