KerasUI是一种可视化工具,可以在图像分类中轻松训练模型,并允许将模型作为服务使用,只需调用API。
https://github.com/zeppaman/KerasUI
主要特点:
用oauth2验证
允许完整的模型定制
可以上传尚未训练的模型并通过API消费
测试表格和视觉检查网络如何工作
批量上传训练集
用法
运行standalone.bat或sh standalone.bat(这将安装需求应用迁移并运行服务器,相同的脚本适用于UNIX和Windows)
使用创建管理员用户 python manage.py createsuperuser
导航到http://127.0.0.1:8000/
这需要python 3+,如果安装了多个版本,请根据(即pip3)更改脚本。
如何管理数据集
Keras UI允许将数据集项(图像)上载到Web应用程序中。您可以逐个执行此操作,也可以一次性添加包含许多图像的zip文件。它管理多个数据集,因此您可以将事物分开。加载图像后,可以单击“训练”按钮并运行训练过程。这将训练您定义的模型,而无需您进行任何交互。你将获得训练结果,如果你很挑剔,你可以转到日志文件,看看系统输出了什么
如何使用Web UI进行测试
为避免失眠,提供了一个简单的表格,可以上传图像并获得结果。
如何使用API UI或邮递员来测试API
在Web UI中看到的所有内容都可以使用API进行复制。
API使用情况
此应用程序使用oauth2来验证请求,因此需要的第一步是获取令牌。这是密码流的一个简单示例。请记住必须启用该应用程序(首次运行时不会默认创建)。
Assumingclient hUiSQJcR9ZrmWSecwh1gloi7pqGTOclss4GwIt1osecret ZuuLK21sQ2uZxk8dVG7k6pO474FBlM6DEQs7FQvDh28gdLtbCDJwFFi0YlTlLsbz9ddjUa7Lun6ifYwkfwyGMD95WsCuzibFWIMpsZHMA039RIv1mOsYUO5nK5ZVv1hB POST to http://127.0.0.1:8000/o/token/ Headers:Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencoded Body:grant_type:passwordusername:adminpassword:admin2019!
回应是
{ "access_token": "h6WeZwYwqahFDqGDRr6mcToyAm3Eae", "expires_in": 36000, "token_type": "Bearer", "scope": "read write", "refresh_token": "eg97atDWMfqC1lYKW81XCvltj0sism"}
获取预测的API可以在json post或form post中使用。在json post中,图像以base64字符串形式发送。这种使用服务的双重方式非常有用,因为可以将其链接到表单或直接与wget或curl工具一起使用,也可以在应用程序中使用它。
POST http://127.0.0.1:8000/api/test/ Headers:Content-Type:application/jsonAuthorization:Bearer Body{ "image":", "dataset":1}
响应
{ "result": ""}
教程
该项目是Codeproject上图像分类上下文的一部分。这里是技术部分的演练,解释它是如何构建的以及它是如何工作的。
项目堆栈:
python
django框架
keras,tensorflow,numpy
sqlite(或您喜欢的其他数据库)
使用的工具:
Visual Studio代码
邮差
一个Web浏览器
项目设置
该项目基于Django,因此首先要做的是使用CLI创建一个Django项目。这需要从pip安装Django。
django-admin startproject kerasui ' create the project
此命令将生成以下结构:
kerasui/ manage.py kerasui/ __init__.py settings.py urls.py wsgi.py
这些文件是:
外部kerasui / root目录只是项目的容器。内部mysite /目录是项目的实际Python包。它的名称是需要用来导入其中任何内容的Python包名称(例如mysite.urls)。
manage.py:一个命令行实用程序,允许以各种方式与此Django项目进行交互。可以在jango-admin和manage.py中阅读有关manage.py的所有详细信息。
__init__.py:一个空文件,告诉Python该目录应该被视为Python包。如果是Python初学者,请阅读官方Python文档中有关包的更多信息。
kerasui / settings.py:此Django项目的设置/配置。Django设置将告诉有关设置如何工作的所有信息。
kerasui / urls.py:此Django项目的URL声明; Django支持的站点的“目录”。可以在URL调度程序中阅读有关URL的更多信息。
kerasui / wsgi.py:与WSGI兼容的Web服务器的入口点,用于为项目提供服务。有关更多详细信息,请参阅如何使用WSGI进行部署。
运行
要检查是否一切正常,只需使用内置服务器运行django
python manage.py runserver
也可以使用setup visual studio代码来运行django /
这是django配置:
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Python: Django", "type": "python", "request": "launch", "program": "${workspaceFolder}\\kerasui\\manage.py", "args": [ "runserver", "--noreload", "--nothreading" ], "django": true } ]}
设置配置
这里配置的基本部分告诉:
使用oauth 2和会话认证使:常规Web用户登录并使用网站和休息沙箱,API用户获取令牌并查询API服务
使用SQLite(可以更改为移动到任何其他数据库)
添加所有Django模块(以及两个自定义:管理UI和API)
启用cors
INSTALLED_APPS = [ 'python_field', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'oauth2_provider', 'corsheaders', 'rest_framework', 'management', 'api',] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'corsheaders.middleware.CorsMiddleware',] ROOT_URLCONF = 'kerasui.urls' REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', ), 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 10,} DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}
第一次运行
Django使用迁移系统从您定义的模型生成迁移文件。要应用迁移,只需运行migrate命令(makemigration即可从模型创建迁移文件)。
用户数据库开始为空,因此需要创建admin用户才能登录。这是通过createsuperadmin命令完成的
python manage.py migratepython manage.py createsuperuseradmin\admin2019!
它是如何构建的
该应用程序分为3个模块:
管理部分: Web UI,模块和所有核心内容
后台工作者:是一个可以在后台执行的Django命令,用于根据数据集训练模型
API:此部分公开API以从外部与应用程序交互。例如,这允许从第三方应用程序向数据集添加项目。此外,最常见的用法是发送图像并获得预测结果
管理
在Django上创建一个应用程序:
python manage.py startapp management
这将创建主文件。在这个模块中,使用的最多是模型和模型表示:
module.py:这里是所有具有现场规格的型号。通过这样的类定义,所有都被设置为对实体具有可用的CRUD
admin.py:此图层描述了如何使用表单显示和编辑数据。
数据模型非常简单。假设只想为每个数据集训练一个模型
DataSet:它包含模型,模型设置和数据集的名称。
DataSetItem:它包含数据集项,因此每行一个图像附加标签。
这里只是一个模型和模型表示的示例:
#from admin.pyclass DataSetForm( forms.ModelForm ): process =forms.CharField( widget=forms.Textarea(attrs={'rows':40, 'cols':115}), initial=settings.PROCESS_TEMPLATE ) model_labels =forms.CharField(initial="[]") class Meta: model = DataSet fields = ['name', 'process','epochs','batchSize','verbose','model_labels','model'] widgets = { 'process': forms.Textarea(attrs={'rows':20, 'cols':200}), } def train(modeladmin, request, queryset): for dataset in queryset: DataSetAdmin.train_async(dataset.id) class DataSetAdmin(admin.ModelAdmin): list_display = ('name','epochs','batchSize','verbose','progress') inlines = [ # DataSetItemInline, ] form=DataSetForm actions = [train] change_list_template = "dataset_changelist.html" @staticmethod def train(datasetid): call_command('train',datasetid) @staticmethod def train_async(datasetid): t = threading.Thread(target=DataSetAdmin.train, args=(datasetid,)) t.setDaemon(True) t.start() admin.site.register(DataSet,DataSetAdmin) #from model.py class DataSet(models.Model): name= models.CharField(max_length=200) process = models.CharField(max_length=5000, default=settings.PROCESS_TEMPLATE) model = models.ImageField(upload_to=path_model_name,max_length=300,db_column='modelPath',blank=True, null=True) #weights = models.ImageField(upload_to=path_model_name,max_length=300,db_column='weightPath',blank=True, null=True) batchSize = models.IntegerField(validators=[MaxValueValidator(100), MinValueValidator(1)],default=10) epochs = models.IntegerField(validators=[MaxValueValidator(100), MinValueValidator(1)],default=10) verbose = models.BooleanField(default=True) progress = models.FloatField(default=0) model_labels= models.CharField(max_length=200) def __str__(self): return self.name
Django采用代码优先方法,因此需要运行python manage.py makemigrations以生成将应用于数据库的迁移文件。
python manage.py makemigrations
背景工作者
要创建后台工作程序,需要一个模块来托管它,使用了管理模块。在其中需要创建一个management文件夹。其上的每个文件都可以python manage.py commandname通过API 运行或通过API 运行。
在例子中,通过常规的Django动作在后台进程中启动命令
这是相关部分:
class DataSetAdmin(admin.ModelAdmin): actions = [train] # .... @staticmethod def train(datasetid): call_command('train',datasetid) @staticmethod def train_async(datasetid): t = threading.Thread(target=DataSetAdmin.train, args=(datasetid,)) t.setDaemon(True) t.start()
API
API是在一个单独的应用程序中创建的
python manage.py startapp API
基本上所有CRUD模型都可以通过API公开,但是需要指定如何序列化它
class DataSetItemSerializer(serializers.HyperlinkedModelSerializer): image = Base64ImageField() dataset= serializers.PrimaryKeyRelatedField(many=False, read_only=True) class Meta: model = DataSetItem # Fields to expose via API fields = ('label', 'image', 'dataset') class DataSetSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = DataSet fields = ('name', 'process')
还需要创建ViewSet模型和数据表示之间的映射:
class DataSetItemViewSet(viewsets.ModelViewSet): queryset = DataSetItem.objects.all() serializer_class = DataSetItemSerializer class DataSetViewSet(viewsets.ModelViewSet): queryset = DataSet.objects.all() serializer_class = DataSetSerializer
最后需要定义所有路由并将viwset映射到url。这足以将模型用作api
router = routers.DefaultRouter()router.register(r'users', views.UserViewSet)router.register(r'datasetitem', views.DataSetItemViewSet)router.register(r'dataset', views.DataSetViewSet)router.register(r'test', views.TestItemViewSet, basename='test') # Wire up our API using automatic URL routing.# Additionally, we include login URLs for the browsable API.urlpatterns = [ url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),] urlpatterns += staticfiles_urlpatterns()
训练
算法非常简单:
从数据集中获取所有图像
将它们标准化并添加到带标签的列表中
创建模型在数据集模型中的指定方式
训练它
这是查询数据集项和加载图像的代码段:
def load_data(self, datasetid): self.stdout.write("loading images") train_data = [] images = DataSetItem.objects.filter(dataset=datasetid) labels = [x['label'] for x in DataSetItem.objects.values('label').distinct()] for image in images: self.stdout.write("Loading {0}".format(image.image)) image_path = image.image.path if "DS_Store" not in image_path: index=[x for x in range(len(labels)) if labels[x]==image.label] label = to_categorical([index,],len(labels)) img = Image.open(image_path) img = img.convert('L') img = img.resize((self.IMAGE_SIZE, self.IMAGE_SIZE), Image.ANTIALIAS) train_data.append([np.array(img), np.array(label[0])]) return train_data
看一眼:
labels = [x['label'] for x in DataSetItem.objects.values('label').distinct()]label = to_categorical([index,],len(labels))
这为所有标签分配了一个顺序,即["CAT","DOGS"]然后to_categorical将位置索引转换为单热表示。用简单的话说,这使得CAT = [1,0]和DOG = [0,1]
训练模型
model=Sequential() exec(dataset.process) model.add(Dense(len(labels), activation = 'softmax')) model.fit(training_images, training_labels, batch_size=dataset.batchSize, epochs=dataset.epochs, verbose=dataset.verbose)
请注意,dataset.process是在Web管理员中输入的python模型定义,可以根据需要进行调整。最后一层添加到用户回调之外,以确保与数组大小匹配。
拟合方法只是使用所有数据运行训练(。
最后存储训练有素的模型:
datasetToSave=DataSet.objects.get(pk=datasetid)datasetToSave.progress=100datasetToSave.model_labels=json.dumps(labels)temp_file_name=str(uuid.uuid4())+'.h5'model.save(temp_file_name)datasetToSave.model.save('weights.h5',File(open(temp_file_name, mode='rb')))os.remove(temp_file_name)datasetToSave.save()
请注意还保存标签顺序beacuse必须与模型相同才能匹配one-hot约定。
预测
有一种常见的方法,给定样本和数据集,检索模型,加载模型并进行预测。这是一段代码:
def predict(image_path,datasetid): dataset=DataSet.objects.get(pk=datasetid) modelpath=dataset.model.path model=load_model(modelpath) labels=json.loads(dataset.model_labels) img = Image.open(image_path) img = img.convert('L') img = img.resize((256, 256), Image.ANTIALIAS) result= model.predict(np.array(img).reshape(-1,256,256, 1)) max=result[0] idx=0 for i in range(1,len(result)): if max max=result[i] idx=i return labels[idx]
使用模型加载模型load_model(modelpath),标签来自数据库。模型预测输出作为值列表,选择较高的索引并用于检索在训练时分配给网络输出的正确标签。
关于图书
《深度学习之TensorFlow:入门、原理与进阶实战》和《Python带我起飞——入门、进阶、商业实战》两本图书是代码医生团队精心编著的 AI入门与提高的精品图书。配套资源丰富:配套视频、QQ读者群、实例源码、 配套论坛:http://bbs.aianaconda.com 。更多请见:https://www.aianaconda.com